-
-
Notifications
You must be signed in to change notification settings - Fork 813
Description
Currently Datasette core can issue API tokens as signed values:
Lines 716 to 753 in 6a2c27b
| def create_token( | |
| self, | |
| actor_id: str, | |
| *, | |
| expires_after: int | None = None, | |
| restrict_all: Iterable[str] | None = None, | |
| restrict_database: Dict[str, Iterable[str]] | None = None, | |
| restrict_resource: Dict[str, Dict[str, Iterable[str]]] | None = None, | |
| ): | |
| token = {"a": actor_id, "t": int(time.time())} | |
| if expires_after: | |
| token["d"] = expires_after | |
| def abbreviate_action(action): | |
| # rename to abbr if possible | |
| action_obj = self.actions.get(action) | |
| if not action_obj: | |
| return action | |
| return action_obj.abbr or action | |
| if expires_after: | |
| token["d"] = expires_after | |
| if restrict_all or restrict_database or restrict_resource: | |
| token["_r"] = {} | |
| if restrict_all: | |
| token["_r"]["a"] = [abbreviate_action(a) for a in restrict_all] | |
| if restrict_database: | |
| token["_r"]["d"] = {} | |
| for database, actions in restrict_database.items(): | |
| token["_r"]["d"][database] = [abbreviate_action(a) for a in actions] | |
| if restrict_resource: | |
| token["_r"]["r"] = {} | |
| for database, resources in restrict_resource.items(): | |
| for resource, actions in resources.items(): | |
| token["_r"]["r"].setdefault(database, {})[resource] = [ | |
| abbreviate_action(a) for a in actions | |
| ] | |
| return "dstok_{}".format(self.sign(token, namespace="token")) |
And then datasette-auth-tokens can issue API tokens that are database-backed (and can hence be audited and revoked): https://github.com/simonw/datasette-auth-tokens
Problem: I'm building a datasette-oauth plugin and it needs to be able to issue tokens. I'd like it to be able to use signed tokens by default but, if dataette-auth-tokens is configured, I'd like them to be database-backed tokens instead.
I tried figuring out how to do that with a new hook in datasette-auth-tokens itself but it felt messy, because I didn't want datasette-oauth to have to depend on that plugin.
So it needs to be a new hook in core, with the existing create_token() mechanism as a default plugin hook implementation.