mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Cascading view permissions, closes #832
- If you have table permission but not database permission you can now view the table page - New BaseView.check_permissions() method
This commit is contained in:
parent
ab76eddf31
commit
d6e03b0430
5 changed files with 108 additions and 12 deletions
|
|
@ -69,6 +69,29 @@ class BaseView:
|
|||
if not ok:
|
||||
raise Forbidden(action)
|
||||
|
||||
async def check_permissions(self, request, permissions):
|
||||
"permissions is a list of (action, resource) tuples or 'action' strings"
|
||||
for permission in permissions:
|
||||
if isinstance(permission, str):
|
||||
action = permission
|
||||
resource = None
|
||||
elif isinstance(permission, (tuple, list)) and len(permission) == 2:
|
||||
action, resource = permission
|
||||
else:
|
||||
assert (
|
||||
False
|
||||
), "permission should be string or tuple of two items: {}".format(
|
||||
repr(permission)
|
||||
)
|
||||
ok = await self.ds.permission_allowed(
|
||||
request.actor, action, resource=resource, default=None,
|
||||
)
|
||||
if ok is not None:
|
||||
if ok:
|
||||
return
|
||||
else:
|
||||
raise Forbidden(action)
|
||||
|
||||
def database_url(self, database):
|
||||
db = self.ds.databases[database]
|
||||
base_url = self.ds.config("base_url")
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ class DatabaseView(DataView):
|
|||
name = "database"
|
||||
|
||||
async def data(self, request, database, hash, default_labels=False, _size=None):
|
||||
await self.check_permission(request, "view-instance")
|
||||
await self.check_permission(request, "view-database", database)
|
||||
await self.check_permissions(
|
||||
request, [("view-database", database), "view-instance",],
|
||||
)
|
||||
metadata = (self.ds.metadata("databases") or {}).get(database, {})
|
||||
self.ds.update_with_inherited_metadata(metadata)
|
||||
|
||||
|
|
@ -88,7 +89,7 @@ class DatabaseView(DataView):
|
|||
"views": views,
|
||||
"queries": canned_queries,
|
||||
"private": not await self.ds.permission_allowed(
|
||||
None, "view-database", database
|
||||
None, "view-database", database, default=True
|
||||
),
|
||||
"allow_execute_sql": await self.ds.permission_allowed(
|
||||
request.actor, "execute-sql", database, default=True
|
||||
|
|
@ -150,17 +151,23 @@ class QueryView(DataView):
|
|||
if "_shape" in params:
|
||||
params.pop("_shape")
|
||||
|
||||
# Respect canned query permissions
|
||||
await self.check_permission(request, "view-instance")
|
||||
await self.check_permission(request, "view-database", database)
|
||||
private = False
|
||||
if canned_query:
|
||||
await self.check_permission(request, "view-query", (database, canned_query))
|
||||
# Respect canned query permissions
|
||||
await self.check_permissions(
|
||||
request,
|
||||
[
|
||||
("view-query", (database, canned_query)),
|
||||
("view-database", database),
|
||||
"view-instance",
|
||||
],
|
||||
)
|
||||
private = not await self.ds.permission_allowed(
|
||||
None, "view-query", (database, canned_query), default=True
|
||||
)
|
||||
else:
|
||||
await self.check_permission(request, "execute-sql", database)
|
||||
|
||||
# Extract any :named parameters
|
||||
named_parameters = named_parameters or self.re_named_parameter.findall(sql)
|
||||
named_parameter_values = {
|
||||
|
|
|
|||
|
|
@ -269,9 +269,14 @@ class TableView(RowTableShared):
|
|||
if not is_view and not table_exists:
|
||||
raise NotFound("Table not found: {}".format(table))
|
||||
|
||||
await self.check_permission(request, "view-instance")
|
||||
await self.check_permission(request, "view-database", database)
|
||||
await self.check_permission(request, "view-table", (database, table))
|
||||
await self.check_permissions(
|
||||
request,
|
||||
[
|
||||
("view-table", (database, table)),
|
||||
("view-database", database),
|
||||
"view-instance",
|
||||
],
|
||||
)
|
||||
|
||||
private = not await self.ds.permission_allowed(
|
||||
None, "view-table", (database, table), default=True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue