Express no opinion if allow block is missing

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
This commit is contained in:
Simon Willison 2020-06-30 15:49:06 -07:00
commit ab76eddf31

View file

@ -15,14 +15,14 @@ def permission_allowed(datasette, actor, action, resource):
elif action == "view-database": elif action == "view-database":
database_allow = datasette.metadata("allow", database=resource) database_allow = datasette.metadata("allow", database=resource)
if database_allow is None: if database_allow is None:
return True return None
return actor_matches_allow(actor, database_allow) return actor_matches_allow(actor, database_allow)
elif action == "view-table": elif action == "view-table":
database, table = resource database, table = resource
tables = datasette.metadata("tables", database=database) or {} tables = datasette.metadata("tables", database=database) or {}
table_allow = (tables.get(table) or {}).get("allow") table_allow = (tables.get(table) or {}).get("allow")
if table_allow is None: if table_allow is None:
return True return None
return actor_matches_allow(actor, table_allow) return actor_matches_allow(actor, table_allow)
elif action == "view-query": elif action == "view-query":
# Check if this query has a "allow" block in metadata # Check if this query has a "allow" block in metadata
@ -31,7 +31,7 @@ def permission_allowed(datasette, actor, action, resource):
assert query is not None assert query is not None
allow = query.get("allow") allow = query.get("allow")
if allow is None: if allow is None:
return True return None
return actor_matches_allow(actor, allow) return actor_matches_allow(actor, allow)
elif action == "execute-sql": elif action == "execute-sql":
# Use allow_sql block from database block, or from top-level # Use allow_sql block from database block, or from top-level
@ -39,7 +39,7 @@ def permission_allowed(datasette, actor, action, resource):
if database_allow_sql is None: if database_allow_sql is None:
database_allow_sql = datasette.metadata("allow_sql") database_allow_sql = datasette.metadata("allow_sql")
if database_allow_sql is None: if database_allow_sql is None:
return True return None
return actor_matches_allow(actor, database_allow_sql) return actor_matches_allow(actor, database_allow_sql)
return inner return inner