mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Default permission policy was returning True by default for permission checks - which means that if allow was not defined for a level it would be treated as a passing check. This is better: we now return None of the allow block is not defined, which means 'I have no opinion on this' and allows other code to make its own decisions. Added while working on #832
45 lines
1.9 KiB
Python
45 lines
1.9 KiB
Python
from datasette import hookimpl
|
|
from datasette.utils import actor_matches_allow
|
|
|
|
|
|
@hookimpl(tryfirst=True)
|
|
def permission_allowed(datasette, actor, action, resource):
|
|
async def inner():
|
|
if action == "permissions-debug":
|
|
if actor and actor.get("id") == "root":
|
|
return True
|
|
elif action == "view-instance":
|
|
allow = datasette.metadata("allow")
|
|
if allow is not None:
|
|
return actor_matches_allow(actor, allow)
|
|
elif action == "view-database":
|
|
database_allow = datasette.metadata("allow", database=resource)
|
|
if database_allow is None:
|
|
return None
|
|
return actor_matches_allow(actor, database_allow)
|
|
elif action == "view-table":
|
|
database, table = resource
|
|
tables = datasette.metadata("tables", database=database) or {}
|
|
table_allow = (tables.get(table) or {}).get("allow")
|
|
if table_allow is None:
|
|
return None
|
|
return actor_matches_allow(actor, table_allow)
|
|
elif action == "view-query":
|
|
# Check if this query has a "allow" block in metadata
|
|
database, query_name = resource
|
|
query = await datasette.get_canned_query(database, query_name, actor)
|
|
assert query is not None
|
|
allow = query.get("allow")
|
|
if allow is None:
|
|
return None
|
|
return actor_matches_allow(actor, allow)
|
|
elif action == "execute-sql":
|
|
# Use allow_sql block from database block, or from top-level
|
|
database_allow_sql = datasette.metadata("allow_sql", database=resource)
|
|
if database_allow_sql is None:
|
|
database_allow_sql = datasette.metadata("allow_sql")
|
|
if database_allow_sql is None:
|
|
return None
|
|
return actor_matches_allow(actor, database_allow_sql)
|
|
|
|
return inner
|