diff --git a/datasette_write_ui/__init__.py b/datasette_write_ui/__init__.py index ff2ad15..14725ab 100644 --- a/datasette_write_ui/__init__.py +++ b/datasette_write_ui/__init__.py @@ -1,4 +1,5 @@ from datasette import hookimpl +from datasette.resources import TableResource from . import routes @@ -9,11 +10,14 @@ def register_routes(): (r"^/-/datasette-write-ui/insert-row-details$", routes.insert_row_details), ] + @hookimpl def extra_template_vars(datasette, database, table): async def permission_allowed(actor, permission): - return await datasette.permission_allowed(actor, permission, (database, table)) + return await datasette.allowed( + actor=actor, + action=permission, + resource=TableResource(database=database, table=table), + ) return {"permission_allowed": permission_allowed} - - diff --git a/datasette_write_ui/routes.py b/datasette_write_ui/routes.py index d94754b..c5cb77b 100644 --- a/datasette_write_ui/routes.py +++ b/datasette_write_ui/routes.py @@ -1,7 +1,9 @@ from datasette import Response, Forbidden +from datasette.resources import TableResource from datasette.utils import escape_sqlite, tilde_decode from typing import Any, TypedDict + def affinity_from_type(type): """ Return the "affinity" a SQLite column type has. @@ -23,8 +25,6 @@ def affinity_from_type(type): return "numeric" - - class EditRowDetailsField(TypedDict): """ Each "field" returned for every editable column in the edit-row-details route. @@ -36,16 +36,12 @@ class EditRowDetailsField(TypedDict): pk: bool editable: bool + async def edit_row_details(scope, receive, datasette, request): db_name = request.args.get("db") table_name = request.args.get("table") pks = request.args.get("primaryKeys") - if not await datasette.permission_allowed( - request.actor, "update-row", (db_name, table_name), default=False - ): - raise Forbidden("update-row permissions required") - if db_name is None: return Response.json( {"ok": False, "message": "db parameter is required"}, status=400 @@ -56,6 +52,13 @@ async def edit_row_details(scope, receive, datasette, request): {"ok": False, "message": "table parameter is required"}, status=400 ) + if not await datasette.allowed( + actor=request.actor, + action="update-row", + resource=TableResource(database=db_name, table=table_name), + ): + raise Forbidden("update-row permissions required") + if pks is None: return Response.json( {"ok": False, "message": "primaryKeys parameter is required"}, status=400 @@ -134,8 +137,20 @@ async def insert_row_details(scope, receive, datasette, request): db_name = request.args.get("db") table_name = request.args.get("table") - if not await datasette.permission_allowed( - request.actor, "insert-row", (db_name, table_name) + if db_name is None: + return Response.json( + {"ok": False, "message": "db parameter is required"}, status=400 + ) + + if table_name is None: + return Response.json( + {"ok": False, "message": "table parameter is required"}, status=400 + ) + + if not await datasette.allowed( + actor=request.actor, + action="insert-row", + resource=TableResource(database=db_name, table=table_name), ): raise Forbidden("insert-row permissions required") @@ -151,8 +166,4 @@ async def insert_row_details(scope, receive, datasette, request): InsertRowDetailField(name=name, affinity=affinity_from_type(type)) ) - return Response.json( - { - "fields": insertable_columns, - } - ) + return Response.json({"fields": insertable_columns}) diff --git a/pyproject.toml b/pyproject.toml index 438f64d..17001f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,13 +4,13 @@ version = "0.0.1a13" description = "Datasette UI plugin for editing and inserting rows" readme = "README.md" authors = [{name = "Alex Garcia"}] -license = {file = "LICENSE"} +license = "Apache-2.0" classifiers=[ "Framework :: Datasette", ] -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ - "datasette==1.0a19", + "datasette>=1.0a21", "sqlite-utils>=3.38", ] diff --git a/tests/test_datasette_write_ui.py b/tests/test_datasette_write_ui.py index 5fc3315..bb8d231 100644 --- a/tests/test_datasette_write_ui.py +++ b/tests/test_datasette_write_ui.py @@ -39,7 +39,9 @@ def students_db_path(tmpdir): students_metadata = { "databases": { "students": { - "tables": {"students": {"permissions": {"insert-row": {"id": "apollo"}}}} + "tables": { + "students": {"permissions": {"insert-row": {"id": ["apollo", "root"]}}} + } } } } @@ -63,6 +65,7 @@ async def test_permissions(students_db_path): [students_db_path], config=students_metadata, ) + datasette.root_enabled = True response = await datasette.client.get("/students/students") permissions = get_permission_from_table_html(response.text) assert permissions["can_delete"] == False @@ -100,6 +103,7 @@ async def test_permissions(students_db_path): @pytest.mark.asyncio async def test_insert_row_details_route(students_db_path): datasette = Datasette([students_db_path]) + datasette.root_enabled = True response = await datasette.client.get( "/-/datasette-write-ui/insert-row-details?db=students&table=students", @@ -123,6 +127,7 @@ async def test_insert_row_details_route(students_db_path): @pytest.mark.asyncio async def test_update_row_details_route(students_db_path): datasette = Datasette([students_db_path]) + datasette.root_enabled = True response = await datasette.client.get( "/-/datasette-write-ui/edit-row-details?db=students&table=students",