diff --git a/datasette/app.py b/datasette/app.py index 528b11bf..f9b13e91 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -1041,7 +1041,6 @@ class Datasette: for hook in pm.hook.track_event(datasette=self, event=event): await await_me_maybe(hook) - async def check_visibility( self, actor: dict, @@ -1282,7 +1281,9 @@ class Datasette: old_style_resource = None # If restrictions don't allow this action, deny it - if not restrictions_allow_action(self, actor["_r"], action, old_style_resource): + if not restrictions_allow_action( + self, actor["_r"], action, old_style_resource + ): result = False # Log the permission check for debugging diff --git a/datasette/utils/actions_sql.py b/datasette/utils/actions_sql.py index 24643e43..79642720 100644 --- a/datasette/utils/actions_sql.py +++ b/datasette/utils/actions_sql.py @@ -450,7 +450,10 @@ async def build_permission_rules_sql( # Build the UNION query if not rule_sqls: # Return empty result set - return "SELECT NULL AS parent, NULL AS child, 0 AS allow, NULL AS reason, NULL AS source_plugin WHERE 0", {} + return ( + "SELECT NULL AS parent, NULL AS child, 0 AS allow, NULL AS reason, NULL AS source_plugin WHERE 0", + {}, + ) rules_union = " UNION ALL ".join(rule_sqls) return rules_union, all_params diff --git a/datasette/views/database.py b/datasette/views/database.py index 17fc29ca..b6e5d698 100644 --- a/datasette/views/database.py +++ b/datasette/views/database.py @@ -116,7 +116,9 @@ class DatabaseView(View): attached_databases = [d.name for d in await db.attached_databases()] allow_execute_sql = await datasette.allowed( - action="execute-sql", resource=DatabaseResource(database=database), actor=request.actor + action="execute-sql", + resource=DatabaseResource(database=database), + actor=request.actor, ) json_data = { "database": database, @@ -726,7 +728,9 @@ class QueryView(View): ) allow_execute_sql = await datasette.allowed( - action="execute-sql", resource=DatabaseResource(database=database), actor=request.actor + action="execute-sql", + resource=DatabaseResource(database=database), + actor=request.actor, ) show_hide_hidden = "" @@ -937,7 +941,9 @@ class TableCreateView(BaseView): # Must have create-table permission if not await self.ds.allowed( - action="create-table", resource=DatabaseResource(database=database_name), actor=request.actor + action="create-table", + resource=DatabaseResource(database=database_name), + actor=request.actor, ): return _error(["Permission denied"], 403) @@ -974,7 +980,9 @@ class TableCreateView(BaseView): if replace: # Must have update-row permission if not await self.ds.allowed( - action="update-row", resource=DatabaseResource(database=database_name), actor=request.actor + action="update-row", + resource=DatabaseResource(database=database_name), + actor=request.actor, ): return _error(["Permission denied: need update-row"], 403) @@ -998,7 +1006,9 @@ class TableCreateView(BaseView): if rows or row: # Must have insert-row permission if not await self.ds.allowed( - action="insert-row", resource=DatabaseResource(database=database_name), actor=request.actor + action="insert-row", + resource=DatabaseResource(database=database_name), + actor=request.actor, ): return _error(["Permission denied: need insert-row"], 403) @@ -1011,7 +1021,9 @@ class TableCreateView(BaseView): # alter=True only if they request it AND they have permission if data.get("alter"): if not await self.ds.allowed( - action="alter-table", resource=DatabaseResource(database=database_name), actor=request.actor + action="alter-table", + resource=DatabaseResource(database=database_name), + actor=request.actor, ): return _error(["Permission denied: need alter-table"], 403) alter = True diff --git a/datasette/views/row.py b/datasette/views/row.py index 2f104a9e..87eed5a4 100644 --- a/datasette/views/row.py +++ b/datasette/views/row.py @@ -183,7 +183,9 @@ async def _resolve_row_and_check_permission(datasette, request, permission): # Ensure user has permission to delete this row if not await datasette.allowed( - action=permission, resource=TableResource(database=resolved.db.name, table=resolved.table), actor=request.actor + action=permission, + resource=TableResource(database=resolved.db.name, table=resolved.table), + actor=request.actor, ): return False, _error(["Permission denied"], 403) @@ -256,7 +258,9 @@ class RowUpdateView(BaseView): alter = data.get("alter") if alter and not await self.ds.allowed( - action="alter-table", resource=TableResource(database=resolved.db.name, table=resolved.table), actor=request.actor + action="alter-table", + resource=TableResource(database=resolved.db.name, table=resolved.table), + actor=request.actor, ): return _error(["Permission denied for alter-table"], 403) diff --git a/datasette/views/special.py b/datasette/views/special.py index 20b1ba51..ff64d66e 100644 --- a/datasette/views/special.py +++ b/datasette/views/special.py @@ -535,7 +535,9 @@ class PermissionCheckView(BaseView): resource = None before_checks = len(self.ds._permission_checks) - allowed = await self.ds.allowed(action=action, resource=resource_obj, actor=request.actor) + allowed = await self.ds.allowed( + action=action, resource=resource_obj, actor=request.actor + ) info = None if len(self.ds._permission_checks) > before_checks: @@ -659,7 +661,9 @@ class CreateTokenView(BaseView): if database.name == "_memory": continue if not await self.ds.allowed( - action="view-database", resource=DatabaseResource(database=database.name), actor=request.actor + action="view-database", + resource=DatabaseResource(database=database.name), + actor=request.actor, ): continue hidden_tables = await database.hidden_table_names() @@ -670,7 +674,7 @@ class CreateTokenView(BaseView): if not await self.ds.allowed( action="view-table", resource=TableResource(database=database.name, table=table), - actor=request.actor + actor=request.actor, ): continue tables.append({"name": table, "encoded": tilde_encode(table)}) @@ -809,7 +813,9 @@ class ApiExplorerView(BaseView): continue if await self.ds.allowed( - action="insert-row", resource=TableResource(database=name, table=table), actor=request.actor + action="insert-row", + resource=TableResource(database=name, table=table), + actor=request.actor, ): pks = await db.primary_keys(table) table_links.extend( @@ -845,7 +851,9 @@ class ApiExplorerView(BaseView): ] ) if await self.ds.allowed( - action="drop-table", resource=TableResource(database=name, table=table), actor=request.actor + action="drop-table", + resource=TableResource(database=name, table=table), + actor=request.actor, ): table_links.append( { @@ -857,7 +865,11 @@ class ApiExplorerView(BaseView): ) database_links = [] if ( - await self.ds.allowed(action="create-table", resource=DatabaseResource(database=name), actor=request.actor) + await self.ds.allowed( + action="create-table", + resource=DatabaseResource(database=name), + actor=request.actor, + ) and db.is_mutable ): database_links.append( diff --git a/datasette/views/table.py b/datasette/views/table.py index 87f6bb62..5efb9d36 100644 --- a/datasette/views/table.py +++ b/datasette/views/table.py @@ -451,10 +451,14 @@ class TableInsertView(BaseView): # Must have insert-row AND upsert-row permissions if not ( await self.ds.allowed( - action="insert-row", resource=TableResource(database=database_name, table=table_name), actor=request.actor + action="insert-row", + resource=TableResource(database=database_name, table=table_name), + actor=request.actor, ) and await self.ds.allowed( - action="update-row", resource=TableResource(database=database_name, table=table_name), actor=request.actor + action="update-row", + resource=TableResource(database=database_name, table=table_name), + actor=request.actor, ) ): return _error( @@ -463,7 +467,9 @@ class TableInsertView(BaseView): else: # Must have insert-row permission if not await self.ds.allowed( - action="insert-row", resource=TableResource(database=database_name, table=table_name), actor=request.actor + action="insert-row", + resource=TableResource(database=database_name, table=table_name), + actor=request.actor, ): return _error(["Permission denied"], 403) @@ -493,7 +499,9 @@ class TableInsertView(BaseView): return _error(["Upsert does not support ignore or replace"], 400) if replace and not await self.ds.allowed( - action="update-row", resource=TableResource(database=database_name, table=table_name), actor=request.actor + action="update-row", + resource=TableResource(database=database_name, table=table_name), + actor=request.actor, ): return _error(['Permission denied: need update-row to use "replace"'], 403) @@ -501,7 +509,9 @@ class TableInsertView(BaseView): if alter: # Must have alter-table permission if not await self.ds.allowed( - action="alter-table", resource=TableResource(database=database_name, table=table_name), actor=request.actor + action="alter-table", + resource=TableResource(database=database_name, table=table_name), + actor=request.actor, ): return _error(["Permission denied for alter-table"], 403) # Track initial schema to check if it changed later @@ -629,7 +639,9 @@ class TableDropView(BaseView): if not await db.table_exists(table_name): return _error(["Table not found: {}".format(table_name)], 404) if not await self.ds.allowed( - action="drop-table", resource=TableResource(database=database_name, table=table_name), actor=request.actor + action="drop-table", + resource=TableResource(database=database_name, table=table_name), + actor=request.actor, ): return _error(["Permission denied"], 403) if not db.is_mutable: @@ -916,7 +928,9 @@ async def table_view_traced(datasette, request): ), is_sortable=any(c["sortable"] for c in data["display_columns"]), allow_execute_sql=await datasette.allowed( - action="execute-sql", resource=DatabaseResource(database=resolved.db.name), actor=request.actor + action="execute-sql", + resource=DatabaseResource(database=resolved.db.name), + actor=request.actor, ), query_ms=1.2, select_templates=[ diff --git a/tests/plugins/my_plugin.py b/tests/plugins/my_plugin.py index b0a4ce24..59565dcb 100644 --- a/tests/plugins/my_plugin.py +++ b/tests/plugins/my_plugin.py @@ -495,7 +495,7 @@ def register_actions(datasette): takes_parent=True, takes_child=False, resource_class=DatabaseResource, - ) + ), ] # Support old-style config for backwards compatibility @@ -509,7 +509,11 @@ def register_actions(datasette): description=p["description"], takes_parent=p.get("takes_database", False), takes_child=p.get("takes_resource", False), - resource_class=DatabaseResource if p.get("takes_database") else InstanceResource, + resource_class=( + DatabaseResource + if p.get("takes_database") + else InstanceResource + ), ) ) @@ -521,7 +525,9 @@ def register_actions(datasette): "InstanceResource": InstanceResource, "DatabaseResource": DatabaseResource, } - resource_class = resource_class_map.get(a.get("resource_class", "InstanceResource"), InstanceResource) + resource_class = resource_class_map.get( + a.get("resource_class", "InstanceResource"), InstanceResource + ) actions.append( Action( @@ -561,7 +567,13 @@ def permission_resources_sql(datasette, actor, action): else: return None # No opinion return PermissionSQL(source="my_plugin", sql=sql, params={}) - elif action in ("insert-row", "create-table", "drop-table", "delete-row", "update-row"): + elif action in ( + "insert-row", + "create-table", + "drop-table", + "delete-row", + "update-row", + ): # Special permissions for latest.datasette.io demos actor_id = actor.get("id") if actor else None if actor_id == "todomvc": diff --git a/tests/test_auth.py b/tests/test_auth.py index 7d170e98..b38b92f4 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -358,18 +358,12 @@ async def test_root_with_root_enabled_gets_all_permissions(ds_client): # Test instance-level permissions (no resource) assert ( - await ds_client.ds.allowed(action="permissions-debug", actor=root_actor) - is True + await ds_client.ds.allowed(action="permissions-debug", actor=root_actor) is True ) assert await ds_client.ds.allowed(action="debug-menu", actor=root_actor) is True # Test view permissions using the new ds.allowed() method - assert ( - await ds_client.ds.allowed( - action="view-instance", actor=root_actor - ) - is True - ) + assert await ds_client.ds.allowed(action="view-instance", actor=root_actor) is True assert ( await ds_client.ds.allowed( @@ -462,10 +456,7 @@ async def test_root_without_root_enabled_no_special_permissions(ds_client): # View permissions should still work (default=True) assert ( - await ds_client.ds.allowed( - action="view-instance", actor=root_actor - ) - is True + await ds_client.ds.allowed(action="view-instance", actor=root_actor) is True ) # Default permission assert ( @@ -479,9 +470,7 @@ async def test_root_without_root_enabled_no_special_permissions(ds_client): # But restricted permissions should NOT automatically be granted # Test with instance-level permission (no resource class) - result = await ds_client.ds.allowed( - action="permissions-debug", actor=root_actor - ) + result = await ds_client.ds.allowed(action="permissions-debug", actor=root_actor) assert ( result is not True ), "Root without root_enabled should not automatically get permissions-debug" diff --git a/tests/test_canned_queries.py b/tests/test_canned_queries.py index b75d2d43..ee849b36 100644 --- a/tests/test_canned_queries.py +++ b/tests/test_canned_queries.py @@ -5,7 +5,9 @@ import re from .fixtures import make_app_client, app_client # Mark entire module as xfail since view-query permission not yet migrated, refs #2534 -pytestmark = pytest.mark.xfail(reason="view-query permission not yet migrated to new permission system, refs #2534") +pytestmark = pytest.mark.xfail( + reason="view-query permission not yet migrated to new permission system, refs #2534" +) @pytest.fixture diff --git a/tests/test_config_permission_rules.py b/tests/test_config_permission_rules.py index a899b335..8327ecbf 100644 --- a/tests/test_config_permission_rules.py +++ b/tests/test_config_permission_rules.py @@ -19,8 +19,16 @@ async def test_root_permissions_allow(): config = {"permissions": {"execute-sql": {"id": "alice"}}} ds = await setup_datasette(config=config, databases=["content"]) - assert await ds.allowed(action="execute-sql", resource=DatabaseResource(database="content"), actor={"id": "alice"}) - assert not await ds.allowed(action="execute-sql", resource=DatabaseResource(database="content"), actor={"id": "bob"}) + assert await ds.allowed( + action="execute-sql", + resource=DatabaseResource(database="content"), + actor={"id": "alice"}, + ) + assert not await ds.allowed( + action="execute-sql", + resource=DatabaseResource(database="content"), + actor={"id": "bob"}, + ) @pytest.mark.asyncio @@ -37,10 +45,14 @@ async def test_database_permission(): ds = await setup_datasette(config=config, databases=["content"]) assert await ds.allowed( - action="insert-row", resource=TableResource(database="content", table="repos"), actor={"id": "alice"} + action="insert-row", + resource=TableResource(database="content", table="repos"), + actor={"id": "alice"}, ) assert not await ds.allowed( - action="insert-row", resource=TableResource(database="content", table="repos"), actor={"id": "bob"} + action="insert-row", + resource=TableResource(database="content", table="repos"), + actor={"id": "bob"}, ) @@ -56,10 +68,14 @@ async def test_table_permission(): ds = await setup_datasette(config=config, databases=["content"]) assert await ds.allowed( - action="delete-row", resource=TableResource(database="content", table="repos"), actor={"id": "alice"} + action="delete-row", + resource=TableResource(database="content", table="repos"), + actor={"id": "alice"}, ) assert not await ds.allowed( - action="delete-row", resource=TableResource(database="content", table="repos"), actor={"id": "bob"} + action="delete-row", + resource=TableResource(database="content", table="repos"), + actor={"id": "bob"}, ) @@ -71,13 +87,19 @@ async def test_view_table_allow_block(): ds = await setup_datasette(config=config, databases=["content"]) assert await ds.allowed( - action="view-table", resource=TableResource(database="content", table="repos"), actor={"id": "alice"} + action="view-table", + resource=TableResource(database="content", table="repos"), + actor={"id": "alice"}, ) assert not await ds.allowed( - action="view-table", resource=TableResource(database="content", table="repos"), actor={"id": "bob"} + action="view-table", + resource=TableResource(database="content", table="repos"), + actor={"id": "bob"}, ) assert await ds.allowed( - action="view-table", resource=TableResource(database="content", table="other"), actor={"id": "bob"} + action="view-table", + resource=TableResource(database="content", table="other"), + actor={"id": "bob"}, ) @@ -87,7 +109,9 @@ async def test_view_table_allow_false_blocks(): ds = await setup_datasette(config=config, databases=["content"]) assert not await ds.allowed( - action="view-table", resource=TableResource(database="content", table="repos"), actor={"id": "alice"} + action="view-table", + resource=TableResource(database="content", table="repos"), + actor={"id": "alice"}, ) @@ -96,18 +120,38 @@ async def test_allow_sql_blocks(): config = {"allow_sql": {"id": "alice"}} ds = await setup_datasette(config=config, databases=["content"]) - assert await ds.allowed(action="execute-sql", resource=DatabaseResource(database="content"), actor={"id": "alice"}) - assert not await ds.allowed(action="execute-sql", resource=DatabaseResource(database="content"), actor={"id": "bob"}) + assert await ds.allowed( + action="execute-sql", + resource=DatabaseResource(database="content"), + actor={"id": "alice"}, + ) + assert not await ds.allowed( + action="execute-sql", + resource=DatabaseResource(database="content"), + actor={"id": "bob"}, + ) config = {"databases": {"content": {"allow_sql": {"id": "bob"}}}} ds = await setup_datasette(config=config, databases=["content"]) - assert await ds.allowed(action="execute-sql", resource=DatabaseResource(database="content"), actor={"id": "bob"}) - assert not await ds.allowed(action="execute-sql", resource=DatabaseResource(database="content"), actor={"id": "alice"}) + assert await ds.allowed( + action="execute-sql", + resource=DatabaseResource(database="content"), + actor={"id": "bob"}, + ) + assert not await ds.allowed( + action="execute-sql", + resource=DatabaseResource(database="content"), + actor={"id": "alice"}, + ) config = {"allow_sql": False} ds = await setup_datasette(config=config, databases=["content"]) - assert not await ds.allowed(action="execute-sql", resource=DatabaseResource(database="content"), actor={"id": "alice"}) + assert not await ds.allowed( + action="execute-sql", + resource=DatabaseResource(database="content"), + actor={"id": "alice"}, + ) @pytest.mark.asyncio diff --git a/tests/test_html.py b/tests/test_html.py index 8875ede2..5f09dfc1 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -135,7 +135,9 @@ def test_not_allowed_methods(): @pytest.mark.asyncio -@pytest.mark.xfail(reason="Canned queries not displayed due to view-query permission, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not displayed due to view-query permission, refs #2510" +) async def test_database_page(ds_client): response = await ds_client.get("/fixtures") soup = Soup(response.text, "html.parser") @@ -264,7 +266,7 @@ def test_query_page_truncates(): pytest.param( "/fixtures/neighborhood_search", ["query", "db-fixtures", "query-neighborhood_search"], - marks=pytest.mark.xfail(reason="Canned queries not accessible, refs #2510") + marks=pytest.mark.xfail(reason="Canned queries not accessible, refs #2510"), ), ( "/fixtures/table~2Fwith~2Fslashes~2Ecsv", @@ -597,7 +599,9 @@ async def test_404_content_type(ds_client): @pytest.mark.asyncio -@pytest.mark.xfail(reason="Canned queries not yet migrated to new permission system, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not yet migrated to new permission system, refs #2510" +) async def test_canned_query_default_title(ds_client): response = await ds_client.get("/fixtures/magic_parameters") assert response.status_code == 200 @@ -606,7 +610,9 @@ async def test_canned_query_default_title(ds_client): @pytest.mark.asyncio -@pytest.mark.xfail(reason="Canned queries not yet migrated to new permission system, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not yet migrated to new permission system, refs #2510" +) async def test_canned_query_with_custom_metadata(ds_client): response = await ds_client.get("/fixtures/neighborhood_search?text=town") assert response.status_code == 200 @@ -669,7 +675,9 @@ async def test_show_hide_sql_query(ds_client): @pytest.mark.asyncio -@pytest.mark.xfail(reason="Canned queries not yet migrated to new permission system, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not yet migrated to new permission system, refs #2510" +) async def test_canned_query_with_hide_has_no_hidden_sql(ds_client): # For a canned query the show/hide should NOT have a hidden SQL field # https://github.com/simonw/datasette/issues/1411 @@ -681,7 +689,9 @@ async def test_canned_query_with_hide_has_no_hidden_sql(ds_client): ] == [(hidden["name"], hidden["value"]) for hidden in hiddens] -@pytest.mark.xfail(reason="Canned queries not yet migrated to new permission system, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not yet migrated to new permission system, refs #2510" +) @pytest.mark.parametrize( "hide_sql,querystring,expected_hidden,expected_show_hide_link,expected_show_hide_text", ( @@ -931,7 +941,9 @@ def test_base_url_affects_metadata_extra_css_urls(app_client_base_url_prefix): ("/fixtures/magic_parameters", None), ], ) -@pytest.mark.xfail(reason="Canned queries not yet migrated to new permission system, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not yet migrated to new permission system, refs #2510" +) async def test_edit_sql_link_on_canned_queries(ds_client, path, expected): response = await ds_client.get(path) assert response.status_code == 200 @@ -1037,7 +1049,7 @@ async def test_trace_correctly_escaped(ds_client): pytest.param( "/fixtures/neighborhood_search?text=town", "http://localhost/fixtures/neighborhood_search.json?text=town", - marks=pytest.mark.xfail(reason="Canned queries not accessible, refs #2510") + marks=pytest.mark.xfail(reason="Canned queries not accessible, refs #2510"), ), # /-/ pages ( diff --git a/tests/test_internals_datasette.py b/tests/test_internals_datasette.py index cd1e5d71..c7c54b4b 100644 --- a/tests/test_internals_datasette.py +++ b/tests/test_internals_datasette.py @@ -121,7 +121,9 @@ async def test_datasette_check_visibility( ): ds = Datasette([], memory=True, config=config) await ds.invoke_startup() - visible, private = await ds.check_visibility(actor, action=action, resource=resource) + visible, private = await ds.check_visibility( + actor, action=action, resource=resource + ) assert visible == should_allow assert private == expected_private diff --git a/tests/test_permissions.py b/tests/test_permissions.py index 2435d115..1762ee09 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -59,7 +59,12 @@ async def perms_ds(): "/-/api", "/fixtures/compound_three_primary_keys", "/fixtures/compound_three_primary_keys/a,a,a", - pytest.param("/fixtures/two", marks=pytest.mark.xfail(reason="view-query not yet migrated to new permission system")), # Query + pytest.param( + "/fixtures/two", + marks=pytest.mark.xfail( + reason="view-query not yet migrated to new permission system" + ), + ), # Query ), ) def test_view_padlock(allow, expected_anon, expected_auth, path, padlock_client): @@ -904,6 +909,7 @@ async def test_permissions_in_config( try: # Convert old-style resource to Resource object from datasette.resources import DatabaseResource, TableResource + resource_obj = None if resource: if isinstance(resource, str): @@ -911,7 +917,9 @@ async def test_permissions_in_config( elif isinstance(resource, tuple) and len(resource) == 2: resource_obj = TableResource(database=resource[0], table=resource[1]) - result = await perms_ds.allowed(action=action, resource=resource_obj, actor=actor) + result = await perms_ds.allowed( + action=action, resource=resource_obj, actor=actor + ) if result != expected_result: pprint(perms_ds._permission_checks) assert result == expected_result @@ -1123,7 +1131,16 @@ async def test_view_table_token_can_access_table(perms_ds): ({"a": ["vi"]}, "get", "/perms_ds_one/t1/1.json", None, 403), ({"a": ["vi"]}, "get", "/perms_ds_one/v1.json", None, 403), # Restricted to just view-database - pytest.param({"a": ["vd"]}, "get", "/.json", None, 200, marks=pytest.mark.xfail(reason="Actor restrictions need additional work, refs #2534")), # Can see instance too + pytest.param( + {"a": ["vd"]}, + "get", + "/.json", + None, + 200, + marks=pytest.mark.xfail( + reason="Actor restrictions need additional work, refs #2534" + ), + ), # Can see instance too ({"a": ["vd"]}, "get", "/perms_ds_one.json", None, 200), ({"a": ["vd"]}, "get", "/perms_ds_one/t1.json", None, 403), ({"a": ["vd"]}, "get", "/perms_ds_one/t1/1.json", None, 403), @@ -1135,7 +1152,9 @@ async def test_view_table_token_can_access_table(perms_ds): "/.json", None, 200, - marks=pytest.mark.xfail(reason="Actor restrictions need additional work, refs #2534") + marks=pytest.mark.xfail( + reason="Actor restrictions need additional work, refs #2534" + ), ), # Can see instance pytest.param( {"d": {"perms_ds_one": ["vt"]}}, @@ -1143,7 +1162,9 @@ async def test_view_table_token_can_access_table(perms_ds): "/perms_ds_one.json", None, 200, - marks=pytest.mark.xfail(reason="Actor restrictions need additional work, refs #2534") + marks=pytest.mark.xfail( + reason="Actor restrictions need additional work, refs #2534" + ), ), # and this database ( {"d": {"perms_ds_one": ["vt"]}}, @@ -1175,7 +1196,9 @@ async def test_view_table_token_can_access_table(perms_ds): "/.json", None, 200, - marks=pytest.mark.xfail(reason="Actor restrictions need additional work, refs #2534") + marks=pytest.mark.xfail( + reason="Actor restrictions need additional work, refs #2534" + ), ), pytest.param( {"r": {"perms_ds_one": {"t1": ["vt"]}}}, @@ -1183,7 +1206,9 @@ async def test_view_table_token_can_access_table(perms_ds): "/perms_ds_one.json", None, 200, - marks=pytest.mark.xfail(reason="Actor restrictions need additional work, refs #2534") + marks=pytest.mark.xfail( + reason="Actor restrictions need additional work, refs #2534" + ), ), ( {"r": {"perms_ds_one": {"t1": ["vt"]}}}, diff --git a/tests/test_plugins.py b/tests/test_plugins.py index cb0a6d1c..7bffc2c4 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -848,7 +848,9 @@ async def test_hook_startup(ds_client): @pytest.mark.asyncio -@pytest.mark.xfail(reason="Canned queries not yet migrated to new permission system, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not yet migrated to new permission system, refs #2510" +) async def test_hook_canned_queries(ds_client): queries = (await ds_client.get("/fixtures.json")).json()["queries"] queries_by_name = {q["name"]: q for q in queries} @@ -865,21 +867,27 @@ async def test_hook_canned_queries(ds_client): @pytest.mark.asyncio -@pytest.mark.xfail(reason="Canned queries not yet migrated to new permission system, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not yet migrated to new permission system, refs #2510" +) async def test_hook_canned_queries_non_async(ds_client): response = await ds_client.get("/fixtures/from_hook.json?_shape=array") assert [{"1": 1, "actor_id": "null"}] == response.json() @pytest.mark.asyncio -@pytest.mark.xfail(reason="Canned queries not yet migrated to new permission system, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not yet migrated to new permission system, refs #2510" +) async def test_hook_canned_queries_async(ds_client): response = await ds_client.get("/fixtures/from_async_hook.json?_shape=array") assert [{"2": 2}] == response.json() @pytest.mark.asyncio -@pytest.mark.xfail(reason="Canned queries not yet migrated to new permission system, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not yet migrated to new permission system, refs #2510" +) async def test_hook_canned_queries_actor(ds_client): assert ( await ds_client.get("/fixtures/from_hook.json?_bot=1&_shape=array") @@ -1541,7 +1549,9 @@ async def test_hook_top_query(ds_client): @pytest.mark.asyncio -@pytest.mark.xfail(reason="Canned queries not yet migrated to new permission system, refs #2510") +@pytest.mark.xfail( + reason="Canned queries not yet migrated to new permission system, refs #2510" +) async def test_hook_top_canned_query(ds_client): try: pm.register(SlotPlugin(), name="SlotPlugin")