New allowed_resources_sql plugin hook and debug tools (#2505)

* allowed_resources_sql plugin hook and infrastructure
* New methods for checking permissions with the new system
* New /-/allowed and /-/check and /-/rules special endpoints

Still needs to be integrated more deeply into Datasette, especially for listing visible tables.

Refs: #2502

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Simon Willison 2025-10-08 14:27:51 -07:00 committed by GitHub
commit 27084caa04
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 3381 additions and 27 deletions

View file

@ -12,8 +12,9 @@ from datasette.app import Datasette
from datasette import cli, hookimpl, Permission
from datasette.filters import FilterArguments
from datasette.plugins import get_plugins, DEFAULT_PLUGINS, pm
from datasette.utils.permissions import PluginSQL
from datasette.utils.sqlite import sqlite3
from datasette.utils import StartupError
from datasette.utils import StartupError, await_me_maybe
from jinja2 import ChoiceLoader, FileSystemLoader
import base64
import datetime
@ -701,6 +702,29 @@ async def test_hook_permission_allowed(action, expected):
pm.unregister(name="undo_register_extras")
@pytest.mark.asyncio
async def test_hook_permission_resources_sql():
ds = Datasette()
await ds.invoke_startup()
collected = []
for block in pm.hook.permission_resources_sql(
datasette=ds,
actor={"id": "alice"},
action="view-table",
):
block = await await_me_maybe(block)
if block is None:
continue
if isinstance(block, (list, tuple)):
collected.extend(block)
else:
collected.append(block)
assert collected
assert all(isinstance(item, PluginSQL) for item in collected)
@pytest.mark.asyncio
async def test_actor_json(ds_client):
assert (await ds_client.get("/-/actor.json")).json() == {"actor": None}