mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
parent
968ce53689
commit
22d932fafc
5 changed files with 83 additions and 0 deletions
|
|
@ -33,6 +33,7 @@ from .views.special import (
|
|||
JsonDataView,
|
||||
PatternPortfolioView,
|
||||
AuthTokenView,
|
||||
LogoutView,
|
||||
PermissionsDebugView,
|
||||
MessagesDebugView,
|
||||
)
|
||||
|
|
@ -853,6 +854,9 @@ class Datasette:
|
|||
add_route(
|
||||
AuthTokenView.as_view(self), r"/-/auth-token$",
|
||||
)
|
||||
add_route(
|
||||
LogoutView.as_view(self), r"/-/logout$",
|
||||
)
|
||||
add_route(
|
||||
PermissionsDebugView.as_view(self), r"/-/permissions$",
|
||||
)
|
||||
|
|
|
|||
25
datasette/templates/logout.html
Normal file
25
datasette/templates/logout.html
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Log out{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
<p class="crumbs">
|
||||
<a href="{{ base_url }}">home</a>
|
||||
</p>
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>Log out</h1>
|
||||
|
||||
<p>You are logged in as <strong>{{ actor.id or actor }}</strong></p>
|
||||
|
||||
<form action="/-/logout" method="post">
|
||||
<div>
|
||||
<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
|
||||
<input type="submit" value="Log out">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -72,6 +72,23 @@ class AuthTokenView(BaseView):
|
|||
return Response("Invalid token", status=403)
|
||||
|
||||
|
||||
class LogoutView(BaseView):
|
||||
name = "logout"
|
||||
|
||||
def __init__(self, datasette):
|
||||
self.ds = datasette
|
||||
|
||||
async def get(self, request):
|
||||
if not request.actor:
|
||||
return Response.redirect("/")
|
||||
return await self.render(["logout.html"], request, {"actor": request.actor},)
|
||||
|
||||
async def post(self, request):
|
||||
response = Response.redirect("/")
|
||||
response.set_cookie("ds_actor", "", expires=0, max_age=0)
|
||||
return response
|
||||
|
||||
|
||||
class PermissionsDebugView(BaseView):
|
||||
name = "permissions_debug"
|
||||
|
||||
|
|
|
|||
|
|
@ -404,6 +404,14 @@ The resulting cookie will encode data that looks something like this:
|
|||
"e": "1jjSji"
|
||||
}
|
||||
|
||||
|
||||
.. _LogoutView:
|
||||
|
||||
The /-/logout page
|
||||
------------------
|
||||
|
||||
The page at ``/-/logout`` provides the ability to log out of a ``ds_actor`` cookie authentication session.
|
||||
|
||||
.. _permissions:
|
||||
|
||||
Built-in permissions
|
||||
|
|
|
|||
|
|
@ -47,3 +47,32 @@ def test_actor_cookie_that_expires(app_client, offset, expected):
|
|||
)
|
||||
response = app_client.get("/", cookies={"ds_actor": cookie})
|
||||
assert expected == app_client.ds._last_request.scope["actor"]
|
||||
|
||||
|
||||
def test_logout(app_client):
|
||||
response = app_client.get(
|
||||
"/-/logout", cookies={"ds_actor": app_client.actor_cookie({"id": "test"})}
|
||||
)
|
||||
assert 200 == response.status
|
||||
assert "<p>You are logged in as <strong>test</strong></p>" in response.text
|
||||
# Actors without an id get full serialization
|
||||
response2 = app_client.get(
|
||||
"/-/logout", cookies={"ds_actor": app_client.actor_cookie({"name2": "bob"})}
|
||||
)
|
||||
assert 200 == response2.status
|
||||
assert (
|
||||
"<p>You are logged in as <strong>{'name2': 'bob'}</strong></p>"
|
||||
in response2.text
|
||||
)
|
||||
# If logged out you get a redirect to /
|
||||
response3 = app_client.get("/-/logout", allow_redirects=False)
|
||||
assert 302 == response3.status
|
||||
# A POST to that page should log the user out
|
||||
response4 = app_client.post(
|
||||
"/-/logout",
|
||||
csrftoken_from=True,
|
||||
cookies={"ds_actor": app_client.actor_cookie({"id": "test"})},
|
||||
allow_redirects=False,
|
||||
)
|
||||
assert {"ds_actor": ""} == response4.cookies
|
||||
assert 302 == response4.status
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue