Commit graph

499 commits

Author SHA1 Message Date
Simon Willison
c06e05b7db New --root mechanism with datasette.root_enabled, closes #2521 2025-10-24 10:32:18 -07:00
Simon Willison
b9c6e7a0f6 PluginSQL renamed to PermissionSQL, closes #2524 2025-10-24 10:32:18 -07:00
Simon Willison
159b9f3fec ds.allowed() is now keyword-argument only, closes #2519 2025-10-24 10:32:18 -07:00
Simon Willison
8e9916b286 Update allowed_resources_sql() and refactor allowed_resources() 2025-10-24 10:32:18 -07:00
Simon Willison
b1080e7d30 Moved Resource defaults to datasette/resources.py 2025-10-24 10:32:18 -07:00
Simon Willison
2b879e462f Implement resource-based permission system with SQL-driven access control
This introduces a new hierarchical permission system that uses SQL queries
for efficient permission checking across resources. The system replaces the
older permission_allowed() pattern with a more flexible resource-based
approach.

Core changes:

- New Resource ABC and Action dataclass in datasette/permissions.py
  * Resources represent hierarchical entities (instance, database, table)
  * Each resource type implements resources_sql() to list all instances
  * Actions define operations on resources with cascading rules

- New plugin hook: register_actions(datasette)
  * Plugins register actions with their associated resource types
  * Replaces register_permissions() and register_resource_types()
  * See docs/plugin_hooks.rst for full documentation

- Three new Datasette methods for permission checks:
  * allowed_resources(action, actor) - returns list[Resource]
  * allowed_resources_with_reasons(action, actor) - for debugging
  * allowed(action, resource, actor) - checks single resource
  * All use SQL for filtering, never Python iteration

- New /-/tables endpoint (TablesView)
  * Returns JSON list of tables user can view
  * Supports ?q= parameter for regex filtering
  * Format: {"matches": [{"name": "db/table", "url": "/db/table"}]}
  * Respects all permission rules from configuration and plugins

- SQL-based permission evaluation (datasette/utils/actions_sql.py)
  * Cascading rules: child-level → parent-level → global-level
  * DENY beats ALLOW at same specificity
  * Uses CTEs for efficient SQL-only filtering
  * Combines permission_resources_sql() hook results

- Default actions in datasette/default_actions.py
  * InstanceResource, DatabaseResource, TableResource, QueryResource
  * Core actions: view-instance, view-database, view-table, etc.

- Fixed default_permissions.py to handle database-level allow blocks
  * Now creates parent-level rules for view-table action
  * Fixes: datasette ... -s databases.fixtures.allow.id root

Documentation:

- Comprehensive register_actions() hook documentation
- Detailed resources_sql() method explanation
- /-/tables endpoint documentation in docs/introspection.rst
- Deprecated register_permissions() with migration guide

Tests:

- tests/test_actions_sql.py: 7 tests for core permission API
- tests/test_tables_endpoint.py: 13 tests for /-/tables endpoint
- All 118 documentation tests pass
- Tests verify SQL does filtering (not Python)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 10:32:18 -07:00
Simon Willison
27084caa04
New allowed_resources_sql plugin hook and debug tools (#2505)
* allowed_resources_sql plugin hook and infrastructure
* New methods for checking permissions with the new system
* New /-/allowed and /-/check and /-/rules special endpoints

Still needs to be integrated more deeply into Datasette, especially for listing visible tables.

Refs: #2502

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-08 14:27:51 -07:00
Simon Willison
209bdee0e8 Don't run prepare_connection() on internal database, closes #2468 2025-02-18 10:23:23 -08:00
Simon Willison
7f23411002 Call db.close() in ds.remove_database()
https://github.com/simonw/datasette/issues/2465#issuecomment-2640712713
2025-02-06 10:46:11 -08:00
Simon Willison
308c243cfd datasette.set_actor_cookie() and datasette.delete_actor_cookie(), closes #1690 2025-01-15 17:37:25 -08:00
Simon Willison
34390bbed8 Fix for params metadata error, closes #2455 2025-01-09 09:54:06 -08:00
Simon Willison
9028d7f805 Support nested JSON in metadata.json, closes #2403 2024-08-21 09:53:52 -07:00
Simon Willison
39dfc7d7d7
Removed units functionality and Pint dependency
Closes #2400, unblocks #2320
2024-08-20 19:03:33 -07:00
Alex Garcia
0dd41efce6
skip over "queries" blocks when processing database-level metadata items (#2386) 2024-08-15 21:48:07 -07:00
Seb Bacon
9cb5700d60
bugfix: correctly detect json1 in versions.json (#2327)
Fixes #2326
2024-08-15 13:20:26 -07:00
Simon Willison
05dfd34fd0 Use text/html for CSRF error page, refs #2390 2024-08-15 08:48:47 -07:00
Simon Willison
06d4ffb92e Custom error on CSRF failures, closes #2390
Uses https://github.com/simonw/asgi-csrf/issues/28
2024-08-14 21:29:16 -07:00
Simon Willison
93067668fe /-/ alternative URL for homepage, closes #2393 2024-08-14 17:57:13 -07:00
Simon Willison
2b0a61ee19 Rename metadata tables and add schema to docs, refs #2382 2024-08-05 13:53:55 -07:00
Alex Garcia
a23c2aee00
Introduce new /$DB/-/query endpoint, soft replaces /$DB?sql=... (#2363)
* Introduce new default /$DB/-/query endpoint
* Fix a lot of tests
* Update pyodide test to use query endpoint
* Link to /fixtures/-/query in a few places
* Documentation for QueryView

---------

Co-authored-by: Simon Willison <swillison@gmail.com>
2024-07-15 10:33:51 -07:00
Simon Willison
263788906a Fix for RowNotFound, refs #2359 2024-06-21 16:10:16 -07:00
Simon Willison
7316dd4ac6 Fix for TableNotFound, refs #2359 2024-06-21 16:09:20 -07:00
Simon Willison
62686114ee Do not show database name in Database Not Found error, refs #2359 2024-06-21 16:02:15 -07:00
Alex Garcia
e1bfab3fca
Move Metadata to --internal database
Refs:
- https://github.com/simonw/datasette/pull/2343
- https://github.com/simonw/datasette/issues/2341
2024-06-11 09:33:23 -07:00
Simon Willison
261fc8d875 Fix datetime.utcnow deprecation warning 2024-03-15 15:32:12 -07:00
Simon Willison
eb8545c172 Refactor duplicate code in DatasetteClient, closes #2307 2024-03-15 15:29:03 -07:00
Simon Willison
54f5604caf Fixed cookies= httpx warning, refs #2307 2024-03-15 15:19:23 -07:00
Simon Willison
5af6837725 Fix httpx warning about app=self.app, refs #2307 2024-03-15 15:15:31 -07:00
Simon Willison
8bfa3a51c2 Consider every plugins opinion in datasette.permission_allowed()
Closes #2275, refs #2262
2024-02-16 13:29:39 -08:00
Simon Willison
bd9ed62e5d Make ds.pemrission_allawed(..., default=) a keyword-only argument, refs #2262 2024-02-08 20:12:31 -08:00
Simon Willison
9ac9f0152f Migrate allow from metadata to config if necessary, closes #2249 2024-02-06 22:18:38 -08:00
Simon Willison
60c6692f68
table_config instead of table_metadata (#2257)
Table configuration that was incorrectly placed in metadata is now treated as if it was in config.

New await datasette.table_config() method.

Closes #2247
2024-02-06 21:57:09 -08:00
Simon Willison
f049103852 datasette.table_metadata() is now await datasette.table_config(), refs #2247 2024-02-06 17:33:18 -08:00
Simon Willison
1e901aa690 /-/config page, closes #2254 2024-02-06 12:33:46 -08:00
Simon Willison
be4f02335f Treat plugins in metadata as if they were in config, closes #2248 2024-02-01 15:33:33 -08:00
Simon Willison
d4bc2b2dfc Remove fail_if_plugins_in_metadata, part of #2248 2024-02-01 14:44:16 -08:00
Simon Willison
bcc4f6bf1f
track_event() mechanism for analytics and plugins
* Closes #2240
* Documentation for event plugin hooks, refs #2240
* Include example track_event plugin in docs, refs #2240
* Tests for track_event() and register_events() hooks, refs #2240
* Initial documentation for core events, refs #2240
* Internals documentation for datasette.track_event()
2024-01-31 15:21:40 -08:00
Simon Willison
c7a4706bcc
jinja2_environment_from_request() plugin hook
Closes #2225
2024-01-05 14:33:23 -08:00
Alex Garcia
3d6d1e3050
Raise an exception if a "plugins" block exists in metadata.json 2023-10-12 09:20:50 -07:00
Alex Garcia
35deaabcb1
Move non-metadata configuration from metadata.yaml to datasette.yaml
* Allow and permission blocks moved to datasette.yaml
* Documentation updates, initial framework for configuration reference
2023-10-12 09:16:37 -07:00
Simon Willison
852f501485 Switch from pkg_resources to importlib.metadata in app.py, refs #2057 2023-09-16 09:35:18 -07:00
Alex Garcia
b2ec8717c3
Plugin configuration now lives in datasette.yaml/json
* Checkpoint, moving top-level plugin config to datasette.json
* Support database-level and table-level plugin configuration in datasette.yaml

Refs #2093
2023-09-13 14:06:25 -07:00
Simon Willison
b645174271
actors_from_ids plugin hook and datasette.actors_from_ids() method (#2181)
* Prototype of actors_from_ids plugin hook, refs #2180
* datasette-remote-actors example plugin, refs #2180
2023-09-07 21:23:59 -07:00
Simon Willison
c26370485a Label expand permission check respects cascade, closes #2178 2023-09-07 16:28:30 -07:00
Simon Willison
dbfad6d220 Foreign key label expanding respects table permissions, closes #2178 2023-09-07 15:51:09 -07:00
Simon Willison
bb12229794 Rename core_ to catalog_, closes #2163 2023-08-29 10:01:28 -07:00
Simon Willison
50da908213
Cascade for restricted token view-table/view-database/view-instance operations (#2154)
Closes #2102

* Permission is now a dataclass, not a namedtuple - refs https://github.com/simonw/datasette/pull/2154/#discussion_r1308087800
* datasette.get_permission() method
2023-08-29 09:32:34 -07:00
Alex Garcia
92b8bf38c0
Add new --internal internal.db option, deprecate legacy _internal database
Refs:
- #2157 
---------

Co-authored-by: Simon Willison <swillison@gmail.com>
2023-08-28 20:24:23 -07:00
Alex Garcia
17ec309e14
Start datasette.json, re-add --config, rm settings.json
The first step in defining the new `datasette.json/yaml` configuration mechanism.

Refs #2093, #2143, #493
2023-08-22 18:26:11 -07:00
Simon Willison
1377a290cd
New JSON design for query views (#2118)
* Refs #2111, closes #2110
* New Context dataclass/subclass mechanism, refs #2127
* Define QueryContext and extract get_tables() method, refs #2127
* Fix OPTIONS bug by porting DaatbaseView to be a View subclass
* Expose async_view_for_class.view_class for test_routes test
* Error/truncated aruments for renderers, closes #2130
2023-08-07 18:47:39 -07:00