From dcec89270a2e3b9fabed93f1d7b9be3ef86e9ed2 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 8 Jun 2020 11:20:21 -0700 Subject: [PATCH] View list respects view-table permission, refs #811 Also makes a small change to the /fixtures.json JSON: "views": ["view_name"] Is now: "views": [{"name": "view_name", "private": true}] --- datasette/templates/database.html | 2 +- datasette/views/database.py | 11 ++++++++++- tests/test_permissions.py | 18 +++++++++++++----- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/datasette/templates/database.html b/datasette/templates/database.html index 089142e2..100faee4 100644 --- a/datasette/templates/database.html +++ b/datasette/templates/database.html @@ -51,7 +51,7 @@

Views

{% endif %} diff --git a/datasette/views/database.py b/datasette/views/database.py index 30817106..824cb632 100644 --- a/datasette/views/database.py +++ b/datasette/views/database.py @@ -37,10 +37,19 @@ class DatabaseView(DataView): db = self.ds.databases[database] table_counts = await db.table_counts(5) - views = await db.view_names() hidden_table_names = set(await db.hidden_table_names()) all_foreign_keys = await db.get_all_foreign_keys() + views = [] + for view_name in await db.view_names(): + visible, private = await check_visibility( + self.ds, request.actor, "view-table", "table", (database, view_name), + ) + if visible: + views.append( + {"name": view_name, "private": private,} + ) + tables = [] for table in table_counts: visible, private = await check_visibility( diff --git a/tests/test_permissions.py b/tests/test_permissions.py index 55b2d673..5c338e04 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -107,19 +107,27 @@ def test_table_list_respects_view_table(): metadata={ "databases": { "fixtures": { - "tables": {"compound_three_primary_keys": {"allow": {"id": "root"}}} + "tables": { + "compound_three_primary_keys": {"allow": {"id": "root"}}, + # And a SQL view too: + "paginated_view": {"allow": {"id": "root"}}, + } } } } ) as client: - html_fragment = 'compound_three_primary_keys 🔒' + html_fragments = [ + ">compound_three_primary_keys 🔒", + ">paginated_view 🔒", + ] anon_response = client.get("/fixtures") - assert html_fragment not in anon_response.text - assert '"/fixtures/compound_three_primary_keys"' not in anon_response.text + for html_fragment in html_fragments: + assert html_fragment not in anon_response.text auth_response = client.get( "/fixtures", cookies={"ds_actor": client.ds.sign({"id": "root"}, "actor")} ) - assert html_fragment in auth_response.text + for html_fragment in html_fragments: + assert html_fragment in auth_response.text @pytest.mark.parametrize(