kopia lustrzana https://github.com/simonw/datasette
Logout link in nav, refs #875
rodzic
51427323e6
commit
2115d7e345
|
@ -44,6 +44,7 @@ from .database import Database, QueryInterrupted
|
||||||
from .utils import (
|
from .utils import (
|
||||||
async_call_with_supported_arguments,
|
async_call_with_supported_arguments,
|
||||||
call_with_supported_arguments,
|
call_with_supported_arguments,
|
||||||
|
display_actor,
|
||||||
escape_css_string,
|
escape_css_string,
|
||||||
escape_sqlite,
|
escape_sqlite,
|
||||||
format_bytes,
|
format_bytes,
|
||||||
|
@ -736,6 +737,8 @@ class Datasette:
|
||||||
template_context = {
|
template_context = {
|
||||||
**context,
|
**context,
|
||||||
**{
|
**{
|
||||||
|
"actor": request.actor if request else None,
|
||||||
|
"display_actor": display_actor,
|
||||||
"app_css_hash": self.app_css_hash(),
|
"app_css_hash": self.app_css_hash(),
|
||||||
"zip": zip,
|
"zip": zip,
|
||||||
"body_scripts": body_scripts,
|
"body_scripts": body_scripts,
|
||||||
|
|
|
@ -100,6 +100,14 @@ table a:visited {
|
||||||
.hd .crumbs {
|
.hd .crumbs {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
.hd .logout {
|
||||||
|
float: right;
|
||||||
|
text-align: right;
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
.hd .logout form {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
.ft {
|
.ft {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
padding: 0.5em 1em 0 1em;
|
padding: 0.5em 1em 0 1em;
|
||||||
|
@ -367,3 +375,13 @@ p.zero-results {
|
||||||
border: 1px solid red;
|
border: 1px solid red;
|
||||||
background-color: pink;
|
background-color: pink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.button-as-link {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
color: blue;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,17 @@
|
||||||
</head>
|
</head>
|
||||||
<body class="{% block body_class %}{% endblock %}">
|
<body class="{% block body_class %}{% endblock %}">
|
||||||
|
|
||||||
<nav class="hd">{% block nav %}{% endblock %}</nav>
|
<nav class="hd">{% block nav %}
|
||||||
|
{% if actor %}
|
||||||
|
<div class="logout">
|
||||||
|
<strong>{{ display_actor(actor) }}</strong> ·
|
||||||
|
<form action="/-/logout" method="post">
|
||||||
|
<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
|
||||||
|
<button class="button-as-link">Log out</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}</nav>
|
||||||
|
|
||||||
<div class="bd">
|
<div class="bd">
|
||||||
{% block messages %}
|
{% block messages %}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
<h1>Log out</h1>
|
<h1>Log out</h1>
|
||||||
|
|
||||||
<p>You are logged in as <strong>{{ actor.id or actor }}</strong></p>
|
<p>You are logged in as <strong>{{ display_actor(actor) }}</strong></p>
|
||||||
|
|
||||||
<form action="/-/logout" method="post">
|
<form action="/-/logout" method="post">
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -924,3 +924,10 @@ def resolve_env_secrets(config, environ):
|
||||||
return [resolve_env_secrets(value, environ) for value in config]
|
return [resolve_env_secrets(value, environ) for value in config]
|
||||||
else:
|
else:
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def display_actor(actor):
|
||||||
|
for key in ("display", "name", "username", "login", "id"):
|
||||||
|
if actor.get(key):
|
||||||
|
return actor[key]
|
||||||
|
return str(actor)
|
||||||
|
|
|
@ -78,3 +78,17 @@ def test_logout(app_client):
|
||||||
# Should also have set a message
|
# Should also have set a message
|
||||||
messages = app_client.ds.unsign(response4.cookies["ds_messages"], "messages")
|
messages = app_client.ds.unsign(response4.cookies["ds_messages"], "messages")
|
||||||
assert [["You are now logged out", 2]] == messages
|
assert [["You are now logged out", 2]] == messages
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("path", ["/", "/fixtures", "/fixtures/facetable"])
|
||||||
|
def test_logout_button_in_navigation(app_client, path):
|
||||||
|
response = app_client.get(
|
||||||
|
path, cookies={"ds_actor": app_client.actor_cookie({"id": "test"})}
|
||||||
|
)
|
||||||
|
anon_response = app_client.get(path)
|
||||||
|
for fragment in (
|
||||||
|
"<strong>test</strong> ·",
|
||||||
|
'<form action="/-/logout" method="post">',
|
||||||
|
):
|
||||||
|
assert fragment in response.text
|
||||||
|
assert fragment not in anon_response.text
|
||||||
|
|
|
@ -517,3 +517,22 @@ def test_actor_matches_allow(actor, allow, expected):
|
||||||
)
|
)
|
||||||
def test_resolve_env_secrets(config, expected):
|
def test_resolve_env_secrets(config, expected):
|
||||||
assert expected == utils.resolve_env_secrets(config, {"FOO": "x"})
|
assert expected == utils.resolve_env_secrets(config, {"FOO": "x"})
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"actor,expected",
|
||||||
|
[
|
||||||
|
({"id": "blah"}, "blah"),
|
||||||
|
({"id": "blah", "login": "l"}, "l"),
|
||||||
|
({"id": "blah", "login": "l"}, "l"),
|
||||||
|
({"id": "blah", "login": "l", "username": "u"}, "u"),
|
||||||
|
({"login": "l", "name": "n"}, "n"),
|
||||||
|
(
|
||||||
|
{"id": "blah", "login": "l", "username": "u", "name": "n", "display": "d"},
|
||||||
|
"d",
|
||||||
|
),
|
||||||
|
({"weird": "shape"}, "{'weird': 'shape'}"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_display_actor(actor, expected):
|
||||||
|
assert expected == utils.display_actor(actor)
|
||||||
|
|
Ładowanie…
Reference in New Issue