From 7c01998c10318d690aaf7f9d0aa1caf6e6581cf8 Mon Sep 17 00:00:00 2001 From: Michael Collins <15347726+michaeljcollinsuk@users.noreply.github.com> Date: Wed, 11 Oct 2023 17:16:27 +0100 Subject: [PATCH] Update datasource detail page only accessible to superuser when deleted --- .../frontend/jinja2/datasource-detail.html | 13 +++++-- controlpanel/frontend/views/datasource.py | 6 +++ tests/frontend/views/test_datasource.py | 37 ++++++++++++++++++- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/controlpanel/frontend/jinja2/datasource-detail.html b/controlpanel/frontend/jinja2/datasource-detail.html index 0c133010a..d7ac893f2 100644 --- a/controlpanel/frontend/jinja2/datasource-detail.html +++ b/controlpanel/frontend/jinja2/datasource-detail.html @@ -20,9 +20,15 @@

{{ page_title }}

- - Open on AWS - + {% if bucket.is_deleted %} +

+ This bucket was deleted by {{ user_name(bucket.deleted_by) }} on {{ bucket.deleted_at.strftime("%Y/%m/%d %H:%M:%S") }}. +

+ {% else %} + + Open on AWS + + {% endif %}

@@ -212,6 +218,7 @@

Data access log

{% endif %} + {% if request.user.has_perm('api.destroy_s3bucket', bucket) %}
diff --git a/controlpanel/frontend/views/datasource.py b/controlpanel/frontend/views/datasource.py index 8e156e770..94c79b12a 100644 --- a/controlpanel/frontend/views/datasource.py +++ b/controlpanel/frontend/views/datasource.py @@ -131,6 +131,12 @@ class BucketDetail( permission_required = "api.retrieve_s3bucket" template_name = "datasource-detail.html" + def get_queryset(self): + queryset = super().get_queryset() + if not self.request.user.is_superuser: + queryset = queryset.filter(is_deleted=False) + return queryset + def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) bucket = kwargs["object"] diff --git a/tests/frontend/views/test_datasource.py b/tests/frontend/views/test_datasource.py index 53459a57d..464f3ece9 100644 --- a/tests/frontend/views/test_datasource.py +++ b/tests/frontend/views/test_datasource.py @@ -101,9 +101,10 @@ def list_all(client, *args): return client.get(reverse("list-all-datasources")) -def detail(client, buckets, *args): +def detail(client, buckets, *args, bucket=None): + bucket = bucket or buckets["warehouse1"] return client.get( - reverse("manage-datasource", kwargs={"pk": buckets["warehouse1"].id}) + reverse("manage-datasource", kwargs={"pk": bucket.id}) ) @@ -416,3 +417,35 @@ def test_delete_calls_soft_delete(client, buckets, users, bucket, success_url): assert bucket.deleted_by == admin assert bucket.deleted_at is not None assert response.url == success_url + + +@pytest.mark.parametrize( + "user, bucket, expected_status", + [ + ("superuser", "app_data1", status.HTTP_200_OK), + ("superuser", "app_data2", status.HTTP_200_OK), + ("superuser", "warehouse1", status.HTTP_200_OK), + ("superuser", "warehouse2", status.HTTP_200_OK), + ("superuser", "other", status.HTTP_200_OK), + ("bucket_viewer", "app_data1", status.HTTP_404_NOT_FOUND), + ("bucket_viewer", "app_data2", status.HTTP_404_NOT_FOUND), + ("bucket_viewer", "warehouse1", status.HTTP_404_NOT_FOUND), + ("bucket_viewer", "warehouse2", status.HTTP_404_NOT_FOUND), + ("bucket_viewer", "other", status.HTTP_404_NOT_FOUND), + ("bucket_admin", "app_data1", status.HTTP_404_NOT_FOUND), + ("bucket_admin", "app_data2", status.HTTP_404_NOT_FOUND), + ("bucket_admin", "warehouse1", status.HTTP_404_NOT_FOUND), + ("bucket_admin", "warehouse2", status.HTTP_404_NOT_FOUND), + ("bucket_admin", "other", status.HTTP_404_NOT_FOUND), + + ] +) +def test_detail_for_deleted_datasouce(client, buckets, users, user, bucket, expected_status): + user = users[user] + bucket = buckets[bucket] + bucket.soft_delete(deleted_by=user) + + client.force_login(user) + response = detail(client, user, bucket=bucket) + + assert response.status_code == expected_status