From bda24168cbbb6c459a66842597beddfc9666c2d3 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Wed, 4 Sep 2024 14:12:36 -0700 Subject: [PATCH 01/49] Map authenticated users to a Django group This will let us grant that group view permission. --- config/settings/base.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/settings/base.py b/config/settings/base.py index 5539f254..152a97d2 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -344,6 +344,11 @@ "request_scope": True, "django_group_name": "Approved by PI for AnVIL access", }, + { + "drupal_machine_name": "authenticated", + "request_scope": True, + "django_group_name": "Authenticated", + }, ], } } From 0c8e12929c1ce4365ab8104d12d1094114814e39 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Wed, 4 Sep 2024 14:28:30 -0700 Subject: [PATCH 02/49] Switch UploadCycleDetail to be visible by View users Modify tests to use a view user by default. Change test structure for checking links by having one test for view users, one for staff view, and one for edit users; these tests check if the proper links are or are not shown. --- .../gregor_anvil/tests/test_views.py | 64 +++++++++++-------- gregor_django/gregor_anvil/views.py | 3 +- .../gregor_anvil/uploadcycle_detail.html | 2 + 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index 32806ab0..d77260a8 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -1006,7 +1006,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -1147,45 +1147,53 @@ def test_partner_upload_workspace_table(self): self.assertIn(workspace.workspace, table.data) self.assertNotIn(other_workspace.workspace, table.data) - def test_link_to_audit(self): - """Response includes a link to the audit page.""" + def test_links_view_user(self): + user = self.user obj = self.model_factory.create() - self.client.force_login(self.user) + self.client.force_login(user) response = self.client.get(self.get_url(obj.cycle)) - self.assertContains( + self.assertNotContains(response, reverse("gregor_anvil:upload_cycles:update", args=[obj.cycle])) + self.assertNotContains( response, reverse("gregor_anvil:audit:upload_workspaces:sharing:by_upload_cycle", args=[obj.cycle]) ) - - def test_link_to_update_view_staff_edit(self): - """Response includes a link to the update view for staff edit users.""" - obj = self.model_factory.create() - self.user.user_permissions.add( - Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) + self.assertNotContains( + response, reverse("gregor_anvil:audit:upload_workspaces:auth_domains:by_upload_cycle", args=[obj.cycle]) ) - self.client.force_login(self.user) - response = self.client.get(self.get_url(obj.cycle)) - self.assertContains(response, reverse("gregor_anvil:upload_cycles:update", args=[obj.cycle])) - def test_link_to_update_view_staff_view(self): - """Response includes a link to the update view for staff edit users.""" + def test_links_staff_view_user(self): + user = User.objects.create_user(username="test-staff-view", password="test-staff-view") + user.user_permissions.add( + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) + ) obj = self.model_factory.create() - self.client.force_login(self.user) + self.client.force_login(user) response = self.client.get(self.get_url(obj.cycle)) self.assertNotContains(response, reverse("gregor_anvil:upload_cycles:update", args=[obj.cycle])) + self.assertContains( + response, reverse("gregor_anvil:audit:upload_workspaces:sharing:by_upload_cycle", args=[obj.cycle]) + ) + self.assertContains( + response, reverse("gregor_anvil:audit:upload_workspaces:auth_domains:by_upload_cycle", args=[obj.cycle]) + ) - def test_contains_sharing_audit_button(self): - obj = self.model_factory.create() - self.client.force_login(self.user) - response = self.client.get(self.get_url(obj.cycle)) - url = reverse("gregor_anvil:audit:upload_workspaces:sharing:by_upload_cycle", args=[obj.cycle]) - self.assertContains(response, url) - - def test_contains_auth_domain_audit_button(self): + def test_links_staff_edit_user(self): + user = User.objects.create_user(username="test-staff-view", password="test-staff-view") + user.user_permissions.add( + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) + ) + user.user_permissions.add( + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) + ) obj = self.model_factory.create() - self.client.force_login(self.user) + self.client.force_login(user) response = self.client.get(self.get_url(obj.cycle)) - url = reverse("gregor_anvil:audit:upload_workspaces:auth_domains:by_upload_cycle", args=[obj.cycle]) - self.assertContains(response, url) + self.assertContains(response, reverse("gregor_anvil:upload_cycles:update", args=[obj.cycle])) + self.assertContains( + response, reverse("gregor_anvil:audit:upload_workspaces:sharing:by_upload_cycle", args=[obj.cycle]) + ) + self.assertContains( + response, reverse("gregor_anvil:audit:upload_workspaces:auth_domains:by_upload_cycle", args=[obj.cycle]) + ) def test_includes_date_ready_for_compute(self): obj = self.model_factory.create(is_past=True, date_ready_for_compute="2022-01-01") diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index cdf8c701..b499acd5 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -2,6 +2,7 @@ from anvil_consortium_manager.auth import ( AnVILConsortiumManagerStaffEditRequired, AnVILConsortiumManagerStaffViewRequired, + AnVILConsortiumManagerViewRequired, ) from anvil_consortium_manager.exceptions import AnVILGroupNotFound from anvil_consortium_manager.models import ( @@ -124,7 +125,7 @@ class UploadCycleUpdate(AnVILConsortiumManagerStaffEditRequired, SuccessMessageM success_message = "Successfully updated Upload Cycle." -class UploadCycleDetail(AnVILConsortiumManagerStaffViewRequired, MultiTableMixin, DetailView): +class UploadCycleDetail(AnVILConsortiumManagerViewRequired, MultiTableMixin, DetailView): """View to show details about an `UploadCycle`.""" model = models.UploadCycle diff --git a/gregor_django/templates/gregor_anvil/uploadcycle_detail.html b/gregor_django/templates/gregor_anvil/uploadcycle_detail.html index b8683f76..28e1850e 100644 --- a/gregor_django/templates/gregor_anvil/uploadcycle_detail.html +++ b/gregor_django/templates/gregor_anvil/uploadcycle_detail.html @@ -68,6 +68,7 @@

Partner upload workspaces

{% endif %} +{% if perms.anvil_consortium_manager.anvil_consortium_manager_staff_view %}

Audit consortium sharing @@ -76,4 +77,5 @@

Partner upload workspaces

Audit auth domain membership

+{% endif %} {% endblock action_buttons %} From 8ae5e005cbbacbb1f65a90eb94d2529762081b7f Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Wed, 4 Sep 2024 14:46:32 -0700 Subject: [PATCH 03/49] Make the upload cycle detail page a bit prettier --- .../gregor_anvil/uploadcycle_detail.html | 116 +++++++++++++++--- 1 file changed, 98 insertions(+), 18 deletions(-) diff --git a/gregor_django/templates/gregor_anvil/uploadcycle_detail.html b/gregor_django/templates/gregor_anvil/uploadcycle_detail.html index 28e1850e..05a1f2ef 100644 --- a/gregor_django/templates/gregor_anvil/uploadcycle_detail.html +++ b/gregor_django/templates/gregor_anvil/uploadcycle_detail.html @@ -28,34 +28,114 @@ {% endblock panel %} {% block after_panel %} -

Upload workspaces

-
- {% render_table tables.0 %} + +

The expandable tables below show information about workspaces associated with this upload cycle.

+ +
+
+

+ +

+
+
+ {% render_table tables.0 %} +
+
+
-

Combined consortium data workspaces

-
- {% render_table tables.1 %} + +
+
+

+ +

+
+
+ {% render_table tables.1 %} +
+
+
-

Release prep workspaces

-
- {% render_table tables.2 %} + +
+
+

+ +

+
+
+ {% render_table tables.3 %} +
+
+
-

DCC processing workspaces

-
- {% render_table tables.3 %} + +
+
+

+ +

+
+
+ {% render_table tables.4 %} +
+
+
-

DCC processed data workspaces

-
- {% render_table tables.4 %} + +
+
+

+ +

+
+
+ {% render_table tables.2 %} +
+
+
-

Partner upload workspaces

-
- {% render_table tables.5 %} + +
+
+

+ +

+
+
+ {% render_table tables.5 %} +
+
+
{% endblock after_panel %} From 8ed852f81c1546e956190d6ecceaecc9b256741d Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Wed, 4 Sep 2024 15:01:00 -0700 Subject: [PATCH 04/49] Show an alert indicating if the upload cycle is current, past, or future --- .../gregor_anvil/tests/test_views.py | 21 +++++++++++++++++++ .../gregor_anvil/uploadcycle_detail.html | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index d77260a8..0327789e 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -1202,6 +1202,27 @@ def test_includes_date_ready_for_compute(self): self.assertEqual(response.status_code, 200) self.assertContains(response, "Jan. 1, 2022") + def test_alert_for_current_cycle(self): + upload_cycle = self.model_factory.create(is_current=True) + self.client.force_login(self.user) + response = self.client.get(self.get_url(upload_cycle.cycle)) + self.assertContains(response, "alert alert-success") + self.assertContains(response, "This is the current upload cycle.") + + def test_alert_for_past_cycle(self): + upload_cycle = self.model_factory.create(is_past=True) + self.client.force_login(self.user) + response = self.client.get(self.get_url(upload_cycle.cycle)) + self.assertContains(response, "alert alert-danger") + self.assertContains(response, "This is a past upload cycle.") + + def test_alert_for_future_cycle(self): + upload_cycle = self.model_factory.create(is_future=True) + self.client.force_login(self.user) + response = self.client.get(self.get_url(upload_cycle.cycle)) + self.assertContains(response, "alert alert-danger") + self.assertContains(response, "This is a future upload cycle.") + class UploadCycleListTest(TestCase): """Tests for the UploadCycleList view.""" diff --git a/gregor_django/templates/gregor_anvil/uploadcycle_detail.html b/gregor_django/templates/gregor_anvil/uploadcycle_detail.html index 05a1f2ef..96d6398d 100644 --- a/gregor_django/templates/gregor_anvil/uploadcycle_detail.html +++ b/gregor_django/templates/gregor_anvil/uploadcycle_detail.html @@ -4,6 +4,11 @@ {% block title %}Upload Cycle: {{ object }}{% endblock %} {% block note %} + + + {% if object.note %} -