kopia lustrzana https://github.com/simonw/datasette
actor_from_request for dstok_ tokens, refs #1852
rodzic
7ab091e8ef
commit
b29e487bc3
|
@ -1,5 +1,7 @@
|
|||
from datasette import hookimpl
|
||||
from datasette.utils import actor_matches_allow
|
||||
import itsdangerous
|
||||
import time
|
||||
|
||||
|
||||
@hookimpl(tryfirst=True)
|
||||
|
@ -45,3 +47,26 @@ def permission_allowed(datasette, actor, action, resource):
|
|||
return actor_matches_allow(actor, database_allow_sql)
|
||||
|
||||
return inner
|
||||
|
||||
|
||||
@hookimpl
|
||||
def actor_from_request(datasette, request):
|
||||
prefix = "dstok_"
|
||||
authorization = request.headers.get("authorization")
|
||||
if not authorization:
|
||||
return None
|
||||
if not authorization.startswith("Bearer "):
|
||||
return None
|
||||
token = authorization[len("Bearer ") :]
|
||||
if not token.startswith(prefix):
|
||||
return None
|
||||
token = token[len(prefix) :]
|
||||
try:
|
||||
decoded = datasette.unsign(token, namespace="token")
|
||||
except itsdangerous.BadSignature:
|
||||
return None
|
||||
expires_at = decoded.get("e")
|
||||
if expires_at is not None:
|
||||
if expires_at < time.time():
|
||||
return None
|
||||
return {"id": decoded["a"], "dstok": True}
|
||||
|
|
|
@ -62,6 +62,7 @@ class TestClient:
|
|||
method="GET",
|
||||
cookies=None,
|
||||
if_none_match=None,
|
||||
headers=None,
|
||||
):
|
||||
return await self._request(
|
||||
path=path,
|
||||
|
@ -70,6 +71,7 @@ class TestClient:
|
|||
method=method,
|
||||
cookies=cookies,
|
||||
if_none_match=if_none_match,
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
@async_to_sync
|
||||
|
|
|
@ -178,3 +178,35 @@ def test_auth_create_token(app_client, post_data, errors, expected_duration):
|
|||
else:
|
||||
about_right = int(time.time()) + expected_duration
|
||||
assert about_right - 2 < details["e"] < about_right + 2
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"scenario,should_work",
|
||||
(
|
||||
("no_token", False),
|
||||
("invalid_token", False),
|
||||
("expired_token", False),
|
||||
("valid_unlimited_token", True),
|
||||
("valid_expiring_token", True),
|
||||
),
|
||||
)
|
||||
def test_auth_with_dstok_token(app_client, scenario, should_work):
|
||||
token = None
|
||||
if scenario == "valid_unlimited_token":
|
||||
token = app_client.ds.sign({"a": "test"}, "token")
|
||||
elif scenario == "valid_expiring_token":
|
||||
token = app_client.ds.sign({"a": "test", "e": int(time.time()) + 1000}, "token")
|
||||
elif scenario == "expired_token":
|
||||
token = app_client.ds.sign({"a": "test", "e": int(time.time()) - 1000}, "token")
|
||||
elif scenario == "invalid_token":
|
||||
token = "invalid"
|
||||
if token:
|
||||
token = "dstok_{}".format(token)
|
||||
headers = {}
|
||||
if token:
|
||||
headers["Authorization"] = "Bearer {}".format(token)
|
||||
response = app_client.get("/-/actor.json", headers=headers)
|
||||
if should_work:
|
||||
assert response.json == {"actor": {"id": "test", "dstok": True}}
|
||||
else:
|
||||
assert response.json == {"actor": None}
|
||||
|
|
Ładowanie…
Reference in New Issue