Filter /-/databases by view-database permission

/-/databases previously listed every attached database (including
filesystem paths and sizes) to any actor with view-instance, while the
homepage and every other endpoint filtered by view-database. The
endpoint now only lists databases the current actor is allowed to view.

JsonDataView data callbacks may now be async.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
This commit is contained in:
Claude 2026-07-04 14:00:30 +00:00
commit f091b6dab1
No known key found for this signature in database
6 changed files with 55 additions and 10 deletions

View file

@ -1800,3 +1800,35 @@ async def test_root_allow_block_with_table_restricted_actor():
actor=admin_actor,
)
assert result is True
@pytest.mark.asyncio
async def test_databases_json_respects_view_database(tmp_path_factory):
# https://github.com/simonw/datasette - /-/databases should not list
# databases the actor is not allowed to view
db_directory = tmp_path_factory.mktemp("dbs")
from datasette.utils import sqlite3 as _sqlite3
paths = []
for name in ("public", "private"):
path = str(db_directory / "{}.db".format(name))
conn = _sqlite3.connect(path)
conn.execute("vacuum")
conn.close()
paths.append(path)
ds = Datasette(
paths,
config={"databases": {"private": {"allow": {"id": "root"}}}},
)
ds.root_enabled = True
await ds.invoke_startup()
try:
anon_response = await ds.client.get("/-/databases.json")
assert anon_response.status_code == 200
anon_names = {db["name"] for db in anon_response.json()["databases"]}
assert anon_names == {"public"}
root_response = await ds.client.get("/-/databases.json", actor={"id": "root"})
root_names = {db["name"] for db in root_response.json()["databases"]}
assert root_names == {"public", "private"}
finally:
ds.close()