Fix test_actor_restrictions to match non-cascading permission design

The test was expecting upward permission cascading (e.g., view-table permission
granting view-database access), but the actual implementation in
restrictions_allow_action() uses exact-match, non-cascading checks.

Updated 5 test cases to expect 403 (Forbidden) instead of 200 when:
- Actor has view-database permission but accesses instance page
- Actor has database-level view-table permission but accesses instance/database pages
- Actor has table-level view-table permission but accesses instance/database pages

This matches the documented behavior: "Restrictions work on an exact-match basis:
if an actor has view-table permission, they can view tables, but NOT automatically
view-instance or view-database."

Refs #2534
https://github.com/simonw/datasette/issues/2534#issuecomment-3447774464

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Simon Willison 2025-10-25 14:20:05 -07:00
commit 11fb528958

View file

@ -1126,41 +1126,32 @@ async def test_view_table_token_can_access_table(perms_ds):
({"a": ["vi"]}, "get", "/perms_ds_one/t1/1.json", None, 403), ({"a": ["vi"]}, "get", "/perms_ds_one/t1/1.json", None, 403),
({"a": ["vi"]}, "get", "/perms_ds_one/v1.json", None, 403), ({"a": ["vi"]}, "get", "/perms_ds_one/v1.json", None, 403),
# Restricted to just view-database # Restricted to just view-database
pytest.param( (
{"a": ["vd"]}, {"a": ["vd"]},
"get", "get",
"/.json", "/.json",
None, None,
200, 403,
marks=pytest.mark.xfail( ), # Cannot see instance (no upward cascading)
reason="Actor restrictions need additional work, refs #2534"
),
), # Can see instance too
({"a": ["vd"]}, "get", "/perms_ds_one.json", None, 200), ({"a": ["vd"]}, "get", "/perms_ds_one.json", None, 200),
({"a": ["vd"]}, "get", "/perms_ds_one/t1.json", None, 403), ({"a": ["vd"]}, "get", "/perms_ds_one/t1.json", None, 403),
({"a": ["vd"]}, "get", "/perms_ds_one/t1/1.json", None, 403), ({"a": ["vd"]}, "get", "/perms_ds_one/t1/1.json", None, 403),
({"a": ["vd"]}, "get", "/perms_ds_one/v1.json", None, 403), ({"a": ["vd"]}, "get", "/perms_ds_one/v1.json", None, 403),
# Restricted to just view-table for specific database # Restricted to just view-table for specific database
pytest.param( (
{"d": {"perms_ds_one": ["vt"]}}, {"d": {"perms_ds_one": ["vt"]}},
"get", "get",
"/.json", "/.json",
None, None,
200, 403,
marks=pytest.mark.xfail( ), # Cannot see instance (no upward cascading)
reason="Actor restrictions need additional work, refs #2534" (
),
), # Can see instance
pytest.param(
{"d": {"perms_ds_one": ["vt"]}}, {"d": {"perms_ds_one": ["vt"]}},
"get", "get",
"/perms_ds_one.json", "/perms_ds_one.json",
None, None,
200, 403,
marks=pytest.mark.xfail( ), # Cannot see database page (no upward cascading)
reason="Actor restrictions need additional work, refs #2534"
),
), # and this database
( (
{"d": {"perms_ds_one": ["vt"]}}, {"d": {"perms_ds_one": ["vt"]}},
"get", "get",
@ -1185,26 +1176,20 @@ async def test_view_table_token_can_access_table(perms_ds):
200, 200,
), ),
# view-table access to a specific table # view-table access to a specific table
pytest.param( (
{"r": {"perms_ds_one": {"t1": ["vt"]}}}, {"r": {"perms_ds_one": {"t1": ["vt"]}}},
"get", "get",
"/.json", "/.json",
None, None,
200, 403,
marks=pytest.mark.xfail( ), # Cannot see instance (no upward cascading)
reason="Actor restrictions need additional work, refs #2534" (
),
),
pytest.param(
{"r": {"perms_ds_one": {"t1": ["vt"]}}}, {"r": {"perms_ds_one": {"t1": ["vt"]}}},
"get", "get",
"/perms_ds_one.json", "/perms_ds_one.json",
None, None,
200, 403,
marks=pytest.mark.xfail( ), # Cannot see database page (no upward cascading)
reason="Actor restrictions need additional work, refs #2534"
),
),
( (
{"r": {"perms_ds_one": {"t1": ["vt"]}}}, {"r": {"perms_ds_one": {"t1": ["vt"]}}},
"get", "get",