Migrate view-query permission to SQL-based system, refs #2510

This change integrates canned queries with Datasette's new SQL-based
permissions system by making the following changes:

1. **Default canned_queries plugin hook**: Added a new hookimpl in
   default_permissions.py that returns canned queries from datasette
   configuration. This extracts config-reading logic into a plugin hook,
   allowing QueryResource to discover all queries.

2. **Async resources_sql()**: Converted Resource.resources_sql() from a
   synchronous class method returning a string to an async method that
   receives the datasette instance. This allows QueryResource to call
   plugin hooks and query the database.

3. **QueryResource implementation**: Implemented QueryResource.resources_sql()
   to gather all canned queries by:
   - Querying catalog_databases for all databases
   - Calling canned_queries hooks for each database with actor=None
   - Building a UNION ALL SQL query of all (database, query_name) pairs
   - Properly escaping single quotes in resource names

4. **Simplified get_canned_queries()**: Removed config-reading logic since
   it's now handled by the default plugin hook.

5. **Added view-query to default allow**: Added "view-query" to the
   default_allow_actions set so canned queries are accessible by default.

6. **Removed xfail markers**: Removed test xfail markers from:
   - tests/test_canned_queries.py (entire module)
   - tests/test_html.py (2 tests)
   - tests/test_permissions.py (1 test)
   - tests/test_plugins.py (1 test)

All canned query tests now pass with the new permission system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Simon Willison 2025-10-25 10:21:50 -07:00
commit 82cc3d5c86
10 changed files with 56 additions and 82 deletions

View file

@ -234,7 +234,6 @@ def test_table_list_respects_view_table():
assert html_fragment in auth_response.text
@pytest.mark.xfail(reason="view-query not yet migrated to new permission system")
@pytest.mark.parametrize(
"allow,expected_anon,expected_auth",
[
@ -365,9 +364,6 @@ def test_query_list_respects_view_query():
("view-database", "fixtures"),
("view-query", ("fixtures", "neighborhood_search")),
],
marks=pytest.mark.xfail(
reason="Canned queries not accessible due to view-query permission not migrated, refs #2510"
),
),
],
)
@ -593,9 +589,6 @@ def test_permissions_cascade(cascade_app_client, path, permissions, expected_sta
cascade_app_client.ds.config = previous_config
@pytest.mark.xfail(
reason="Canned queries not accessible due to view-query permission not migrated, refs #2510"
)
def test_padlocks_on_database_page(cascade_app_client):
config = {
"databases": {