kopia lustrzana https://github.com/simonw/datasette
Handle non-initials in permission_allowed_actor_restrictions, closes #1956
rodzic
1a3dcf4943
commit
e238df3959
|
@ -173,14 +173,20 @@ async def _resolve_metadata_view_permissions(datasette, actor, action, resource)
|
|||
|
||||
|
||||
@hookimpl(specname="permission_allowed")
|
||||
def permission_allowed_actor_restrictions(actor, action, resource):
|
||||
def permission_allowed_actor_restrictions(datasette, actor, action, resource):
|
||||
if actor is None:
|
||||
return None
|
||||
if "_r" not in actor:
|
||||
# No restrictions, so we have no opinion
|
||||
return None
|
||||
_r = actor.get("_r")
|
||||
action_initials = "".join([word[0] for word in action.split("-")])
|
||||
|
||||
# Does this action have an abbreviation?
|
||||
to_check = {action}
|
||||
permission = datasette.permissions.get(action)
|
||||
if permission and permission.abbr:
|
||||
to_check.add(permission.abbr)
|
||||
|
||||
# If _r is defined then we use those to further restrict the actor
|
||||
# Crucially, we only use this to say NO (return False) - we never
|
||||
# use it to return YES (True) because that might over-ride other
|
||||
|
@ -188,14 +194,14 @@ def permission_allowed_actor_restrictions(actor, action, resource):
|
|||
all_allowed = _r.get("a")
|
||||
if all_allowed is not None:
|
||||
assert isinstance(all_allowed, list)
|
||||
if action_initials in all_allowed:
|
||||
if to_check.intersection(all_allowed):
|
||||
return None
|
||||
# How about for the current database?
|
||||
if isinstance(resource, str):
|
||||
database_allowed = _r.get("d", {}).get(resource)
|
||||
if database_allowed is not None:
|
||||
assert isinstance(database_allowed, list)
|
||||
if action_initials in database_allowed:
|
||||
if to_check.intersection(database_allowed):
|
||||
return None
|
||||
# Or the current table? That's any time the resource is (database, table)
|
||||
if resource is not None and not isinstance(resource, str) and len(resource) == 2:
|
||||
|
@ -204,7 +210,7 @@ def permission_allowed_actor_restrictions(actor, action, resource):
|
|||
# TODO: What should this do for canned queries?
|
||||
if table_allowed is not None:
|
||||
assert isinstance(table_allowed, list)
|
||||
if action_initials in table_allowed:
|
||||
if to_check.intersection(table_allowed):
|
||||
return None
|
||||
# This action is not specifically allowed, so reject it
|
||||
return False
|
||||
|
|
|
@ -609,6 +609,22 @@ DEF = "USE_DEFAULT"
|
|||
"t2",
|
||||
False,
|
||||
),
|
||||
# non-abbreviations should work too
|
||||
({"id": "t", "_r": {"a": ["view-instance"]}}, "view-instance", None, None, DEF),
|
||||
(
|
||||
{"id": "t", "_r": {"d": {"one": ["view-database"]}}},
|
||||
"view-database",
|
||||
"one",
|
||||
None,
|
||||
DEF,
|
||||
),
|
||||
(
|
||||
{"id": "t", "_r": {"r": {"one": {"t1": ["view-table"]}}}},
|
||||
"view-table",
|
||||
"one",
|
||||
"t1",
|
||||
DEF,
|
||||
),
|
||||
),
|
||||
)
|
||||
async def test_actor_restricted_permissions(
|
||||
|
|
Ładowanie…
Reference in New Issue