Update permissions documentation for new action system (#2551)

This commit is contained in:
Simon Willison 2025-10-30 17:59:54 -07:00 committed by GitHub
commit e4be95b16c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 177 additions and 168 deletions

View file

@ -342,33 +342,6 @@ If no plugins that implement that hook are installed, the default return value l
"2": {"id": "2"}
}
.. _datasette_permission_allowed:
await .permission_allowed(actor, action, resource=None, default=...)
--------------------------------------------------------------------
``actor`` - dictionary
The authenticated actor. This is usually ``request.actor``.
``action`` - string
The name of the action that is being permission checked.
``resource`` - string or tuple, optional
The resource, e.g. the name of the database, or a tuple of two strings containing the name of the database and the name of the table. Only some permissions apply to a resource.
``default`` - optional: True, False or None
What value should be returned by default if nothing provides an opinion on this permission check.
Set to ``True`` for default allow or ``False`` for default deny.
If not specified the ``default`` from the ``Permission()`` tuple that was registered using :ref:`plugin_register_permissions` will be used.
Check if the given actor has :ref:`permission <authentication_permissions>` to perform the given action on the given resource.
Some permission checks are carried out against :ref:`rules defined in datasette.yaml <authentication_permissions_config>`, while other custom permissions may be decided by plugins that implement the :ref:`plugin_hook_permission_allowed` plugin hook.
If neither ``metadata.json`` nor any of the plugins provide an answer to the permission query the ``default`` argument will be returned.
See :ref:`permissions` for a full list of permission actions included in Datasette core.
.. _datasette_allowed:
await .allowed(\*, action, resource, actor=None)
@ -385,8 +358,6 @@ await .allowed(\*, action, resource, actor=None)
This method checks if the given actor has permission to perform the given action on the given resource. All parameters must be passed as keyword arguments.
This is the modern resource-based permission checking method. It works with Resource objects that provide structured information about what is being accessed.
Example usage:
.. code-block:: python
@ -414,7 +385,50 @@ Example usage:
The method returns ``True`` if the permission is granted, ``False`` if denied.
For legacy string/tuple based permission checking, use :ref:`datasette_permission_allowed` instead.
.. _datasette_allowed_resources:
await .allowed_resources(action, actor=None, \*, parent=None, include_is_private=False)
---------------------------------------------------------------------------------------
Returns a list of ``Resource`` objects that the actor can access for the
specified action. Each returned object is an instance of the action's
``resource_class`` and may include a ``.private`` attribute (when
``include_is_private=True``) to indicate that anonymous actors would be denied
access.
Example::
tables = await datasette.allowed_resources(
"view-table", actor=request.actor, parent="fixtures"
)
for table in tables:
print(table.parent, table.child)
This method uses :ref:`datasette_allowed_resources_sql` under the hood and is an
efficient way to list the databases, tables or queries visible to a user.
.. _datasette_allowed_resources_with_reasons:
await .allowed_resources_with_reasons(action, actor=None)
---------------------------------------------------------
Returns a list of :class:`datasette.permissions.AllowedResource` tuples. Each tuple contains a ``Resource`` plus a list of strings describing the rules that granted access. This powers the debugging data shown by the ``/-/allowed`` endpoint and is helpful when building administrative tooling that needs to show why access was granted.
.. _datasette_allowed_resources_sql:
await .allowed_resources_sql(\*, action, actor=None, parent=None, include_is_private=False)
-------------------------------------------------------------------------------------------
Builds the SQL query that Datasette uses to determine which resources an actor may access for a specific action. Returns a ``(sql: str, params: dict)`` tuple that can be executed against the internal ``catalog_*`` database tables. ``parent`` can be used to limit results to a specific database, and ``include_is_private`` adds a column indicating whether anonymous users would be denied access to that resource.
Plugins that need to execute custom analysis over the raw allow/deny rules can use this helper to run the same query that powers the ``/-/allowed`` debugging interface.
The SQL query built by this method will return the following columns:
- ``parent``: The parent resource identifier (or NULL)
- ``child``: The child resource identifier (or NULL)
- ``reason``: The reason from the rule that granted access
- ``is_private``: (if ``include_is_private``) 1 if anonymous users cannot access, 0 otherwise
.. _datasette_ensure_permission:
@ -422,7 +436,7 @@ await .ensure_permission(action, resource=None, actor=None)
-----------------------------------------------------------
``action`` - string
The action to check. See :ref:`permissions` for a list of available actions.
The action to check. See :ref:`actions` for a list of available actions.
``resource`` - Resource object (optional)
The resource to check the permission against. Must be an instance of ``InstanceResource``, ``DatabaseResource``, or ``TableResource`` from the ``datasette.resources`` module. If omitted, defaults to ``InstanceResource()`` for instance-level permissions.