From 177059284dc953e6c76f86213aa470db2ff3eaca Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 8 Jun 2020 10:05:32 -0700 Subject: [PATCH] New request.actor property, refs #811 --- datasette/app.py | 2 +- datasette/utils/asgi.py | 4 ++++ datasette/views/base.py | 2 +- datasette/views/database.py | 4 ++-- datasette/views/index.py | 2 +- datasette/views/special.py | 2 +- docs/authentication.rst | 2 ++ docs/internals.rst | 5 ++++- 8 files changed, 16 insertions(+), 7 deletions(-) diff --git a/datasette/app.py b/datasette/app.py index 23c293c9..87e542c1 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -667,7 +667,7 @@ class Datasette: return d def _actor(self, request): - return {"actor": request.scope.get("actor", None)} + return {"actor": request.actor} def table_metadata(self, database, table): "Fetch table-specific metadata." diff --git a/datasette/utils/asgi.py b/datasette/utils/asgi.py index fa78c8df..bca9c9ab 100644 --- a/datasette/utils/asgi.py +++ b/datasette/utils/asgi.py @@ -74,6 +74,10 @@ class Request: def args(self): return MultiParams(parse_qs(qs=self.query_string)) + @property + def actor(self): + return self.scope.get("actor", None) + async def post_vars(self): body = [] body = b"" diff --git a/datasette/views/base.py b/datasette/views/base.py index 9c2cbbcc..000d354b 100644 --- a/datasette/views/base.py +++ b/datasette/views/base.py @@ -68,7 +68,7 @@ class BaseView(AsgiView): self, request, action, resource_type=None, resource_identifier=None ): ok = await self.ds.permission_allowed( - request.scope.get("actor"), + request.actor, action, resource_type=resource_type, resource_identifier=resource_identifier, diff --git a/datasette/views/database.py b/datasette/views/database.py index 2d7e6b31..dee6c9c8 100644 --- a/datasette/views/database.py +++ b/datasette/views/database.py @@ -45,7 +45,7 @@ class DatabaseView(DataView): for table in table_counts: visible, private = await check_visibility( self.ds, - request.scope.get("actor"), + request.actor, "view-table", "table", (database, table), @@ -71,7 +71,7 @@ class DatabaseView(DataView): for query in self.ds.get_canned_queries(database): visible, private = await check_visibility( self.ds, - request.scope.get("actor"), + request.actor, "view-query", "query", (database, query["name"]), diff --git a/datasette/views/index.py b/datasette/views/index.py index 8cbe28f0..609bfa6a 100644 --- a/datasette/views/index.py +++ b/datasette/views/index.py @@ -26,7 +26,7 @@ class IndexView(BaseView): databases = [] for name, db in self.ds.databases.items(): visible, private = await check_visibility( - self.ds, request.scope.get("actor"), "view-database", "database", name, + self.ds, request.actor, "view-database", "database", name, ) if not visible: continue diff --git a/datasette/views/special.py b/datasette/views/special.py index 37c04697..b8bd57c6 100644 --- a/datasette/views/special.py +++ b/datasette/views/special.py @@ -86,7 +86,7 @@ class PermissionsDebugView(BaseView): async def get(self, request): if not await self.ds.permission_allowed( - request.scope.get("actor"), "permissions-debug" + request.actor, "permissions-debug" ): return Response("Permission denied", status=403) return await self.render( diff --git a/docs/authentication.rst b/docs/authentication.rst index 2caca66f..bda6a0b7 100644 --- a/docs/authentication.rst +++ b/docs/authentication.rst @@ -140,6 +140,8 @@ Plugins that wish to implement the same permissions scheme as canned queries can actor_matches_allow({"id": "root"}, {"id": "*"}) # returns True +The currently authenticated actor is made available to plugins as ``request.actor``. + .. _PermissionsDebugView: Permissions Debug diff --git a/docs/internals.rst b/docs/internals.rst index 25b2d875..7498f017 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -42,6 +42,9 @@ The request object is passed to various plugin hooks. It represents an incoming ``.args`` - MultiParams An object representing the parsed querystring parameters, see below. +``.actor`` - dictionary (str -> Any) or None + The currently authenticated actor (see :ref:`actors `), or ``None`` if the request is unauthenticated. + The object also has one awaitable method: ``await request.post_vars()`` - dictionary @@ -122,7 +125,7 @@ await .permission_allowed(actor, action, resource_type=None, resource_identifier ----------------------------------------------------------------------------------------------------- ``actor`` - dictionary - The authenticated actor. This is usually ``request.scope.get("actor")``. + The authenticated actor. This is usually ``request.actor``. ``action`` - string The name of the action that is being permission checked.