Cascading permissions for .db download, closes #1058

pull/1059/head
Simon Willison 2020-10-27 20:15:41 -07:00
rodzic c3aba4aa98
commit 7d9fedc176
3 zmienionych plików z 20 dodań i 5 usunięć

Wyświetl plik

@ -131,9 +131,14 @@ class DatabaseDownload(DataView):
name = "database_download"
async def view_get(self, request, database, hash, correct_hash_present, **kwargs):
await self.check_permission(request, "view-instance")
await self.check_permission(request, "view-database", database)
await self.check_permission(request, "view-database-download", database)
await self.check_permissions(
request,
[
("view-database-download", database),
("view-database", database),
"view-instance",
],
)
if database not in self.ds.databases:
raise DatasetteError("Invalid database", status=404)
db = self.ds.databases[database]

Wyświetl plik

@ -193,6 +193,8 @@ def permission_allowed(actor, action):
return True
elif action == "this_is_denied":
return False
elif action == "view-database-download":
return (actor and actor.get("can_download")) or None
@hookimpl

Wyświetl plik

@ -394,7 +394,7 @@ def test_view_instance(path, view_instance_client):
@pytest.fixture(scope="session")
def cascade_app_client():
with make_app_client() as client:
with make_app_client(is_immutable=True) as client:
yield client
@ -439,6 +439,11 @@ def cascade_app_client():
("/fixtures", [], 403),
("/fixtures", ["instance"], 403),
("/fixtures", ["database"], 200),
# Downloading the fixtures.db file
("/fixtures.db", [], 403),
("/fixtures.db", ["instance"], 403),
("/fixtures.db", ["database"], 200),
("/fixtures.db", ["download"], 200),
],
)
def test_permissions_cascade(cascade_app_client, path, permissions, expected_status):
@ -447,6 +452,9 @@ def test_permissions_cascade(cascade_app_client, path, permissions, expected_sta
deny = {}
previous_metadata = cascade_app_client.ds._metadata
updated_metadata = copy.deepcopy(previous_metadata)
actor = {"id": "test"}
if "download" in permissions:
actor["can_download"] = 1
try:
# Set up the different allow blocks
updated_metadata["allow"] = allow if "instance" in permissions else deny
@ -462,7 +470,7 @@ def test_permissions_cascade(cascade_app_client, path, permissions, expected_sta
cascade_app_client.ds._metadata = updated_metadata
response = cascade_app_client.get(
path,
cookies={"ds_actor": cascade_app_client.actor_cookie({"id": "test"})},
cookies={"ds_actor": cascade_app_client.actor_cookie(actor)},
)
assert expected_status == response.status
finally: