Remove permission_allowed hook entirely, refs #2528

The permission_allowed hook has been fully replaced by permission_resources_sql.
This commit removes:
- hookspec definition from hookspecs.py
- 4 implementations from default_permissions.py
- implementations from test plugins (my_plugin.py, my_plugin_2.py)
- hook monitoring infrastructure from conftest.py
- references from fixtures.py
- Also fixes test_get_permission to use ds.get_action() instead of ds.get_permission()
- Removes 5th column (source_plugin) from PermissionSQL queries

This completes the migration to the SQL-based permission system.
This commit is contained in:
Simon Willison 2025-10-25 08:52:48 -07:00
commit 5feb5fcf5d
7 changed files with 23 additions and 159 deletions

View file

@ -214,29 +214,6 @@ def asgi_wrapper():
return wrap
@hookimpl
def permission_allowed(actor, action):
if action == "this_is_allowed":
return True
elif action == "this_is_denied":
return False
elif action == "view-database-download":
return actor.get("can_download") if actor else None
# Special permissions for latest.datasette.io demos
# See https://github.com/simonw/todomvc-datasette/issues/2
actor_id = None
if actor:
actor_id = actor.get("id")
if actor_id == "todomvc" and action in (
"insert-row",
"create-table",
"drop-table",
"delete-row",
"update-row",
):
return True
@hookimpl
def register_routes():
async def one(datasette):
@ -549,24 +526,30 @@ def permission_resources_sql(datasette, actor, action):
# Handle test actions used in test_hook_permission_allowed
if action == "this_is_allowed":
sql = "SELECT NULL AS parent, NULL AS child, 1 AS allow, 'test plugin allows this_is_allowed' AS reason, 'my_plugin' AS source_plugin"
sql = "SELECT NULL AS parent, NULL AS child, 1 AS allow, 'test plugin allows this_is_allowed' AS reason"
return PermissionSQL(source="my_plugin", sql=sql, params={})
elif action == "this_is_denied":
sql = "SELECT NULL AS parent, NULL AS child, 0 AS allow, 'test plugin denies this_is_denied' AS reason, 'my_plugin' AS source_plugin"
sql = "SELECT NULL AS parent, NULL AS child, 0 AS allow, 'test plugin denies this_is_denied' AS reason"
return PermissionSQL(source="my_plugin", sql=sql, params={})
elif action == "this_is_allowed_async":
sql = "SELECT NULL AS parent, NULL AS child, 1 AS allow, 'test plugin allows this_is_allowed_async' AS reason, 'my_plugin' AS source_plugin"
sql = "SELECT NULL AS parent, NULL AS child, 1 AS allow, 'test plugin allows this_is_allowed_async' AS reason"
return PermissionSQL(source="my_plugin", sql=sql, params={})
elif action == "this_is_denied_async":
sql = "SELECT NULL AS parent, NULL AS child, 0 AS allow, 'test plugin denies this_is_denied_async' AS reason, 'my_plugin' AS source_plugin"
sql = "SELECT NULL AS parent, NULL AS child, 0 AS allow, 'test plugin denies this_is_denied_async' AS reason"
return PermissionSQL(source="my_plugin", sql=sql, params={})
elif action == "view-database-download":
# Return rule based on actor's can_download permission
if actor and actor.get("can_download"):
sql = "SELECT NULL AS parent, NULL AS child, 1 AS allow, 'actor has can_download' AS reason, 'my_plugin' AS source_plugin"
sql = "SELECT NULL AS parent, NULL AS child, 1 AS allow, 'actor has can_download' AS reason"
else:
return None # No opinion
return PermissionSQL(source="my_plugin", sql=sql, params={})
elif action == "view-database":
# Also grant view-database if actor has can_download (needed for download to work)
if actor and actor.get("can_download"):
sql = "SELECT NULL AS parent, NULL AS child, 1 AS allow, 'actor has can_download, grants view-database' AS reason"
return PermissionSQL(source="my_plugin", sql=sql, params={})
return None
elif action in (
"insert-row",
"create-table",
@ -577,7 +560,7 @@ def permission_resources_sql(datasette, actor, action):
# Special permissions for latest.datasette.io demos
actor_id = actor.get("id") if actor else None
if actor_id == "todomvc":
sql = f"SELECT NULL AS parent, NULL AS child, 1 AS allow, 'todomvc actor allowed for {action}' AS reason, 'my_plugin' AS source_plugin"
sql = f"SELECT NULL AS parent, NULL AS child, 1 AS allow, 'todomvc actor allowed for {action}' AS reason"
return PermissionSQL(source="my_plugin", sql=sql, params={})
return None

View file

@ -113,24 +113,6 @@ def actor_from_request(datasette, request):
return inner
@hookimpl
def permission_allowed(datasette, actor, action):
# Testing asyncio version of permission_allowed
async def inner():
assert (
2
== (
await datasette.get_internal_database().execute("select 1 + 1")
).first()[0]
)
if action == "this_is_allowed_async":
return True
elif action == "this_is_denied_async":
return False
return inner
@hookimpl
def prepare_jinja2_environment(env, datasette):
env.filters["format_numeric"] = lambda s: f"{float(s):,.0f}"