diff --git a/dataworkspace/dataworkspace/apps/applications/utils.py b/dataworkspace/dataworkspace/apps/applications/utils.py index 3a9f1b0c04..8e67aeafa8 100644 --- a/dataworkspace/dataworkspace/apps/applications/utils.py +++ b/dataworkspace/dataworkspace/apps/applications/utils.py @@ -49,6 +49,7 @@ create_tools_access_iam_role, database_dsn, stable_identification_suffix, + source_tables_for_app, source_tables_for_user, new_private_database_credentials, postgres_user, @@ -253,19 +254,32 @@ def is_published_visualisation_and_requires_authorisation_and_has_authorisation( raise DatasetPermissionDenied(visualisation_catalogue_item) return vis_requires_auth - def is_visualisation_preview_and_has_gitlab_developer(): + def is_visualisation_preview_and_has_gitlab_developer_and_has_dataset_access(): is_vis_preview = is_preview and visualisation_catalogue_item if is_vis_preview and not gitlab_has_developer_access( request.user, application_template.gitlab_project_id ): raise ManageVisualisationsPermissionDeniedError() + + user_source_tables = source_tables_for_user(request.user) + app_source_tables = source_tables_for_app(application_template) + + user_authorised_datasets = set( + (source_table["dataset"]["id"] for source_table in user_source_tables) + ) + app_authorised_datasets = set( + (source_table["dataset"]["id"] for source_table in app_source_tables) + ) + if app_authorised_datasets - user_authorised_datasets: + raise ManageVisualisationsPermissionDeniedError() + return is_vis_preview return ( is_tool_and_correct_user_and_allowed_to_start() or is_published_visualisation_and_requires_authentication() or is_published_visualisation_and_requires_authorisation_and_has_authorisation() - or is_visualisation_preview_and_has_gitlab_developer() + or is_visualisation_preview_and_has_gitlab_developer_and_has_dataset_access() ) diff --git a/test/test_application.py b/test/test_application.py index 4c823dfffd..66bab3b614 100644 --- a/test/test_application.py +++ b/test/test_application.py @@ -752,6 +752,43 @@ def handle_general_gitlab(request): self.assertIn("testvisualisation [11372717]", application_content_1) self.assertIn("is loading...", application_content_1) + # Grant the visualisation access to a dataset that the user doesn't have access to + dataset_id_dataset_1 = "3be91019-ee77-4759-ba75-af9541601df4" + table_id = "e5c1318d-610a-4300-8b8d-2b96e9f6ab9c" + stdout, stderr, code = await create_private_dataset( + "test_external_db", + "MASTER", + dataset_id_dataset_1, + "dataset_121", + table_id, + "dataset_121", + ) + self.assertEqual(stdout, b"") + self.assertEqual(stderr, b"") + self.assertEqual(code, 0) + stdout, stderr, code = await give_visualisation_dataset_perms( + "testvisualisation", "dataset_121" + ) + self.assertEqual(stdout, b"") + self.assertEqual(stderr, b"") + self.assertEqual(code, 0) + + # Ensure the user doesn't have access to the application since they + # don't have access to this dataset + async with session.request( + "GET", "http://testvisualisation--11372717.dataworkspace.test:8000/" + ) as response: + content = await response.text() + self.assertIn("You do not have access to this page", content) + self.assertIn("You do not have permission to manage visualisations.", content) + self.assertEqual(response.status, 403) + + # Give the user access to the dataset + stdout, stderr, code = await give_user_dataset_perms("dataset_121") + self.assertEqual(stdout, b"") + self.assertEqual(stderr, b"") + self.assertEqual(code, 0) + await until_non_202(session, "http://testvisualisation--11372717.dataworkspace.test:8000/") sent_headers = {"from-downstream": "downstream-header-value"}