ds.allowed() is now keyword-argument only, closes #2519

This commit is contained in:
Simon Willison 2025-10-23 09:25:33 -07:00
commit 159b9f3fec
2 changed files with 31 additions and 12 deletions

View file

@ -1369,6 +1369,7 @@ class Datasette:
async def allowed(
self,
*,
action: str,
resource: "Resource",
actor: dict | None = None,
@ -1382,9 +1383,9 @@ class Datasette:
Example:
from datasette.resources import TableResource
can_view = await datasette.allowed(
"view-table",
TableResource(database="analytics", table="users"),
actor
action="view-table",
resource=TableResource(database="analytics", table="users"),
actor=actor
)
"""
from datasette.utils.actions_sql import check_permission_for_resource

View file

@ -113,13 +113,19 @@ async def test_allowed_specific_resource(test_ds):
# Check specific resources using allowed()
# This should use SQL WHERE clause, not fetch all resources
assert await test_ds.allowed(
"view-table", TableResource("analytics", "users"), actor
action="view-table",
resource=TableResource("analytics", "users"),
actor=actor,
)
assert await test_ds.allowed(
"view-table", TableResource("analytics", "events"), actor
action="view-table",
resource=TableResource("analytics", "events"),
actor=actor,
)
assert not await test_ds.allowed(
"view-table", TableResource("production", "orders"), actor
action="view-table",
resource=TableResource("production", "orders"),
actor=actor,
)
finally:
@ -200,10 +206,14 @@ async def test_child_deny_overrides_parent_allow(test_ds):
# Verify with allowed() method
assert await test_ds.allowed(
"view-table", TableResource("analytics", "users"), actor
action="view-table",
resource=TableResource("analytics", "users"),
actor=actor,
)
assert not await test_ds.allowed(
"view-table", TableResource("analytics", "sensitive"), actor
action="view-table",
resource=TableResource("analytics", "sensitive"),
actor=actor,
)
finally:
@ -240,10 +250,14 @@ async def test_child_allow_overrides_parent_deny(test_ds):
# Verify with allowed() method
assert await test_ds.allowed(
"view-table", TableResource("production", "orders"), actor
action="view-table",
resource=TableResource("production", "orders"),
actor=actor,
)
assert not await test_ds.allowed(
"view-table", TableResource("production", "customers"), actor
action="view-table",
resource=TableResource("production", "customers"),
actor=actor,
)
finally:
@ -301,10 +315,14 @@ async def test_sql_does_filtering_not_python(test_ds):
# allowed() should execute a targeted SQL query
# NOT fetch all resources and filter in Python
assert await test_ds.allowed(
"view-table", TableResource("analytics", "users"), actor
action="view-table",
resource=TableResource("analytics", "users"),
actor=actor,
)
assert not await test_ds.allowed(
"view-table", TableResource("analytics", "events"), actor
action="view-table",
resource=TableResource("analytics", "events"),
actor=actor,
)
# allowed_resources() should also use SQL filtering