New plugin hook: canned_queries(), refs #852

This commit is contained in:
Simon Willison 2020-06-18 16:22:33 -07:00
commit 6c26345836
12 changed files with 203 additions and 50 deletions

View file

@ -4,41 +4,42 @@ from datasette.utils import actor_matches_allow
@hookimpl(tryfirst=True)
def permission_allowed(datasette, actor, action, resource):
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:
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 True
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 True
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 True
return actor_matches_allow(actor, allow)
elif action == "view-database":
database_allow = datasette.metadata("allow", database=resource)
if database_allow is None:
return True
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 True
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
queries_metadata = datasette.metadata("queries", database=database)
assert query_name in queries_metadata
if isinstance(queries_metadata[query_name], str):
return True
allow = queries_metadata[query_name].get("allow")
if allow is None:
return True
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 True
return actor_matches_allow(actor, database_allow_sql)
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 True
return actor_matches_allow(actor, database_allow_sql)
return inner