mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Refactor check_visibility() to use Resource objects, refs #2537
Updated check_visibility() method signature to accept Resource objects (DatabaseResource, TableResource, QueryResource) instead of plain strings and tuples. Changes: - Updated check_visibility() signature to only accept Resource objects - Added validation with helpful error message for incorrect types - Updated all check_visibility() calls throughout the codebase: - datasette/views/database.py: Use DatabaseResource and QueryResource - datasette/views/special.py: Use DatabaseResource and TableResource - datasette/views/row.py: Use TableResource - datasette/views/table.py: Use TableResource - datasette/app.py: Use TableResource in expand_foreign_keys - Updated tests to use Resource objects - Updated documentation in docs/internals.rst: - Removed outdated permissions parameter - Updated examples to use Resource objects 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
653475edde
commit
95286fbb60
7 changed files with 34 additions and 47 deletions
|
|
@ -1072,7 +1072,7 @@ class Datasette:
|
|||
self,
|
||||
actor: dict,
|
||||
action: str,
|
||||
resource: Optional[Union[str, Tuple[str, str]]] = None,
|
||||
resource: Optional["Resource"] = None,
|
||||
):
|
||||
"""
|
||||
Check if actor can see a resource and if it's private.
|
||||
|
|
@ -1081,26 +1081,22 @@ class Datasette:
|
|||
- visible: bool - can the actor see it?
|
||||
- private: bool - if visible, can anonymous users NOT see it?
|
||||
"""
|
||||
# Convert old-style resource to Resource object
|
||||
if resource is None:
|
||||
resource_obj = None
|
||||
elif isinstance(resource, str):
|
||||
# Database resource
|
||||
resource_obj = self.resource_for_action(action, parent=resource, child=None)
|
||||
elif isinstance(resource, tuple) and len(resource) == 2:
|
||||
# Database + child resource (table or query)
|
||||
resource_obj = self.resource_for_action(
|
||||
action, parent=resource[0], child=resource[1]
|
||||
from datasette.permissions import Resource
|
||||
|
||||
# Validate that resource is a Resource object or None
|
||||
if resource is not None and not isinstance(resource, Resource):
|
||||
raise TypeError(
|
||||
f"resource must be a Resource object or None, not {type(resource).__name__}. "
|
||||
f"Use DatabaseResource(database=...), TableResource(database=..., table=...), "
|
||||
f"or QueryResource(database=..., query=...) instead."
|
||||
)
|
||||
else:
|
||||
resource_obj = None
|
||||
|
||||
# Check if actor can see it
|
||||
if not await self.allowed(action=action, resource=resource_obj, actor=actor):
|
||||
if not await self.allowed(action=action, resource=resource, actor=actor):
|
||||
return False, False
|
||||
|
||||
# Check if anonymous user can see it (for "private" flag)
|
||||
if not await self.allowed(action=action, resource=resource_obj, actor=None):
|
||||
if not await self.allowed(action=action, resource=resource, actor=None):
|
||||
# Actor can see it but anonymous cannot - it's private
|
||||
return True, True
|
||||
|
||||
|
|
@ -1386,12 +1382,14 @@ class Datasette:
|
|||
except IndexError:
|
||||
return {}
|
||||
# Ensure user has permission to view the referenced table
|
||||
from datasette.resources import TableResource
|
||||
|
||||
other_table = fk["other_table"]
|
||||
other_column = fk["other_column"]
|
||||
visible, _ = await self.check_visibility(
|
||||
actor,
|
||||
action="view-table",
|
||||
resource=(database, other_table),
|
||||
resource=TableResource(database=database, table=other_table),
|
||||
)
|
||||
if not visible:
|
||||
return {}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from typing import List
|
|||
|
||||
from datasette.events import AlterTableEvent, CreateTableEvent, InsertRowsEvent
|
||||
from datasette.database import QueryInterrupted
|
||||
from datasette.resources import DatabaseResource
|
||||
from datasette.resources import DatabaseResource, QueryResource
|
||||
from datasette.utils import (
|
||||
add_cors_headers,
|
||||
await_me_maybe,
|
||||
|
|
@ -51,7 +51,7 @@ class DatabaseView(View):
|
|||
visible, private = await datasette.check_visibility(
|
||||
request.actor,
|
||||
action="view-database",
|
||||
resource=database,
|
||||
resource=DatabaseResource(database=database),
|
||||
)
|
||||
if not visible:
|
||||
raise Forbidden("You do not have permission to view this database")
|
||||
|
|
@ -541,7 +541,7 @@ class QueryView(View):
|
|||
visible, private = await datasette.check_visibility(
|
||||
request.actor,
|
||||
action="view-query",
|
||||
resource=(database, canned_query["name"]),
|
||||
resource=QueryResource(database=database, query=canned_query["name"]),
|
||||
)
|
||||
if not visible:
|
||||
raise Forbidden("You do not have permission to view this query")
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class RowView(DataView):
|
|||
visible, private = await self.ds.check_visibility(
|
||||
request.actor,
|
||||
action="view-table",
|
||||
resource=(database, table),
|
||||
resource=TableResource(database=database, table=table),
|
||||
)
|
||||
if not visible:
|
||||
raise Forbidden("You do not have permission to view this table")
|
||||
|
|
|
|||
|
|
@ -789,7 +789,9 @@ class ApiExplorerView(BaseView):
|
|||
if name == "_internal":
|
||||
continue
|
||||
database_visible, _ = await self.ds.check_visibility(
|
||||
request.actor, action="view-database", resource=name
|
||||
request.actor,
|
||||
action="view-database",
|
||||
resource=DatabaseResource(database=name),
|
||||
)
|
||||
if not database_visible:
|
||||
continue
|
||||
|
|
@ -799,7 +801,7 @@ class ApiExplorerView(BaseView):
|
|||
visible, _ = await self.ds.check_visibility(
|
||||
request.actor,
|
||||
action="view-table",
|
||||
resource=(name, table),
|
||||
resource=TableResource(database=name, table=table),
|
||||
)
|
||||
if not visible:
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -978,7 +978,7 @@ async def table_view_data(
|
|||
visible, private = await datasette.check_visibility(
|
||||
request.actor,
|
||||
action="view-table",
|
||||
resource=(database_name, table_name),
|
||||
resource=TableResource(database=database_name, table=table_name),
|
||||
)
|
||||
if not visible:
|
||||
raise Forbidden("You do not have permission to view this table")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue