From 44074897e2d920bfc567460b01a52b64e1ab7e5b Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 30 Aug 2024 13:34:55 -0700 Subject: [PATCH 01/97] Fix template for UploadWorkspaceAuthDomainAudit view This view was using the template for the upload workspace sharing audit instead of the auth domain audit. The behavior of the view is fine since the templates are very similar; it's just that the explanation and title are incorrect. --- gregor_django/gregor_anvil/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index 8b43b389..cdf8c701 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -394,7 +394,7 @@ def form_valid(self, form): class UploadWorkspaceAuthDomainAudit(AnVILConsortiumManagerStaffViewRequired, TemplateView): """View to audit UploadWorkspace auth domain membership for all UploadWorkspaces.""" - template_name = "gregor_anvil/upload_workspace_sharing_audit.html" + template_name = "gregor_anvil/upload_workspace_auth_domain_audit.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) From c4a9481cffadd43fb37fc465bbd00f51ad1e95cc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 16:25:10 +0000 Subject: [PATCH 02/97] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.6.2 → v0.6.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.2...v0.6.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 06d31928..ae91c05a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.6.2 + rev: v0.6.3 hooks: # Run the linter. - id: ruff From 7d48b0ca52588bd4de5f92dacaa558dcdca892c7 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 10:39:21 -0700 Subject: [PATCH 03/97] Add text to title when auditing all upload workspaces Instead of having the page title just have a colon followed by nothing when auditing all upload workspaces, instead check if there is an object and if not, display "all upload workspaces". Otherwise, display the object str as before. --- .../gregor_anvil/tests/test_views.py | 46 +++++++++++++++++++ .../upload_workspace_auth_domain_audit.html | 2 +- .../upload_workspace_sharing_audit.html | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index fa752a8a..32806ab0 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -2693,6 +2693,12 @@ def test_context_error_table_stop_sharing(self): ) self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + def test_title(self): + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + # self.assertContains(response, str(self.upload_workspace)) + self.assertIn("all upload workspaces", response.content.decode().lower()) + class UploadWorkspaceSharingAuditByWorkspaceTest(AnVILAPIMockTestMixin, TestCase): """Tests for the UploadWorkspaceSharingAuditByWorkspace view.""" @@ -3059,6 +3065,17 @@ def test_context_error_table_stop_sharing(self): ) self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + def test_title(self): + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.upload_workspace.workspace.billing_project.name, + self.upload_workspace.workspace.name, + ) + ) + self.assertContains(response, str(self.upload_workspace)) + # self.assertNotIn("all upload workspaces", response.content.decode().lower()) + class UploadWorkspaceSharingAuditByUploadCycleTest(AnVILAPIMockTestMixin, TestCase): """Tests for the UploadWorkspaceSharingAuditByUploadCycle view.""" @@ -3393,6 +3410,12 @@ def test_context_error_table_stop_sharing(self): ) self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + def test_title(self): + self.client.force_login(self.user) + response = self.client.get(self.get_url(self.upload_cycle.cycle)) + self.assertContains(response, str(self.upload_cycle)) + self.assertNotIn("all upload workspaces", response.content.decode().lower()) + class UploadWorkspaceSharingAuditResolveTest(AnVILAPIMockTestMixin, TestCase): def setUp(self): @@ -4847,6 +4870,12 @@ def test_context_needs_action_table_change_to_admin(self): ) self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + def test_title(self): + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + # self.assertContains(response, str(self.upload_workspace)) + self.assertIn("all upload workspaces", response.content.decode().lower()) + class UploadWorkspaceAuthDomainAuditByWorkspaceTest(AnVILAPIMockTestMixin, TestCase): """Tests for the UploadWorkspaceAuthDomainAuditByWorkspace view.""" @@ -5225,6 +5254,17 @@ def test_context_needs_action_table_change_to_admin(self): ) self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + def test_title(self): + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.upload_workspace.workspace.billing_project.name, + self.upload_workspace.workspace.name, + ) + ) + self.assertContains(response, str(self.upload_workspace)) + self.assertNotIn("all upload workspaces", response.content.decode().lower()) + class UploadWorkspaceAuthDomainAuditByUploadCycleTest(AnVILAPIMockTestMixin, TestCase): """Tests for the UploadWorkspaceSharingAuditByUploadCycle view.""" @@ -5566,6 +5606,12 @@ def test_context_needs_action_table_change_to_admin(self): ) self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + def test_title(self): + self.client.force_login(self.user) + response = self.client.get(self.get_url(self.upload_cycle.cycle)) + self.assertContains(response, str(self.upload_cycle)) + self.assertNotIn("all upload workspaces", response.content.decode().lower()) + class UploadWorkspaceAuthDomainAuditResolveTest(AnVILAPIMockTestMixin, TestCase): """Tests for the UploadWorkspaceAuthDomainAuditResolve view.""" diff --git a/gregor_django/templates/gregor_anvil/upload_workspace_auth_domain_audit.html b/gregor_django/templates/gregor_anvil/upload_workspace_auth_domain_audit.html index 1588d613..bfc33c32 100644 --- a/gregor_django/templates/gregor_anvil/upload_workspace_auth_domain_audit.html +++ b/gregor_django/templates/gregor_anvil/upload_workspace_auth_domain_audit.html @@ -6,7 +6,7 @@ {% block content %} -

Upload workspace auth domain audit: {{ object }}

+

Upload workspace auth domain audit: {% if object %} {{ object }} {% else %} all Upload Workspaces{% endif %}

diff --git a/gregor_django/templates/gregor_anvil/upload_workspace_sharing_audit.html b/gregor_django/templates/gregor_anvil/upload_workspace_sharing_audit.html index dc4b1a0c..80c50a37 100644 --- a/gregor_django/templates/gregor_anvil/upload_workspace_sharing_audit.html +++ b/gregor_django/templates/gregor_anvil/upload_workspace_sharing_audit.html @@ -6,7 +6,7 @@ {% block content %} -

Upload workspace sharing audit: {{ object }}

+

Upload workspace sharing audit: {% if object %}{{ object }}{% else %} all Upload Workspaces{% endif %}

From 96f73ea77b904736d28d8ea3fc9ef3f13076d523 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 10:51:19 -0700 Subject: [PATCH 04/97] Color can_compute=False black in audit table This makes more sense; red typically indicates an error while black indicates "no but not a problem". --- .../gregor_anvil/audit/upload_workspace_sharing_audit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py b/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py index 249c7a24..3ef33806 100644 --- a/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py +++ b/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py @@ -135,7 +135,7 @@ class UploadWorkspaceSharingAuditTable(tables.Table): managed_group = tables.Column(linkify=True) # is_shared = tables.Column() access = tables.Column(verbose_name="Current access") - can_compute = BooleanIconColumn(show_false_icon=True, null=True) + can_compute = BooleanIconColumn(show_false_icon=True, null=True, true_color="green", false_color="black") note = tables.Column() # action = tables.Column() action = tables.TemplateColumn( From 13134c15d1579b28f9085c4375687b37eca7ac84 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 11:03:09 -0700 Subject: [PATCH 05/97] Add (basic) tests for audit tables --- .../gregor_anvil/tests/test_audit.py | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/gregor_django/gregor_anvil/tests/test_audit.py b/gregor_django/gregor_anvil/tests/test_audit.py index 83dc8ff5..ac30b6ac 100644 --- a/gregor_django/gregor_anvil/tests/test_audit.py +++ b/gregor_django/gregor_anvil/tests/test_audit.py @@ -162,6 +162,67 @@ def test_get_errors_table(self): self.assertEqual(table.rows[0].get_cell("value"), "c") +class UploadWorkspaceSharingAuditTableTest(TestCase): + """General tests of the UploadWorkspaceSharingAuditTable class.""" + + def test_no_rows(self): + """Table works with no rows.""" + table = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable([]) + self.assertIsInstance(table, upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable) + self.assertEqual(len(table.rows), 0) + + def test_one_row(self): + """Table works with one row.""" + upload_workspace = factories.UploadWorkspaceFactory.create() + group = ManagedGroupFactory.create() + WorkspaceGroupSharingFactory.create( + workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.READER + ) + data = [ + { + "workspace": upload_workspace, + "managed_group": group, + "access": WorkspaceGroupSharing.READER, + "can_compute": None, + "note": "a note", + "action": "", + }, + ] + table = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable(data) + self.assertIsInstance(table, upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable) + self.assertEqual(len(table.rows), 1) + + def test_two_rows(self): + """Table works with two rows.""" + upload_workspace = factories.UploadWorkspaceFactory.create() + group_1 = ManagedGroupFactory.create() + group_2 = ManagedGroupFactory.create() + WorkspaceGroupSharingFactory.create( + workspace=upload_workspace.workspace, group=group_1, access=WorkspaceGroupSharing.READER + ) + data = [ + { + "workspace": upload_workspace, + "managed_group": group_1, + "access": WorkspaceGroupSharing.READER, + "can_compute": None, + "note": "a note", + "action": "", + }, + { + "workspace": upload_workspace, + "managed_group": group_2, + "access": None, + "can_compute": None, + "note": "a note", + "action": "", + }, + ] + table = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable(data) + self.assertIsInstance(table, upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable) + self.assertEqual(len(table.rows), 2) + + class UploadWorkspaceSharingAuditTest(TestCase): """General tests of the `UploadWorkspaceSharingAudit` class.""" @@ -3860,6 +3921,68 @@ def test_other_group_shared_as_owner(self): self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) +class UploadWorkspaceAuthDomainAuditTableTest(TestCase): + """General tests of the UploadWorkspaceAuthDomainAuditTable class.""" + + def test_no_rows(self): + """Table works with no rows.""" + table = upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable([]) + self.assertIsInstance(table, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable) + self.assertEqual(len(table.rows), 0) + + def test_one_row(self): + """Table works with one row.""" + upload_workspace = factories.UploadWorkspaceFactory.create() + group = ManagedGroupFactory.create() + GroupGroupMembershipFactory.create( + parent_group=upload_workspace.workspace.authorization_domains.first(), + child_group=group, + role=GroupGroupMembership.MEMBER, + ) + data = [ + { + "workspace": upload_workspace, + "managed_group": group, + "role": GroupGroupMembership.MEMBER, + "note": "a note", + "action": "", + }, + ] + table = upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable(data) + self.assertIsInstance(table, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable) + self.assertEqual(len(table.rows), 1) + + def test_two_rows(self): + """Table works with two rows.""" + upload_workspace = factories.UploadWorkspaceFactory.create() + group_1 = ManagedGroupFactory.create() + group_2 = ManagedGroupFactory.create() + GroupGroupMembershipFactory.create( + parent_group=upload_workspace.workspace.authorization_domains.first(), + child_group=group_1, + role=GroupGroupMembership.MEMBER, + ) + data = [ + { + "workspace": upload_workspace, + "managed_group": group_1, + "role": GroupGroupMembership.MEMBER, + "note": "a note", + "action": "", + }, + { + "workspace": upload_workspace, + "managed_group": group_2, + "role": None, + "note": "a note", + "action": "", + }, + ] + table = upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable(data) + self.assertIsInstance(table, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable) + self.assertEqual(len(table.rows), 2) + + class UploadWorkspaceAuthDomainAuditTest(TestCase): """General tests of the `UploadWorkspaceAuthDomainAudit` class.""" From ac6c5193e7d17581defd2b409c1a65a2a7288f13 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 11:18:08 -0700 Subject: [PATCH 06/97] Only show can_compute icon for owners and writers Do not show can_compute for readers. Also, add tests for the audit result classes so that we can test the get_table_dictionary method. In this case, there is no need to test the individual classes, since they are all just inheriting from the main class without much different behavior. --- .../audit/upload_workspace_sharing_audit.py | 5 +- .../gregor_anvil/tests/test_audit.py | 131 ++++++++++++++++++ 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py b/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py index 3ef33806..af7befe6 100644 --- a/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py +++ b/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py @@ -34,11 +34,14 @@ def get_action_url(self): def get_table_dictionary(self): """Return a dictionary that can be used to populate an instance of `dbGaPDataSharingSnapshotAuditTable`.""" + can_compute = None + if self.current_sharing_instance and self.current_sharing_instance.access != WorkspaceGroupSharing.READER: + can_compute = self.current_sharing_instance.can_compute row = { "workspace": self.workspace, "managed_group": self.managed_group, "access": self.current_sharing_instance.access if self.current_sharing_instance else None, - "can_compute": self.current_sharing_instance.can_compute if self.current_sharing_instance else None, + "can_compute": can_compute, "note": self.note, "action": self.action, "action_url": self.get_action_url(), diff --git a/gregor_django/gregor_anvil/tests/test_audit.py b/gregor_django/gregor_anvil/tests/test_audit.py index ac30b6ac..83f4975e 100644 --- a/gregor_django/gregor_anvil/tests/test_audit.py +++ b/gregor_django/gregor_anvil/tests/test_audit.py @@ -162,6 +162,87 @@ def test_get_errors_table(self): self.assertEqual(table.rows[0].get_cell("value"), "c") +class UploadWorkspaceSharingAuditResultTest(TestCase): + """General tests of the UploadWorkspaceSharingAuditResult dataclasses.""" + + def test_shared_as_owner(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + sharing = WorkspaceGroupSharingFactory.create( + workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.OWNER, can_compute=True + ) + instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + workspace=upload_workspace, + managed_group=group, + current_sharing_instance=sharing, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertEqual(table_dictionary["access"], sharing.OWNER) + self.assertEqual(table_dictionary["can_compute"], True) + + def test_shared_as_writer_with_compute(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + sharing = WorkspaceGroupSharingFactory.create( + workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.WRITER, can_compute=True + ) + instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + workspace=upload_workspace, + managed_group=group, + current_sharing_instance=sharing, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertEqual(table_dictionary["access"], sharing.WRITER) + self.assertEqual(table_dictionary["can_compute"], True) + + def test_shared_as_writer_without_compute(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + sharing = WorkspaceGroupSharingFactory.create( + workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.WRITER, can_compute=False + ) + instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + workspace=upload_workspace, + managed_group=group, + current_sharing_instance=sharing, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertEqual(table_dictionary["access"], sharing.WRITER) + self.assertEqual(table_dictionary["can_compute"], False) + + def test_shared_as_reader(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + sharing = WorkspaceGroupSharingFactory.create( + workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.READER + ) + instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + workspace=upload_workspace, + managed_group=group, + current_sharing_instance=sharing, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertEqual(table_dictionary["access"], sharing.READER) + self.assertIsNone(table_dictionary["can_compute"]) + + def test_not_shared(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + workspace=upload_workspace, + managed_group=group, + current_sharing_instance=None, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertIsNone(table_dictionary["access"]) + self.assertIsNone(table_dictionary["can_compute"]) + + class UploadWorkspaceSharingAuditTableTest(TestCase): """General tests of the UploadWorkspaceSharingAuditTable class.""" @@ -3921,6 +4002,56 @@ def test_other_group_shared_as_owner(self): self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) +class UploadWorkspaceAuthDomainAuditResultTest(TestCase): + """General tests of the UploadWorkspaceAuthDomainAuditResult dataclasses.""" + + def test_member_as_admin(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + membership = GroupGroupMembershipFactory.create( + parent_group=upload_workspace.workspace.authorization_domains.first(), + child_group=group, + role=GroupGroupMembership.ADMIN, + ) + instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + workspace=upload_workspace, + managed_group=group, + current_membership_instance=membership, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertEqual(table_dictionary["role"], membership.ADMIN) + + def test_member_as_member(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + membership = GroupGroupMembershipFactory.create( + parent_group=upload_workspace.workspace.authorization_domains.first(), + child_group=group, + role=GroupGroupMembership.MEMBER, + ) + instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + workspace=upload_workspace, + managed_group=group, + current_membership_instance=membership, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertEqual(table_dictionary["role"], membership.MEMBER) + + def test_not_member(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + workspace=upload_workspace, + managed_group=group, + current_membership_instance=None, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertIsNone(table_dictionary["role"]) + + class UploadWorkspaceAuthDomainAuditTableTest(TestCase): """General tests of the UploadWorkspaceAuthDomainAuditTable class.""" From a2b0ee07fc903a9e65001a11b982846b462eb429 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 11:22:08 -0700 Subject: [PATCH 07/97] Remove unused code from sharing audit --- .../audit/upload_workspace_sharing_audit.py | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py b/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py index af7befe6..45d640aa 100644 --- a/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py +++ b/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py @@ -20,18 +20,6 @@ class UploadWorkspaceSharingAuditResult(GREGoRAuditResult): action: str = None current_sharing_instance: WorkspaceGroupSharing = None - def get_action_url(self): - """The URL that handles the action needed.""" - # return reverse( - # "gregor_anvil:audit:upload_workspaces:sharing:resolve", - # args=[ - # self.dbgap_application.dbgap_project_id, - # self.workspace.workspace.billing_project.name, - # self.workspace.workspace.name, - # ], - # ) - return "" - def get_table_dictionary(self): """Return a dictionary that can be used to populate an instance of `dbGaPDataSharingSnapshotAuditTable`.""" can_compute = None @@ -44,7 +32,6 @@ def get_table_dictionary(self): "can_compute": can_compute, "note": self.note, "action": self.action, - "action_url": self.get_action_url(), } return row @@ -53,8 +40,6 @@ def get_table_dictionary(self): class VerifiedShared(UploadWorkspaceSharingAuditResult): """Audit results class for when Sharing has been verified.""" - is_shared: bool = True - def __str__(self): return f"Verified sharing: {self.note}" @@ -63,8 +48,6 @@ def __str__(self): class VerifiedNotShared(UploadWorkspaceSharingAuditResult): """Audit results class for when no Sharing has been verified.""" - is_shared: bool = False - def __str__(self): return f"Verified not shared: {self.note}" @@ -73,7 +56,6 @@ def __str__(self): class ShareAsReader(UploadWorkspaceSharingAuditResult): """Audit results class for when Sharing should be granted as a reader.""" - is_shared: bool = False action: str = "Share as reader" def __str__(self): @@ -84,7 +66,6 @@ def __str__(self): class ShareAsWriter(UploadWorkspaceSharingAuditResult): """Audit results class for when Sharing should be granted as a writer.""" - is_shared: bool = False action: str = "Share as writer" def __str__(self): @@ -95,7 +76,6 @@ def __str__(self): class ShareAsOwner(UploadWorkspaceSharingAuditResult): """Audit results class for when Sharing should be granted as an owner.""" - is_shared: bool = False action: str = "Share as owner" def __str__(self): @@ -106,7 +86,6 @@ def __str__(self): class ShareWithCompute(UploadWorkspaceSharingAuditResult): """Audit results class for when Sharing should be granted with compute access.""" - is_shared: bool = False action: str = "Share with compute" def __str__(self): @@ -117,7 +96,6 @@ def __str__(self): class StopSharing(UploadWorkspaceSharingAuditResult): """Audit results class for when Sharing should be removed for a known reason.""" - is_shared: bool = True action: str = "Stop sharing" def __str__(self): @@ -136,11 +114,9 @@ class UploadWorkspaceSharingAuditTable(tables.Table): workspace = tables.Column(linkify=True) managed_group = tables.Column(linkify=True) - # is_shared = tables.Column() access = tables.Column(verbose_name="Current access") can_compute = BooleanIconColumn(show_false_icon=True, null=True, true_color="green", false_color="black") note = tables.Column() - # action = tables.Column() action = tables.TemplateColumn( template_name="gregor_anvil/snippets/upload_workspace_sharing_audit_action_button.html" ) From e3fa75157aa5351b81f5b34e65ef0f2b6ba305c9 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 12:02:59 -0700 Subject: [PATCH 08/97] Fix tests for auth domain audit classes --- gregor_django/gregor_anvil/tests/test_audit.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gregor_django/gregor_anvil/tests/test_audit.py b/gregor_django/gregor_anvil/tests/test_audit.py index 83f4975e..7c0b4b10 100644 --- a/gregor_django/gregor_anvil/tests/test_audit.py +++ b/gregor_django/gregor_anvil/tests/test_audit.py @@ -4013,7 +4013,7 @@ def test_member_as_admin(self): child_group=group, role=GroupGroupMembership.ADMIN, ) - instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + instance = upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditResult( workspace=upload_workspace, managed_group=group, current_membership_instance=membership, @@ -4030,7 +4030,7 @@ def test_member_as_member(self): child_group=group, role=GroupGroupMembership.MEMBER, ) - instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + instance = upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditResult( workspace=upload_workspace, managed_group=group, current_membership_instance=membership, @@ -4042,7 +4042,7 @@ def test_member_as_member(self): def test_not_member(self): upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) group = ManagedGroupFactory.create() - instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + instance = upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditResult( workspace=upload_workspace, managed_group=group, current_membership_instance=None, From 1cc3f8783693cc9891b1f19df3ff892f631c9d38 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 12:04:39 -0700 Subject: [PATCH 09/97] Shorten error explanation for sharing audit --- .../snippets/upload_workspace_sharing_audit_explanation.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gregor_django/templates/gregor_anvil/snippets/upload_workspace_sharing_audit_explanation.html b/gregor_django/templates/gregor_anvil/snippets/upload_workspace_sharing_audit_explanation.html index af07d58f..cdf2a379 100644 --- a/gregor_django/templates/gregor_anvil/snippets/upload_workspace_sharing_audit_explanation.html +++ b/gregor_django/templates/gregor_anvil/snippets/upload_workspace_sharing_audit_explanation.html @@ -36,7 +36,7 @@

  • Errors
    • -
    • The workspace has been shared with an unexpected group as an "OWNER".
    • +
    • The workspace has been shared with an unexpected group.

    From f4552b1d8b895148f179d43fc440951352daeb4f Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 12:07:02 -0700 Subject: [PATCH 10/97] Fix auth domain audit explanation for final changes The auth domain audit explanation still had the previous behavior (before Cat's review and subsequent changes). Update the explanation to reflect the actual behavior. --- ...ad_workspace_auth_domain_audit_explanation.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gregor_django/templates/gregor_anvil/snippets/upload_workspace_auth_domain_audit_explanation.html b/gregor_django/templates/gregor_anvil/snippets/upload_workspace_auth_domain_audit_explanation.html index edd9af6c..8eca84f7 100644 --- a/gregor_django/templates/gregor_anvil/snippets/upload_workspace_auth_domain_audit_explanation.html +++ b/gregor_django/templates/gregor_anvil/snippets/upload_workspace_auth_domain_audit_explanation.html @@ -12,6 +12,12 @@

    This audit checks that auth domain membership is appropriate for the current point in the upload cycle. Membership is expected to be as follows.
      +
    • Before the upload cycle begins:
    • +
        +
      • GREGOR_DCC_ADMINS (as admin)
      • +
      • GREGOR_DCC_WRITERS
      • +
      • GREGOR_DCC_MEMBERS
      • +
    • Before the combined workspace is completed:
      • GREGOR_DCC_ADMINS (as admin)
      • @@ -21,6 +27,14 @@

      • The member group for the Research Center associated with this upload workspace
      • The non-member group for the Research Center associated with this upload workspace
      +
    • After QC has been completed:
    • +
        +
      • GREGOR_DCC_ADMINS (as admin)
      • +
      • GREGOR_DCC_WRITERS
      • +
      • GREGOR_DCC_MEMBERS
      • +
      • The member group for the Research Center associated with this upload workspace
      • +
      • The non-member group for the Research Center associated with this upload workspace
      • +
    • After the combined workspace is completed:
      • GREGOR_DCC_ADMINS (as admin)
      • From dd6d56c145bca4253b085ba94ad4f29b32fa19db Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 12:48:11 -0700 Subject: [PATCH 11/97] Update CI to fail if no files are found The coverage job is failing because github added a breaking change in v4.4 of the upload-artifact job such that hidden files were no longer uploaded by default. This breaks the current coverage setup where the coverage file is hidden (.coverage). This change causes the upload-artifact job to fail if no files are found, which is really what we want. With this change, I expect all pytest jobs to fail at the step of uploading the coverage file. --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e45bc4a..eaab61e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,6 +103,7 @@ jobs: with: name: coverage-data-${{ strategy.job-index }} path: .coverage-${{ strategy.job-index }} + if-no-files-found: error coverage: needs: From 3f04ec354423e1b74a28f213c7643d0ce4fe1d1f Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 13:38:59 -0700 Subject: [PATCH 12/97] Rename coverage files to not have a . at the beginning This way they won't be considered hidden files by the upload-artifacts action. --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eaab61e3..b8200359 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,7 +93,7 @@ jobs: - name: Run tests run: | pytest --cov=gregor_django -n auto - mv .coverage .coverage-${{ strategy.job-index }} + mv .coverage coverage-${{ strategy.job-index }} - name: List files for debugging purposes run: ls -lhta @@ -102,7 +102,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: coverage-data-${{ strategy.job-index }} - path: .coverage-${{ strategy.job-index }} + path: coverage-${{ strategy.job-index }} if-no-files-found: error coverage: @@ -130,7 +130,7 @@ jobs: - name: Merge coverage files run: | - python -m coverage combine ./artifacts/coverage-data*/.coverage-* + python -m coverage combine ./artifacts/coverage-data*/coverage-* python -m coverage xml ls -la .coverage* From c6b541e1ef7c13579b96a2882c08774fd846bac9 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 16:10:51 -0700 Subject: [PATCH 13/97] Pin github actions to full versions in workflows This way, they should get updated via dependabot and then we can fix any issues with new versions in the dependabot branch, instead of in a random branch after something changes. --- .github/workflows/ci.yml | 19 ++++++++++--------- .github/workflows/gitleaks.yml | 4 ++-- .github/workflows/pip-compile.yml | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b8200359..4e094143 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,10 +54,10 @@ jobs: steps: - name: Checkout Code Repository - uses: actions/checkout@v4 + uses: actions/checkout@v4.1.7 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v5.2.0 with: python-version: ${{ matrix.python-version }} cache: pip @@ -78,8 +78,8 @@ jobs: - name: Recompile pip files if requested if: matrix.pip-recompile run: | - pip-compile requirements/requirements.in - pip-compile requirements/test-requirements.in + pip-compile -v requirements/requirements.in + pip-compile -v requirements/test-requirements.in # Print out changes. git diff @@ -99,7 +99,7 @@ jobs: run: ls -lhta - name: Upload coverage data - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.4.0 with: name: coverage-data-${{ strategy.job-index }} path: coverage-${{ strategy.job-index }} @@ -111,10 +111,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repo - uses: actions/checkout@v4 + uses: actions/checkout@v4.1.7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v5.2.0 with: python-version: '3.10' @@ -124,12 +124,13 @@ jobs: pip install --upgrade coverage "django<4" django-coverage-plugin - name: Download coverage data - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v4.1.8 with: path: ./artifacts/ - name: Merge coverage files run: | + ls -la ./artifacts/coverage-data* python -m coverage combine ./artifacts/coverage-data*/coverage-* python -m coverage xml ls -la .coverage* @@ -139,6 +140,6 @@ jobs: python -m coverage report - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v4.5.0 with: token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml index 9efde5a6..f6cca493 100644 --- a/.github/workflows/gitleaks.yml +++ b/.github/workflows/gitleaks.yml @@ -10,10 +10,10 @@ jobs: name: gitleaks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4.1.7 with: fetch-depth: 0 - - uses: gitleaks/gitleaks-action@v2 + - uses: gitleaks/gitleaks-action@v2.3.6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE}} # Only required for Organizations, not personal accounts. diff --git a/.github/workflows/pip-compile.yml b/.github/workflows/pip-compile.yml index 95d11720..93c60d63 100644 --- a/.github/workflows/pip-compile.yml +++ b/.github/workflows/pip-compile.yml @@ -13,12 +13,12 @@ jobs: steps: - name: Checkout Code Repository - uses: actions/checkout@v4 + uses: actions/checkout@v4.1.7 with: ref: ${{ github.head_ref }} - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v5.2.0 with: python-version: "3.10" From dd5c2d90681e2b053be56f65a3ac48323a8922ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 23:33:36 +0000 Subject: [PATCH 14/97] Bump pytest-django from 4.8.0 to 4.9.0 Bumps [pytest-django](https://github.com/pytest-dev/pytest-django) from 4.8.0 to 4.9.0. - [Release notes](https://github.com/pytest-dev/pytest-django/releases) - [Changelog](https://github.com/pytest-dev/pytest-django/blob/main/docs/changelog.rst) - [Commits](https://github.com/pytest-dev/pytest-django/compare/v4.8.0...v4.9.0) --- updated-dependencies: - dependency-name: pytest-django dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/test-requirements.txt b/requirements/test-requirements.txt index cd16f745..6f167ee1 100644 --- a/requirements/test-requirements.txt +++ b/requirements/test-requirements.txt @@ -58,7 +58,7 @@ pytest==8.3.2 # pytest-xdist pytest-cov==5.0.0 # via -r requirements/test-requirements.in -pytest-django==4.8.0 +pytest-django==4.9.0 # via -r requirements/test-requirements.in pytest-sugar==1.0.0 # via -r requirements/test-requirements.in From c5b53970e0eae37474cd0bc7201eee4257015914 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 23:33:50 +0000 Subject: [PATCH 15/97] Bump sphinx-autobuild from 2024.4.16 to 2024.9.3 Bumps [sphinx-autobuild](https://github.com/sphinx-doc/sphinx-autobuild) from 2024.4.16 to 2024.9.3. - [Release notes](https://github.com/sphinx-doc/sphinx-autobuild/releases) - [Changelog](https://github.com/sphinx-doc/sphinx-autobuild/blob/main/NEWS.rst) - [Commits](https://github.com/sphinx-doc/sphinx-autobuild/compare/2024.04.16...2024.09.03) --- updated-dependencies: - dependency-name: sphinx-autobuild dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index cce27783..36dc29dc 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -165,7 +165,7 @@ sphinx==8.0.2 # via # -r requirements/dev-requirements.in # sphinx-autobuild -sphinx-autobuild==2024.4.16 +sphinx-autobuild==2024.9.3 # via -r requirements/dev-requirements.in sphinxcontrib-applehelp==1.0.4 # via sphinx From bdedaf70c0816b7b1ce7a7d78333be98700a558b Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 3 Sep 2024 16:39:40 -0700 Subject: [PATCH 16/97] Bump cryptography version to address security update --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index c5bf25ab..48ec6dac 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -31,7 +31,7 @@ crispy-bootstrap5==2024.2 # via # -r requirements/requirements.in # django-anvil-consortium-manager -cryptography==42.0.4 +cryptography==43.0.1 # via pyjwt defusedxml==0.7.1 # via python3-openid From af625981a9db29a1a019b86d75acdb706371cff1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 23:53:02 +0000 Subject: [PATCH 17/97] Bump django from 4.2.15 to 4.2.16 Bumps [django](https://github.com/django/django) from 4.2.15 to 4.2.16. - [Commits](https://github.com/django/django/compare/4.2.15...4.2.16) --- updated-dependencies: - dependency-name: django dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- requirements/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index cce27783..80b59c0a 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -48,7 +48,7 @@ dill==0.3.8 # via pylint distlib==0.3.8 # via virtualenv -django==4.2.15 +django==4.2.16 # via # -c requirements/requirements.txt # django-debug-toolbar diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 48ec6dac..e395dfd0 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -35,7 +35,7 @@ cryptography==43.0.1 # via pyjwt defusedxml==0.7.1 # via python3-openid -django==4.2.15 +django==4.2.16 # via # -r requirements/requirements.in # crispy-bootstrap5 From 1d58767ef20f302cd1dfa335be7299e27349fe19 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Wed, 4 Sep 2024 11:44:43 -0700 Subject: [PATCH 18/97] Add upload workspace audit to cron job --- gregor_apps.cron | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gregor_apps.cron b/gregor_apps.cron index 38bf78ad..d857f24c 100644 --- a/gregor_apps.cron +++ b/gregor_apps.cron @@ -10,3 +10,6 @@ MAILTO="gregorweb@uw.edu" # Nightly user data audit 0 3 * * * . /var/www/django/gregor_apps/gregor-apps-activate.sh; python manage.py sync-drupal-data --update --email gregorweb@uw.edu >> cron.log + +# Nightly upload workspace audit +0 3 * * * . /var/www/django/gregor_apps/gregor-apps-activate.sh; python manage.py run_upload_workspace_audit --email gregorweb@uw.edu >> cron.log From 9cd89674e2f829058bd930096860a4cd268ed53a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:47:09 +0000 Subject: [PATCH 19/97] Bump django-model-utils from 4.5.1 to 5.0.0 Bumps [django-model-utils](https://github.com/jazzband/django-model-utils) from 4.5.1 to 5.0.0. - [Release notes](https://github.com/jazzband/django-model-utils/releases) - [Changelog](https://github.com/jazzband/django-model-utils/blob/master/CHANGES.rst) - [Commits](https://github.com/jazzband/django-model-utils/compare/4.5.1...5.0.0) --- updated-dependencies: - dependency-name: django-model-utils dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index e395dfd0..c29c1d52 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -80,7 +80,7 @@ django-login-required-middleware==0.9.0 # via -r requirements/requirements.in django-maintenance-mode==0.21.1 # via -r requirements/requirements.in -django-model-utils==4.5.1 +django-model-utils==5.0.0 # via -r requirements/requirements.in django-picklefield==3.2 # via -r requirements/requirements.in From 468c27db1795c8185ef3813303f342463909aef1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:02:10 +0000 Subject: [PATCH 20/97] Bump django-constance from 4.0.1 to 4.1.1 Bumps [django-constance](https://github.com/jazzband/django-constance) from 4.0.1 to 4.1.1. - [Release notes](https://github.com/jazzband/django-constance/releases) - [Changelog](https://github.com/jazzband/django-constance/blob/master/docs/changes.rst) - [Commits](https://github.com/jazzband/django-constance/compare/4.0.1...4.1.1) --- updated-dependencies: - dependency-name: django-constance dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index e395dfd0..c7b646bf 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -57,7 +57,7 @@ django-anvil-consortium-manager @ git+https://github.com/UW-GAC/django-anvil-con # via -r requirements/requirements.in django-autocomplete-light==3.11.0 # via django-anvil-consortium-manager -django-constance==4.0.1 +django-constance==4.1.1 # via -r requirements/requirements.in django-crispy-forms==2.3 # via From e8c7775e88bb88a65c149f747d1c60eb6f64552c Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Thu, 5 Sep 2024 15:32:23 -0700 Subject: [PATCH 21/97] Start splitting audit results into their own source files We can reuse the audit results classes for audits of other workspace types in the future. Split them into their own source file. --- .../upload_workspace_auth_domain_audit.py | 189 ++--- .../audit/upload_workspace_sharing_audit.py | 186 ++--- .../workspace_auth_domain_audit_results.py | 104 +++ .../audit/workspace_sharing_audit_results.py | 105 +++ .../gregor_anvil/tests/test_audit.py | 687 +++++++++--------- .../gregor_anvil/tests/test_views.py | 49 +- gregor_django/gregor_anvil/views.py | 37 +- 7 files changed, 692 insertions(+), 665 deletions(-) create mode 100644 gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py create mode 100644 gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py diff --git a/gregor_django/gregor_anvil/audit/upload_workspace_auth_domain_audit.py b/gregor_django/gregor_anvil/audit/upload_workspace_auth_domain_audit.py index ebb98e34..0910e548 100644 --- a/gregor_django/gregor_anvil/audit/upload_workspace_auth_domain_audit.py +++ b/gregor_django/gregor_anvil/audit/upload_workspace_auth_domain_audit.py @@ -1,110 +1,11 @@ -from dataclasses import dataclass - import django_tables2 as tables from anvil_consortium_manager.models import GroupGroupMembership, ManagedGroup from django.conf import settings from django.db.models import Q, QuerySet from ..models import CombinedConsortiumDataWorkspace, UploadWorkspace -from .base import GREGoRAudit, GREGoRAuditResult - - -@dataclass -class UploadWorkspaceAuthDomainAuditResult(GREGoRAuditResult): - """Base class to hold results for auditing upload workspace sharing.""" - - workspace: UploadWorkspace - note: str - managed_group: ManagedGroup - action: str = None - current_membership_instance: GroupGroupMembership = None - - def get_table_dictionary(self): - """Return a dictionary that can be used to populate an instance of `dbGaPDataSharingSnapshotAuditTable`.""" - row = { - "workspace": self.workspace, - "managed_group": self.managed_group, - "role": self.current_membership_instance.role if self.current_membership_instance else None, - "note": self.note, - "action": self.action, - } - return row - - -@dataclass -class VerifiedMember(UploadWorkspaceAuthDomainAuditResult): - """Audit results class for when member membership has been verified.""" - - def __str__(self): - return f"Verified member: {self.note}" - - -@dataclass -class VerifiedAdmin(UploadWorkspaceAuthDomainAuditResult): - """Audit results class for when membership with an admin role has been verified.""" - - is_shared: bool = False - - def __str__(self): - return f"Verified admin: {self.note}" - - -@dataclass -class VerifiedNotMember(UploadWorkspaceAuthDomainAuditResult): - """Audit results class for when member membership has been verified.""" - - def __str__(self): - return f"Verified member: {self.note}" - - -@dataclass -class AddMember(UploadWorkspaceAuthDomainAuditResult): - """Audit results class for when a member role should be added.""" - - action: str = "Add member" - - def __str__(self): - return f"Add member: {self.note}" - - -@dataclass -class AddAdmin(UploadWorkspaceAuthDomainAuditResult): - """Audit results class for when an admin role should be added.""" - - action: str = "Add admin" - - def __str__(self): - return f"Add admin: {self.note}" - - -@dataclass -class ChangeToMember(UploadWorkspaceAuthDomainAuditResult): - """Audit results class for when an admin role should be changed to a member role.""" - - action: str = "Change to member" - - def __str__(self): - return f"Change to member: {self.note}" - - -@dataclass -class ChangeToAdmin(UploadWorkspaceAuthDomainAuditResult): - """Audit results class for when a member role should be changed to an admin role.""" - - action: str = "Change to admin" - - def __str__(self): - return f"Change to admin: {self.note}" - - -@dataclass -class Remove(UploadWorkspaceAuthDomainAuditResult): - """Audit results class for when group membership should be removed.""" - - action: str = "Remove" - - def __str__(self): - return f"Share as owner: {self.note}" +from . import workspace_auth_domain_audit_results as audit_results +from .base import GREGoRAudit class UploadWorkspaceAuthDomainAuditTable(tables.Table): @@ -254,35 +155,35 @@ def _audit_workspace_and_group_for_rc_uploaders(self, upload_workspace, managed_ if upload_workspace.upload_cycle.is_future: note = self.RC_FUTURE_CYCLE if membership and membership.role == GroupGroupMembership.ADMIN: - self.errors.append(Remove(note=note, **result_kwargs)) + self.errors.append(audit_results.Remove(note=note, **result_kwargs)) elif membership: - self.needs_action.append(Remove(note=note, **result_kwargs)) + self.needs_action.append(audit_results.Remove(note=note, **result_kwargs)) else: - self.verified.append(VerifiedNotMember(note=note, **result_kwargs)) + self.verified.append(audit_results.VerifiedNotMember(note=note, **result_kwargs)) elif upload_workspace.upload_cycle.is_current: note = self.RC_UPLOADERS_BEFORE_QC if membership and membership.role == GroupGroupMembership.ADMIN: - self.errors.append(ChangeToMember(note=note, **result_kwargs)) + self.errors.append(audit_results.ChangeToMember(note=note, **result_kwargs)) elif membership: - self.verified.append(VerifiedMember(note=note, **result_kwargs)) + self.verified.append(audit_results.VerifiedMember(note=note, **result_kwargs)) else: - self.needs_action.append(AddMember(note=note, **result_kwargs)) + self.needs_action.append(audit_results.AddMember(note=note, **result_kwargs)) elif upload_workspace.upload_cycle.is_past and not upload_workspace.date_qc_completed: note = self.RC_UPLOADERS_BEFORE_QC if membership and membership.role == GroupGroupMembership.ADMIN: - self.errors.append(ChangeToMember(note=note, **result_kwargs)) + self.errors.append(audit_results.ChangeToMember(note=note, **result_kwargs)) elif membership: - self.verified.append(VerifiedMember(note=note, **result_kwargs)) + self.verified.append(audit_results.VerifiedMember(note=note, **result_kwargs)) else: - self.needs_action.append(AddMember(note=note, **result_kwargs)) + self.needs_action.append(audit_results.AddMember(note=note, **result_kwargs)) else: note = self.RC_UPLOADERS_AFTER_QC if membership and membership.role == GroupGroupMembership.ADMIN: - self.errors.append(Remove(note=note, **result_kwargs)) + self.errors.append(audit_results.Remove(note=note, **result_kwargs)) elif membership: - self.needs_action.append(Remove(note=note, **result_kwargs)) + self.needs_action.append(audit_results.Remove(note=note, **result_kwargs)) else: - self.verified.append(VerifiedNotMember(note=note, **result_kwargs)) + self.verified.append(audit_results.VerifiedNotMember(note=note, **result_kwargs)) def _audit_workspace_and_group_for_rc_members(self, upload_workspace, managed_group): membership = self._get_current_membership(upload_workspace, managed_group) @@ -296,27 +197,27 @@ def _audit_workspace_and_group_for_rc_members(self, upload_workspace, managed_gr if upload_workspace.upload_cycle.is_future: note = self.RC_FUTURE_CYCLE if membership and membership.role == GroupGroupMembership.ADMIN: - self.errors.append(Remove(note=note, **result_kwargs)) + self.errors.append(audit_results.Remove(note=note, **result_kwargs)) elif membership: - self.needs_action.append(Remove(note=note, **result_kwargs)) + self.needs_action.append(audit_results.Remove(note=note, **result_kwargs)) else: - self.verified.append(VerifiedNotMember(note=note, **result_kwargs)) + self.verified.append(audit_results.VerifiedNotMember(note=note, **result_kwargs)) elif not combined_workspace: note = self.RC_MEMBERS_BEFORE_COMBINED if membership and membership.role == GroupGroupMembership.ADMIN: - self.errors.append(ChangeToMember(note=note, **result_kwargs)) + self.errors.append(audit_results.ChangeToMember(note=note, **result_kwargs)) elif membership: - self.verified.append(VerifiedMember(note=note, **result_kwargs)) + self.verified.append(audit_results.VerifiedMember(note=note, **result_kwargs)) else: - self.needs_action.append(AddMember(note=note, **result_kwargs)) + self.needs_action.append(audit_results.AddMember(note=note, **result_kwargs)) else: note = self.RC_MEMBERS_AFTER_COMBINED if membership and membership.role == GroupGroupMembership.ADMIN: - self.errors.append(Remove(note=note, **result_kwargs)) + self.errors.append(audit_results.Remove(note=note, **result_kwargs)) elif membership: - self.needs_action.append(Remove(note=note, **result_kwargs)) + self.needs_action.append(audit_results.Remove(note=note, **result_kwargs)) else: - self.verified.append(VerifiedNotMember(note=note, **result_kwargs)) + self.verified.append(audit_results.VerifiedNotMember(note=note, **result_kwargs)) def _audit_workspace_and_group_for_rc_non_members(self, upload_workspace, managed_group): membership = self._get_current_membership(upload_workspace, managed_group) @@ -329,25 +230,25 @@ def _audit_workspace_and_group_for_rc_non_members(self, upload_workspace, manage if upload_workspace.upload_cycle.is_future: note = self.RC_FUTURE_CYCLE if membership and membership.role == GroupGroupMembership.ADMIN: - self.errors.append(Remove(note=note, **result_kwargs)) + self.errors.append(audit_results.Remove(note=note, **result_kwargs)) elif membership: - self.needs_action.append(Remove(note=note, **result_kwargs)) + self.needs_action.append(audit_results.Remove(note=note, **result_kwargs)) else: - self.verified.append(VerifiedNotMember(note=note, **result_kwargs)) + self.verified.append(audit_results.VerifiedNotMember(note=note, **result_kwargs)) else: note = self.RC_NON_MEMBERS_AFTER_START if membership and membership.role == GroupGroupMembership.ADMIN: - self.errors.append(ChangeToMember(note=note, **result_kwargs)) + self.errors.append(audit_results.ChangeToMember(note=note, **result_kwargs)) elif membership: - self.verified.append(VerifiedMember(note=note, **result_kwargs)) + self.verified.append(audit_results.VerifiedMember(note=note, **result_kwargs)) else: - self.needs_action.append(AddMember(note=note, **result_kwargs)) + self.needs_action.append(audit_results.AddMember(note=note, **result_kwargs)) def _audit_workspace_and_group_for_dcc_admin(self, upload_workspace, managed_group): membership = self._get_current_membership(upload_workspace, managed_group) if not membership: self.needs_action.append( - AddAdmin( + audit_results.AddAdmin( workspace=upload_workspace, managed_group=managed_group, note=self.DCC_ADMINS, @@ -356,7 +257,7 @@ def _audit_workspace_and_group_for_dcc_admin(self, upload_workspace, managed_gro ) elif membership.role == GroupGroupMembership.ADMIN: self.verified.append( - VerifiedAdmin( + audit_results.VerifiedAdmin( workspace=upload_workspace, managed_group=managed_group, note=self.DCC_ADMINS, @@ -365,7 +266,7 @@ def _audit_workspace_and_group_for_dcc_admin(self, upload_workspace, managed_gro ) else: self.needs_action.append( - ChangeToAdmin( + audit_results.ChangeToAdmin( workspace=upload_workspace, managed_group=managed_group, note=self.DCC_ADMINS, @@ -388,19 +289,19 @@ def _audit_workspace_and_group_for_dcc(self, upload_workspace, managed_group): } if not combined_workspace and not membership: - self.needs_action.append(AddMember(**result_kwargs)) + self.needs_action.append(audit_results.AddMember(**result_kwargs)) elif not combined_workspace and membership: if membership.role == GroupGroupMembership.MEMBER: - self.verified.append(VerifiedMember(**result_kwargs)) + self.verified.append(audit_results.VerifiedMember(**result_kwargs)) else: - self.errors.append(ChangeToMember(**result_kwargs)) + self.errors.append(audit_results.ChangeToMember(**result_kwargs)) elif combined_workspace and not membership: - self.verified.append(VerifiedNotMember(**result_kwargs)) + self.verified.append(audit_results.VerifiedNotMember(**result_kwargs)) elif combined_workspace and membership: if membership.role == GroupGroupMembership.ADMIN: - self.errors.append(Remove(**result_kwargs)) + self.errors.append(audit_results.Remove(**result_kwargs)) else: - self.needs_action.append(Remove(**result_kwargs)) + self.needs_action.append(audit_results.Remove(**result_kwargs)) def _audit_workspace_and_group_for_gregor_all(self, upload_workspace, managed_group): combined_workspace = self._get_combined_workspace(upload_workspace.upload_cycle) @@ -417,16 +318,16 @@ def _audit_workspace_and_group_for_gregor_all(self, upload_workspace, managed_gr } if not combined_workspace and not membership: - self.verified.append(VerifiedNotMember(**result_kwargs)) + self.verified.append(audit_results.VerifiedNotMember(**result_kwargs)) elif not combined_workspace and membership: - self.errors.append(Remove(**result_kwargs)) + self.errors.append(audit_results.Remove(**result_kwargs)) elif combined_workspace and not membership: - self.needs_action.append(AddMember(**result_kwargs)) + self.needs_action.append(audit_results.AddMember(**result_kwargs)) elif combined_workspace and membership: if membership.role == GroupGroupMembership.MEMBER: - self.verified.append(VerifiedMember(**result_kwargs)) + self.verified.append(audit_results.VerifiedMember(**result_kwargs)) else: - self.errors.append(ChangeToMember(**result_kwargs)) + self.errors.append(audit_results.ChangeToMember(**result_kwargs)) def _audit_workspace_and_anvil_group(self, upload_workspace, managed_group): """Ignore the AnVIL groups in this audit. @@ -444,6 +345,6 @@ def _audit_workspace_and_other_group(self, upload_workspace, managed_group): } if not membership: - self.verified.append(VerifiedNotMember(**result_kwargs)) + self.verified.append(audit_results.VerifiedNotMember(**result_kwargs)) elif membership: - self.errors.append(Remove(**result_kwargs)) + self.errors.append(audit_results.Remove(**result_kwargs)) diff --git a/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py b/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py index 45d640aa..079b8d13 100644 --- a/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py +++ b/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py @@ -1,5 +1,3 @@ -from dataclasses import dataclass - import django_tables2 as tables from anvil_consortium_manager.models import ManagedGroup, WorkspaceGroupSharing from django.conf import settings @@ -7,106 +5,8 @@ from ..models import CombinedConsortiumDataWorkspace, UploadWorkspace from ..tables import BooleanIconColumn -from .base import GREGoRAudit, GREGoRAuditResult - - -@dataclass -class UploadWorkspaceSharingAuditResult(GREGoRAuditResult): - """Base class to hold results for auditing upload workspace sharing.""" - - workspace: UploadWorkspace - note: str - managed_group: ManagedGroup - action: str = None - current_sharing_instance: WorkspaceGroupSharing = None - - def get_table_dictionary(self): - """Return a dictionary that can be used to populate an instance of `dbGaPDataSharingSnapshotAuditTable`.""" - can_compute = None - if self.current_sharing_instance and self.current_sharing_instance.access != WorkspaceGroupSharing.READER: - can_compute = self.current_sharing_instance.can_compute - row = { - "workspace": self.workspace, - "managed_group": self.managed_group, - "access": self.current_sharing_instance.access if self.current_sharing_instance else None, - "can_compute": can_compute, - "note": self.note, - "action": self.action, - } - return row - - -@dataclass -class VerifiedShared(UploadWorkspaceSharingAuditResult): - """Audit results class for when Sharing has been verified.""" - - def __str__(self): - return f"Verified sharing: {self.note}" - - -@dataclass -class VerifiedNotShared(UploadWorkspaceSharingAuditResult): - """Audit results class for when no Sharing has been verified.""" - - def __str__(self): - return f"Verified not shared: {self.note}" - - -@dataclass -class ShareAsReader(UploadWorkspaceSharingAuditResult): - """Audit results class for when Sharing should be granted as a reader.""" - - action: str = "Share as reader" - - def __str__(self): - return f"Share as reader: {self.note}" - - -@dataclass -class ShareAsWriter(UploadWorkspaceSharingAuditResult): - """Audit results class for when Sharing should be granted as a writer.""" - - action: str = "Share as writer" - - def __str__(self): - return f"Share as writer: {self.note}" - - -@dataclass -class ShareAsOwner(UploadWorkspaceSharingAuditResult): - """Audit results class for when Sharing should be granted as an owner.""" - - action: str = "Share as owner" - - def __str__(self): - return f"Share as owner: {self.note}" - - -@dataclass -class ShareWithCompute(UploadWorkspaceSharingAuditResult): - """Audit results class for when Sharing should be granted with compute access.""" - - action: str = "Share with compute" - - def __str__(self): - return f"Share with compute: {self.note}" - - -@dataclass -class StopSharing(UploadWorkspaceSharingAuditResult): - """Audit results class for when Sharing should be removed for a known reason.""" - - action: str = "Stop sharing" - - def __str__(self): - return f"Stop sharing: {self.note}" - - -@dataclass -class Error(UploadWorkspaceSharingAuditResult): - """Audit results class for when an error has been detected (e.g., shared and never should have been).""" - - pass +from . import workspace_sharing_audit_results +from .base import GREGoRAudit class UploadWorkspaceSharingAuditTable(tables.Table): @@ -266,59 +166,61 @@ def _audit_workspace_and_rc_uploader_group(self, upload_workspace, managed_group if upload_cycle.is_future: note = self.RC_UPLOADERS_FUTURE_CYCLE if not current_sharing: - self.verified.append(VerifiedNotShared(note=note, **audit_result_args)) + self.verified.append(workspace_sharing_audit_results.VerifiedNotShared(note=note, **audit_result_args)) elif current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(StopSharing(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.StopSharing(note=note, **audit_result_args)) else: - self.needs_action.append(StopSharing(note=note, **audit_result_args)) + self.needs_action.append(workspace_sharing_audit_results.StopSharing(note=note, **audit_result_args)) elif upload_cycle.is_current and not upload_cycle.date_ready_for_compute: note = self.RC_UPLOADERS_CURRENT_CYCLE_BEFORE_COMPUTE if current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(ShareAsWriter(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.ShareAsWriter(note=note, **audit_result_args)) elif ( current_sharing and current_sharing.access == WorkspaceGroupSharing.WRITER and not current_sharing.can_compute ): - self.verified.append(VerifiedShared(note=note, **audit_result_args)) + self.verified.append(workspace_sharing_audit_results.VerifiedShared(note=note, **audit_result_args)) else: - self.needs_action.append(ShareAsWriter(note=note, **audit_result_args)) + self.needs_action.append(workspace_sharing_audit_results.ShareAsWriter(note=note, **audit_result_args)) elif upload_cycle.is_current and upload_cycle.date_ready_for_compute: note = self.RC_UPLOADERS_CURRENT_CYCLE_AFTER_COMPUTE if current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(ShareWithCompute(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.ShareWithCompute(note=note, **audit_result_args)) elif ( current_sharing and current_sharing.access == WorkspaceGroupSharing.WRITER and current_sharing.can_compute ): - self.verified.append(VerifiedShared(note=note, **audit_result_args)) + self.verified.append(workspace_sharing_audit_results.VerifiedShared(note=note, **audit_result_args)) else: - self.needs_action.append(ShareWithCompute(note=note, **audit_result_args)) + self.needs_action.append( + workspace_sharing_audit_results.ShareWithCompute(note=note, **audit_result_args) + ) elif upload_cycle.is_past and not upload_workspace.date_qc_completed: note = self.RC_UPLOADERS_PAST_CYCLE_BEFORE_QC_COMPLETE if not current_sharing: - self.verified.append(VerifiedNotShared(note=note, **audit_result_args)) + self.verified.append(workspace_sharing_audit_results.VerifiedNotShared(note=note, **audit_result_args)) elif current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(StopSharing(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.StopSharing(note=note, **audit_result_args)) else: - self.needs_action.append(StopSharing(note=note, **audit_result_args)) + self.needs_action.append(workspace_sharing_audit_results.StopSharing(note=note, **audit_result_args)) elif upload_cycle.is_past and upload_workspace.date_qc_completed and not combined_workspace: note = self.RC_UPLOADERS_PAST_CYCLE_AFTER_QC_COMPLETE if not current_sharing: - self.verified.append(VerifiedNotShared(note=note, **audit_result_args)) + self.verified.append(workspace_sharing_audit_results.VerifiedNotShared(note=note, **audit_result_args)) elif current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(StopSharing(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.StopSharing(note=note, **audit_result_args)) else: - self.needs_action.append(StopSharing(note=note, **audit_result_args)) + self.needs_action.append(workspace_sharing_audit_results.StopSharing(note=note, **audit_result_args)) elif upload_cycle.is_past and combined_workspace: note = self.RC_UPLOADERS_PAST_CYCLE_COMBINED_WORKSPACE_READY if not current_sharing: - self.verified.append(VerifiedNotShared(note=note, **audit_result_args)) + self.verified.append(workspace_sharing_audit_results.VerifiedNotShared(note=note, **audit_result_args)) elif current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(StopSharing(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.StopSharing(note=note, **audit_result_args)) else: - self.needs_action.append(StopSharing(note=note, **audit_result_args)) + self.needs_action.append(workspace_sharing_audit_results.StopSharing(note=note, **audit_result_args)) else: raise ValueError("No case matched for RC uploader group.") @@ -343,21 +245,21 @@ def _audit_workspace_and_dcc_writer_group(self, upload_workspace, managed_group) if upload_cycle.is_future: note = self.DCC_WRITERS_FUTURE_CYCLE if current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(ShareWithCompute(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.ShareWithCompute(note=note, **audit_result_args)) elif ( current_sharing and current_sharing.access == WorkspaceGroupSharing.WRITER and current_sharing.can_compute ): self.verified.append( - VerifiedShared( + workspace_sharing_audit_results.VerifiedShared( note=note, **audit_result_args, ) ) else: self.needs_action.append( - ShareWithCompute( + workspace_sharing_audit_results.ShareWithCompute( note=note, **audit_result_args, ) @@ -365,21 +267,21 @@ def _audit_workspace_and_dcc_writer_group(self, upload_workspace, managed_group) elif upload_cycle.is_current: note = self.DCC_WRITERS_CURRENT_CYCLE if current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(ShareWithCompute(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.ShareWithCompute(note=note, **audit_result_args)) elif ( current_sharing and current_sharing.access == WorkspaceGroupSharing.WRITER and current_sharing.can_compute ): self.verified.append( - VerifiedShared( + workspace_sharing_audit_results.VerifiedShared( note=note, **audit_result_args, ) ) else: self.needs_action.append( - ShareWithCompute( + workspace_sharing_audit_results.ShareWithCompute( note=note, **audit_result_args, ) @@ -387,21 +289,21 @@ def _audit_workspace_and_dcc_writer_group(self, upload_workspace, managed_group) elif upload_cycle.is_past and not upload_workspace.date_qc_completed: note = self.DCC_WRITERS_PAST_CYCLE_BEFORE_QC_COMPLETE if current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(ShareWithCompute(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.ShareWithCompute(note=note, **audit_result_args)) elif ( current_sharing and current_sharing.access == WorkspaceGroupSharing.WRITER and current_sharing.can_compute ): self.verified.append( - VerifiedShared( + workspace_sharing_audit_results.VerifiedShared( note=note, **audit_result_args, ) ) else: self.needs_action.append( - ShareWithCompute( + workspace_sharing_audit_results.ShareWithCompute( note=note, **audit_result_args, ) @@ -409,17 +311,17 @@ def _audit_workspace_and_dcc_writer_group(self, upload_workspace, managed_group) elif upload_cycle.is_past and upload_workspace.date_qc_completed and not combined_workspace: note = self.DCC_WRITERS_PAST_CYCLE_AFTER_QC_COMPLETE if current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(StopSharing(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.StopSharing(note=note, **audit_result_args)) elif not current_sharing: self.verified.append( - VerifiedNotShared( + workspace_sharing_audit_results.VerifiedNotShared( note=note, **audit_result_args, ) ) else: self.needs_action.append( - StopSharing( + workspace_sharing_audit_results.StopSharing( note=note, **audit_result_args, ) @@ -427,17 +329,17 @@ def _audit_workspace_and_dcc_writer_group(self, upload_workspace, managed_group) elif upload_cycle.is_past and combined_workspace: note = self.DCC_WRITERS_PAST_CYCLE_COMBINED_WORKSPACE_READY if current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(StopSharing(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.StopSharing(note=note, **audit_result_args)) elif not current_sharing: self.verified.append( - VerifiedNotShared( + workspace_sharing_audit_results.VerifiedNotShared( note=note, **audit_result_args, ) ) else: self.needs_action.append( - StopSharing( + workspace_sharing_audit_results.StopSharing( note=note, **audit_result_args, ) @@ -462,17 +364,17 @@ def _audit_workspace_and_auth_domain(self, upload_workspace, managed_group): note = self.AUTH_DOMAIN_AS_READER if current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: - self.errors.append(ShareAsReader(note=note, **audit_result_args)) + self.errors.append(workspace_sharing_audit_results.ShareAsReader(note=note, **audit_result_args)) elif current_sharing and current_sharing.access == WorkspaceGroupSharing.READER: self.verified.append( - VerifiedShared( + workspace_sharing_audit_results.VerifiedShared( note=note, **audit_result_args, ) ) else: self.needs_action.append( - ShareAsReader( + workspace_sharing_audit_results.ShareAsReader( note=note, **audit_result_args, ) @@ -495,14 +397,14 @@ def _audit_workspace_and_dcc_admin_group(self, upload_workspace, managed_group): note = self.DCC_ADMIN_AS_OWNER if current_sharing and current_sharing.access == WorkspaceGroupSharing.OWNER: self.verified.append( - VerifiedShared( + workspace_sharing_audit_results.VerifiedShared( note=note, **audit_result_args, ) ) else: self.needs_action.append( - ShareAsOwner( + workspace_sharing_audit_results.ShareAsOwner( note=note, **audit_result_args, ) @@ -524,14 +426,14 @@ def _audit_workspace_and_other_group(self, upload_workspace, managed_group): if not current_sharing: self.verified.append( - VerifiedNotShared( + workspace_sharing_audit_results.VerifiedNotShared( note=self.OTHER_GROUP_NO_ACCESS, **audit_result_args, ) ) else: self.errors.append( - StopSharing( + workspace_sharing_audit_results.StopSharing( note=self.OTHER_GROUP_NO_ACCESS, **audit_result_args, ) diff --git a/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py b/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py new file mode 100644 index 00000000..655c0803 --- /dev/null +++ b/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py @@ -0,0 +1,104 @@ +from dataclasses import dataclass + +from anvil_consortium_manager.models import GroupGroupMembership, ManagedGroup + +from ..models import UploadWorkspace +from .base import GREGoRAuditResult + + +@dataclass +class WorkspaceAuthDomainAuditResult(GREGoRAuditResult): + """Base class to hold results for auditing upload workspace sharing.""" + + workspace: UploadWorkspace + note: str + managed_group: ManagedGroup + action: str = None + current_membership_instance: GroupGroupMembership = None + + def get_table_dictionary(self): + """Return a dictionary that can be used to populate an instance of `dbGaPDataSharingSnapshotAuditTable`.""" + row = { + "workspace": self.workspace, + "managed_group": self.managed_group, + "role": self.current_membership_instance.role if self.current_membership_instance else None, + "note": self.note, + "action": self.action, + } + return row + + +@dataclass +class VerifiedMember(WorkspaceAuthDomainAuditResult): + """Audit results class for when member membership has been verified.""" + + def __str__(self): + return f"Verified member: {self.note}" + + +@dataclass +class VerifiedAdmin(WorkspaceAuthDomainAuditResult): + """Audit results class for when membership with an admin role has been verified.""" + + is_shared: bool = False + + def __str__(self): + return f"Verified admin: {self.note}" + + +@dataclass +class VerifiedNotMember(WorkspaceAuthDomainAuditResult): + """Audit results class for when member membership has been verified.""" + + def __str__(self): + return f"Verified member: {self.note}" + + +@dataclass +class AddMember(WorkspaceAuthDomainAuditResult): + """Audit results class for when a member role should be added.""" + + action: str = "Add member" + + def __str__(self): + return f"Add member: {self.note}" + + +@dataclass +class AddAdmin(WorkspaceAuthDomainAuditResult): + """Audit results class for when an admin role should be added.""" + + action: str = "Add admin" + + def __str__(self): + return f"Add admin: {self.note}" + + +@dataclass +class ChangeToMember(WorkspaceAuthDomainAuditResult): + """Audit results class for when an admin role should be changed to a member role.""" + + action: str = "Change to member" + + def __str__(self): + return f"Change to member: {self.note}" + + +@dataclass +class ChangeToAdmin(WorkspaceAuthDomainAuditResult): + """Audit results class for when a member role should be changed to an admin role.""" + + action: str = "Change to admin" + + def __str__(self): + return f"Change to admin: {self.note}" + + +@dataclass +class Remove(WorkspaceAuthDomainAuditResult): + """Audit results class for when group membership should be removed.""" + + action: str = "Remove" + + def __str__(self): + return f"Share as owner: {self.note}" diff --git a/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py b/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py new file mode 100644 index 00000000..47454a81 --- /dev/null +++ b/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py @@ -0,0 +1,105 @@ +from dataclasses import dataclass + +from anvil_consortium_manager.models import ManagedGroup, WorkspaceGroupSharing + +from ..models import UploadWorkspace +from .base import GREGoRAuditResult + + +@dataclass +class WorkspaceSharingAuditResult(GREGoRAuditResult): + """Base class to hold results for auditing upload workspace sharing.""" + + workspace: UploadWorkspace + note: str + managed_group: ManagedGroup + action: str = None + current_sharing_instance: WorkspaceGroupSharing = None + + def get_table_dictionary(self): + """Return a dictionary that can be used to populate an instance of `dbGaPDataSharingSnapshotAuditTable`.""" + can_compute = None + if self.current_sharing_instance and self.current_sharing_instance.access != WorkspaceGroupSharing.READER: + can_compute = self.current_sharing_instance.can_compute + row = { + "workspace": self.workspace, + "managed_group": self.managed_group, + "access": self.current_sharing_instance.access if self.current_sharing_instance else None, + "can_compute": can_compute, + "note": self.note, + "action": self.action, + } + return row + + +@dataclass +class VerifiedShared(WorkspaceSharingAuditResult): + """Audit results class for when Sharing has been verified.""" + + def __str__(self): + return f"Verified sharing: {self.note}" + + +@dataclass +class VerifiedNotShared(WorkspaceSharingAuditResult): + """Audit results class for when no Sharing has been verified.""" + + def __str__(self): + return f"Verified not shared: {self.note}" + + +@dataclass +class ShareAsReader(WorkspaceSharingAuditResult): + """Audit results class for when Sharing should be granted as a reader.""" + + action: str = "Share as reader" + + def __str__(self): + return f"Share as reader: {self.note}" + + +@dataclass +class ShareAsWriter(WorkspaceSharingAuditResult): + """Audit results class for when Sharing should be granted as a writer.""" + + action: str = "Share as writer" + + def __str__(self): + return f"Share as writer: {self.note}" + + +@dataclass +class ShareAsOwner(WorkspaceSharingAuditResult): + """Audit results class for when Sharing should be granted as an owner.""" + + action: str = "Share as owner" + + def __str__(self): + return f"Share as owner: {self.note}" + + +@dataclass +class ShareWithCompute(WorkspaceSharingAuditResult): + """Audit results class for when Sharing should be granted with compute access.""" + + action: str = "Share with compute" + + def __str__(self): + return f"Share with compute: {self.note}" + + +@dataclass +class StopSharing(WorkspaceSharingAuditResult): + """Audit results class for when Sharing should be removed for a known reason.""" + + action: str = "Stop sharing" + + def __str__(self): + return f"Stop sharing: {self.note}" + + +@dataclass +class Error(WorkspaceSharingAuditResult): + """Audit results class for when an error has been detected (e.g., shared and never should have been).""" + + pass diff --git a/gregor_django/gregor_anvil/tests/test_audit.py b/gregor_django/gregor_anvil/tests/test_audit.py index 7c0b4b10..6552b921 100644 --- a/gregor_django/gregor_anvil/tests/test_audit.py +++ b/gregor_django/gregor_anvil/tests/test_audit.py @@ -14,7 +14,12 @@ from faker import Faker from .. import models -from ..audit import upload_workspace_auth_domain_audit, upload_workspace_sharing_audit +from ..audit import ( + upload_workspace_auth_domain_audit, + upload_workspace_sharing_audit, + workspace_auth_domain_audit_results, + workspace_sharing_audit_results, +) from ..audit.base import GREGoRAudit, GREGoRAuditResult from ..tests import factories @@ -171,7 +176,7 @@ def test_shared_as_owner(self): sharing = WorkspaceGroupSharingFactory.create( workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.OWNER, can_compute=True ) - instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( workspace=upload_workspace, managed_group=group, current_sharing_instance=sharing, @@ -187,7 +192,7 @@ def test_shared_as_writer_with_compute(self): sharing = WorkspaceGroupSharingFactory.create( workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.WRITER, can_compute=True ) - instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( workspace=upload_workspace, managed_group=group, current_sharing_instance=sharing, @@ -203,7 +208,7 @@ def test_shared_as_writer_without_compute(self): sharing = WorkspaceGroupSharingFactory.create( workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.WRITER, can_compute=False ) - instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( workspace=upload_workspace, managed_group=group, current_sharing_instance=sharing, @@ -219,7 +224,7 @@ def test_shared_as_reader(self): sharing = WorkspaceGroupSharingFactory.create( workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.READER ) - instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( workspace=upload_workspace, managed_group=group, current_sharing_instance=sharing, @@ -232,7 +237,7 @@ def test_shared_as_reader(self): def test_not_shared(self): upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) group = ManagedGroupFactory.create() - instance = upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult( + instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( workspace=upload_workspace, managed_group=group, current_sharing_instance=None, @@ -331,7 +336,7 @@ def test_one_upload_workspace_no_groups(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, upload_workspace.workspace.authorization_domains.first()) self.assertEqual(record.current_sharing_instance, None) @@ -348,7 +353,7 @@ def test_one_upload_workspace_rc_upload_group(self): self.assertEqual(len(audit.needs_action), 1) # auth domain is not shared self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -364,7 +369,7 @@ def test_one_upload_workspace_dcc_writer_group(self): self.assertEqual(len(audit.needs_action), 1) # auth domain is not shared self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -380,7 +385,7 @@ def test_one_upload_workspace_auth_domain(self): self.assertEqual(len(audit.needs_action), 0) # auth domain is shared self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -396,7 +401,7 @@ def test_one_upload_workspace_dcc_admin_group(self): self.assertEqual(len(audit.needs_action), 1) # auth domain is not shared self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -413,7 +418,7 @@ def test_one_upload_workspace_dcc_admin_group_different_name(self): self.assertEqual(len(audit.needs_action), 1) # auth domain is not shared self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -449,7 +454,7 @@ def test_one_upload_workspace_other_group_shared(self): self.assertEqual(len(audit.needs_action), 1) # auth domain is not shared self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -476,13 +481,13 @@ def test_two_upload_workspaces(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, upload_workspace_1) self.assertEqual(record.managed_group, upload_workspace_1.workspace.authorization_domains.first()) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, upload_workspace_2) self.assertEqual(record.managed_group, upload_workspace_2.workspace.authorization_domains.first()) self.assertIsNone(record.current_sharing_instance) @@ -505,7 +510,7 @@ def test_queryset(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, upload_workspace_1) self.assertEqual(record.managed_group, upload_workspace_1.workspace.authorization_domains.first()) self.assertEqual(record.current_sharing_instance, sharing) @@ -519,7 +524,7 @@ def test_queryset(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, upload_workspace_2) self.assertEqual(record.managed_group, upload_workspace_2.workspace.authorization_domains.first()) self.assertIsNone(record.current_sharing_instance) @@ -568,7 +573,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -583,7 +588,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) @@ -604,7 +609,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -622,7 +627,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -640,7 +645,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -659,7 +664,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -674,7 +679,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) @@ -695,7 +700,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -713,7 +718,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -731,7 +736,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -750,7 +755,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -763,7 +768,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) @@ -782,7 +787,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -798,7 +803,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -814,7 +819,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -831,7 +836,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -844,7 +849,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) @@ -863,7 +868,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -879,7 +884,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -895,7 +900,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -913,7 +918,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1032,7 +1037,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1045,7 +1050,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) @@ -1064,7 +1069,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1080,7 +1085,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1096,7 +1101,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1138,7 +1143,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1154,7 +1159,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsWriter) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsWriter) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) @@ -1176,7 +1181,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsWriter) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsWriter) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1195,7 +1200,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsWriter) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsWriter) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1214,7 +1219,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsWriter) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsWriter) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1234,7 +1239,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1249,7 +1254,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) @@ -1270,7 +1275,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1288,7 +1293,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1306,7 +1311,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1325,7 +1330,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -1338,7 +1343,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) @@ -1357,7 +1362,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -1373,7 +1378,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -1389,7 +1394,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -1406,7 +1411,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1419,7 +1424,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) @@ -1438,7 +1443,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1454,7 +1459,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1470,7 +1475,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1488,7 +1493,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1607,7 +1612,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1620,7 +1625,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) @@ -1639,7 +1644,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1655,7 +1660,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1671,7 +1676,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1715,7 +1720,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1731,7 +1736,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) @@ -1753,7 +1758,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1772,7 +1777,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1791,7 +1796,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1811,7 +1816,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1826,7 +1831,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) @@ -1847,7 +1852,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1865,7 +1870,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1883,7 +1888,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1902,7 +1907,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -1915,7 +1920,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) @@ -1934,7 +1939,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -1950,7 +1955,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -1966,7 +1971,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -1983,7 +1988,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -1996,7 +2001,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) @@ -2015,7 +2020,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2031,7 +2036,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2047,7 +2052,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2065,7 +2070,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2184,7 +2189,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2197,7 +2202,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) @@ -2216,7 +2221,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2232,7 +2237,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2248,7 +2253,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2289,7 +2294,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2305,7 +2310,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) @@ -2327,7 +2332,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2346,7 +2351,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2365,7 +2370,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2385,7 +2390,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2401,7 +2406,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) @@ -2423,7 +2428,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2442,7 +2447,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2461,7 +2466,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2481,7 +2486,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -2494,7 +2499,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) @@ -2513,7 +2518,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -2529,7 +2534,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -2545,7 +2550,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -2562,7 +2567,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2575,7 +2580,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) @@ -2594,7 +2599,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2610,7 +2615,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2626,7 +2631,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2644,7 +2649,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2763,7 +2768,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2776,7 +2781,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) @@ -2795,7 +2800,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2811,7 +2816,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2827,7 +2832,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2869,7 +2874,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2885,7 +2890,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) @@ -2907,7 +2912,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2926,7 +2931,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2945,7 +2950,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2965,7 +2970,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -2981,7 +2986,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) @@ -3003,7 +3008,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3022,7 +3027,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3041,7 +3046,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3061,7 +3066,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -3074,7 +3079,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) @@ -3093,7 +3098,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -3109,7 +3114,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -3125,7 +3130,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -3142,7 +3147,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3155,7 +3160,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) @@ -3174,7 +3179,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3190,7 +3195,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3206,7 +3211,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3224,7 +3229,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3343,7 +3348,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3356,7 +3361,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) @@ -3375,7 +3380,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3391,7 +3396,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3407,7 +3412,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3457,7 +3462,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3473,7 +3478,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) @@ -3495,7 +3500,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3514,7 +3519,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3533,7 +3538,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3553,7 +3558,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3569,7 +3574,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) @@ -3591,7 +3596,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3610,7 +3615,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3629,7 +3634,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3649,7 +3654,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -3662,7 +3667,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) @@ -3681,7 +3686,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -3697,7 +3702,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -3713,7 +3718,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) @@ -3730,7 +3735,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3743,7 +3748,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) @@ -3762,7 +3767,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3778,7 +3783,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3794,7 +3799,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3812,7 +3817,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3931,7 +3936,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3944,7 +3949,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) @@ -3963,7 +3968,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3979,7 +3984,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) @@ -3995,15 +4000,15 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) -class UploadWorkspaceAuthDomainAuditResultTest(TestCase): - """General tests of the UploadWorkspaceAuthDomainAuditResult dataclasses.""" +class WorkspaceAuthDomainAuditResultTest(TestCase): + """General tests of the WorkspaceAuthDomainAuditResult dataclasses.""" def test_member_as_admin(self): upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) @@ -4013,7 +4018,7 @@ def test_member_as_admin(self): child_group=group, role=GroupGroupMembership.ADMIN, ) - instance = upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditResult( + instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( workspace=upload_workspace, managed_group=group, current_membership_instance=membership, @@ -4030,7 +4035,7 @@ def test_member_as_member(self): child_group=group, role=GroupGroupMembership.MEMBER, ) - instance = upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditResult( + instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( workspace=upload_workspace, managed_group=group, current_membership_instance=membership, @@ -4042,7 +4047,7 @@ def test_member_as_member(self): def test_not_member(self): upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) group = ManagedGroupFactory.create() - instance = upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditResult( + instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( workspace=upload_workspace, managed_group=group, current_membership_instance=None, @@ -4166,7 +4171,7 @@ def test_one_upload_workspace_rc_member_group(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -4181,7 +4186,7 @@ def test_one_upload_workspace_rc_upload_group(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -4196,7 +4201,7 @@ def test_one_upload_workspace_rc_nonmember_group(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -4212,7 +4217,7 @@ def test_one_upload_workspace_dcc_member_group(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -4228,7 +4233,7 @@ def test_one_upload_workspace_dcc_writer_group(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -4246,7 +4251,7 @@ def test_one_upload_workspace_dcc_admin_group(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -4265,7 +4270,7 @@ def test_one_upload_workspace_dcc_admin_group_different_name(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -4306,7 +4311,7 @@ def test_one_upload_workspace_gregor_all_group(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -4324,7 +4329,7 @@ def test_one_upload_workspace_other_group_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, upload_workspace) self.assertEqual(record.managed_group, group) @@ -4353,13 +4358,13 @@ def test_two_upload_workspaces(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(record.workspace, upload_workspace_1) self.assertEqual(record.managed_group, admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, upload_workspace_2) self.assertEqual(record.managed_group, admin_group) self.assertIsNone(record.current_membership_instance) @@ -4384,7 +4389,7 @@ def test_queryset(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(record.workspace, upload_workspace_1) self.assertEqual(record.managed_group, admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -4398,7 +4403,7 @@ def test_queryset(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, upload_workspace_2) self.assertEqual(record.managed_group, admin_group) self.assertIsNone(record.current_membership_instance) @@ -4446,7 +4451,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) @@ -4464,7 +4469,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -4482,7 +4487,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -4495,7 +4500,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) @@ -4513,7 +4518,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -4531,7 +4536,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -4544,7 +4549,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) @@ -4562,7 +4567,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -4580,7 +4585,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -4593,7 +4598,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) @@ -4611,7 +4616,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -4629,7 +4634,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -4644,7 +4649,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) @@ -4657,7 +4662,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) @@ -4677,7 +4682,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -4697,7 +4702,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -4712,7 +4717,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) @@ -4732,7 +4737,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -4752,7 +4757,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -4767,7 +4772,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) @@ -4787,7 +4792,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -4807,7 +4812,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -4822,7 +4827,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) @@ -4840,7 +4845,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -4858,7 +4863,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -4961,7 +4966,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) @@ -4981,7 +4986,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -5001,7 +5006,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -5016,7 +5021,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) @@ -5036,7 +5041,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5056,7 +5061,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5071,7 +5076,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) @@ -5091,7 +5096,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5111,7 +5116,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5126,7 +5131,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) @@ -5144,7 +5149,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -5162,7 +5167,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -5177,7 +5182,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) @@ -5190,7 +5195,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) @@ -5210,7 +5215,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -5230,7 +5235,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -5245,7 +5250,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) @@ -5265,7 +5270,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5285,7 +5290,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5300,7 +5305,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) @@ -5320,7 +5325,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -5340,7 +5345,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -5355,7 +5360,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) @@ -5373,7 +5378,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -5391,7 +5396,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -5496,7 +5501,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) @@ -5516,7 +5521,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -5536,7 +5541,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -5551,7 +5556,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) @@ -5571,7 +5576,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5591,7 +5596,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5606,7 +5611,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) @@ -5626,7 +5631,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5646,7 +5651,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5661,7 +5666,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) @@ -5679,7 +5684,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -5697,7 +5702,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -5712,7 +5717,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) @@ -5725,7 +5730,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) @@ -5745,7 +5750,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -5765,7 +5770,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -5780,7 +5785,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) @@ -5800,7 +5805,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5820,7 +5825,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -5835,7 +5840,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) @@ -5855,7 +5860,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -5875,7 +5880,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -5890,7 +5895,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) @@ -5908,7 +5913,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -5926,7 +5931,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -6033,7 +6038,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) @@ -6053,7 +6058,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -6073,7 +6078,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -6088,7 +6093,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) @@ -6108,7 +6113,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6128,7 +6133,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6143,7 +6148,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) @@ -6163,7 +6168,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6183,7 +6188,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6198,7 +6203,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) @@ -6216,7 +6221,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -6234,7 +6239,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -6249,7 +6254,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) @@ -6262,7 +6267,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) @@ -6282,7 +6287,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -6302,7 +6307,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -6317,7 +6322,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) @@ -6337,7 +6342,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6357,7 +6362,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6372,7 +6377,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) @@ -6392,7 +6397,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -6412,7 +6417,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -6427,7 +6432,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) @@ -6445,7 +6450,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -6463,7 +6468,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -6571,7 +6576,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) @@ -6591,7 +6596,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -6611,7 +6616,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -6626,7 +6631,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) @@ -6646,7 +6651,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6666,7 +6671,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6681,7 +6686,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) @@ -6701,7 +6706,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6721,7 +6726,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6736,7 +6741,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) @@ -6754,7 +6759,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -6772,7 +6777,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -6787,7 +6792,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) @@ -6800,7 +6805,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) @@ -6820,7 +6825,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -6840,7 +6845,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -6855,7 +6860,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) @@ -6875,7 +6880,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6895,7 +6900,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -6910,7 +6915,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) @@ -6930,7 +6935,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -6950,7 +6955,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -6965,7 +6970,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) @@ -6983,7 +6988,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -7001,7 +7006,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -7112,7 +7117,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) @@ -7132,7 +7137,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -7152,7 +7157,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) @@ -7167,7 +7172,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) @@ -7187,7 +7192,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -7207,7 +7212,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -7222,7 +7227,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) @@ -7242,7 +7247,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -7262,7 +7267,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -7277,7 +7282,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) @@ -7295,7 +7300,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -7313,7 +7318,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -7328,7 +7333,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) @@ -7341,7 +7346,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) @@ -7361,7 +7366,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -7381,7 +7386,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) @@ -7396,7 +7401,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) @@ -7416,7 +7421,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -7436,7 +7441,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) @@ -7451,7 +7456,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) @@ -7471,7 +7476,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -7491,7 +7496,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) @@ -7506,7 +7511,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 0) record = audit.verified[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) @@ -7524,7 +7529,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) @@ -7542,7 +7547,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.needs_action), 0) self.assertEqual(len(audit.errors), 1) record = audit.errors[0] - self.assertIsInstance(record, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) self.assertEqual(record.workspace, self.upload_workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index 32806ab0..8652c613 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -25,7 +25,12 @@ from gregor_django.users.tests.factories import UserFactory from .. import forms, models, tables, views -from ..audit import upload_workspace_auth_domain_audit, upload_workspace_sharing_audit +from ..audit import ( + upload_workspace_auth_domain_audit, + upload_workspace_sharing_audit, + workspace_auth_domain_audit_results, + workspace_sharing_audit_results, +) from . import factories # from .utils import AnVILAPIMockTestMixin @@ -3530,7 +3535,7 @@ def test_get_context_audit_result(self): self.assertIn("audit_result", response.context_data) self.assertIsInstance( response.context_data["audit_result"], - upload_workspace_sharing_audit.UploadWorkspaceSharingAuditResult, + workspace_sharing_audit_results.WorkspaceSharingAuditResult, ) def test_get_verified_shared(self): @@ -3548,7 +3553,7 @@ def test_get_verified_shared(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.VerifiedShared) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.VerifiedShared) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -3565,7 +3570,7 @@ def test_get_verified_not_shared(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.VerifiedNotShared) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.VerifiedNotShared) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -3582,7 +3587,7 @@ def test_get_share_as_reader(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsReader) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -3601,7 +3606,7 @@ def test_get_share_as_writer(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.ShareAsWriter) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsWriter) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -3618,7 +3623,7 @@ def test_get_share_with_compute(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareWithCompute) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -3634,7 +3639,7 @@ def test_get_share_as_owner(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsOwner) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -4233,7 +4238,7 @@ def test_post_share_as_reader_anvil_api_error(self): # Audit result is still as expected. self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.ShareAsReader) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsReader) # A message was added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -4264,7 +4269,7 @@ def test_post_new_share_as_writer_anvil_api_error(self): # Audit result is still as expected. self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.ShareAsWriter) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsWriter) # A message was added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -4294,7 +4299,7 @@ def test_post_new_share_with_compute_anvil_api_error(self): # Audit result is still as expected. self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.ShareWithCompute) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareWithCompute) # A message was added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -4324,7 +4329,7 @@ def test_post_new_share_as_owner_anvil_api_error(self): # Audit result is still as expected. self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.ShareAsOwner) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsOwner) # A message was added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -4363,7 +4368,7 @@ def test_post_new_stop_sharing_anvil_api_error(self): # Audit result is still as expected. self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_sharing_audit.StopSharing) + self.assertIsInstance(audit_result, workspace_sharing_audit_results.StopSharing) # A message was added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -5728,7 +5733,7 @@ def test_get_context_audit_result(self): self.assertIn("audit_result", response.context_data) self.assertIsInstance( response.context_data["audit_result"], - upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditResult, + workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult, ) def test_get_verified_member(self): @@ -5746,7 +5751,7 @@ def test_get_verified_member(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_auth_domain_audit.VerifiedMember) + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.VerifiedMember) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -5768,7 +5773,7 @@ def test_get_verified_admin(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_auth_domain_audit.VerifiedAdmin) + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.VerifiedAdmin) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -5785,7 +5790,7 @@ def test_get_verified_not_member(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_auth_domain_audit.VerifiedNotMember) + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.VerifiedNotMember) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -5802,7 +5807,7 @@ def test_get_add_member(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_auth_domain_audit.AddMember) + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.AddMember) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -5819,7 +5824,7 @@ def test_get_add_admin(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_auth_domain_audit.AddAdmin) + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.AddAdmin) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -5841,7 +5846,7 @@ def test_get_change_to_member(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_auth_domain_audit.ChangeToMember) + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.ChangeToMember) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -5863,7 +5868,7 @@ def test_get_change_to_admin(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_auth_domain_audit.ChangeToAdmin) + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.ChangeToAdmin) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( @@ -5884,7 +5889,7 @@ def test_get_remove(self): ) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] - self.assertIsInstance(audit_result, upload_workspace_auth_domain_audit.Remove) + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.Remove) self.assertEqual(audit_result.workspace, upload_workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index cdf8c701..4a16ad21 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -25,7 +25,12 @@ from gregor_django.users.tables import UserTable from . import forms, models, tables -from .audit import upload_workspace_auth_domain_audit, upload_workspace_sharing_audit +from .audit import ( + upload_workspace_auth_domain_audit, + upload_workspace_sharing_audit, + workspace_auth_domain_audit_results, + workspace_sharing_audit_results, +) User = get_user_model() @@ -353,26 +358,26 @@ def form_valid(self, form): group=self.managed_group, ) with transaction.atomic(): - if isinstance(self.audit_result, upload_workspace_sharing_audit.VerifiedShared): + if isinstance(self.audit_result, workspace_sharing_audit_results.VerifiedShared): # No changes needed. pass - elif isinstance(self.audit_result, upload_workspace_sharing_audit.VerifiedNotShared): + elif isinstance(self.audit_result, workspace_sharing_audit_results.VerifiedNotShared): # No changes needed. pass - elif isinstance(self.audit_result, upload_workspace_sharing_audit.StopSharing): + elif isinstance(self.audit_result, workspace_sharing_audit_results.StopSharing): sharing.anvil_delete() sharing.delete() else: - if isinstance(self.audit_result, upload_workspace_sharing_audit.ShareAsReader): + if isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsReader): sharing.access = WorkspaceGroupSharing.READER sharing.can_compute = False - elif isinstance(self.audit_result, upload_workspace_sharing_audit.ShareAsWriter): + elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsWriter): sharing.access = WorkspaceGroupSharing.WRITER sharing.can_compute = False - elif isinstance(self.audit_result, upload_workspace_sharing_audit.ShareWithCompute): + elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareWithCompute): sharing.access = WorkspaceGroupSharing.WRITER sharing.can_compute = True - elif isinstance(self.audit_result, upload_workspace_sharing_audit.ShareAsOwner): + elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsOwner): sharing.access = WorkspaceGroupSharing.OWNER sharing.can_compute = True sharing.full_clean() @@ -557,26 +562,26 @@ def form_valid(self, form): child_group=self.managed_group, ) # Now process the result. - if isinstance(self.audit_result, upload_workspace_auth_domain_audit.VerifiedMember): + if isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedMember): pass - elif isinstance(self.audit_result, upload_workspace_auth_domain_audit.VerifiedAdmin): + elif isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedAdmin): pass - elif isinstance(self.audit_result, upload_workspace_auth_domain_audit.VerifiedNotMember): + elif isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedNotMember): pass - elif isinstance(self.audit_result, upload_workspace_auth_domain_audit.Remove): + elif isinstance(self.audit_result, workspace_auth_domain_audit_results.Remove): membership.anvil_delete() membership.delete() else: - if isinstance(self.audit_result, upload_workspace_auth_domain_audit.ChangeToMember): + if isinstance(self.audit_result, workspace_auth_domain_audit_results.ChangeToMember): membership.anvil_delete() membership.role = GroupGroupMembership.MEMBER - elif isinstance(self.audit_result, upload_workspace_auth_domain_audit.ChangeToAdmin): + elif isinstance(self.audit_result, workspace_auth_domain_audit_results.ChangeToAdmin): membership.anvil_delete() membership.role = GroupGroupMembership.ADMIN else: - if isinstance(self.audit_result, upload_workspace_auth_domain_audit.AddMember): + if isinstance(self.audit_result, workspace_auth_domain_audit_results.AddMember): membership.role = GroupGroupMembership.MEMBER - elif isinstance(self.audit_result, upload_workspace_auth_domain_audit.AddAdmin): + elif isinstance(self.audit_result, workspace_auth_domain_audit_results.AddAdmin): membership.role = GroupGroupMembership.ADMIN membership.full_clean() membership.save() From d42d3debfe48ebfbd3a01109523238f3ed1ddd80 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Thu, 5 Sep 2024 16:37:14 -0700 Subject: [PATCH 22/97] Switch workspace class in audit results to just "Workspace" Because these audit result classes are intended to be used for multiple differnet types of workspace auditing, we shouldn't set the class of the "workspace" field to UploadWorkspace. Change it, and also update the tests and templates where necessary. --- .../upload_workspace_auth_domain_audit.py | 18 +- .../audit/upload_workspace_sharing_audit.py | 10 +- .../workspace_auth_domain_audit_results.py | 5 +- .../audit/workspace_sharing_audit_results.py | 9 +- .../gregor_anvil/tests/test_audit.py | 688 +++++++++--------- .../gregor_anvil/tests/test_views.py | 118 +-- ...space_auth_domain_audit_action_button.html | 4 +- ...workspace_sharing_audit_action_button.html | 4 +- 8 files changed, 429 insertions(+), 427 deletions(-) diff --git a/gregor_django/gregor_anvil/audit/upload_workspace_auth_domain_audit.py b/gregor_django/gregor_anvil/audit/upload_workspace_auth_domain_audit.py index 0910e548..77ebdd04 100644 --- a/gregor_django/gregor_anvil/audit/upload_workspace_auth_domain_audit.py +++ b/gregor_django/gregor_anvil/audit/upload_workspace_auth_domain_audit.py @@ -146,7 +146,7 @@ def audit_workspace_and_group(self, upload_workspace, managed_group): def _audit_workspace_and_group_for_rc_uploaders(self, upload_workspace, managed_group): membership = self._get_current_membership(upload_workspace, managed_group) result_kwargs = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_membership_instance": membership, } @@ -189,7 +189,7 @@ def _audit_workspace_and_group_for_rc_members(self, upload_workspace, managed_gr membership = self._get_current_membership(upload_workspace, managed_group) combined_workspace = self._get_combined_workspace(upload_workspace.upload_cycle) result_kwargs = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_membership_instance": membership, } @@ -222,7 +222,7 @@ def _audit_workspace_and_group_for_rc_members(self, upload_workspace, managed_gr def _audit_workspace_and_group_for_rc_non_members(self, upload_workspace, managed_group): membership = self._get_current_membership(upload_workspace, managed_group) result_kwargs = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_membership_instance": membership, } @@ -249,7 +249,7 @@ def _audit_workspace_and_group_for_dcc_admin(self, upload_workspace, managed_gro if not membership: self.needs_action.append( audit_results.AddAdmin( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=managed_group, note=self.DCC_ADMINS, current_membership_instance=membership, @@ -258,7 +258,7 @@ def _audit_workspace_and_group_for_dcc_admin(self, upload_workspace, managed_gro elif membership.role == GroupGroupMembership.ADMIN: self.verified.append( audit_results.VerifiedAdmin( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=managed_group, note=self.DCC_ADMINS, current_membership_instance=membership, @@ -267,7 +267,7 @@ def _audit_workspace_and_group_for_dcc_admin(self, upload_workspace, managed_gro else: self.needs_action.append( audit_results.ChangeToAdmin( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=managed_group, note=self.DCC_ADMINS, current_membership_instance=membership, @@ -282,7 +282,7 @@ def _audit_workspace_and_group_for_dcc(self, upload_workspace, managed_group): else: note = self.DCC_BEFORE_COMBINED result_kwargs = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_membership_instance": membership, "note": note, @@ -311,7 +311,7 @@ def _audit_workspace_and_group_for_gregor_all(self, upload_workspace, managed_gr else: note = self.GREGOR_ALL_BEFORE_COMBINED result_kwargs = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_membership_instance": membership, "note": note, @@ -338,7 +338,7 @@ def _audit_workspace_and_anvil_group(self, upload_workspace, managed_group): def _audit_workspace_and_other_group(self, upload_workspace, managed_group): membership = self._get_current_membership(upload_workspace, managed_group) result_kwargs = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_membership_instance": membership, "note": self.OTHER_GROUP, diff --git a/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py b/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py index 079b8d13..fefa24d9 100644 --- a/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py +++ b/gregor_django/gregor_anvil/audit/upload_workspace_sharing_audit.py @@ -158,7 +158,7 @@ def _audit_workspace_and_rc_uploader_group(self, upload_workspace, managed_group combined_workspace = self._get_combined_workspace(upload_cycle) audit_result_args = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_sharing_instance": current_sharing, } @@ -237,7 +237,7 @@ def _audit_workspace_and_dcc_writer_group(self, upload_workspace, managed_group) combined_workspace = self._get_combined_workspace(upload_cycle) audit_result_args = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_sharing_instance": current_sharing, } @@ -357,7 +357,7 @@ def _audit_workspace_and_auth_domain(self, upload_workspace, managed_group): current_sharing = self._get_current_sharing(upload_workspace, managed_group) audit_result_args = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_sharing_instance": current_sharing, } @@ -389,7 +389,7 @@ def _audit_workspace_and_dcc_admin_group(self, upload_workspace, managed_group): current_sharing = self._get_current_sharing(upload_workspace, managed_group) audit_result_args = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_sharing_instance": current_sharing, } @@ -419,7 +419,7 @@ def _audit_workspace_and_other_group(self, upload_workspace, managed_group): current_sharing = self._get_current_sharing(upload_workspace, managed_group) audit_result_args = { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": managed_group, "current_sharing_instance": current_sharing, } diff --git a/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py b/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py index 655c0803..11ccf580 100644 --- a/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py +++ b/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py @@ -1,8 +1,7 @@ from dataclasses import dataclass -from anvil_consortium_manager.models import GroupGroupMembership, ManagedGroup +from anvil_consortium_manager.models import GroupGroupMembership, ManagedGroup, Workspace -from ..models import UploadWorkspace from .base import GREGoRAuditResult @@ -10,7 +9,7 @@ class WorkspaceAuthDomainAuditResult(GREGoRAuditResult): """Base class to hold results for auditing upload workspace sharing.""" - workspace: UploadWorkspace + workspace: Workspace note: str managed_group: ManagedGroup action: str = None diff --git a/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py b/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py index 47454a81..7d9b93f6 100644 --- a/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py +++ b/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py @@ -1,8 +1,11 @@ from dataclasses import dataclass -from anvil_consortium_manager.models import ManagedGroup, WorkspaceGroupSharing +from anvil_consortium_manager.models import ( + ManagedGroup, + Workspace, + WorkspaceGroupSharing, +) -from ..models import UploadWorkspace from .base import GREGoRAuditResult @@ -10,7 +13,7 @@ class WorkspaceSharingAuditResult(GREGoRAuditResult): """Base class to hold results for auditing upload workspace sharing.""" - workspace: UploadWorkspace + workspace: Workspace note: str managed_group: ManagedGroup action: str = None diff --git a/gregor_django/gregor_anvil/tests/test_audit.py b/gregor_django/gregor_anvil/tests/test_audit.py index 6552b921..9e7781dc 100644 --- a/gregor_django/gregor_anvil/tests/test_audit.py +++ b/gregor_django/gregor_anvil/tests/test_audit.py @@ -177,7 +177,7 @@ def test_shared_as_owner(self): workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.OWNER, can_compute=True ) instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=group, current_sharing_instance=sharing, note="foo", @@ -193,7 +193,7 @@ def test_shared_as_writer_with_compute(self): workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.WRITER, can_compute=True ) instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=group, current_sharing_instance=sharing, note="foo", @@ -209,7 +209,7 @@ def test_shared_as_writer_without_compute(self): workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.WRITER, can_compute=False ) instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=group, current_sharing_instance=sharing, note="foo", @@ -225,7 +225,7 @@ def test_shared_as_reader(self): workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.READER ) instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=group, current_sharing_instance=sharing, note="foo", @@ -238,7 +238,7 @@ def test_not_shared(self): upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) group = ManagedGroupFactory.create() instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=group, current_sharing_instance=None, note="foo", @@ -266,7 +266,7 @@ def test_one_row(self): ) data = [ { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": group, "access": WorkspaceGroupSharing.READER, "can_compute": None, @@ -288,7 +288,7 @@ def test_two_rows(self): ) data = [ { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": group_1, "access": WorkspaceGroupSharing.READER, "can_compute": None, @@ -296,7 +296,7 @@ def test_two_rows(self): "action": "", }, { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": group_2, "access": None, "can_compute": None, @@ -337,7 +337,7 @@ def test_one_upload_workspace_no_groups(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, upload_workspace.workspace.authorization_domains.first()) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -354,7 +354,7 @@ def test_one_upload_workspace_rc_upload_group(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_dcc_writer_group(self): @@ -370,7 +370,7 @@ def test_one_upload_workspace_dcc_writer_group(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_auth_domain(self): @@ -386,7 +386,7 @@ def test_one_upload_workspace_auth_domain(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_dcc_admin_group(self): @@ -402,7 +402,7 @@ def test_one_upload_workspace_dcc_admin_group(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) @override_settings(ANVIL_DCC_ADMINS_GROUP_NAME="foo") @@ -419,7 +419,7 @@ def test_one_upload_workspace_dcc_admin_group_different_name(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_anvil_admin_group(self): @@ -455,7 +455,7 @@ def test_one_upload_workspace_other_group_shared(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_other_group_not_shared(self): @@ -482,13 +482,13 @@ def test_two_upload_workspaces(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, upload_workspace_1) + self.assertEqual(record.workspace, upload_workspace_1.workspace) self.assertEqual(record.managed_group, upload_workspace_1.workspace.authorization_domains.first()) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, upload_workspace_2) + self.assertEqual(record.workspace, upload_workspace_2.workspace) self.assertEqual(record.managed_group, upload_workspace_2.workspace.authorization_domains.first()) self.assertIsNone(record.current_sharing_instance) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -511,7 +511,7 @@ def test_queryset(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, upload_workspace_1) + self.assertEqual(record.workspace, upload_workspace_1.workspace) self.assertEqual(record.managed_group, upload_workspace_1.workspace.authorization_domains.first()) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -525,7 +525,7 @@ def test_queryset(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, upload_workspace_2) + self.assertEqual(record.workspace, upload_workspace_2.workspace) self.assertEqual(record.managed_group, upload_workspace_2.workspace.authorization_domains.first()) self.assertIsNone(record.current_sharing_instance) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -574,7 +574,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -589,7 +589,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -610,7 +610,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -628,7 +628,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -646,7 +646,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -665,7 +665,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -680,7 +680,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -701,7 +701,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -719,7 +719,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -737,7 +737,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -756,7 +756,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -769,7 +769,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -788,7 +788,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -804,7 +804,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -820,7 +820,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -837,7 +837,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -850,7 +850,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -869,7 +869,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -885,7 +885,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -901,7 +901,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -919,7 +919,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -1038,7 +1038,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -1051,7 +1051,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -1070,7 +1070,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -1086,7 +1086,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -1102,7 +1102,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -1144,7 +1144,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1160,7 +1160,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsWriter) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -1182,7 +1182,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsWriter) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1201,7 +1201,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsWriter) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1220,7 +1220,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsWriter) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1240,7 +1240,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1255,7 +1255,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -1276,7 +1276,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1294,7 +1294,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1312,7 +1312,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1331,7 +1331,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -1344,7 +1344,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -1363,7 +1363,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -1379,7 +1379,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -1395,7 +1395,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -1412,7 +1412,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -1425,7 +1425,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -1444,7 +1444,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -1460,7 +1460,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -1476,7 +1476,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -1494,7 +1494,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -1613,7 +1613,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -1626,7 +1626,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -1645,7 +1645,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -1661,7 +1661,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -1677,7 +1677,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -1721,7 +1721,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1737,7 +1737,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -1759,7 +1759,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1778,7 +1778,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1797,7 +1797,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1817,7 +1817,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1832,7 +1832,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -1853,7 +1853,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1871,7 +1871,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1889,7 +1889,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -1908,7 +1908,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -1921,7 +1921,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -1940,7 +1940,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -1956,7 +1956,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -1972,7 +1972,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -1989,7 +1989,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2002,7 +2002,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2021,7 +2021,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2037,7 +2037,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2053,7 +2053,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2071,7 +2071,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2190,7 +2190,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -2203,7 +2203,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -2222,7 +2222,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -2238,7 +2238,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -2254,7 +2254,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -2295,7 +2295,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2311,7 +2311,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -2333,7 +2333,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2352,7 +2352,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2371,7 +2371,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2391,7 +2391,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2407,7 +2407,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -2429,7 +2429,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2448,7 +2448,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2467,7 +2467,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2487,7 +2487,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -2500,7 +2500,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -2519,7 +2519,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -2535,7 +2535,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -2551,7 +2551,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -2568,7 +2568,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2581,7 +2581,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2600,7 +2600,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2616,7 +2616,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2632,7 +2632,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2650,7 +2650,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -2769,7 +2769,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -2782,7 +2782,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -2801,7 +2801,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -2817,7 +2817,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -2833,7 +2833,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -2875,7 +2875,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2891,7 +2891,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -2913,7 +2913,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2932,7 +2932,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2951,7 +2951,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2971,7 +2971,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -2987,7 +2987,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -3009,7 +3009,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3028,7 +3028,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3047,7 +3047,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3067,7 +3067,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -3080,7 +3080,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -3099,7 +3099,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -3115,7 +3115,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -3131,7 +3131,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -3148,7 +3148,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3161,7 +3161,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3180,7 +3180,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3196,7 +3196,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3212,7 +3212,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3230,7 +3230,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3349,7 +3349,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -3362,7 +3362,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -3381,7 +3381,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -3397,7 +3397,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -3413,7 +3413,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -3463,7 +3463,7 @@ def test_uploaders_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3479,7 +3479,7 @@ def test_uploaders_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -3501,7 +3501,7 @@ def test_uploaders_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3520,7 +3520,7 @@ def test_uploaders_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3539,7 +3539,7 @@ def test_uploaders_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3559,7 +3559,7 @@ def test_dcc_writers_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3575,7 +3575,7 @@ def test_dcc_writers_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual( @@ -3597,7 +3597,7 @@ def test_dcc_writers_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3616,7 +3616,7 @@ def test_dcc_writers_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3635,7 +3635,7 @@ def test_dcc_writers_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual( @@ -3655,7 +3655,7 @@ def test_auth_domain_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -3668,7 +3668,7 @@ def test_auth_domain_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -3687,7 +3687,7 @@ def test_auth_domain_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -3703,7 +3703,7 @@ def test_auth_domain_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -3719,7 +3719,7 @@ def test_auth_domain_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.auth_domain) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER) @@ -3736,7 +3736,7 @@ def test_dcc_admin_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3749,7 +3749,7 @@ def test_dcc_admin_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3768,7 +3768,7 @@ def test_dcc_admin_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3784,7 +3784,7 @@ def test_dcc_admin_shared_as_reader(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3800,7 +3800,7 @@ def test_dcc_admin_shared_as_owner(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3818,7 +3818,7 @@ def test_dcc_admin_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER) @@ -3937,7 +3937,7 @@ def test_other_group_shared_as_writer_no_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -3950,7 +3950,7 @@ def test_other_group_not_shared(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, None) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -3969,7 +3969,7 @@ def test_other_group_shared_as_writer_can_compute(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -3985,7 +3985,7 @@ def test_other_group_shared_as_reader(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -4001,7 +4001,7 @@ def test_other_group_shared_as_owner(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_sharing_audit_results.StopSharing) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_sharing_instance, sharing) self.assertEqual(record.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) @@ -4019,7 +4019,7 @@ def test_member_as_admin(self): role=GroupGroupMembership.ADMIN, ) instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=group, current_membership_instance=membership, note="foo", @@ -4036,7 +4036,7 @@ def test_member_as_member(self): role=GroupGroupMembership.MEMBER, ) instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=group, current_membership_instance=membership, note="foo", @@ -4048,7 +4048,7 @@ def test_not_member(self): upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) group = ManagedGroupFactory.create() instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( - workspace=upload_workspace, + workspace=upload_workspace.workspace, managed_group=group, current_membership_instance=None, note="foo", @@ -4077,7 +4077,7 @@ def test_one_row(self): ) data = [ { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": group, "role": GroupGroupMembership.MEMBER, "note": "a note", @@ -4100,14 +4100,14 @@ def test_two_rows(self): ) data = [ { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": group_1, "role": GroupGroupMembership.MEMBER, "note": "a note", "action": "", }, { - "workspace": upload_workspace, + "workspace": upload_workspace.workspace, "managed_group": group_2, "role": None, "note": "a note", @@ -4172,7 +4172,7 @@ def test_one_upload_workspace_rc_member_group(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_rc_upload_group(self): @@ -4187,7 +4187,7 @@ def test_one_upload_workspace_rc_upload_group(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_rc_nonmember_group(self): @@ -4202,7 +4202,7 @@ def test_one_upload_workspace_rc_nonmember_group(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_dcc_member_group(self): @@ -4218,7 +4218,7 @@ def test_one_upload_workspace_dcc_member_group(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_dcc_writer_group(self): @@ -4234,7 +4234,7 @@ def test_one_upload_workspace_dcc_writer_group(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_dcc_admin_group(self): @@ -4252,7 +4252,7 @@ def test_one_upload_workspace_dcc_admin_group(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) @override_settings(ANVIL_DCC_ADMINS_GROUP_NAME="foo") @@ -4271,7 +4271,7 @@ def test_one_upload_workspace_dcc_admin_group_different_name(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_anvil_admin_group(self): @@ -4312,7 +4312,7 @@ def test_one_upload_workspace_gregor_all_group(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_other_group_member(self): @@ -4330,7 +4330,7 @@ def test_one_upload_workspace_other_group_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, upload_workspace) + self.assertEqual(record.workspace, upload_workspace.workspace) self.assertEqual(record.managed_group, group) def test_one_upload_workspace_other_group_not_member(self): @@ -4359,13 +4359,13 @@ def test_two_upload_workspaces(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(record.workspace, upload_workspace_1) + self.assertEqual(record.workspace, upload_workspace_1.workspace) self.assertEqual(record.managed_group, admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, upload_workspace_2) + self.assertEqual(record.workspace, upload_workspace_2.workspace) self.assertEqual(record.managed_group, admin_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -4390,7 +4390,7 @@ def test_queryset(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(record.workspace, upload_workspace_1) + self.assertEqual(record.workspace, upload_workspace_1.workspace) self.assertEqual(record.managed_group, admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -4404,7 +4404,7 @@ def test_queryset(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, upload_workspace_2) + self.assertEqual(record.workspace, upload_workspace_2.workspace) self.assertEqual(record.managed_group, admin_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -4452,7 +4452,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.RC_FUTURE_CYCLE) @@ -4470,7 +4470,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.RC_FUTURE_CYCLE) @@ -4488,7 +4488,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.RC_FUTURE_CYCLE) @@ -4501,7 +4501,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.RC_FUTURE_CYCLE) @@ -4519,7 +4519,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.RC_FUTURE_CYCLE) @@ -4537,7 +4537,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.RC_FUTURE_CYCLE) @@ -4550,7 +4550,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.RC_FUTURE_CYCLE) @@ -4568,7 +4568,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.RC_FUTURE_CYCLE) @@ -4586,7 +4586,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.RC_FUTURE_CYCLE) @@ -4599,7 +4599,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -4617,7 +4617,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -4635,7 +4635,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -4650,7 +4650,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -4663,7 +4663,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -4683,7 +4683,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -4703,7 +4703,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -4718,7 +4718,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -4738,7 +4738,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -4758,7 +4758,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -4773,7 +4773,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -4793,7 +4793,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -4813,7 +4813,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -4828,7 +4828,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -4846,7 +4846,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -4864,7 +4864,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -4967,7 +4967,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -4987,7 +4987,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5007,7 +5007,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5022,7 +5022,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5042,7 +5042,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5062,7 +5062,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5077,7 +5077,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5097,7 +5097,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5117,7 +5117,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5132,7 +5132,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -5150,7 +5150,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -5168,7 +5168,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -5183,7 +5183,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -5196,7 +5196,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5216,7 +5216,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5236,7 +5236,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5251,7 +5251,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5271,7 +5271,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5291,7 +5291,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5306,7 +5306,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5326,7 +5326,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5346,7 +5346,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5361,7 +5361,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -5379,7 +5379,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -5397,7 +5397,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -5502,7 +5502,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5522,7 +5522,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5542,7 +5542,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5557,7 +5557,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5577,7 +5577,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5597,7 +5597,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5612,7 +5612,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5632,7 +5632,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5652,7 +5652,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5667,7 +5667,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -5685,7 +5685,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -5703,7 +5703,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -5718,7 +5718,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -5731,7 +5731,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5751,7 +5751,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5771,7 +5771,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5786,7 +5786,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5806,7 +5806,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5826,7 +5826,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5841,7 +5841,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -5861,7 +5861,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5881,7 +5881,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -5896,7 +5896,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -5914,7 +5914,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -5932,7 +5932,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -6039,7 +6039,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6059,7 +6059,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6079,7 +6079,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6094,7 +6094,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6114,7 +6114,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6134,7 +6134,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6149,7 +6149,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6169,7 +6169,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6189,7 +6189,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6204,7 +6204,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -6222,7 +6222,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -6240,7 +6240,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -6255,7 +6255,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -6268,7 +6268,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6288,7 +6288,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6308,7 +6308,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6323,7 +6323,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6343,7 +6343,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6363,7 +6363,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6378,7 +6378,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6398,7 +6398,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6418,7 +6418,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6433,7 +6433,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -6451,7 +6451,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -6469,7 +6469,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -6577,7 +6577,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6597,7 +6597,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6617,7 +6617,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6632,7 +6632,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6652,7 +6652,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6672,7 +6672,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6687,7 +6687,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6707,7 +6707,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6727,7 +6727,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6742,7 +6742,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -6760,7 +6760,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -6778,7 +6778,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -6793,7 +6793,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -6806,7 +6806,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6826,7 +6826,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6846,7 +6846,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6861,7 +6861,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6881,7 +6881,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6901,7 +6901,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6916,7 +6916,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -6936,7 +6936,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6956,7 +6956,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -6971,7 +6971,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -6989,7 +6989,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -7007,7 +7007,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -7118,7 +7118,7 @@ def test_rc_uploaders_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -7138,7 +7138,7 @@ def test_rc_uploaders_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7158,7 +7158,7 @@ def test_rc_uploaders_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_uploader_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7173,7 +7173,7 @@ def test_rc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -7193,7 +7193,7 @@ def test_rc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7213,7 +7213,7 @@ def test_rc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7228,7 +7228,7 @@ def test_rc_non_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -7248,7 +7248,7 @@ def test_rc_non_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7268,7 +7268,7 @@ def test_rc_non_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.rc_non_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7283,7 +7283,7 @@ def test_dcc_admins_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -7301,7 +7301,7 @@ def test_dcc_admins_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -7319,7 +7319,7 @@ def test_dcc_admins_admin(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -7334,7 +7334,7 @@ def test_dcc_admins_different_setting(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS) @@ -7347,7 +7347,7 @@ def test_dcc_writers_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -7367,7 +7367,7 @@ def test_dcc_writers_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7387,7 +7387,7 @@ def test_dcc_writers_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_writer_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7402,7 +7402,7 @@ def test_dcc_members_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -7422,7 +7422,7 @@ def test_dcc_members_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7442,7 +7442,7 @@ def test_dcc_members_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_member_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7457,7 +7457,7 @@ def test_gregor_all_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertIsNone(record.current_membership_instance) self.assertEqual( @@ -7477,7 +7477,7 @@ def test_gregor_all_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7497,7 +7497,7 @@ def test_gregor_all_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.gregor_all_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual( @@ -7512,7 +7512,7 @@ def test_other_group_not_member(self): self.assertEqual(len(audit.errors), 0) record = audit.verified[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertIsNone(record.current_membership_instance) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -7530,7 +7530,7 @@ def test_other_group_member(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) @@ -7548,7 +7548,7 @@ def test_other_group_admin(self): self.assertEqual(len(audit.errors), 1) record = audit.errors[0] self.assertIsInstance(record, workspace_auth_domain_audit_results.Remove) - self.assertEqual(record.workspace, self.upload_workspace) + self.assertEqual(record.workspace, self.upload_workspace.workspace) self.assertEqual(record.managed_group, self.other_group) self.assertEqual(record.current_membership_instance, membership) self.assertEqual(record.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP) diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index 8652c613..5707db1d 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -2501,7 +2501,7 @@ def test_context_verified_table_access(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("access"), acm_models.WorkspaceGroupSharing.OWNER) self.assertEqual( @@ -2524,7 +2524,7 @@ def test_context_needs_action_table_share_as_reader(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -2556,7 +2556,7 @@ def test_context_needs_action_table_share_as_writer(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -2585,7 +2585,7 @@ def test_context_needs_action_table_share_with_compute(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -2614,7 +2614,7 @@ def test_context_needs_action_table_share_as_owner(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -2654,7 +2654,7 @@ def test_context_needs_action_table_stop_sharing(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("access"), "READER") self.assertEqual( @@ -2689,7 +2689,7 @@ def test_context_error_table_stop_sharing(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("access"), "READER") self.assertEqual( @@ -2843,7 +2843,7 @@ def test_context_verified_table_access(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("access"), acm_models.WorkspaceGroupSharing.OWNER) self.assertEqual( @@ -2870,7 +2870,7 @@ def test_context_needs_action_table_share_as_reader(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -2907,7 +2907,7 @@ def test_context_needs_action_table_share_as_writer(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -2940,7 +2940,7 @@ def test_context_needs_action_table_share_with_compute(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -2973,7 +2973,7 @@ def test_context_needs_action_table_share_as_owner(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -3021,7 +3021,7 @@ def test_context_needs_action_table_stop_sharing(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("access"), "READER") self.assertEqual( @@ -3061,7 +3061,7 @@ def test_context_error_table_stop_sharing(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("access"), "READER") self.assertEqual( @@ -3214,7 +3214,7 @@ def test_context_verified_table_access(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("access"), acm_models.WorkspaceGroupSharing.OWNER) self.assertEqual( @@ -3237,7 +3237,7 @@ def test_context_needs_action_table_share_as_reader(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -3269,7 +3269,7 @@ def test_context_needs_action_table_share_as_writer(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -3298,7 +3298,7 @@ def test_context_needs_action_table_share_with_compute(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -3327,7 +3327,7 @@ def test_context_needs_action_table_share_as_owner(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("access")) self.assertEqual( @@ -3370,7 +3370,7 @@ def test_context_needs_action_table_stop_sharing(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("access"), "READER") self.assertEqual( @@ -3406,7 +3406,7 @@ def test_context_error_table_stop_sharing(self): upload_workspace_sharing_audit.UploadWorkspaceSharingAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("access"), "READER") self.assertEqual( @@ -3554,7 +3554,7 @@ def test_get_verified_shared(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_sharing_audit_results.VerifiedShared) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER @@ -3571,7 +3571,7 @@ def test_get_verified_not_shared(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_sharing_audit_results.VerifiedNotShared) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS @@ -3588,7 +3588,7 @@ def test_get_share_as_reader(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsReader) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.AUTH_DOMAIN_AS_READER @@ -3607,7 +3607,7 @@ def test_get_share_as_writer(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsWriter) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, @@ -3624,7 +3624,7 @@ def test_get_share_with_compute(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareWithCompute) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_WRITERS_FUTURE_CYCLE @@ -3640,7 +3640,7 @@ def test_get_share_as_owner(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsOwner) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_sharing_audit.UploadWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER @@ -4675,7 +4675,7 @@ def test_context_verified_table_access(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.ADMIN) self.assertEqual( @@ -4703,7 +4703,7 @@ def test_context_verified_table_no_access(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), None) self.assertEqual( @@ -4726,7 +4726,7 @@ def test_context_needs_action_table_add_member(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("role")) self.assertEqual( @@ -4749,7 +4749,7 @@ def test_context_needs_action_table_add_admin(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("role")) self.assertEqual( @@ -4782,7 +4782,7 @@ def test_context_needs_action_table_remove(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) self.assertEqual( @@ -4810,7 +4810,7 @@ def test_context_error_table_remove(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) self.assertEqual( @@ -4838,7 +4838,7 @@ def test_context_errors_table_change_to_member(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.ADMIN) self.assertEqual( @@ -4866,7 +4866,7 @@ def test_context_needs_action_table_change_to_admin(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) self.assertEqual( @@ -5025,7 +5025,7 @@ def test_context_verified_table_access(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.ADMIN) self.assertEqual( @@ -5060,7 +5060,7 @@ def test_context_verified_table_no_access(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), None) self.assertEqual( @@ -5087,7 +5087,7 @@ def test_context_needs_action_table_add_member(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("role")) self.assertEqual( @@ -5114,7 +5114,7 @@ def test_context_needs_action_table_add_admin(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("role")) self.assertEqual( @@ -5154,7 +5154,7 @@ def test_context_needs_action_table_remove(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) self.assertEqual( @@ -5186,7 +5186,7 @@ def test_context_error_table_remove(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) self.assertEqual( @@ -5218,7 +5218,7 @@ def test_context_errors_table_change_to_member(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.ADMIN) self.assertEqual( @@ -5250,7 +5250,7 @@ def test_context_needs_action_table_change_to_admin(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) self.assertEqual( @@ -5405,7 +5405,7 @@ def test_context_verified_table_access(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.ADMIN) self.assertEqual( @@ -5436,7 +5436,7 @@ def test_context_verified_table_no_access(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), None) self.assertEqual( @@ -5459,7 +5459,7 @@ def test_context_needs_action_table_add_member(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("role")) self.assertEqual( @@ -5482,7 +5482,7 @@ def test_context_needs_action_table_add_admin(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertIsNone(table.rows[0].get_cell_value("role")) self.assertEqual( @@ -5518,7 +5518,7 @@ def test_context_needs_action_table_remove(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) self.assertEqual( @@ -5546,7 +5546,7 @@ def test_context_error_table_remove(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) self.assertEqual( @@ -5574,7 +5574,7 @@ def test_context_errors_table_change_to_member(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.ADMIN) self.assertEqual( @@ -5602,7 +5602,7 @@ def test_context_needs_action_table_change_to_admin(self): upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace) + self.assertEqual(table.rows[0].get_cell_value("workspace"), upload_workspace.workspace) self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) self.assertEqual( @@ -5752,7 +5752,7 @@ def test_get_verified_member(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.VerifiedMember) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_BEFORE_COMBINED @@ -5774,7 +5774,7 @@ def test_get_verified_admin(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.VerifiedAdmin) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS @@ -5791,7 +5791,7 @@ def test_get_verified_not_member(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.VerifiedNotMember) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP @@ -5808,7 +5808,7 @@ def test_get_add_member(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.AddMember) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_BEFORE_COMBINED @@ -5825,7 +5825,7 @@ def test_get_add_admin(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.AddAdmin) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS @@ -5847,7 +5847,7 @@ def test_get_change_to_member(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.ChangeToMember) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_BEFORE_COMBINED @@ -5869,7 +5869,7 @@ def test_get_change_to_admin(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.ChangeToAdmin) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.DCC_ADMINS @@ -5890,7 +5890,7 @@ def test_get_remove(self): self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.Remove) - self.assertEqual(audit_result.workspace, upload_workspace) + self.assertEqual(audit_result.workspace, upload_workspace.workspace) self.assertEqual(audit_result.managed_group, group) self.assertEqual( audit_result.note, upload_workspace_auth_domain_audit.UploadWorkspaceAuthDomainAudit.OTHER_GROUP diff --git a/gregor_django/templates/gregor_anvil/snippets/upload_workspace_auth_domain_audit_action_button.html b/gregor_django/templates/gregor_anvil/snippets/upload_workspace_auth_domain_audit_action_button.html index 1e0437e9..1f101cbc 100644 --- a/gregor_django/templates/gregor_anvil/snippets/upload_workspace_auth_domain_audit_action_button.html +++ b/gregor_django/templates/gregor_anvil/snippets/upload_workspace_auth_domain_audit_action_button.html @@ -2,13 +2,13 @@ {% if record.action %}
        + action="{% url 'gregor_anvil:audit:upload_workspaces:auth_domains:resolve' record.workspace.billing_project.name record.workspace.name record.managed_group.name %}"> {% csrf_token %} +

    +
    +
    + +

    + This audit checks that workspace sharing is appropriate for the current point in the upload cycle. + Sharing with the following groups are checked: +

      +
    • The authorization domain of the workspace
    • +
    • GREGOR_DCC_ADMINS
    • +
    • GREGOR_DCC_WRITERS
    • +
    • GREGOR_DCC_MEMBERS
    • +
    • Any additional groups that the workspace is shared with
    • +
    + Note that groups associated with AnVIL (e.g., anvil-admins, anvil-devs) are ignored by the audit. +

    +

    The audit result categories are explained below. +

      + +
    • Verified includes the following:
    • +
        +
      • The workspace is shared with a group with appropriate permissions.
      • +
      • The workspace is not shared with a group that it should not be shared with.
      • +
      + +
    • Needs action includes the following:
    • +
        +
      • The access level for a specific group needs to be changed.
      • +
      + +
    • Errors
    • +
        +
      • The workspace has been shared with an unexpected group.
      • +
      +
    +

    +

    Any errors should be reported!

    +
    +
    +

    +
    From d3f5d81d5f6474b329c768ea340e9be9629fc5ab Mon Sep 17 00:00:00 2001 From: Jonas Carson Date: Fri, 27 Sep 2024 09:36:05 -0700 Subject: [PATCH 33/97] Add auth cycle error logging to our social account adapter and update social login error template to show more info --- .../socialaccount/authentication_error.html | 15 +++++++++++++++ gregor_django/users/adapters.py | 8 ++++++++ 2 files changed, 23 insertions(+) create mode 100644 gregor_django/templates/socialaccount/authentication_error.html diff --git a/gregor_django/templates/socialaccount/authentication_error.html b/gregor_django/templates/socialaccount/authentication_error.html new file mode 100644 index 00000000..92a5b4c8 --- /dev/null +++ b/gregor_django/templates/socialaccount/authentication_error.html @@ -0,0 +1,15 @@ +{% extends "socialaccount/base.html" %} + +{% load i18n %} + +{% block head_title %}{% trans "Social Network Login Failure" %}{% endblock %} + +{% block content %} +

    {% trans "Social Network Login Failure" %}

    + +

    {% trans "Sorry. An error occurred while attempting to login via your social network account." %}

    + +

    + Authentication error code: {{ auth_error.code }}, Error: {{ auth_error.exception }} +

    +{% endblock %} diff --git a/gregor_django/users/adapters.py b/gregor_django/users/adapters.py index 286214cd..26f0075c 100644 --- a/gregor_django/users/adapters.py +++ b/gregor_django/users/adapters.py @@ -185,3 +185,11 @@ def update_user_data(self, sociallogin: Any): self.update_user_research_centers(user, extra_data) self.update_user_partner_groups(user, extra_data) self.update_user_groups(user, extra_data) + + def authentication_error(self, request, provider_id, error, exception, extra_context): + """ + Invoked when there is an error in auth cycle. + Log so we know what is going on. + """ + logger.error(f"[SocialAccountAdapter:authentication_error] Error {error} Exception: {exception}") + super().authentication_error(request, provider_id, error, exception, extra_context) From 82893140345694a6ab8fe45b26b5158de8b122e8 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 30 Sep 2024 14:27:48 -0700 Subject: [PATCH 34/97] Add a view to resolve CombinedConsortiumDataWorkspace sharing audits --- .../gregor_anvil/tests/test_views.py | 1446 +++++++++++++++++ gregor_django/gregor_anvil/urls.py | 10 +- gregor_django/gregor_anvil/views.py | 114 ++ ...umdataworkspace_sharing_audit_resolve.html | 44 + 4 files changed, 1609 insertions(+), 5 deletions(-) create mode 100644 gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_sharing_audit_resolve.html diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index a26790f6..9d7e1729 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -7512,3 +7512,1449 @@ def test_title(self): ) # self.assertContains(response, str(self.workspace)) self.assertIn(str(self.workspace), response.content.decode().lower()) + + +class CombinedConsortiumDataWorkspaceSharingAuditResolveTest(AnVILAPIMockTestMixin, TestCase): + def setUp(self): + """Set up test class.""" + super().setUp() + self.factory = RequestFactory() + # 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=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) + ) + self.user.user_permissions.add( + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) + ) + + def get_url(self, *args): + """Get the url for the view being tested.""" + return reverse( + "gregor_anvil:audit:combined_workspaces:sharing:resolve", + args=args, + ) + + def get_view(self): + """Return the view being tested.""" + return views.CombinedConsortiumDataWorkspaceSharingAuditResolve.as_view() + + def test_view_redirect_not_logged_in(self): + "View redirects to login view when user is not logged in." + # Need a client for redirects. + response = self.client.get(self.get_url("foo", "bar", "foobar")) + self.assertRedirects( + response, + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo", "bar", "foobar"), + ) + + def test_status_code_with_user_permission_staff_edit(self): + """Returns successful response code if the user has staff edit permission.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.get( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + + def test_status_code_with_user_permission_staff_view(self): + """Returns 403 response code if the user has staff view permission.""" + user_view = User.objects.create_user(username="test-view", password="test-view") + user_view.user_permissions.add( + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) + ) + self.client.force_login(self.user) + request = self.factory.get(self.get_url("foo", "bar", "foobar")) + request.user = user_view + with self.assertRaises(PermissionDenied): + self.get_view()(request) + + def test_status_code_with_user_permission_view(self): + """Returns forbidden response code if the user has view permission.""" + user = User.objects.create_user(username="test-none", password="test-none") + user.user_permissions.add(Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME)) + request = self.factory.get(self.get_url("foo", "bar", "foobar")) + request.user = user + with self.assertRaises(PermissionDenied): + self.get_view()(request) + + def test_access_without_user_permission(self): + """Raises permission denied if user has no permissions.""" + user_no_perms = User.objects.create_user(username="test-none", password="test-none") + request = self.factory.get(self.get_url("foo", "bar", "foobar")) + request.user = user_no_perms + with self.assertRaises(PermissionDenied): + self.get_view()(request) + + def test_get_billing_project_does_not_exist(self): + """Raises a 404 error with an invalid billing project.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.get(self.get_url("foo", workspace.workspace.name, group.name)) + self.assertEqual(response.status_code, 404) + + def test_get_workspace_name_does_not_exist(self): + """Raises a 404 error with an invalid billing project.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.get(self.get_url(workspace.workspace.billing_project.name, "foo", group.name)) + self.assertEqual(response.status_code, 404) + + def test_get_group_does_not_exist(self): + """get request raises a 404 error with an non-existent email.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + "foo", + ) + ) + self.assertEqual(response.status_code, 404) + + def test_get_context_audit_result(self): + """The audit_results exists in the context.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.get( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertIn("audit_result", response.context_data) + self.assertIsInstance( + response.context_data["audit_result"], + workspace_sharing_audit_results.WorkspaceSharingAuditResult, + ) + + def test_get_verified_shared(self): + """Get request with VerifiedShared result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + date_completed=timezone.now() - timedelta(days=1) + ) + group = workspace.workspace.authorization_domains.first() + acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.READER, + ) + self.client.force_login(self.user) + response = self.client.get( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.VerifiedShared) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit.AUTH_DOMAIN_AFTER_COMPLETE, + ) + + def test_get_verified_not_shared(self): + """Get request with VerifiedNotShared result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.get( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.VerifiedNotShared) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit.OTHER_GROUP + ) + + def test_get_share_as_reader(self): + """Get request with ShareAsReader result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + date_completed=timezone.now() - timedelta(days=1) + ) + group = workspace.workspace.authorization_domains.first() + self.client.force_login(self.user) + response = self.client.get( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsReader) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit.AUTH_DOMAIN_AFTER_COMPLETE, + ) + + def test_get_share_with_compute(self): + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_DCC_WRITERS") + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + self.client.force_login(self.user) + response = self.client.get( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareWithCompute) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit.DCC_WRITERS_BEFORE_COMPLETE, + ) + + def test_get_share_as_owner(self): + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + self.client.force_login(self.user) + response = self.client.get( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsOwner) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit.DCC_ADMIN_AS_OWNER, + ) + + def test_get_stop_sharing(self): + """Get request with StopSharing result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + ) + self.client.force_login(self.user) + response = self.client.get( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.StopSharing) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit.OTHER_GROUP + ) + + def test_post_billing_project_does_not_exist(self): + """Raises a 404 error with an invalid billing project.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.post(self.get_url("foo", workspace.workspace.name, group.name)) + self.assertEqual(response.status_code, 404) + + def test_post_workspace_name_does_not_exist(self): + """Raises a 404 error with an invalid billing project.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.post(self.get_url(workspace.workspace.billing_project.name, "foo", group.name)) + self.assertEqual(response.status_code, 404) + + def test_post_group_does_not_exist(self): + """post request raises a 404 error with an non-existent email.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + self.client.force_login(self.user) + response = self.client.post( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + "foo", + ) + ) + self.assertEqual(response.status_code, 404) + + def test_post_verified_shared(self): + """Post request with VerifiedShared result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + date_completed=timezone.now() - timedelta(days=1) + ) + group = workspace.workspace.authorization_domains.first() + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.READER, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.created, date_created) + self.assertEqual(sharing.modified, date_created) + + def test_post_verified_not_shared(self): + """Post request with VerifiedNotShared result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 0) + + def test_post_new_share_as_reader(self): + """Post request with ShareAsReader result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + date_completed=timezone.now() - timedelta(days=1), + ) + group = workspace.workspace.authorization_domains.first() + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "READER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing = acm_models.WorkspaceGroupSharing.objects.get(workspace=workspace.workspace, group=group) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.READER) + self.assertFalse(sharing.can_compute) + + def test_post_new_share_with_compute(self): + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_DCC_WRITERS") + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing = acm_models.WorkspaceGroupSharing.objects.get(workspace=workspace.workspace, group=group) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.WRITER) + self.assertTrue(sharing.can_compute) + + def test_post_new_share_as_owner(self): + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + upload_cycle__is_future=True, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "OWNER", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing = acm_models.WorkspaceGroupSharing.objects.get(workspace=workspace.workspace, group=group) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.OWNER) + self.assertTrue(sharing.can_compute) + + def test_post_new_stop_sharing(self): + group = acm_factories.ManagedGroupFactory.create() + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "NO ACCESS", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 0) + + def test_post_update_share_as_reader(self): + """Post request with ShareAsReader result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + date_completed=timezone.now() - timedelta(days=1), + ) + group = workspace.workspace.authorization_domains.first() + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.WRITER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "READER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.created, date_created) + self.assertGreater(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.READER) + self.assertFalse(sharing.can_compute) + + def test_post_update_share_with_compute(self): + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_DCC_WRITERS") + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.READER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.created, date_created) + self.assertGreater(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.WRITER) + self.assertTrue(sharing.can_compute) + + def test_post_update_share_as_owner(self): + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.READER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "OWNER", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.created, date_created) + self.assertGreater(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.OWNER) + self.assertTrue(sharing.can_compute) + + def test_post_new_share_as_reader_htmx(self): + """Post request with ShareAsReader result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + date_completed=timezone.now() - timedelta(days=1), + ) + group = workspace.workspace.authorization_domains.first() + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "READER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual( + response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_success + ) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing = acm_models.WorkspaceGroupSharing.objects.get(workspace=workspace.workspace, group=group) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.READER) + self.assertFalse(sharing.can_compute) + + def test_post_new_share_with_compute_htmx(self): + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_DCC_WRITERS") + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual( + response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_success + ) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing = acm_models.WorkspaceGroupSharing.objects.get(workspace=workspace.workspace, group=group) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.WRITER) + self.assertTrue(sharing.can_compute) + + def test_post_new_share_as_owner_htmx(self): + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + upload_cycle__is_future=True, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "OWNER", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual( + response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_success + ) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing = acm_models.WorkspaceGroupSharing.objects.get(workspace=workspace.workspace, group=group) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.OWNER) + self.assertTrue(sharing.can_compute) + + def test_post_new_stop_sharing_htmx(self): + group = acm_factories.ManagedGroupFactory.create() + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "NO ACCESS", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual( + response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_success + ) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 0) + + def test_post_update_share_as_reader_htmx(self): + """Post request with ShareAsReader result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + date_completed=timezone.now() - timedelta(days=1), + ) + group = workspace.workspace.authorization_domains.first() + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.WRITER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "READER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual( + response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_success + ) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.created, date_created) + self.assertGreater(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.READER) + self.assertFalse(sharing.can_compute) + + def test_post_update_share_with_compute_htmx(self): + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_DCC_WRITERS") + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.READER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual( + response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_success + ) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.created, date_created) + self.assertGreater(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.WRITER) + self.assertTrue(sharing.can_compute) + + def test_post_update_share_as_owner_htmx(self): + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.READER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "OWNER", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual( + response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_success + ) + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.created, date_created) + self.assertGreater(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.OWNER) + self.assertTrue(sharing.can_compute) + + def test_post_new_share_as_reader_api_error(self): + """Post request with ShareAsReader result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + date_completed=timezone.now() - timedelta(days=1), + ) + group = workspace.workspace.authorization_domains.first() + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "READER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # No sharing object was created. + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 0) + # Audit result is still as expected. + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsReader) + # A message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_new_share_with_compute_api_error(self): + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_DCC_WRITERS") + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # No sharing object was created. + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 0) + # Audit result is still as expected. + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareWithCompute) + # A message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_new_share_as_owner_api_error(self): + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + upload_cycle__is_future=True, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "OWNER", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # No sharing object was created. + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 0) + # Audit result is still as expected. + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsOwner) + # A message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_new_stop_sharing_api_error(self): + group = acm_factories.ManagedGroupFactory.create() + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "NO ACCESS", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # Sharing result has not changed. + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace.workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.READER) + # Audit result is still as expected. + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.StopSharing) + # A message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_update_share_as_reader_api_error(self): + """Post request with ShareAsReader result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + date_completed=timezone.now() - timedelta(days=1), + ) + group = workspace.workspace.authorization_domains.first() + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.WRITER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "READER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # Sharing result has not changed. + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace.workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.WRITER) + # Audit result is still as expected. + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsReader) + # A message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_update_share_with_compute_api_error(self): + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_DCC_WRITERS") + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.READER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # Sharing result has not changed. + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace.workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.READER) + # Audit result is still as expected. + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareWithCompute) + # A message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_update_share_as_owner_api_error(self): + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.READER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "OWNER", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + match=[responses.matchers.json_params_matcher(acls)], + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # Sharing result has not changed. + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace.workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.READER) + # Audit result is still as expected. + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_sharing_audit_results.ShareAsOwner) + # A message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_new_share_as_reader_api_error_htmx(self): + """Post request with ShareAsReader result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + date_completed=timezone.now() - timedelta(days=1), + ) + group = workspace.workspace.authorization_domains.first() + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "READER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual(response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_error) + # No sharing object was created. + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 0) + # No messages were added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_new_share_with_compute_api_error_htmx(self): + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_DCC_WRITERS") + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual(response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_error) + # No sharing object was created. + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 0) + # No messages were added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_new_share_as_owner_api_error_htmx(self): + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + upload_cycle__is_future=True, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "OWNER", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual(response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_error) + # No sharing object was created. + self.assertEqual(acm_models.WorkspaceGroupSharing.objects.count(), 0) + # No messages were added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_new_stop_sharing_api_error_htmx(self): + group = acm_factories.ManagedGroupFactory.create() + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "NO ACCESS", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual(response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_error) + # Sharing result has not changed. + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace.workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.READER) + # No messages were added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_update_share_as_reader_api_error_htmx(self): + """Post request with ShareAsReader result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + date_completed=timezone.now() - timedelta(days=1), + ) + group = workspace.workspace.authorization_domains.first() + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.WRITER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "READER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual(response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_error) + # Sharing result has not changed. + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace.workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.WRITER) + # No messages were added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_update_share_with_compute_api_error_htmx(self): + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_DCC_WRITERS") + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.READER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=500, + json=ErrorResponseFactory().response, + match=[responses.matchers.json_params_matcher(acls)], + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual(response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_error) + # Sharing result has not changed. + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace.workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.READER) + # No messages were added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_update_share_as_owner_api_error_htmx(self): + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + workspace__billing_project__name="test-bp", + workspace__name="test-ws", + ) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + sharing = acm_factories.WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=group, + access=acm_models.WorkspaceGroupSharing.READER, + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "OWNER", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + match=[responses.matchers.json_params_matcher(acls)], + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), + **header, + ) + self.assertEqual(response.content.decode(), views.CombinedConsortiumDataWorkspaceSharingAuditResolve.htmx_error) + # Sharing result has not changed. + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace.workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.modified, date_created) + self.assertEqual(sharing.access, acm_models.WorkspaceGroupSharing.READER) + # No messages were added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) diff --git a/gregor_django/gregor_anvil/urls.py b/gregor_django/gregor_anvil/urls.py index cdda487b..d03b3c6c 100644 --- a/gregor_django/gregor_anvil/urls.py +++ b/gregor_django/gregor_anvil/urls.py @@ -101,11 +101,11 @@ combined_workspace_sharing_audit_patterns = ( [ path("all/", views.CombinedConsortiumDataWorkspaceSharingAudit.as_view(), name="all"), - # path( - # "resolve////", - # views.UploadWorkspaceSharingAuditResolve.as_view(), - # name="resolve", - # ), + path( + "resolve////", + views.CombinedConsortiumDataWorkspaceSharingAuditResolve.as_view(), + name="resolve", + ), path( "//", views.CombinedConsortiumDataWorkspaceSharingAuditByWorkspace.as_view(), diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index 694dfe08..d6b34e88 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -652,3 +652,117 @@ def get_context_data(self, **kwargs): context["needs_action_table"] = audit.get_needs_action_table() context["audit_results"] = audit return context + + +class CombinedConsortiumDataWorkspaceSharingAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): + """View to resolve CombinedConsortiumDataWorkspace audit results.""" + + form_class = Form + template_name = "gregor_anvil/combinedconsortiumdataworkspace_sharing_audit_resolve.html" + htmx_success = """ Handled!""" + htmx_error = """ Error!""" + + def get_combined_workspace(self): + """Look up the CombinedConsortiumDataWorkspace by billing project and name.""" + # Filter the queryset based on kwargs. + billing_project_slug = self.kwargs.get("billing_project_slug", None) + workspace_slug = self.kwargs.get("workspace_slug", None) + queryset = models.CombinedConsortiumDataWorkspace.objects.filter( + workspace__billing_project__name=billing_project_slug, + workspace__name=workspace_slug, + ) + try: + # Get the single item from the filtered queryset + obj = queryset.get() + except queryset.model.DoesNotExist: + raise Http404( + _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name} + ) + return obj + + def get_managed_group(self, queryset=None): + """Look up the ManagedGroup by name.""" + try: + obj = ManagedGroup.objects.get(name=self.kwargs.get("managed_group_slug", None)) + except ManagedGroup.DoesNotExist: + raise Http404("No ManagedGroups found matching the query") + return obj + + def get_audit_result(self): + audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit() + # No way to set the group queryset, since it is dynamically determined by the workspace. + audit.audit_workspace_and_group(self.combined_workspace, self.managed_group) + # Set to completed, because we are just running this one specific check. + audit.completed = True + return audit.get_all_results()[0] + + def get(self, request, *args, **kwargs): + self.combined_workspace = self.get_combined_workspace() + self.managed_group = self.get_managed_group() + self.audit_result = self.get_audit_result() + return super().get(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + self.combined_workspace = self.get_combined_workspace() + self.managed_group = self.get_managed_group() + self.audit_result = self.get_audit_result() + return super().post(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["combined_workspace"] = self.combined_workspace + context["managed_group"] = self.managed_group + context["audit_result"] = self.audit_result + return context + + def get_success_url(self): + return self.combined_workspace.get_absolute_url() + + def form_valid(self, form): + # Handle the result. + try: + # Set up the sharing instance. + if self.audit_result.current_sharing_instance: + sharing = self.audit_result.current_sharing_instance + else: + sharing = WorkspaceGroupSharing( + workspace=self.combined_workspace.workspace, + group=self.managed_group, + ) + with transaction.atomic(): + if isinstance(self.audit_result, workspace_sharing_audit_results.VerifiedShared): + # No changes needed. + pass + elif isinstance(self.audit_result, workspace_sharing_audit_results.VerifiedNotShared): + # No changes needed. + pass + elif isinstance(self.audit_result, workspace_sharing_audit_results.StopSharing): + sharing.anvil_delete() + sharing.delete() + else: + if isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsReader): + sharing.access = WorkspaceGroupSharing.READER + sharing.can_compute = False + elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsWriter): + sharing.access = WorkspaceGroupSharing.WRITER + sharing.can_compute = False + elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareWithCompute): + sharing.access = WorkspaceGroupSharing.WRITER + sharing.can_compute = True + elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsOwner): + sharing.access = WorkspaceGroupSharing.OWNER + sharing.can_compute = True + sharing.full_clean() + sharing.save() + sharing.anvil_create_or_update() + except (AnVILAPIError, AnVILGroupNotFound) as e: + if self.request.htmx: + return HttpResponse(self.htmx_error) + else: + messages.error(self.request, "AnVIL API Error: " + str(e)) + return super().form_invalid(form) + # Otherwise, the audit resolution succeeded. + if self.request.htmx: + return HttpResponse(self.htmx_success) + else: + return super().form_valid(form) diff --git a/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_sharing_audit_resolve.html b/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_sharing_audit_resolve.html new file mode 100644 index 00000000..a7ddb739 --- /dev/null +++ b/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_sharing_audit_resolve.html @@ -0,0 +1,44 @@ +{% extends "anvil_consortium_manager/base.html" %} +{% load django_tables2 %} +{% load crispy_forms_tags %} + +{% block title %}Resolve combined workspace audit{% endblock %} + + +{% block content %} + +

    Resolve combined workspace sharing audit

    + +
    + + + {% include "gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_explanation.html" %} + +
    + +

    Audit results

    + + +
    +
    +
    Result
    +

    {{ audit_result }}

    + {% if audit_result.action %} + + + {% csrf_token %} + {{ form|crispy }} + + + + {% else %} + + {% endif %} +
    +
    + + +{% endblock content %} From ecc4dec563a57297c32929a09c63f87bd11ec9aa Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 30 Sep 2024 15:58:07 -0700 Subject: [PATCH 35/97] Update the action button for combined workspace sharing audit Add a specific template for this action button, and then use that action button in the table. (Previously it was using the upload workspace audit template because this one didn't exist yet.) --- .../audit/combined_workspace_audit.py | 2 +- ...workspace_sharing_audit_action_button.html | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_action_button.html diff --git a/gregor_django/gregor_anvil/audit/combined_workspace_audit.py b/gregor_django/gregor_anvil/audit/combined_workspace_audit.py index aed80698..ec66a3b2 100644 --- a/gregor_django/gregor_anvil/audit/combined_workspace_audit.py +++ b/gregor_django/gregor_anvil/audit/combined_workspace_audit.py @@ -185,7 +185,7 @@ class CombinedConsortiumDataWorkspaceSharingAuditTable(tables.Table): can_compute = BooleanIconColumn(show_false_icon=True, null=True, true_color="green", false_color="black") note = tables.Column() action = tables.TemplateColumn( - template_name="gregor_anvil/snippets/upload_workspace_sharing_audit_action_button.html" + template_name="gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_action_button.html" ) class Meta: diff --git a/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_action_button.html b/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_action_button.html new file mode 100644 index 00000000..0e36afb8 --- /dev/null +++ b/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_action_button.html @@ -0,0 +1,22 @@ +
    + {% if record.action %} +
    + + {% csrf_token %} + +
    + + {% else %} + — + {% endif %} +
    From 70db266193618c2e4724e4912bef5f1366863b90 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 30 Sep 2024 16:32:30 -0700 Subject: [PATCH 36/97] Add skeleton views for auth domain auditing Also add templates, which will likely be updated as the views are actually written. --- gregor_django/gregor_anvil/views.py | 18 ++++++++ ...ortiumdataworkspace_auth_domain_audit.html | 25 +++++++++++ ...taworkspace_auth_domain_audit_resolve.html | 44 +++++++++++++++++++ ...space_auth_domain_audit_action_button.html | 22 ++++++++++ ...rkspace_auth_domain_audit_explanation.html | 24 ++++++++++ 5 files changed, 133 insertions(+) create mode 100644 gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html create mode 100644 gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit_resolve.html create mode 100644 gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_action_button.html create mode 100644 gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_explanation.html diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index d6b34e88..5582d7e8 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -766,3 +766,21 @@ def form_valid(self, form): return HttpResponse(self.htmx_success) else: return super().form_valid(form) + + +class CombinedConsortiumDataWorkspaceAuthDomainAudit(AnVILConsortiumManagerStaffViewRequired, TemplateView): + """View to audit auth domain membership for all CombinedConsortiumDataWorkspaces.""" + + pass + + +class CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace(AnVILConsortiumManagerStaffEditRequired, DetailView): + """View to audit auth domain membership for a specific CombinedConsortiumDataWorkspace.""" + + pass + + +class CombinedConsortiumDataWorkspaceAuthDomainAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): + """View to resolve CombinedConsortiumDataWorkspace auth domain audit results.""" + + pass diff --git a/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html b/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html new file mode 100644 index 00000000..a89d33f3 --- /dev/null +++ b/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html @@ -0,0 +1,25 @@ +{% extends "anvil_consortium_manager/base.html" %} +{% load django_tables2 %} + +{% block title %}Combined workspace auth domain audit{% endblock %} + + +{% block content %} + +

    Combined consortium data workspace auth domain audit: {% if object %} {{ object }} {% else %} all Combined Workspaces{% endif %}

    + +
    +

    + When auditing combined workspace auth domain membership, + all records in the "Needs action" table should be handled by clicking on the action button. + Any records in the "Errors" table should be reported. +

    + {% include "gregor_anvil/snippets/combinedconsortiumdataworkspac_auth_domain_audit_explanation.html" %} + +
    + +

    Audit results

    + +{% include "__audit_tables.html" with verified_table=verified_table needs_action_table=needs_action_table errors_table=errors_table %} + +{% endblock content %} diff --git a/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit_resolve.html b/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit_resolve.html new file mode 100644 index 00000000..0a506c47 --- /dev/null +++ b/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit_resolve.html @@ -0,0 +1,44 @@ +{% extends "anvil_consortium_manager/base.html" %} +{% load django_tables2 %} +{% load crispy_forms_tags %} + +{% block title %}Resolve combined workspace audit{% endblock %} + + +{% block content %} + +

    Resolve combined workspace auth domain audit

    + +
    + + + {% include "gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_explanation.html" %} + +
    + +

    Audit results

    + + +
    +
    +
    Result
    +

    {{ audit_result }}

    + {% if audit_result.action %} +
    + + {% csrf_token %} + {{ form|crispy }} + + +
    + {% else %} + + {% endif %} +
    +
    + + +{% endblock content %} diff --git a/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_action_button.html b/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_action_button.html new file mode 100644 index 00000000..94e5e134 --- /dev/null +++ b/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_action_button.html @@ -0,0 +1,22 @@ +
    + {% if record.action %} +
    + + {% csrf_token %} + +
    + + {% else %} + — + {% endif %} +
    diff --git a/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_explanation.html b/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_explanation.html new file mode 100644 index 00000000..f2785a71 --- /dev/null +++ b/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_explanation.html @@ -0,0 +1,24 @@ +
    +
    +

    + +

    +
    +
    + +

    + This audit checks that auth domain membership is appropriate for the current point in the upload cycle. + Membership is expected to be as follows. +

      +
    • GREGOR_ALL
    • +
    • GREGOR_DCC_ADMINS (as admin)
    • +
    + Note that groups associated with AnVIL (e.g., anvil-admins, anvil-devs) are ignored by the audit. +

    +

    Any errors should be reported!

    +
    +
    +
    +
    From 83358d566c777ff30e03833b35b521c9d3894cae Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 30 Sep 2024 16:40:22 -0700 Subject: [PATCH 37/97] Fix template for combined workspace sharing audit The view was accidentally pointing the upload workspace sharing audit template. --- gregor_django/gregor_anvil/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index 5582d7e8..89b2d11e 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -619,7 +619,7 @@ def get_context_data(self, **kwargs): class CombinedConsortiumDataWorkspaceSharingAuditByWorkspace(AnVILConsortiumManagerStaffViewRequired, DetailView): """View to audit CombinedConsortiumDataWorkspace sharing for a specific CombinedConsortiumDataWorkspace.""" - template_name = "gregor_anvil/upload_workspace_sharing_audit.html" + template_name = "gregor_anvil/combinedconsortiumdataworkspace_sharing_audit.html" model = models.CombinedConsortiumDataWorkspace def get_object(self, queryset=None): From 872b187a36bf301f1d4293a85d212a0caa42cb6c Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 1 Oct 2024 15:29:38 -0700 Subject: [PATCH 38/97] Add view to audit auth domain membership for all combined workspaces --- .../audit/combined_workspace_audit.py | 6 + .../gregor_anvil/tests/test_views.py | 259 +++++++++++++++++- gregor_django/gregor_anvil/urls.py | 6 +- gregor_django/gregor_anvil/views.py | 13 +- ...ortiumdataworkspace_auth_domain_audit.html | 2 +- 5 files changed, 280 insertions(+), 6 deletions(-) diff --git a/gregor_django/gregor_anvil/audit/combined_workspace_audit.py b/gregor_django/gregor_anvil/audit/combined_workspace_audit.py index ec66a3b2..1a91d937 100644 --- a/gregor_django/gregor_anvil/audit/combined_workspace_audit.py +++ b/gregor_django/gregor_anvil/audit/combined_workspace_audit.py @@ -14,6 +14,12 @@ class CombinedConsortiumDataWorkspaceAuthDomainAuditTable(tables.Table): workspace = tables.Column(verbose_name="Workspace") managed_group = tables.Column(verbose_name="Group") + role = tables.Column(verbose_name="Current role") + note = tables.Column() + action = tables.TemplateColumn( + # Temporarily use this button template, until we have the resolve view working for this workspace type. + template_name="gregor_anvil/snippets/upload_workspace_auth_domain_audit_action_button.html" + ) class Meta: attrs = {"class": "table align-middle"} diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index 9d7e1729..2cb6dabd 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -4553,7 +4553,7 @@ def get_url(self, *args): def get_view(self): """Return the view being tested.""" - return views.UploadWorkspaceAuthDomainAuditByUploadCycle.as_view() + return views.UploadWorkspaceAuthDomainAudit.as_view() def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." @@ -8958,3 +8958,260 @@ def test_post_update_share_as_owner_api_error_htmx(self): # No messages were added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 0) + + +class CombinedConsortiumDataWorkspaceAuthDomainAuditTest(AnVILAPIMockTestMixin, TestCase): + """Tests for the CombinedConsortiumDataWorkspaceAuthDomainAudit view.""" + + def setUp(self): + """Set up test class.""" + super().setUp() + self.factory = RequestFactory() + # 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=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) + ) + + def get_url(self, *args): + """Get the url for the view being tested.""" + return reverse( + "gregor_anvil:audit:combined_workspaces:auth_domains:all", + args=args, + ) + + def get_view(self): + """Return the view being tested.""" + return views.CombinedConsortiumDataWorkspaceAuthDomainAudit.as_view() + + def test_view_redirect_not_logged_in(self): + "View redirects to login view when user is not logged in." + # Need a client for redirects. + response = self.client.get(self.get_url()) + self.assertRedirects( + response, + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(), + ) + + def test_status_code_with_user_permission_view(self): + """Returns successful response code if the user has view permission.""" + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + self.assertEqual(response.status_code, 200) + + def test_access_without_user_permission(self): + """Raises permission denied if user has no permissions.""" + user_no_perms = User.objects.create_user(username="test-none", password="test-none") + request = self.factory.get(self.get_url()) + request.user = user_no_perms + with self.assertRaises(PermissionDenied): + self.get_view()(request) + + def test_context_audit_results_no_workspaces(self): + """The audit_results exists in the context.""" + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + self.assertIn("audit_results", response.context_data) + audit_results = response.context_data["audit_results"] + self.assertIsInstance( + audit_results, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit, + ) + self.assertTrue(audit_results.completed) + self.assertEqual(audit_results.queryset.count(), 0) + + def test_context_audit_results_one_workspace(self): + """The audit_results exists in the context.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + self.assertIn("audit_results", response.context_data) + audit_results = response.context_data["audit_results"] + self.assertIsInstance( + audit_results, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit, + ) + self.assertTrue(audit_results.completed) + self.assertEqual(audit_results.queryset.count(), 1) + self.assertIn(workspace, audit_results.queryset) + + def test_context_audit_results_two_workspaces(self): + """The audit_results exists in the context.""" + workspace_1 = factories.CombinedConsortiumDataWorkspaceFactory.create() + workspace_2 = factories.CombinedConsortiumDataWorkspaceFactory.create() + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + self.assertIn("audit_results", response.context_data) + audit_results = response.context_data["audit_results"] + self.assertIsInstance( + audit_results, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit, + ) + self.assertTrue(audit_results.completed) + self.assertEqual(audit_results.queryset.count(), 2) + self.assertIn(workspace_1, audit_results.queryset) + self.assertIn(workspace_2, audit_results.queryset) + + def test_context_verified_table_access(self): + """verified_table shows a record when audit has verified access.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + self.assertIn("verified_table", response.context_data) + table = response.context_data["verified_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.ADMIN) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.DCC_ADMIN_AS_ADMIN, + ) + self.assertEqual(table.rows[0].get_cell_value("action"), "—") + + def test_context_needs_action_table_add_member(self): + """needs_action_table shows a record when audit finds that access needs to be granted.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + self.assertIn("needs_action_table", response.context_data) + table = response.context_data["needs_action_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertIsNone(table.rows[0].get_cell_value("role")) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.GREGOR_ALL_AS_MEMBER, + ) + self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + + def test_context_needs_action_table_add_admin(self): + """needs_action_table shows a record when audit finds that access needs to be granted.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + self.assertIn("needs_action_table", response.context_data) + table = response.context_data["needs_action_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertIsNone(table.rows[0].get_cell_value("role")) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.DCC_ADMIN_AS_ADMIN, + ) + self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + + def test_context_error_table_remove(self): + """error table shows a record when audit finds that access needs to be removed.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + self.assertIn("errors_table", response.context_data) + table = response.context_data["errors_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.OTHER_GROUP, + ) + self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + + def test_context_errors_table_change_to_member(self): + """errors table shows a record when audit finds that access needs to be removed.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + self.assertIn("errors_table", response.context_data) + table = response.context_data["errors_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.ADMIN) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.GREGOR_ALL_AS_MEMBER, + ) + self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + + def test_context_needs_action_table_change_to_admin(self): + """error table shows a record when audit finds that access needs to be removed.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + self.assertIn("needs_action_table", response.context_data) + table = response.context_data["needs_action_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.DCC_ADMIN_AS_ADMIN, + ) + self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + + def test_title(self): + self.client.force_login(self.user) + response = self.client.get(self.get_url()) + # self.assertContains(response, str(self.workspace)) + self.assertIn("all combined workspaces", response.content.decode().lower()) diff --git a/gregor_django/gregor_anvil/urls.py b/gregor_django/gregor_anvil/urls.py index d03b3c6c..d12b8476 100644 --- a/gregor_django/gregor_anvil/urls.py +++ b/gregor_django/gregor_anvil/urls.py @@ -117,7 +117,7 @@ combined_workspace_auth_domain_audit_patterns = ( [ - # path("all/", views.UploadWorkspaceAuthDomainAudit.as_view(), name="all"), + path("all/", views.CombinedConsortiumDataWorkspaceAuthDomainAudit.as_view(), name="all"), # path( # "resolve////", # views.UploadWorkspaceAuthDomainAuditResolve.as_view(), @@ -125,8 +125,8 @@ # ), # path( # "//", - # views.UploadWorkspaceAuthDomainAuditByWorkspace.as_view(), - # name="by_upload_workspace", + # views.CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace.as_view(), + # name="by_workspace", # ), ], "auth_domains", diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index 89b2d11e..e55a82f7 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -771,7 +771,18 @@ def form_valid(self, form): class CombinedConsortiumDataWorkspaceAuthDomainAudit(AnVILConsortiumManagerStaffViewRequired, TemplateView): """View to audit auth domain membership for all CombinedConsortiumDataWorkspaces.""" - pass + template_name = "gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + # Run the audit. + audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit() + audit.run_audit() + context["verified_table"] = audit.get_verified_table() + context["errors_table"] = audit.get_errors_table() + context["needs_action_table"] = audit.get_needs_action_table() + context["audit_results"] = audit + return context class CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace(AnVILConsortiumManagerStaffEditRequired, DetailView): diff --git a/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html b/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html index a89d33f3..b6472dcc 100644 --- a/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html +++ b/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html @@ -14,7 +14,7 @@

    Combined consortium data workspace auth domain audit: {% if object %} {{ obj all records in the "Needs action" table should be handled by clicking on the action button. Any records in the "Errors" table should be reported.

    - {% include "gregor_anvil/snippets/combinedconsortiumdataworkspac_auth_domain_audit_explanation.html" %} + {% include "gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_explanation.html" %} From d3ff69d25da8684e0ad28c5ac3b0d23008eed84f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:27:06 +0000 Subject: [PATCH 39/97] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.6.0 → v5.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.6.0...v5.0.0) - [github.com/astral-sh/ruff-pre-commit: v0.6.5 → v0.6.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.5...v0.6.9) - [github.com/gitleaks/gitleaks: v8.19.2 → v8.20.0](https://github.com/gitleaks/gitleaks/compare/v8.19.2...v8.20.0) --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 500af5b1..c976519c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,10 +1,10 @@ exclude: 'docs|node_modules|migrations|.git|.tox' -default_stages: [commit] +default_stages: [Nonepre-commitNone] fail_fast: true repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -12,7 +12,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.6.5 + rev: v0.6.9 hooks: # Run the linter. - id: ruff @@ -21,7 +21,7 @@ repos: - id: ruff-format - repo: https://github.com/gitleaks/gitleaks - rev: v8.19.2 + rev: v8.20.0 hooks: - id: gitleaks From cfeedbf60853d4882aeddcb5ba485c0517be8022 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp <3944584+amstilp@users.noreply.github.com> Date: Mon, 7 Oct 2024 10:35:05 -0700 Subject: [PATCH 40/97] Fix default_stages incorrect update The default_stages value was incorrectly updated by the pre-commit update bot, which broke pre-commit. Fix it to be "pre-commit" instead of "commit" or "Nonepre-commitNone". --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c976519c..808e8b7b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ exclude: 'docs|node_modules|migrations|.git|.tox' -default_stages: [Nonepre-commitNone] +default_stages: [pre-commit] fail_fast: true repos: From 343c0211c5700544c8dfd489fa25426b00ee5ec6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:44:48 +0000 Subject: [PATCH 41/97] Bump codecov/codecov-action from 4.5.0 to 4.6.0 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.5.0 to 4.6.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.5.0...v4.6.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e094143..00051e4b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -140,6 +140,6 @@ jobs: python -m coverage report - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4.5.0 + uses: codecov/codecov-action@v4.6.0 with: token: ${{ secrets.CODECOV_TOKEN }} From 46126e6a19249b08883583264815c0739ccbb498 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:44:57 +0000 Subject: [PATCH 42/97] Bump actions/checkout from 4.1.7 to 4.2.1 Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.7 to 4.2.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.7...v4.2.1) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- .github/workflows/gitleaks.yml | 2 +- .github/workflows/pip-compile.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e094143..dfb8827d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,7 @@ jobs: steps: - name: Checkout Code Repository - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4.2.1 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5.2.0 @@ -111,7 +111,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repo - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4.2.1 - name: Set up Python uses: actions/setup-python@v5.2.0 diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml index f6cca493..b898bbac 100644 --- a/.github/workflows/gitleaks.yml +++ b/.github/workflows/gitleaks.yml @@ -10,7 +10,7 @@ jobs: name: gitleaks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.1 with: fetch-depth: 0 - uses: gitleaks/gitleaks-action@v2.3.6 diff --git a/.github/workflows/pip-compile.yml b/.github/workflows/pip-compile.yml index 93c60d63..9f906bd1 100644 --- a/.github/workflows/pip-compile.yml +++ b/.github/workflows/pip-compile.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout Code Repository - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4.2.1 with: ref: ${{ github.head_ref }} From 5b75f78b3b9fc16a6e3d0aebfe87d786f4a29fc2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:45:16 +0000 Subject: [PATCH 43/97] Bump ruff from 0.6.5 to 0.6.9 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.5 to 0.6.9. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.5...0.6.9) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 668dfdde..67d8a4b7 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -150,7 +150,7 @@ requests==2.32.3 # -c requirements/requirements.txt # -c requirements/test-requirements.txt # sphinx -ruff==0.6.5 +ruff==0.6.9 # via -r requirements/dev-requirements.in six==1.16.0 # via From aa6e25b5428d8fe20e6814404c5aa4689c988199 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:45:32 +0000 Subject: [PATCH 44/97] Bump sphinx-autobuild from 2024.9.17 to 2024.10.3 Bumps [sphinx-autobuild](https://github.com/sphinx-doc/sphinx-autobuild) from 2024.9.17 to 2024.10.3. - [Release notes](https://github.com/sphinx-doc/sphinx-autobuild/releases) - [Changelog](https://github.com/sphinx-doc/sphinx-autobuild/blob/main/NEWS.rst) - [Commits](https://github.com/sphinx-doc/sphinx-autobuild/compare/2024.09.17...2024.10.03) --- updated-dependencies: - dependency-name: sphinx-autobuild dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 668dfdde..28bd67d1 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -165,7 +165,7 @@ sphinx==8.0.2 # via # -r requirements/dev-requirements.in # sphinx-autobuild -sphinx-autobuild==2024.9.17 +sphinx-autobuild==2024.10.3 # via -r requirements/dev-requirements.in sphinxcontrib-applehelp==1.0.4 # via sphinx From 66cd1168460d09c724d8c72ea92a8b2018422bab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:45:50 +0000 Subject: [PATCH 45/97] Bump django-constance from 4.1.1 to 4.1.2 Bumps [django-constance](https://github.com/jazzband/django-constance) from 4.1.1 to 4.1.2. - [Release notes](https://github.com/jazzband/django-constance/releases) - [Changelog](https://github.com/jazzband/django-constance/blob/master/docs/changes.rst) - [Commits](https://github.com/jazzband/django-constance/compare/4.1.1...4.1.2) --- updated-dependencies: - dependency-name: django-constance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index a314a609..6e83e7b4 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -57,7 +57,7 @@ django-anvil-consortium-manager @ git+https://github.com/UW-GAC/django-anvil-con # via -r requirements/requirements.in django-autocomplete-light==3.11.0 # via django-anvil-consortium-manager -django-constance==4.1.1 +django-constance==4.1.2 # via -r requirements/requirements.in django-crispy-forms==2.3 # via From e25bd064533e80946fced92604d352f4c346a87f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 19:18:21 +0000 Subject: [PATCH 46/97] Bump crispy-bootstrap5 from 2024.2 to 2024.10 Bumps [crispy-bootstrap5](https://github.com/django-crispy-forms/crispy-bootstrap5) from 2024.2 to 2024.10. - [Release notes](https://github.com/django-crispy-forms/crispy-bootstrap5/releases) - [Changelog](https://github.com/django-crispy-forms/crispy-bootstrap5/blob/main/CHANGELOG.md) - [Commits](https://github.com/django-crispy-forms/crispy-bootstrap5/compare/2024.2...2024.10) --- updated-dependencies: - dependency-name: crispy-bootstrap5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 6e83e7b4..fb4316be 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -27,7 +27,7 @@ charset-normalizer==3.3.2 # via requests click==8.1.7 # via pip-tools -crispy-bootstrap5==2024.2 +crispy-bootstrap5==2024.10 # via # -r requirements/requirements.in # django-anvil-consortium-manager From 5475f65f76d52f7ebd38489b87618a503669c4e3 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 7 Oct 2024 12:57:08 -0700 Subject: [PATCH 47/97] Add a view to audit auth domain membership for a single combined workspace --- .../gregor_anvil/tests/test_views.py | 303 ++++++++++++++++++ gregor_django/gregor_anvil/urls.py | 10 +- gregor_django/gregor_anvil/views.py | 36 ++- 3 files changed, 342 insertions(+), 7 deletions(-) diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index 2cb6dabd..305d6c57 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -9215,3 +9215,306 @@ def test_title(self): response = self.client.get(self.get_url()) # self.assertContains(response, str(self.workspace)) self.assertIn("all combined workspaces", response.content.decode().lower()) + + +class CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspaceTest(AnVILAPIMockTestMixin, TestCase): + """Tests for the CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace view.""" + + def setUp(self): + """Set up test class.""" + super().setUp() + self.factory = RequestFactory() + # 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=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) + ) + self.workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + + def get_url(self, *args): + """Get the url for the view being tested.""" + return reverse( + "gregor_anvil:audit:combined_workspaces:auth_domains:by_workspace", + args=args, + ) + + def get_view(self): + """Return the view being tested.""" + return views.CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace.as_view() + + def test_view_redirect_not_logged_in(self): + "View redirects to login view when user is not logged in." + # Need a client for redirects. + response = self.client.get( + self.get_url(self.workspace.workspace.billing_project.name, self.workspace.workspace.name) + ) + self.assertRedirects( + response, + resolve_url(settings.LOGIN_URL) + + "?next=" + + self.get_url(self.workspace.workspace.billing_project.name, self.workspace.workspace.name), + ) + + def test_status_code_with_user_permission_view(self): + """Returns successful response code if the user has view permission.""" + self.client.force_login(self.user) + response = self.client.get( + self.get_url(self.workspace.workspace.billing_project.name, self.workspace.workspace.name) + ) + self.assertEqual(response.status_code, 200) + + def test_access_without_user_permission(self): + """Raises permission denied if user has no permissions.""" + user_no_perms = User.objects.create_user(username="test-none", password="test-none") + request = self.factory.get(self.get_url("foo", "bar")) + request.user = user_no_perms + with self.assertRaises(PermissionDenied): + self.get_view()(request) + + def test_invalid_billing_project_name(self): + """Raises a 404 error with an invalid object billing project.""" + request = self.factory.get(self.get_url("foo", self.workspace.workspace.name)) + request.user = self.user + with self.assertRaises(Http404): + self.get_view()( + request, + billing_project_slug="foo", + workspace_slug=self.workspace.workspace.name, + ) + + def test_invalid_workspace_name(self): + """Raises a 404 error with an invalid workspace name.""" + request = self.factory.get(self.get_url(self.workspace.workspace.billing_project.name, "foo")) + request.user = self.user + with self.assertRaises(Http404): + self.get_view()( + request, + billing_project_slug=self.workspace.workspace.billing_project.name, + workspace_slug="foo", + ) + + def test_context_audit_results(self): + """The audit_results exists in the context.""" + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.workspace.workspace.billing_project.name, + self.workspace.workspace.name, + ) + ) + self.assertIn("audit_results", response.context_data) + audit_results = response.context_data["audit_results"] + self.assertIsInstance( + audit_results, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit, + ) + self.assertTrue(audit_results.completed) + self.assertEqual(audit_results.queryset.count(), 1) + self.assertIn(self.workspace, audit_results.queryset) + + def test_context_audit_results_does_not_include_other_workspaces(self): + """The audit_results does not include other workspaces.""" + other_workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.workspace.workspace.billing_project.name, + self.workspace.workspace.name, + ) + ) + audit_results = response.context_data["audit_results"] + self.assertEqual(audit_results.queryset.count(), 1) + self.assertNotIn(other_workspace, audit_results.queryset) + + def test_context_verified_table_access(self): + """verified_table shows a record when audit has verified access.""" + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + acm_factories.GroupGroupMembershipFactory.create( + parent_group=self.workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.workspace.workspace.billing_project.name, + self.workspace.workspace.name, + ) + ) + self.assertIn("verified_table", response.context_data) + table = response.context_data["verified_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.ADMIN) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.DCC_ADMIN_AS_ADMIN, + ) + self.assertEqual(table.rows[0].get_cell_value("action"), "—") + + def test_context_needs_action_table_add_member(self): + """needs_action_table shows a record when audit finds that access needs to be granted.""" + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.workspace.workspace.billing_project.name, + self.workspace.workspace.name, + ) + ) + self.assertIn("needs_action_table", response.context_data) + table = response.context_data["needs_action_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertIsNone(table.rows[0].get_cell_value("role")) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.GREGOR_ALL_AS_MEMBER, + ) + self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + + def test_context_needs_action_table_add_admin(self): + """needs_action_table shows a record when audit finds that access needs to be granted.""" + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.workspace.workspace.billing_project.name, + self.workspace.workspace.name, + ) + ) + self.assertIn("needs_action_table", response.context_data) + table = response.context_data["needs_action_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertIsNone(table.rows[0].get_cell_value("role")) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.DCC_ADMIN_AS_ADMIN, + ) + self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + + def test_context_error_table_remove(self): + """error table shows a record when audit finds that access needs to be removed.""" + group = acm_factories.ManagedGroupFactory.create() + acm_factories.GroupGroupMembershipFactory.create( + parent_group=self.workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.workspace.workspace.billing_project.name, + self.workspace.workspace.name, + ) + ) + self.assertIn("errors_table", response.context_data) + table = response.context_data["errors_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.OTHER_GROUP, + ) + self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + + def test_context_errors_table_change_to_member(self): + """errors table shows a record when audit finds that access needs to be removed.""" + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + acm_factories.GroupGroupMembershipFactory.create( + parent_group=self.workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.workspace.workspace.billing_project.name, + self.workspace.workspace.name, + ) + ) + self.assertIn("errors_table", response.context_data) + table = response.context_data["errors_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.ADMIN) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.GREGOR_ALL_AS_MEMBER, + ) + self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + + def test_context_needs_action_table_change_to_admin(self): + """error table shows a record when audit finds that access needs to be removed.""" + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + acm_factories.GroupGroupMembershipFactory.create( + parent_group=self.workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.workspace.workspace.billing_project.name, + self.workspace.workspace.name, + ) + ) + self.assertIn("needs_action_table", response.context_data) + table = response.context_data["needs_action_table"] + self.assertIsInstance( + table, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAuditTable, + ) + self.assertEqual(len(table.rows), 1) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.workspace.workspace) + self.assertEqual(table.rows[0].get_cell_value("managed_group"), group) + self.assertEqual(table.rows[0].get_cell_value("role"), acm_models.GroupGroupMembership.MEMBER) + self.assertEqual( + table.rows[0].get_cell_value("note"), + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.DCC_ADMIN_AS_ADMIN, + ) + self.assertNotEqual(table.rows[0].get_cell_value("action"), "—") + + def test_title(self): + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + self.workspace.workspace.billing_project.name, + self.workspace.workspace.name, + ) + ) + self.assertContains(response, str(self.workspace)) + # self.assertIn("all combined workspaces", response.content.decode().lower()) diff --git a/gregor_django/gregor_anvil/urls.py b/gregor_django/gregor_anvil/urls.py index d12b8476..1a996136 100644 --- a/gregor_django/gregor_anvil/urls.py +++ b/gregor_django/gregor_anvil/urls.py @@ -123,11 +123,11 @@ # views.UploadWorkspaceAuthDomainAuditResolve.as_view(), # name="resolve", # ), - # path( - # "//", - # views.CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace.as_view(), - # name="by_workspace", - # ), + path( + "//", + views.CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace.as_view(), + name="by_workspace", + ), ], "auth_domains", ) diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index e55a82f7..c41f4e39 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -785,10 +785,42 @@ def get_context_data(self, **kwargs): return context -class CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace(AnVILConsortiumManagerStaffEditRequired, DetailView): +class CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace(AnVILConsortiumManagerStaffViewRequired, DetailView): """View to audit auth domain membership for a specific CombinedConsortiumDataWorkspace.""" - pass + template_name = "gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html" + model = models.CombinedConsortiumDataWorkspace + + def get_object(self, queryset=None): + """Look up the CombinedConsortiumDataWorkspace by billing project and name.""" + # Filter the queryset based on kwargs. + billing_project_slug = self.kwargs.get("billing_project_slug", None) + workspace_slug = self.kwargs.get("workspace_slug", None) + queryset = models.CombinedConsortiumDataWorkspace.objects.filter( + workspace__billing_project__name=billing_project_slug, + workspace__name=workspace_slug, + ) + try: + # Get the single item from the filtered queryset + obj = queryset.get() + except queryset.model.DoesNotExist: + raise Http404( + _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name} + ) + return obj + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + # Run the audit. + audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit( + queryset=self.model.objects.filter(pk=self.object.pk) + ) + audit.run_audit() + context["verified_table"] = audit.get_verified_table() + context["errors_table"] = audit.get_errors_table() + context["needs_action_table"] = audit.get_needs_action_table() + context["audit_results"] = audit + return context class CombinedConsortiumDataWorkspaceAuthDomainAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): From 19bc38da1c4f607a64021210b540fd4e73c0f6b0 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 7 Oct 2024 14:49:37 -0700 Subject: [PATCH 48/97] Change audit class when DCC admins is a member It should be ChangeToAdmin, not AddMember. Fix the audit and tests. --- gregor_django/gregor_anvil/audit/combined_workspace_audit.py | 2 ++ gregor_django/gregor_anvil/tests/test_audit.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gregor_django/gregor_anvil/audit/combined_workspace_audit.py b/gregor_django/gregor_anvil/audit/combined_workspace_audit.py index 1a91d937..cf35bec2 100644 --- a/gregor_django/gregor_anvil/audit/combined_workspace_audit.py +++ b/gregor_django/gregor_anvil/audit/combined_workspace_audit.py @@ -96,6 +96,8 @@ def _audit_workspace_and_dcc_admin_group(self, combined_workspace, managed_group if current_membership and current_membership.role == GroupGroupMembership.ADMIN: self.verified.append(workspace_auth_domain_audit_results.VerifiedAdmin(**audit_result_args)) + elif current_membership and current_membership.role == GroupGroupMembership.MEMBER: + self.needs_action.append(workspace_auth_domain_audit_results.ChangeToAdmin(**audit_result_args)) else: self.needs_action.append(workspace_auth_domain_audit_results.AddAdmin(**audit_result_args)) diff --git a/gregor_django/gregor_anvil/tests/test_audit.py b/gregor_django/gregor_anvil/tests/test_audit.py index baaaae43..8f8125eb 100644 --- a/gregor_django/gregor_anvil/tests/test_audit.py +++ b/gregor_django/gregor_anvil/tests/test_audit.py @@ -7609,7 +7609,7 @@ def test_dcc_admin_as_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) self.assertEqual(record.workspace, self.combined_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) @@ -7874,7 +7874,7 @@ def test_dcc_admin_as_member(self): self.assertEqual(len(audit.needs_action), 1) self.assertEqual(len(audit.errors), 0) record = audit.needs_action[0] - self.assertIsInstance(record, workspace_auth_domain_audit_results.AddAdmin) + self.assertIsInstance(record, workspace_auth_domain_audit_results.ChangeToAdmin) self.assertEqual(record.workspace, self.combined_workspace.workspace) self.assertEqual(record.managed_group, self.dcc_admin_group) self.assertEqual(record.current_membership_instance, membership) From 6808d64ecf8441b7c709f86b31581234b91a68cf Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 7 Oct 2024 15:21:08 -0700 Subject: [PATCH 49/97] Add view to resolve auth domain audits for combined workspaces --- .../gregor_anvil/tests/test_views.py | 1307 +++++++++++++++++ gregor_django/gregor_anvil/urls.py | 10 +- gregor_django/gregor_anvil/views.py | 112 +- 3 files changed, 1422 insertions(+), 7 deletions(-) diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index 305d6c57..e49f67f8 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -9518,3 +9518,1310 @@ def test_title(self): ) self.assertContains(response, str(self.workspace)) # self.assertIn("all combined workspaces", response.content.decode().lower()) + + +class CombinedConsortiumDataWorkspaceAuthDomainAuditResolveTest(AnVILAPIMockTestMixin, TestCase): + def setUp(self): + """Set up test class.""" + super().setUp() + self.factory = RequestFactory() + # 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=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) + ) + self.user.user_permissions.add( + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) + ) + + def get_url(self, *args): + """Get the url for the view being tested.""" + return reverse( + "gregor_anvil:audit:combined_workspaces:auth_domains:resolve", + args=args, + ) + + def get_view(self): + """Return the view being tested.""" + return views.CombinedConsortiumDataWorkspaceAuthDomainAuditResolve.as_view() + + def test_view_redirect_not_logged_in(self): + "View redirects to login view when user is not logged in." + # Need a client for redirects. + response = self.client.get(self.get_url("foo", "bar", "foobar")) + self.assertRedirects( + response, + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo", "bar", "foobar"), + ) + + def test_status_code_with_user_permission_staff_edit(self): + """Returns successful response code if the user has staff edit permission.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.get( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + + def test_status_code_with_user_permission_staff_view(self): + """Returns 403 response code if the user has staff view permission.""" + user_view = User.objects.create_user(username="test-view", password="test-view") + user_view.user_permissions.add( + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) + ) + self.client.force_login(self.user) + request = self.factory.get(self.get_url("foo", "bar", "foobar")) + request.user = user_view + with self.assertRaises(PermissionDenied): + self.get_view()(request) + + def test_status_code_with_user_permission_view(self): + """Returns forbidden response code if the user has view permission.""" + user = User.objects.create_user(username="test-none", password="test-none") + user.user_permissions.add(Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME)) + request = self.factory.get(self.get_url("foo", "bar", "foobar")) + request.user = user + with self.assertRaises(PermissionDenied): + self.get_view()(request) + + def test_access_without_user_permission(self): + """Raises permission denied if user has no permissions.""" + user_no_perms = User.objects.create_user(username="test-none", password="test-none") + request = self.factory.get(self.get_url("foo", "bar", "foobar")) + request.user = user_no_perms + with self.assertRaises(PermissionDenied): + self.get_view()(request) + + def test_get_billing_project_does_not_exist(self): + """Raises a 404 error with an invalid billing project.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.get(self.get_url("foo", workspace.workspace.name, group.name)) + self.assertEqual(response.status_code, 404) + + def test_get_workspace_name_does_not_exist(self): + """Raises a 404 error with an invalid billing project.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.get(self.get_url(workspace.workspace.billing_project.name, "foo", group.name)) + self.assertEqual(response.status_code, 404) + + def test_get_group_does_not_exist(self): + """get request raises a 404 error with an non-existent email.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + "foo", + ) + ) + self.assertEqual(response.status_code, 404) + + def test_get_context_audit_result(self): + """The audit_results exists in the context.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.get( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertIn("audit_result", response.context_data) + self.assertIsInstance( + response.context_data["audit_result"], + workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult, + ) + + def test_get_verified_admin(self): + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + group.name, + ) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.VerifiedAdmin) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.DCC_ADMIN_AS_ADMIN, + ) + + def test_get_verified_member(self): + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + group.name, + ) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.VerifiedMember) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.GREGOR_ALL_AS_MEMBER, + ) + + def test_get_verified_not_member(self): + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + group.name, + ) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.VerifiedNotMember) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.OTHER_GROUP, + ) + + def test_get_add_member(self): + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + group.name, + ) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.AddMember) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.GREGOR_ALL_AS_MEMBER, + ) + + def test_get_add_admin(self): + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + group.name, + ) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.AddAdmin) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.DCC_ADMIN_AS_ADMIN, + ) + + def test_get_change_to_member(self): + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + group.name, + ) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.ChangeToMember) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.GREGOR_ALL_AS_MEMBER, + ) + + def test_get_change_to_admin(self): + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + group.name, + ) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.ChangeToAdmin) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.DCC_ADMIN_AS_ADMIN, + ) + + def test_get_remove(self): + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Check the table in the context. + self.client.force_login(self.user) + response = self.client.get( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + group.name, + ) + ) + self.assertIn("audit_result", response.context_data) + audit_result = response.context_data["audit_result"] + self.assertIsInstance(audit_result, workspace_auth_domain_audit_results.Remove) + self.assertEqual(audit_result.workspace, workspace.workspace) + self.assertEqual(audit_result.managed_group, group) + self.assertEqual( + audit_result.note, + combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit.OTHER_GROUP, + ) + + def test_post_billing_project_does_not_exist(self): + """Raises a 404 error with an invalid billing project.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.post(self.get_url("foo", workspace.workspace.name, group.name)) + self.assertEqual(response.status_code, 404) + + def test_post_workspace_name_does_not_exist(self): + """Raises a 404 error with an invalid billing project.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.post(self.get_url(workspace.workspace.billing_project.name, "foo", group.name)) + self.assertEqual(response.status_code, 404) + + def test_post_group_does_not_exist(self): + """post request raises a 404 error with an non-existent email.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + self.client.force_login(self.user) + response = self.client.post( + self.get_url( + workspace.workspace.billing_project.name, + workspace.workspace.name, + "foo", + ) + ) + self.assertEqual(response.status_code, 404) + + def test_post_verified_member(self): + """Get request with VerifiedMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + + def test_post_verified_admin(self): + """Get request with VerifiedAdmin result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + + def test_post_verified_not_member(self): + """Get request with VerifiedNotMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 0) + + def test_post_add_member(self): + """Get request with AddMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership = acm_models.GroupGroupMembership.objects.get( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + ) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.MEMBER) + + def test_post_add_admin(self): + """Get request with AddAdmin result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + self.client.force_login(self.user) + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership = acm_models.GroupGroupMembership.objects.get( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + ) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN) + + def test_post_change_to_member(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertGreater(membership.modified, membership.created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.MEMBER) + + def test_post_change_to_admin(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertGreater(membership.modified, membership.created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN) + + def test_post_remove_admin(self): + """Post request with Remove result for an admin membership.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + upload_cycle__is_future=True, workspace__name="test-ws" + ) + group = acm_factories.ManagedGroupFactory.create() + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 0) + + def test_post_remove_member(self): + """Post request with Remove result for a member membership.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + upload_cycle__is_future=True, workspace__name="test-ws" + ) + group = acm_factories.ManagedGroupFactory.create() + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertRedirects(response, workspace.get_absolute_url()) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 0) + + def test_post_verified_member_htmx(self): + """Get request with VerifiedMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_success) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + + def test_post_verified_admin_htmx(self): + """Get request with VerifiedAdmin result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_success) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + + def test_post_verified_not_member_htmx(self): + """Get request with VerifiedNotMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + group = acm_factories.ManagedGroupFactory.create() + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_success) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 0) + + def test_post_add_member_htmx(self): + """Get request with AddMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_success) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership = acm_models.GroupGroupMembership.objects.get( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + ) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.MEMBER) + + def test_post_add_admin_htmx(self): + """Get request with AddAdmin result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + self.client.force_login(self.user) + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_success) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership = acm_models.GroupGroupMembership.objects.get( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + ) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN) + + def test_post_change_to_member_htmx(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_success) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertGreater(membership.modified, membership.created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.MEMBER) + + def test_post_change_to_admin_htmx(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_success) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertGreater(membership.modified, membership.created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN) + + def test_post_remove_admin_htmx(self): + """Post request with Remove result for an admin membership.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + upload_cycle__is_future=True, workspace__name="test-ws" + ) + group = acm_factories.ManagedGroupFactory.create() + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_success) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 0) + + def test_post_remove_member_htmx(self): + """Post request with Remove result for a member membership.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + upload_cycle__is_future=True, workspace__name="test-ws" + ) + group = acm_factories.ManagedGroupFactory.create() + acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_success) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 0) + + def test_post_api_error_add_member(self): + """Get request with AddMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # No memberships were created. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 0) + # Error message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_api_error_add_admin(self): + """Get request with AddAdmin result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + self.client.force_login(self.user) + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # No memberships were created. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 0) + # Error message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_api_error_change_to_member_error_on_put_call(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # The membership was not updated. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN) + # Error message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_api_error_change_to_member_error_on_delete_call(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # The membership was not updated. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN) + # Error message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_api_error_change_to_admin_error_on_delete_call(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # The membership was not updated. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.MEMBER) + # Error message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_api_error_change_to_admin_error_on_put_call(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # The membership was not updated. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.MEMBER) + # Error message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_api_error_remove_admin(self): + """Post request with Remove result for an admin membership.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # The membership was not updated. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN) + # Error message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_api_error_remove_member(self): + """Post request with Remove result for a member membership.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name) + ) + self.assertEqual(response.status_code, 200) + # The membership was not updated. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.MEMBER) + # Error message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 1) + self.assertIn("AnVIL API Error", str(messages[0])) + + def test_post_api_error_htmx_add_member(self): + """Get request with AddMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_error) + # The membership was not updated. + # No memberships were created. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 0) + # No message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_api_error_htmx_add_admin(self): + """Get request with AddAdmin result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + self.client.force_login(self.user) + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_error) + # No memberships were created. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 0) + # No message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_api_error_htmx_change_to_member_error_on_put_call(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_error) + # The membership was not updated. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN) + # No message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_api_error_htmx_change_to_member_error_on_delete_call(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name="GREGOR_ALL") + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_error) + # The membership was not updated. + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN) + # No message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_api_error_htmx_change_to_admin_error_on_delete_call(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_error) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.MEMBER) + # No message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_api_error_htmx_change_to_admin_error_on_put_call(self): + """Get request with ChangeToMember result.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + # Add the mocked API responses - one to create and one to delete. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_error) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.MEMBER) + # No message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_api_error_htmx_remove_admin(self): + """Post request with Remove result for an admin membership.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.ADMIN, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/admin/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_error) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN) + # No message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) + + def test_post_api_error_htmx_remove_member(self): + """Post request with Remove result for a member membership.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create(workspace__name="test-ws") + group = acm_factories.ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(weeks=3) + with freeze_time(date_created): + membership = acm_factories.GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group=group, + role=acm_models.GroupGroupMembership.MEMBER, + ) + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth_test-ws/member/{group.name}@firecloud.org", + status=500, + json=ErrorResponseFactory().response, + ) + self.client.force_login(self.user) + header = {"HTTP_HX-Request": "true"} + response = self.client.post( + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name, group.name), **header + ) + self.assertEqual(response.content.decode(), views.UploadWorkspaceAuthDomainAuditResolve.htmx_error) + self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + self.assertEqual(membership.role, acm_models.GroupGroupMembership.MEMBER) + # No message was added. + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(len(messages), 0) diff --git a/gregor_django/gregor_anvil/urls.py b/gregor_django/gregor_anvil/urls.py index 1a996136..6e7e7939 100644 --- a/gregor_django/gregor_anvil/urls.py +++ b/gregor_django/gregor_anvil/urls.py @@ -118,11 +118,11 @@ combined_workspace_auth_domain_audit_patterns = ( [ path("all/", views.CombinedConsortiumDataWorkspaceAuthDomainAudit.as_view(), name="all"), - # path( - # "resolve////", - # views.UploadWorkspaceAuthDomainAuditResolve.as_view(), - # name="resolve", - # ), + path( + "resolve////", + views.CombinedConsortiumDataWorkspaceAuthDomainAuditResolve.as_view(), + name="resolve", + ), path( "//", views.CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace.as_view(), diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index c41f4e39..b1e90636 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -824,6 +824,114 @@ def get_context_data(self, **kwargs): class CombinedConsortiumDataWorkspaceAuthDomainAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): - """View to resolve CombinedConsortiumDataWorkspace auth domain audit results.""" + """View to resolve UploadWorkspace auth domain audit results.""" + + form_class = Form + template_name = "gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit_resolve.html" + htmx_success = """ Handled!""" + htmx_error = """ Error!""" + + def get_workspace(self): + """Look up the CombinedConsortiumDataWorkspace by billing project and name.""" + # Filter the queryset based on kwargs. + billing_project_slug = self.kwargs.get("billing_project_slug", None) + workspace_slug = self.kwargs.get("workspace_slug", None) + queryset = models.CombinedConsortiumDataWorkspace.objects.filter( + workspace__billing_project__name=billing_project_slug, + workspace__name=workspace_slug, + ) + try: + # Get the single item from the filtered queryset + obj = queryset.get() + except queryset.model.DoesNotExist: + raise Http404( + _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name} + ) + return obj + + def get_managed_group(self, queryset=None): + """Look up the ManagedGroup by name.""" + try: + obj = ManagedGroup.objects.get(name=self.kwargs.get("managed_group_slug", None)) + except ManagedGroup.DoesNotExist: + raise Http404("No ManagedGroups found matching the query") + return obj + + def get_audit_result(self): + audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit() + # No way to set the group queryset, since it is dynamically determined by the workspace. + audit.audit_workspace_and_group(self.workspace, self.managed_group) + # Set to completed, because we are just running this one specific check. + audit.completed = True + return audit.get_all_results()[0] + + def get(self, request, *args, **kwargs): + self.workspace = self.get_workspace() + self.managed_group = self.get_managed_group() + self.audit_result = self.get_audit_result() + return super().get(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + self.workspace = self.get_workspace() + self.managed_group = self.get_managed_group() + self.audit_result = self.get_audit_result() + return super().post(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["workspace"] = self.workspace + context["managed_group"] = self.managed_group + context["audit_result"] = self.audit_result + return context + + def get_success_url(self): + return self.workspace.get_absolute_url() - pass + def form_valid(self, form): + # Handle the result. + try: + with transaction.atomic(): + # Set up the membership instance. + if self.audit_result.current_membership_instance: + membership = self.audit_result.current_membership_instance + else: + membership = GroupGroupMembership( + parent_group=self.workspace.workspace.authorization_domains.first(), + child_group=self.managed_group, + ) + # Now process the result. + if isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedMember): + pass + elif isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedAdmin): + pass + elif isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedNotMember): + pass + elif isinstance(self.audit_result, workspace_auth_domain_audit_results.Remove): + membership.anvil_delete() + membership.delete() + else: + if isinstance(self.audit_result, workspace_auth_domain_audit_results.ChangeToMember): + membership.anvil_delete() + membership.role = GroupGroupMembership.MEMBER + elif isinstance(self.audit_result, workspace_auth_domain_audit_results.ChangeToAdmin): + membership.anvil_delete() + membership.role = GroupGroupMembership.ADMIN + else: + if isinstance(self.audit_result, workspace_auth_domain_audit_results.AddMember): + membership.role = GroupGroupMembership.MEMBER + elif isinstance(self.audit_result, workspace_auth_domain_audit_results.AddAdmin): + membership.role = GroupGroupMembership.ADMIN + membership.full_clean() + membership.save() + membership.anvil_create() + except (AnVILAPIError, AnVILGroupNotFound) as e: + if self.request.htmx: + return HttpResponse(self.htmx_error) + else: + messages.error(self.request, "AnVIL API Error: " + str(e)) + return super().form_invalid(form) + # Otherwise, the audit resolution succeeded. + if self.request.htmx: + return HttpResponse(self.htmx_success) + else: + return super().form_valid(form) From de6f45c9c0f6a70228eebb2be48343684f810f60 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 7 Oct 2024 15:24:47 -0700 Subject: [PATCH 50/97] Remove accidentally-added test I had added this test to a different TestCase thinking it had been missed earlier, but I was incorrect - the test in question is not needed in the TestCase, and already exists where it is needed. --- gregor_django/gregor_anvil/tests/test_views.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index e49f67f8..1f475108 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -4578,13 +4578,6 @@ def test_access_without_user_permission(self): with self.assertRaises(PermissionDenied): self.get_view()(request) - def test_invalid_upload_cycle(self): - """Raises a 404 error with an invalid upload cycle.""" - request = self.factory.get(self.get_url()) - request.user = self.user - with self.assertRaises(Http404): - self.get_view()(request) - def test_context_audit_results_no_upload_workspaces(self): """The audit_results exists in the context.""" self.client.force_login(self.user) From 445a39d2d30a7accf9a6215d9c4b473b2bc3a6dc Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 8 Oct 2024 08:32:39 -0700 Subject: [PATCH 51/97] Start updating test data script for combined workspace auditing Also rename the file to have a more descriptive name - it's not just upload workspaces anymore. --- ....py => add_upload_cycle_audit_test_data.py | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) rename add_upload_workspace_audit_test_data.py => add_upload_cycle_audit_test_data.py (98%) diff --git a/add_upload_workspace_audit_test_data.py b/add_upload_cycle_audit_test_data.py similarity index 98% rename from add_upload_workspace_audit_test_data.py rename to add_upload_cycle_audit_test_data.py index 704c19de..3758244b 100644 --- a/add_upload_workspace_audit_test_data.py +++ b/add_upload_cycle_audit_test_data.py @@ -28,7 +28,7 @@ ) -# Create a future upload cycle. +## Future upload cycle. upload_cycle = factories.UploadCycleFactory.create( cycle=1, is_future=True, @@ -39,7 +39,7 @@ workspace__name="TEST_U01_RC1", ) -# Create a current upload cycle before compute. +## Current upload cycle before compute. upload_cycle = factories.UploadCycleFactory.create( cycle=2, is_current=True, @@ -111,7 +111,7 @@ ) -# Create a current upload cycle after compute. +## Current upload cycle after compute. upload_cycle = factories.UploadCycleFactory.create( cycle=3, is_current=True, @@ -256,7 +256,7 @@ role=GroupGroupMembership.ADMIN, ) -# Create a past upload cycle after QC is completed. +## Past upload cycle after QC is completed. upload_cycle = factories.UploadCycleFactory.create( cycle=5, is_past=True, @@ -321,7 +321,7 @@ role=GroupGroupMembership.ADMIN, ) -# Create a past upload cycle with a combined workspace. +## Past upload cycle with a combined workspace. upload_cycle = factories.UploadCycleFactory.create( cycle=6, is_past=True, @@ -332,11 +332,6 @@ workspace__name="TEST_U06_RC1", date_qc_completed=timezone.now(), ) -factories.CombinedConsortiumDataWorkspaceFactory.create( - upload_cycle=upload_cycle, - date_completed=timezone.now(), - workspace__name="TEST_U06_COMBINED", -) # Create records as appropriate for the previous point in the cycle - past cycle before QC complete. # Auth domain. WorkspaceGroupSharingFactory.create( @@ -383,3 +378,9 @@ child_group=dcc_admin_group, role=GroupGroupMembership.ADMIN, ) +# Create the combined workspace and its records. +factories.CombinedConsortiumDataWorkspaceFactory.create( + upload_cycle=upload_cycle, + date_completed=timezone.now(), + workspace__name="TEST_U06_COMBINED", +) From d23137ebec96a6e5cf46e228ccdbd1b4717babe3 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 8 Oct 2024 10:53:44 -0700 Subject: [PATCH 52/97] Update test data for combined workspace auditing --- add_upload_cycle_audit_test_data.py | 49 +++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/add_upload_cycle_audit_test_data.py b/add_upload_cycle_audit_test_data.py index 3758244b..ded2a130 100644 --- a/add_upload_cycle_audit_test_data.py +++ b/add_upload_cycle_audit_test_data.py @@ -17,6 +17,7 @@ rc_1_uploader_group = ManagedGroupFactory(name="DEMO_RC1_UPLOADERS") rc_1_nonmember_group = ManagedGroupFactory(name="DEMO_RC1_NONMEMBERS") gregor_all_group = ManagedGroupFactory(name="GREGOR_ALL") +combined_auth_domain = ManagedGroupFactory(name="AUTH_GREGOR_COMBINED") # Create an RC rc = factories.ResearchCenterFactory.create( @@ -27,6 +28,18 @@ non_member_group=rc_1_nonmember_group, ) +# Add GREGOR_ALL and DCC_ADMINS to the combined auth domain. +GroupGroupMembershipFactory.create( + parent_group=combined_auth_domain, + child_group=gregor_all_group, + role=GroupGroupMembership.MEMBER, +) +GroupGroupMembershipFactory.create( + parent_group=combined_auth_domain, + child_group=dcc_admin_group, + role=GroupGroupMembership.ADMIN, +) + ## Future upload cycle. upload_cycle = factories.UploadCycleFactory.create( @@ -256,7 +269,7 @@ role=GroupGroupMembership.ADMIN, ) -## Past upload cycle after QC is completed. +## Past upload cycle after QC is completed; combined workspace is not complete. upload_cycle = factories.UploadCycleFactory.create( cycle=5, is_past=True, @@ -320,6 +333,16 @@ child_group=dcc_admin_group, role=GroupGroupMembership.ADMIN, ) +# Create the combined workspace and its records. +combined_workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( + upload_cycle=upload_cycle, + workspace__name="TEST_U05_COMBINED", +) +# Delete the auth domain created by the factory and add the shared auth domain. +combined_workspace.workspace.authorization_domains.clear() +combined_workspace.workspace.authorization_domains.add(combined_auth_domain) +# No sharing records yet. + ## Past upload cycle with a combined workspace. upload_cycle = factories.UploadCycleFactory.create( @@ -379,8 +402,30 @@ role=GroupGroupMembership.ADMIN, ) # Create the combined workspace and its records. -factories.CombinedConsortiumDataWorkspaceFactory.create( +combined_workspace = factories.CombinedConsortiumDataWorkspaceFactory.create( upload_cycle=upload_cycle, date_completed=timezone.now(), workspace__name="TEST_U06_COMBINED", ) +# Delete the auth domain created by the factory and add the shared auth domain. +combined_workspace.workspace.authorization_domains.clear() +combined_workspace.workspace.authorization_domains.add(combined_auth_domain) +# Add sharing records from previous step - DCC admins, writers, and members. +WorkspaceGroupSharingFactory.create( + workspace=combined_workspace.workspace, + group=dcc_admin_group, + access=WorkspaceGroupSharing.OWNER, + can_compute=True, +) +WorkspaceGroupSharingFactory.create( + workspace=combined_workspace.workspace, + group=dcc_writer_group, + access=WorkspaceGroupSharing.WRITER, + can_compute=True, +) +WorkspaceGroupSharingFactory.create( + workspace=combined_workspace.workspace, + group=dcc_member_group, + access=WorkspaceGroupSharing.READER, + can_compute=False, +) From 7274f5428b695dbc19ddc7932fe5ce1695935d6c Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 8 Oct 2024 10:56:08 -0700 Subject: [PATCH 53/97] Make can_compute icons black in tables For both the Combined workspace sharing audit and the upload workspace sharing audit. Green/black or green/red imply errors vs correctness, but black does not. --- gregor_django/gregor_anvil/audit/combined_workspace_audit.py | 2 +- gregor_django/gregor_anvil/audit/upload_workspace_audit.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gregor_django/gregor_anvil/audit/combined_workspace_audit.py b/gregor_django/gregor_anvil/audit/combined_workspace_audit.py index cf35bec2..0885a4c6 100644 --- a/gregor_django/gregor_anvil/audit/combined_workspace_audit.py +++ b/gregor_django/gregor_anvil/audit/combined_workspace_audit.py @@ -190,7 +190,7 @@ class CombinedConsortiumDataWorkspaceSharingAuditTable(tables.Table): workspace = tables.Column(linkify=True) managed_group = tables.Column(linkify=True) access = tables.Column(verbose_name="Current access") - can_compute = BooleanIconColumn(show_false_icon=True, null=True, true_color="green", false_color="black") + can_compute = BooleanIconColumn(show_false_icon=True, null=True, true_color="black", false_color="black") note = tables.Column() action = tables.TemplateColumn( template_name="gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_action_button.html" diff --git a/gregor_django/gregor_anvil/audit/upload_workspace_audit.py b/gregor_django/gregor_anvil/audit/upload_workspace_audit.py index 0fa69467..bde9201d 100644 --- a/gregor_django/gregor_anvil/audit/upload_workspace_audit.py +++ b/gregor_django/gregor_anvil/audit/upload_workspace_audit.py @@ -357,7 +357,7 @@ class UploadWorkspaceSharingAuditTable(tables.Table): workspace = tables.Column(linkify=True) managed_group = tables.Column(linkify=True) access = tables.Column(verbose_name="Current access") - can_compute = BooleanIconColumn(show_false_icon=True, null=True, true_color="green", false_color="black") + can_compute = BooleanIconColumn(show_false_icon=True, null=True, true_color="black", false_color="black") note = tables.Column() action = tables.TemplateColumn( template_name="gregor_anvil/snippets/upload_workspace_sharing_audit_action_button.html" From f488b1569efe9103b61e0062499f0470a809e635 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 8 Oct 2024 11:21:55 -0700 Subject: [PATCH 54/97] Add links to audit views on combined workspace detail page --- .../gregor_anvil/tests/test_views.py | 24 +++++++++++++++++++ ...ombinedconsortiumdataworkspace_detail.html | 16 +++++++++++++ 2 files changed, 40 insertions(+) diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index 1f475108..fc714590 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -1911,6 +1911,30 @@ def test_contains_upload_workspaces_from_previous_cycles(self): self.assertIn(upload_workspace_1, response.context_data["upload_workspace_table"].data) self.assertIn(upload_workspace_2, response.context_data["upload_workspace_table"].data) + def test_contains_sharing_audit_button(self): + self.client.force_login(self.user) + response = self.client.get(self.get_url(self.object.workspace.billing_project.name, self.object.workspace.name)) + url = reverse( + "gregor_anvil:audit:combined_workspaces:sharing:by_workspace", + args=[ + self.object.workspace.billing_project.name, + self.object.workspace.name, + ], + ) + self.assertContains(response, url) + + def test_contains_auth_domain_audit_button(self): + self.client.force_login(self.user) + response = self.client.get(self.get_url(self.object.workspace.billing_project.name, self.object.workspace.name)) + url = reverse( + "gregor_anvil:audit:combined_workspaces:auth_domains:by_workspace", + args=[ + self.object.workspace.billing_project.name, + self.object.workspace.name, + ], + ) + self.assertContains(response, url) + def test_includes_date_completed(self): self.object.date_completed = "2022-01-01" self.object.save() diff --git a/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_detail.html b/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_detail.html index c3ee4efa..6727465a 100644 --- a/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_detail.html +++ b/gregor_django/templates/gregor_anvil/combinedconsortiumdataworkspace_detail.html @@ -7,3 +7,19 @@
    Date completed
    {{ workspace_data_object.date_completed }}
    {% endblock workspace_data %} + + +{% block action_buttons %} +{% if show_edit_links %} +

    + + Audit consortium sharing + + + Audit auth domain membership + +

    +{% endif %} + +{{ block.super }} +{% endblock action_buttons %} From fe2bc687271b035f92d46362acd2eaf4eb583d44 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 8 Oct 2024 11:23:36 -0700 Subject: [PATCH 55/97] Update wording on upload cycle detail audit buttons Make it clear that the buttons are for auditing upload workspaces, not the combined workspace. --- gregor_django/templates/gregor_anvil/uploadcycle_detail.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gregor_django/templates/gregor_anvil/uploadcycle_detail.html b/gregor_django/templates/gregor_anvil/uploadcycle_detail.html index b8683f76..8a96d6ad 100644 --- a/gregor_django/templates/gregor_anvil/uploadcycle_detail.html +++ b/gregor_django/templates/gregor_anvil/uploadcycle_detail.html @@ -70,10 +70,10 @@

    Partner upload workspaces

    {% endif %}

    - Audit consortium sharing + Audit upload workspace sharing - Audit auth domain membership + Audit upload workspace auth domains

    {% endblock action_buttons %} From bd47e7a87e31c647b3300139f5f1b0ffe12319eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 19:05:30 +0000 Subject: [PATCH 56/97] Bump pre-commit from 3.8.0 to 4.0.1 Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.8.0 to 4.0.1. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v3.8.0...v4.0.1) --- updated-dependencies: - dependency-name: pre-commit dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 132223a6..553a3ef9 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -121,7 +121,7 @@ platformdirs==4.2.0 # via # pylint # virtualenv -pre-commit==3.8.0 +pre-commit==4.0.1 # via -r requirements/dev-requirements.in prompt-toolkit==3.0.43 # via ipython From 0e7a60454c8fb57cfb7e985cc35eb1c0da58cb6d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 19:06:31 +0000 Subject: [PATCH 57/97] Bump tablib from 3.6.1 to 3.7.0 Bumps [tablib](https://github.com/jazzband/tablib) from 3.6.1 to 3.7.0. - [Release notes](https://github.com/jazzband/tablib/releases) - [Changelog](https://github.com/jazzband/tablib/blob/master/HISTORY.md) - [Commits](https://github.com/jazzband/tablib/compare/v3.6.1...v3.7.0) --- updated-dependencies: - dependency-name: tablib dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 6e83e7b4..f96bd07d 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -152,7 +152,7 @@ six==1.16.0 # via google-auth sqlparse==0.5.1 # via django -tablib==3.6.1 +tablib==3.7.0 # via -r requirements/requirements.in tenacity==8.2.3 # via From 9626fb05036a56d9b6d8e828a140f34ae0a5f178 Mon Sep 17 00:00:00 2001 From: Jonas Carson Date: Wed, 9 Oct 2024 11:17:46 -0700 Subject: [PATCH 58/97] Updates to our drupal oauth provider and adapter to be compatible with updated django-allauth --- config/settings/base.py | 1 + .../drupal_oauth_provider/provider.py | 10 ++ gregor_django/drupal_oauth_provider/tests.py | 110 +++++++++++++-- gregor_django/drupal_oauth_provider/views.py | 4 +- .../socialaccount/authentication_error.html | 2 +- gregor_django/users/adapters.py | 21 ++- gregor_django/users/tests/test_adapters.py | 131 ++++++++++++------ requirements/requirements.in | 2 +- requirements/requirements.txt | 2 +- 9 files changed, 222 insertions(+), 61 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index 5539f254..f33bb9ec 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -155,6 +155,7 @@ "maintenance_mode.middleware.MaintenanceModeMiddleware", "simple_history.middleware.HistoryRequestMiddleware", "django_htmx.middleware.HtmxMiddleware", + "allauth.account.middleware.AccountMiddleware", ] # STATIC diff --git a/gregor_django/drupal_oauth_provider/provider.py b/gregor_django/drupal_oauth_provider/provider.py index ef2d9c93..c7c36f60 100644 --- a/gregor_django/drupal_oauth_provider/provider.py +++ b/gregor_django/drupal_oauth_provider/provider.py @@ -2,11 +2,14 @@ from allauth.account.models import EmailAddress from allauth.socialaccount import app_settings, providers +from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from django.conf import settings from django.core.exceptions import ImproperlyConfigured +from .views import CustomAdapter + logger = logging.getLogger(__name__) DRUPAL_PROVIDER_ID = "drupal_oauth_provider" @@ -27,6 +30,13 @@ class CustomProvider(OAuth2Provider): id = DRUPAL_PROVIDER_ID name = OVERRIDE_NAME account_class = CustomAccount + oauth2_adapter_class = CustomAdapter + supports_token_authentication = True + + def __init__(self, request, app=None): + if app is None: + app = get_adapter().get_app(request, self.id) + super().__init__(request, app=app) def extract_uid(self, data): return str(data["sub"]) diff --git a/gregor_django/drupal_oauth_provider/tests.py b/gregor_django/drupal_oauth_provider/tests.py index 7fc52d06..2d9b5af5 100644 --- a/gregor_django/drupal_oauth_provider/tests.py +++ b/gregor_django/drupal_oauth_provider/tests.py @@ -1,11 +1,18 @@ +import base64 import datetime +import hashlib import json +from urllib.parse import parse_qs, urlparse import jwt +import requests +from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter +from allauth.socialaccount.models import SocialApp from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from django.conf import settings +from django.contrib.auth import get_user_model from django.core.exceptions import ImproperlyConfigured from django.test import RequestFactory from django.test.utils import override_settings @@ -83,10 +90,18 @@ def sign_id_token(payload): # disable token storing for testing as it conflicts with drupals use # of tokens for user info -@override_settings(SOCIALACCOUNT_STORE_TOKENS=False) +@override_settings(SOCIALACCOUNT_STORE_TOKENS=True) class CustomProviderTests(OAuth2TestsMixin, TestCase): provider_id = CustomProvider.id + def setUp(self): + super(CustomProviderTests, self).setUp() + # workaround to create a session. see: + # https://code.djangoproject.com/ticket/11475 + User = get_user_model() + User.objects.create_user("testuser", "testuser@testuser.com", "testpw") + self.client.login(username="testuser", password="testpw") + # Provide two mocked responses, first is to the public key request # second is used for the profile request for extra data def get_mocked_response(self): @@ -104,13 +119,68 @@ def get_mocked_response(self): ), ] - # This login response mimics drupals in that it contains a set of scopes - # and the uid which has the name sub - def get_login_response_json(self, with_refresh_token=True): + def login(self, resp_mock=None, process="login", with_refresh_token=True): + """ + Unfortunately due to how our provider works we need to alter + this test login function as the default one fails. + """ + with self.mocked_response(): + resp = self.client.post(self.provider.get_login_url(self.request, process=process)) + p = urlparse(resp["location"]) + q = parse_qs(p.query) + pkce_enabled = app_settings.PROVIDERS.get(self.app.provider, {}).get( + "OAUTH_PKCE_ENABLED", self.provider.pkce_enabled_default + ) + + self.assertEqual("code_challenge" in q, pkce_enabled) + self.assertEqual("code_challenge_method" in q, pkce_enabled) + if pkce_enabled: + code_challenge = q["code_challenge"][0] + self.assertEqual(q["code_challenge_method"][0], "S256") + + complete_url = self.provider.get_callback_url() + self.assertGreater(q["redirect_uri"][0].find(complete_url), 0) + response_json = self.get_login_response_json(with_refresh_token=with_refresh_token) + + resp_mocks = resp_mock if isinstance(resp_mock, list) else ([resp_mock] if resp_mock is not None else []) + + with self.mocked_response( + MockedResponse(200, response_json, {"content-type": "application/json"}), + *resp_mocks, + ): + resp = self.client.get(complete_url, self.get_complete_parameters(q)) + + # Find the access token POST request, and assert that it contains + # the correct code_verifier if and only if PKCE is enabled + request_calls = requests.Session.request.call_args_list + import sys + + print(f"REQUEST CALLS {request_calls}", file=sys.stderr) + for args, kwargs in request_calls: + print(f"RC: {args} kwargs: {kwargs}", file=sys.stderr) + data = kwargs.get("data", {}) + if ( + args + and args[0] == "POST" + and isinstance(data, dict) + and data.get("redirect_uri", "").endswith(complete_url) + ): + self.assertEqual("code_verifier" in data, pkce_enabled) + + if pkce_enabled: + hashed_code_verifier = hashlib.sha256(data["code_verifier"].encode("ascii")) + expected_code_challenge = ( + base64.urlsafe_b64encode(hashed_code_verifier.digest()).rstrip(b"=").decode() + ) + self.assertEqual(code_challenge, expected_code_challenge) + + return resp + + def get_id_token(self): now = datetime.datetime.now(datetime.timezone.utc) app = get_adapter().get_app(request=None, provider=self.provider_id) allowed_audience = app.client_id - id_token = sign_id_token( + return sign_id_token( { "exp": now + datetime.timedelta(hours=1), "iat": now, @@ -119,6 +189,17 @@ def get_login_response_json(self, with_refresh_token=True): "sub": 20122, } ) + + def get_access_token(self) -> str: + return self.get_id_token() + + def get_expected_to_str(self): + return "test@testmaster.net" + + # This login response mimics drupals in that it contains a set of scopes + # and the uid which has the name sub + def get_login_response_json(self, with_refresh_token=True): + id_token = self.get_id_token() response_data = { "access_token": id_token, "expires_in": 3600, @@ -131,6 +212,19 @@ def get_login_response_json(self, with_refresh_token=True): class TestProviderConfig(TestCase): + def setUp(self): + # workaround to create a session. see: + # https://code.djangoproject.com/ticket/11475 + + app = SocialApp.objects.create( + provider=CustomProvider.id, + name=CustomProvider.id, + client_id="app123id", + key=CustomProvider.id, + secret="dummy", + ) + self.app = app + def test_custom_provider_scope_config(self): custom_provider_settings = settings.SOCIALACCOUNT_PROVIDERS rf = RequestFactory() @@ -138,7 +232,7 @@ def test_custom_provider_scope_config(self): custom_provider_settings["drupal_oauth_provider"]["SCOPES"] = None with override_settings(SOCIALACCOUNT_PROVIDERS=custom_provider_settings): with self.assertRaises(ImproperlyConfigured): - CustomProvider(request).get_provider_scope_config() + CustomProvider(request, app=self.app).get_provider_scope_config() def test_custom_provider_scope_detail_config(self): custom_provider_settings = settings.SOCIALACCOUNT_PROVIDERS @@ -153,7 +247,7 @@ def test_custom_provider_scope_detail_config(self): ] with override_settings(SOCIALACCOUNT_PROVIDERS=custom_provider_settings): with self.assertRaises(ImproperlyConfigured): - CustomProvider(request).get_provider_managed_scope_status() + CustomProvider(request, app=self.app).get_provider_managed_scope_status() def test_custom_provider_has_scope(self): custom_provider_settings = settings.SOCIALACCOUNT_PROVIDERS @@ -167,4 +261,4 @@ def test_custom_provider_has_scope(self): } ] with override_settings(SOCIALACCOUNT_PROVIDERS=custom_provider_settings): - CustomProvider(request).get_provider_managed_scope_status(scopes_granted=["X"]) + CustomProvider(request, app=self.app).get_provider_managed_scope_status(scopes_granted=["X"]) diff --git a/gregor_django/drupal_oauth_provider/views.py b/gregor_django/drupal_oauth_provider/views.py index 317021a8..655f6f4d 100644 --- a/gregor_django/drupal_oauth_provider/views.py +++ b/gregor_django/drupal_oauth_provider/views.py @@ -12,13 +12,13 @@ OAuth2LoginView, ) -from .provider import CustomProvider +# from .provider import CustomProvider logger = logging.getLogger(__name__) class CustomAdapter(OAuth2Adapter): - provider_id = CustomProvider.id + provider_id = "drupal_oauth_provider" provider_settings = app_settings.PROVIDERS.get(provider_id, {}) diff --git a/gregor_django/templates/socialaccount/authentication_error.html b/gregor_django/templates/socialaccount/authentication_error.html index 92a5b4c8..ba0bb87a 100644 --- a/gregor_django/templates/socialaccount/authentication_error.html +++ b/gregor_django/templates/socialaccount/authentication_error.html @@ -1,4 +1,4 @@ -{% extends "socialaccount/base.html" %} +{% extends "base.html" %} {% load i18n %} diff --git a/gregor_django/users/adapters.py b/gregor_django/users/adapters.py index 26f0075c..90272c3b 100644 --- a/gregor_django/users/adapters.py +++ b/gregor_django/users/adapters.py @@ -24,6 +24,10 @@ def is_open_for_signup(self, request: HttpRequest, sociallogin: Any): return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True) def update_user_info(self, user, extra_data: Dict): + import sys + + print(f"USER3: {user} {user.username} id: {user.id}", file=sys.stderr) + logger.info(f"User {user} username {user.username}") drupal_username = extra_data.get("preferred_username") drupal_email = extra_data.get("email") first_name = extra_data.get("first_name") @@ -32,21 +36,21 @@ def update_user_info(self, user, extra_data: Dict): user_changed = False if user.name != full_name: logger.info( - f"[SocialAccountAdatpter:update_user_name] user {user} " f"name updated from {user.name} to {full_name}" + f"[SocialAccountAdatpter:update_user_info] user {user} " f"name updated from {user.name} to {full_name}" ) user.name = full_name user_changed = True if user.username != drupal_username: logger.info( - f"[SocialAccountAdatpter:update_user_name] user {user} " + f"[SocialAccountAdatpter:update_user_info] user {user} " f"username updated from {user.username} to {drupal_username}" ) user.username = drupal_username user_changed = True if user.email != drupal_email: logger.info( - f"[SocialAccountAdatpter:update_user_name] user {user}" - f" email updated from {user.email} to {drupal_email}" + f"[SocialAccountAdatpter:update_user_info] user {user.username}" + # f" email updated from {user.email} to {drupal_email}" ) user.email = drupal_email user_changed = True @@ -186,10 +190,13 @@ def update_user_data(self, sociallogin: Any): self.update_user_partner_groups(user, extra_data) self.update_user_groups(user, extra_data) - def authentication_error(self, request, provider_id, error, exception, extra_context): + def on_authentication_error(self, request, provider_id, error, exception, extra_context): """ Invoked when there is an error in auth cycle. Log so we know what is going on. """ - logger.error(f"[SocialAccountAdapter:authentication_error] Error {error} Exception: {exception}") - super().authentication_error(request, provider_id, error, exception, extra_context) + logger.error( + f"[SocialAccountAdapter:on_authentication_error] Provider: {provider_id} " + f"Error {error} Exception: {exception} extra {extra_context}" + ) + super().on_authentication_error(request, provider_id, error, exception, extra_context) diff --git a/gregor_django/users/tests/test_adapters.py b/gregor_django/users/tests/test_adapters.py index 4e37d11e..4e6b77ae 100644 --- a/gregor_django/users/tests/test_adapters.py +++ b/gregor_django/users/tests/test_adapters.py @@ -1,15 +1,20 @@ +# myapp/tests.py + import pytest from allauth.account import app_settings as account_settings -from allauth.socialaccount.helpers import complete_social_login -from allauth.socialaccount.models import SocialAccount, SocialLogin -from allauth.utils import get_user_model +from allauth.account import signals +from allauth.socialaccount.models import SocialAccount, SocialApp, SocialLogin +from django.contrib.auth import get_user_model +from django.contrib.auth.middleware import AuthenticationMiddleware from django.contrib.auth.models import AnonymousUser -from django.contrib.messages.middleware import MessageMiddleware from django.contrib.sessions.middleware import SessionMiddleware +from django.contrib.sites.models import Site from django.core.exceptions import ImproperlyConfigured +from django.test import TestCase from django.test.client import RequestFactory from django.test.utils import override_settings +from gregor_django.drupal_oauth_provider.provider import CustomProvider from gregor_django.gregor_anvil.tests.factories import ( PartnerGroupFactory, ResearchCenterFactory, @@ -18,48 +23,77 @@ from .factories import GroupFactory, UserFactory +User = get_user_model() -@pytest.mark.django_db -class TestsUserSocialLoginAdapter(object): - @override_settings( - SOCIALACCOUNT_AUTO_SIGNUP=True, - ACCOUNT_SIGNUP_FORM_CLASS=None, - ACCOUNT_EMAIL_VERIFICATION=account_settings.EmailVerificationMethod.NONE, # noqa - ) - def test_drupal_social_login_adapter(self): - factory = RequestFactory() - request = factory.get("/accounts/login/callback/") - request.user = AnonymousUser() - SessionMiddleware(lambda request: None).process_request(request) - MessageMiddleware(lambda request: None).process_request(request) - - User = get_user_model() - user = User() - old_name = "Old Name" - old_username = "test" - old_email = "test@example.com" - setattr(user, account_settings.USER_MODEL_USERNAME_FIELD, "test") - setattr(user, "name", "Old Name") - setattr(user, account_settings.USER_MODEL_EMAIL_FIELD, "test@example.com") - account = SocialAccount( +class SocialAccountAdapterTest(TestCase): + def setUp(self): + self.factory = RequestFactory() + # Setup a mock social app + current_site = Site.objects.get_current() + self.social_app = SocialApp.objects.create( + provider=CustomProvider.id, + name="DOA", + client_id="test-client-id", + secret="test-client-secret", + ) + self.social_app.sites.add(current_site) + + def extract_state_from_url(self, url): + from urllib.parse import parse_qs, urlparse + + parsed_url = urlparse(url) + query_params = parse_qs(parsed_url.query) + return query_params.get("state", [None])[0] + + def test_social_login_success(self): + # Mock user + request = self.factory.get("/") + middleware = SessionMiddleware(lambda x: None) + middleware.process_request(request) + request.session.save() + middleware = AuthenticationMiddleware(lambda x: None) + middleware.process_request(request) + request.user = AnonymousUser() + user = User.objects.create(username="testuser", email="testuser@example.com") + + # # Mock social login + # Create a mock SocialAccount and link it to the user + new_first_name = "Bob" + new_last_name = "Rob" + social_account = SocialAccount.objects.create( + user=user, provider="drupal_oauth_provider", - uid="123", - extra_data=dict( - first_name="Old", - last_name="Name", - email=old_email, - preferred_username=old_username, - ), + uid="12345", + extra_data={ + "preferred_username": "testuser", + "first_name": new_first_name, + "last_name": new_last_name, + "email": "testuser@example.com", + }, ) - sociallogin = SocialLogin(user=user, account=account) - complete_social_login(request, sociallogin) - user = User.objects.get(**{account_settings.USER_MODEL_USERNAME_FIELD: "test"}) - assert SocialAccount.objects.filter(user=user, uid=account.uid).exists() is True - assert user.name == old_name - assert user.username == old_username - assert user.email == old_email + # Create a mock SocialLogin object and associate the user and social account + sociallogin = SocialLogin(user=user, account=social_account) + + # Simulate social login + from allauth.account.adapter import get_adapter + + # adapter = SocialAccountAdapter() + adapter = get_adapter(request) + + adapter.login(request, user) + + signals.user_logged_in.send( + sender=user.__class__, + request=request, + user=user, + sociallogin=sociallogin, + ) + # Check if the login completed successfully + self.assertEqual(sociallogin.user, user) + self.assertEqual(request.user, user) + self.assertEqual(user.name, f"{new_first_name} {new_last_name}") def test_update_user_info(self): adapter = SocialAccountAdapter() @@ -105,6 +139,21 @@ def test_update_user_research_centers_add(self): assert user.research_centers.filter(pk=rc1.pk).exists() assert user.research_centers.all().count() == 1 + def test_update_user_research_centers_short_name_add(self): + adapter = SocialAccountAdapter() + rc1 = ResearchCenterFactory(short_name="rc1") + + User = get_user_model() + user = User() + setattr(user, account_settings.USER_MODEL_USERNAME_FIELD, "test") + setattr(user, account_settings.USER_MODEL_EMAIL_FIELD, "test@example.com") + + user.save() + + adapter.update_user_research_centers(user, dict(research_center_or_site=[rc1.short_name])) + assert user.research_centers.filter(pk=rc1.pk).exists() + assert user.research_centers.all().count() == 1 + def test_update_user_research_centers_remove(self): adapter = SocialAccountAdapter() rc1 = ResearchCenterFactory(short_name="rc1") diff --git a/requirements/requirements.in b/requirements/requirements.in index 313b7167..ecf9c6a2 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -5,7 +5,7 @@ pip-tools whitenoise # https://github.com/evansd/whitenoise # Login via oauth oauthlib # https://github.com/oauthlib/oauthlib - +cryptography # https://github.com/pyca/cryptography # Password hashing argon2-cffi # https://github.com/hynek/argon2_cffi diff --git a/requirements/requirements.txt b/requirements/requirements.txt index a314a609..789a5fa5 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -51,7 +51,7 @@ django==4.2.16 # django-picklefield # django-simple-history # django-tables2 -django-allauth==0.54.0 +django-allauth==65.0.2 # via -r requirements/requirements.in django-anvil-consortium-manager @ git+https://github.com/UW-GAC/django-anvil-consortium-manager.git@v0.25 # via -r requirements/requirements.in From b3bb77feec18a4e7bef022cf81297c734fc99c36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 19:47:00 +0000 Subject: [PATCH 59/97] Bump actions/upload-artifact from 4.4.0 to 4.4.3 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.4.0 to 4.4.3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4.4.0...v4.4.3) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dfb8827d..0fc29662 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,7 +99,7 @@ jobs: run: ls -lhta - name: Upload coverage data - uses: actions/upload-artifact@v4.4.0 + uses: actions/upload-artifact@v4.4.3 with: name: coverage-data-${{ strategy.job-index }} path: coverage-${{ strategy.job-index }} From 705893b6f85ae687cf85a4b19c6d5e7ef8a05f19 Mon Sep 17 00:00:00 2001 From: Jonas Carson Date: Thu, 10 Oct 2024 08:50:31 -0700 Subject: [PATCH 60/97] Clean up un-needed changes introduced when working through compatiblity issues with new allauth. --- gregor_django/drupal_oauth_provider/tests.py | 3 --- gregor_django/drupal_oauth_provider/views.py | 2 -- gregor_django/users/adapters.py | 8 ++------ 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/gregor_django/drupal_oauth_provider/tests.py b/gregor_django/drupal_oauth_provider/tests.py index 2d9b5af5..c27164ab 100644 --- a/gregor_django/drupal_oauth_provider/tests.py +++ b/gregor_django/drupal_oauth_provider/tests.py @@ -153,11 +153,8 @@ def login(self, resp_mock=None, process="login", with_refresh_token=True): # Find the access token POST request, and assert that it contains # the correct code_verifier if and only if PKCE is enabled request_calls = requests.Session.request.call_args_list - import sys - print(f"REQUEST CALLS {request_calls}", file=sys.stderr) for args, kwargs in request_calls: - print(f"RC: {args} kwargs: {kwargs}", file=sys.stderr) data = kwargs.get("data", {}) if ( args diff --git a/gregor_django/drupal_oauth_provider/views.py b/gregor_django/drupal_oauth_provider/views.py index 655f6f4d..80274a40 100644 --- a/gregor_django/drupal_oauth_provider/views.py +++ b/gregor_django/drupal_oauth_provider/views.py @@ -12,8 +12,6 @@ OAuth2LoginView, ) -# from .provider import CustomProvider - logger = logging.getLogger(__name__) diff --git a/gregor_django/users/adapters.py b/gregor_django/users/adapters.py index 90272c3b..27ac8a2b 100644 --- a/gregor_django/users/adapters.py +++ b/gregor_django/users/adapters.py @@ -24,10 +24,6 @@ def is_open_for_signup(self, request: HttpRequest, sociallogin: Any): return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True) def update_user_info(self, user, extra_data: Dict): - import sys - - print(f"USER3: {user} {user.username} id: {user.id}", file=sys.stderr) - logger.info(f"User {user} username {user.username}") drupal_username = extra_data.get("preferred_username") drupal_email = extra_data.get("email") first_name = extra_data.get("first_name") @@ -49,8 +45,8 @@ def update_user_info(self, user, extra_data: Dict): user_changed = True if user.email != drupal_email: logger.info( - f"[SocialAccountAdatpter:update_user_info] user {user.username}" - # f" email updated from {user.email} to {drupal_email}" + f"[SocialAccountAdatpter:update_user_info] user {user}" + f" email updated from {user.email} to {drupal_email}" ) user.email = drupal_email user_changed = True From a1262e97c01403c1672345fa4e30401ee399629a Mon Sep 17 00:00:00 2001 From: Jonas Carson Date: Thu, 10 Oct 2024 10:09:23 -0700 Subject: [PATCH 61/97] Updated requirements needed due to allauth upgrade --- requirements/requirements.in | 2 ++ requirements/requirements.txt | 15 +++++---------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/requirements/requirements.in b/requirements/requirements.in index ecf9c6a2..e39662ee 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -6,6 +6,8 @@ whitenoise # https://github.com/evansd/whitenoise # Login via oauth oauthlib # https://github.com/oauthlib/oauthlib cryptography # https://github.com/pyca/cryptography +pyjwt # https://github.com/jpadilla/pyjwt +requests-oauthlib # https://github.com/requests/requests-oauthlib # Password hashing argon2-cffi # https://github.com/hynek/argon2_cffi diff --git a/requirements/requirements.txt b/requirements/requirements.txt index d66cb52f..36695d7a 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -32,9 +32,7 @@ crispy-bootstrap5==2024.2 # -r requirements/requirements.in # django-anvil-consortium-manager cryptography==43.0.1 - # via pyjwt -defusedxml==0.7.1 - # via python3-openid + # via -r requirements/requirements.in django==4.2.16 # via # -r requirements/requirements.in @@ -124,28 +122,25 @@ pyasn1-modules==0.3.0 # via google-auth pycparser==2.21 # via cffi -pyjwt[crypto]==2.8.0 - # via django-allauth +pyjwt==2.8.0 + # via -r requirements/requirements.in pyproject-hooks==1.0.0 # via # build # pip-tools python-fsutil==0.13.1 # via django-maintenance-mode -python3-openid==3.2.0 - # via django-allauth pytz==2023.4 # via # django-anvil-consortium-manager # django-dbbackup requests==2.32.3 # via - # django-allauth # django-anvil-consortium-manager # jsonapi-requests # requests-oauthlib -requests-oauthlib==1.3.1 - # via django-allauth +requests-oauthlib==2.0.0 + # via -r requirements/requirements.in rsa==4.9 # via google-auth six==1.16.0 From 89b640c1f7718c9db98e5e2d8cb86031730b10ef Mon Sep 17 00:00:00 2001 From: Jonas Carson Date: Thu, 10 Oct 2024 11:01:41 -0700 Subject: [PATCH 62/97] Fix missing coverage and remove unused test function --- gregor_django/drupal_oauth_provider/tests.py | 10 +++++++++- .../templates/socialaccount/authentication_error.html | 2 +- gregor_django/users/tests/test_adapters.py | 7 ------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/gregor_django/drupal_oauth_provider/tests.py b/gregor_django/drupal_oauth_provider/tests.py index c27164ab..214787e6 100644 --- a/gregor_django/drupal_oauth_provider/tests.py +++ b/gregor_django/drupal_oauth_provider/tests.py @@ -13,6 +13,7 @@ from allauth.tests import MockedResponse, TestCase from django.conf import settings from django.contrib.auth import get_user_model +from django.contrib.sites.models import Site from django.core.exceptions import ImproperlyConfigured from django.test import RequestFactory from django.test.utils import override_settings @@ -212,7 +213,7 @@ class TestProviderConfig(TestCase): def setUp(self): # workaround to create a session. see: # https://code.djangoproject.com/ticket/11475 - + current_site = Site.objects.get_current() app = SocialApp.objects.create( provider=CustomProvider.id, name=CustomProvider.id, @@ -221,6 +222,13 @@ def setUp(self): secret="dummy", ) self.app = app + self.app.sites.add(current_site) + + def test_custom_provider_no_app(self): + rf = RequestFactory() + request = rf.get("/fake-url/") + provider = CustomProvider(request) + assert provider.app is not None def test_custom_provider_scope_config(self): custom_provider_settings = settings.SOCIALACCOUNT_PROVIDERS diff --git a/gregor_django/templates/socialaccount/authentication_error.html b/gregor_django/templates/socialaccount/authentication_error.html index ba0bb87a..76166bfe 100644 --- a/gregor_django/templates/socialaccount/authentication_error.html +++ b/gregor_django/templates/socialaccount/authentication_error.html @@ -2,7 +2,7 @@ {% load i18n %} -{% block head_title %}{% trans "Social Network Login Failure" %}{% endblock %} +{% block title %}{% trans "Social Network Login Failure" %}{% endblock %} {% block content %}

    {% trans "Social Network Login Failure" %}

    diff --git a/gregor_django/users/tests/test_adapters.py b/gregor_django/users/tests/test_adapters.py index 4e6b77ae..c21abe34 100644 --- a/gregor_django/users/tests/test_adapters.py +++ b/gregor_django/users/tests/test_adapters.py @@ -39,13 +39,6 @@ def setUp(self): ) self.social_app.sites.add(current_site) - def extract_state_from_url(self, url): - from urllib.parse import parse_qs, urlparse - - parsed_url = urlparse(url) - query_params = parse_qs(parsed_url.query) - return query_params.get("state", [None])[0] - def test_social_login_success(self): # Mock user request = self.factory.get("/") From a5613f0658d2b3d8bd27a00078260e17c046c5ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 19:25:56 +0000 Subject: [PATCH 63/97] Bump pylint-django from 2.5.5 to 2.6.1 Bumps [pylint-django](https://github.com/pylint-dev/pylint-django) from 2.5.5 to 2.6.1. - [Release notes](https://github.com/pylint-dev/pylint-django/releases) - [Changelog](https://github.com/pylint-dev/pylint-django/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pylint-dev/pylint-django/commits/v2.6.1) --- updated-dependencies: - dependency-name: pylint-django dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 132223a6..c9ad1d43 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -137,7 +137,7 @@ pylint==3.1.0 # via # pylint-django # pylint-plugin-utils -pylint-django==2.5.5 +pylint-django==2.6.1 # via -r requirements/dev-requirements.in pylint-plugin-utils==0.8.2 # via pylint-django From c81ff3ed28314255bc2307184b114185e4e0ad38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 19:32:41 +0000 Subject: [PATCH 64/97] Bump github/combine-prs from 5.1.0 to 5.2.0 Bumps [github/combine-prs](https://github.com/github/combine-prs) from 5.1.0 to 5.2.0. - [Release notes](https://github.com/github/combine-prs/releases) - [Commits](https://github.com/github/combine-prs/compare/v5.1.0...v5.2.0) --- updated-dependencies: - dependency-name: github/combine-prs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/combine-prs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/combine-prs.yml b/.github/workflows/combine-prs.yml index cf9c0d74..82d39e94 100644 --- a/.github/workflows/combine-prs.yml +++ b/.github/workflows/combine-prs.yml @@ -16,7 +16,7 @@ jobs: steps: - name: combine-prs id: combine-prs - uses: github/combine-prs@v5.1.0 + uses: github/combine-prs@v5.2.0 with: labels: combined-pr # Optional: add a label to the combined PR ci_required: true # require all checks to pass before combining From 926b429850730df622720896d699337ce90ded07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 19:16:02 +0000 Subject: [PATCH 65/97] Bump gitleaks/gitleaks-action from 2.3.6 to 2.3.7 Bumps [gitleaks/gitleaks-action](https://github.com/gitleaks/gitleaks-action) from 2.3.6 to 2.3.7. - [Release notes](https://github.com/gitleaks/gitleaks-action/releases) - [Commits](https://github.com/gitleaks/gitleaks-action/compare/v2.3.6...v2.3.7) --- updated-dependencies: - dependency-name: gitleaks/gitleaks-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/gitleaks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml index b898bbac..00a67cc8 100644 --- a/.github/workflows/gitleaks.yml +++ b/.github/workflows/gitleaks.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v4.2.1 with: fetch-depth: 0 - - uses: gitleaks/gitleaks-action@v2.3.6 + - uses: gitleaks/gitleaks-action@v2.3.7 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE}} # Only required for Organizations, not personal accounts. From 501cd1cf8978433aa53e1a7aaa68d68b6fc0ee11 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 8 Oct 2024 12:05:31 -0700 Subject: [PATCH 66/97] Add (and use) a mixin for running audits This mixin defines a method to run an audit, and then adds the results of that audit to the context. Use the new mixin in the views. Note that we aren't using the mixin in the audit resolve method, because it doesn't run audits in the same way. --- gregor_django/gregor_anvil/viewmixins.py | 16 +++ gregor_django/gregor_anvil/views.py | 136 ++++++++--------------- 2 files changed, 63 insertions(+), 89 deletions(-) create mode 100644 gregor_django/gregor_anvil/viewmixins.py diff --git a/gregor_django/gregor_anvil/viewmixins.py b/gregor_django/gregor_anvil/viewmixins.py new file mode 100644 index 00000000..4eba88f8 --- /dev/null +++ b/gregor_django/gregor_anvil/viewmixins.py @@ -0,0 +1,16 @@ +class AuditMixin: + """Mixin to assist with auditing views.""" + + def run_audit(self): + raise NotImplementedError("AuditMixin.run_audit() must be implemented in a subclass") + + def get_context_data(self, **kwargs): + """Run the audit and add it to the context.""" + context = super().get_context_data(**kwargs) + # Run the audit. + audit_results = self.run_audit() + context["verified_table"] = audit_results.get_verified_table() + context["errors_table"] = audit_results.get_errors_table() + context["needs_action_table"] = audit_results.get_needs_action_table() + context["audit_results"] = audit_results + return context diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index b1e90636..343adf0b 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -24,7 +24,7 @@ from gregor_django.users.tables import UserTable -from . import forms, models, tables +from . import forms, models, tables, viewmixins from .audit import ( combined_workspace_audit, upload_workspace_audit, @@ -193,24 +193,20 @@ def get_context_data(self, **kwargs): return context -class UploadWorkspaceSharingAudit(AnVILConsortiumManagerStaffViewRequired, TemplateView): +class UploadWorkspaceSharingAudit(AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, TemplateView): """View to audit UploadWorkspace sharing for all UploadWorkspaces.""" template_name = "gregor_anvil/upload_workspace_sharing_audit.html" - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - # Run the audit. + def run_audit(self, **kwargs): audit = upload_workspace_audit.UploadWorkspaceSharingAudit() audit.run_audit() - context["verified_table"] = audit.get_verified_table() - context["errors_table"] = audit.get_errors_table() - context["needs_action_table"] = audit.get_needs_action_table() - context["audit_results"] = audit - return context + return audit -class UploadWorkspaceSharingAuditByWorkspace(AnVILConsortiumManagerStaffViewRequired, DetailView): +class UploadWorkspaceSharingAuditByWorkspace( + AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, DetailView +): """View to audit UploadWorkspace sharing for a specific UploadWorkspace.""" template_name = "gregor_anvil/upload_workspace_sharing_audit.html" @@ -234,21 +230,17 @@ def get_object(self, queryset=None): ) return obj - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - # Run the audit. + def run_audit(self, **kwargs): audit = upload_workspace_audit.UploadWorkspaceSharingAudit( queryset=self.model.objects.filter(pk=self.object.pk) ) audit.run_audit() - context["verified_table"] = audit.get_verified_table() - context["errors_table"] = audit.get_errors_table() - context["needs_action_table"] = audit.get_needs_action_table() - context["audit_results"] = audit - return context + return audit -class UploadWorkspaceSharingAuditByUploadCycle(AnVILConsortiumManagerStaffViewRequired, DetailView): +class UploadWorkspaceSharingAuditByUploadCycle( + AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, DetailView +): """View to audit UploadWorkspace sharing for a specific UploadWorkspace.""" template_name = "gregor_anvil/upload_workspace_sharing_audit.html" @@ -268,18 +260,13 @@ def get_object(self, queryset=None): ) return obj - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) + def run_audit(self, **kwargs): # Run the audit. audit = upload_workspace_audit.UploadWorkspaceSharingAudit( queryset=models.UploadWorkspace.objects.filter(upload_cycle=self.object) ) audit.run_audit() - context["verified_table"] = audit.get_verified_table() - context["errors_table"] = audit.get_errors_table() - context["needs_action_table"] = audit.get_needs_action_table() - context["audit_results"] = audit - return context + return audit class UploadWorkspaceSharingAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): @@ -396,24 +383,20 @@ def form_valid(self, form): return super().form_valid(form) -class UploadWorkspaceAuthDomainAudit(AnVILConsortiumManagerStaffViewRequired, TemplateView): +class UploadWorkspaceAuthDomainAudit(AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, TemplateView): """View to audit UploadWorkspace auth domain membership for all UploadWorkspaces.""" template_name = "gregor_anvil/upload_workspace_auth_domain_audit.html" - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - # Run the audit. + def run_audit(self): audit = upload_workspace_audit.UploadWorkspaceAuthDomainAudit() audit.run_audit() - context["verified_table"] = audit.get_verified_table() - context["errors_table"] = audit.get_errors_table() - context["needs_action_table"] = audit.get_needs_action_table() - context["audit_results"] = audit - return context + return audit -class UploadWorkspaceAuthDomainAuditByWorkspace(AnVILConsortiumManagerStaffEditRequired, DetailView): +class UploadWorkspaceAuthDomainAuditByWorkspace( + AnVILConsortiumManagerStaffEditRequired, viewmixins.AuditMixin, DetailView +): """View to audit UploadWorkspace sharing for a specific UploadWorkspace.""" template_name = "gregor_anvil/upload_workspace_auth_domain_audit.html" @@ -437,21 +420,17 @@ def get_object(self, queryset=None): ) return obj - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - # Run the audit. + def run_audit(self): audit = upload_workspace_audit.UploadWorkspaceAuthDomainAudit( queryset=self.model.objects.filter(pk=self.object.pk) ) audit.run_audit() - context["verified_table"] = audit.get_verified_table() - context["errors_table"] = audit.get_errors_table() - context["needs_action_table"] = audit.get_needs_action_table() - context["audit_results"] = audit - return context + return audit -class UploadWorkspaceAuthDomainAuditByUploadCycle(AnVILConsortiumManagerStaffViewRequired, DetailView): +class UploadWorkspaceAuthDomainAuditByUploadCycle( + AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, DetailView +): """View to audit UploadWorkspace sharing for a specific UploadWorkspace.""" template_name = "gregor_anvil/upload_workspace_auth_domain_audit.html" @@ -471,18 +450,12 @@ def get_object(self, queryset=None): ) return obj - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - # Run the audit. + def run_audit(self, **kwargs): audit = upload_workspace_audit.UploadWorkspaceAuthDomainAudit( queryset=models.UploadWorkspace.objects.filter(upload_cycle=self.object) ) audit.run_audit() - context["verified_table"] = audit.get_verified_table() - context["errors_table"] = audit.get_errors_table() - context["needs_action_table"] = audit.get_needs_action_table() - context["audit_results"] = audit - return context + return audit class UploadWorkspaceAuthDomainAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): @@ -599,24 +572,22 @@ def form_valid(self, form): return super().form_valid(form) -class CombinedConsortiumDataWorkspaceSharingAudit(AnVILConsortiumManagerStaffViewRequired, TemplateView): +class CombinedConsortiumDataWorkspaceSharingAudit( + AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, TemplateView +): """View to audit CombinedConsortiumDataWorkspace sharing for all CombinedConsortiumDataWorkspacs.""" template_name = "gregor_anvil/combinedconsortiumdataworkspace_sharing_audit.html" - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - # Run the audit. + def run_audit(self, **kwargs): audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit() audit.run_audit() - context["verified_table"] = audit.get_verified_table() - context["errors_table"] = audit.get_errors_table() - context["needs_action_table"] = audit.get_needs_action_table() - context["audit_results"] = audit - return context + return audit -class CombinedConsortiumDataWorkspaceSharingAuditByWorkspace(AnVILConsortiumManagerStaffViewRequired, DetailView): +class CombinedConsortiumDataWorkspaceSharingAuditByWorkspace( + AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, DetailView +): """View to audit CombinedConsortiumDataWorkspace sharing for a specific CombinedConsortiumDataWorkspace.""" template_name = "gregor_anvil/combinedconsortiumdataworkspace_sharing_audit.html" @@ -640,18 +611,12 @@ def get_object(self, queryset=None): ) return obj - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - # Run the audit. + def run_audit(self, **kwargs): audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit( queryset=self.model.objects.filter(pk=self.object.pk) ) audit.run_audit() - context["verified_table"] = audit.get_verified_table() - context["errors_table"] = audit.get_errors_table() - context["needs_action_table"] = audit.get_needs_action_table() - context["audit_results"] = audit - return context + return audit class CombinedConsortiumDataWorkspaceSharingAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): @@ -768,24 +733,22 @@ def form_valid(self, form): return super().form_valid(form) -class CombinedConsortiumDataWorkspaceAuthDomainAudit(AnVILConsortiumManagerStaffViewRequired, TemplateView): +class CombinedConsortiumDataWorkspaceAuthDomainAudit( + AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, TemplateView +): """View to audit auth domain membership for all CombinedConsortiumDataWorkspaces.""" template_name = "gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html" - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - # Run the audit. + def run_audit(self, **kwargs): audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit() audit.run_audit() - context["verified_table"] = audit.get_verified_table() - context["errors_table"] = audit.get_errors_table() - context["needs_action_table"] = audit.get_needs_action_table() - context["audit_results"] = audit - return context + return audit -class CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace(AnVILConsortiumManagerStaffViewRequired, DetailView): +class CombinedConsortiumDataWorkspaceAuthDomainAuditByWorkspace( + AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, DetailView +): """View to audit auth domain membership for a specific CombinedConsortiumDataWorkspace.""" template_name = "gregor_anvil/combinedconsortiumdataworkspace_auth_domain_audit.html" @@ -809,18 +772,13 @@ def get_object(self, queryset=None): ) return obj - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) + def run_audit(self, **kwargs): # Run the audit. audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit( queryset=self.model.objects.filter(pk=self.object.pk) ) audit.run_audit() - context["verified_table"] = audit.get_verified_table() - context["errors_table"] = audit.get_errors_table() - context["needs_action_table"] = audit.get_needs_action_table() - context["audit_results"] = audit - return context + return audit class CombinedConsortiumDataWorkspaceAuthDomainAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): From bcb60fec830d2d1ec254238ca7852de50ca4fb37 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 14 Oct 2024 13:56:09 -0700 Subject: [PATCH 67/97] Move code to handle audit results into the result subclasses Instead of having the logic in the view, move it into the audit result classes themselves. This makes it so the view only has to handle exceptions instead of logic. --- .../workspace_auth_domain_audit_results.py | 57 +- .../audit/workspace_sharing_audit_results.py | 79 ++ .../gregor_anvil/tests/test_audit.py | 762 ++++++++++++++++-- gregor_django/gregor_anvil/views.py | 140 +--- 4 files changed, 835 insertions(+), 203 deletions(-) diff --git a/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py b/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py index 11ccf580..493203a8 100644 --- a/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py +++ b/gregor_django/gregor_anvil/audit/workspace_auth_domain_audit_results.py @@ -14,6 +14,7 @@ class WorkspaceAuthDomainAuditResult(GREGoRAuditResult): managed_group: ManagedGroup action: str = None current_membership_instance: GroupGroupMembership = None + handled: bool = False def get_table_dictionary(self): """Return a dictionary that can be used to populate an instance of `dbGaPDataSharingSnapshotAuditTable`.""" @@ -26,6 +27,13 @@ def get_table_dictionary(self): } return row + def _handle(self): + raise NotImplementedError("Subclasses must implement this method.") + + def handle(self): + self._handle() + self.handled = True + @dataclass class VerifiedMember(WorkspaceAuthDomainAuditResult): @@ -34,16 +42,20 @@ class VerifiedMember(WorkspaceAuthDomainAuditResult): def __str__(self): return f"Verified member: {self.note}" + def _handle(self): + pass + @dataclass class VerifiedAdmin(WorkspaceAuthDomainAuditResult): """Audit results class for when membership with an admin role has been verified.""" - is_shared: bool = False - def __str__(self): return f"Verified admin: {self.note}" + def _handle(self): + pass + @dataclass class VerifiedNotMember(WorkspaceAuthDomainAuditResult): @@ -52,6 +64,9 @@ class VerifiedNotMember(WorkspaceAuthDomainAuditResult): def __str__(self): return f"Verified member: {self.note}" + def _handle(self): + pass + @dataclass class AddMember(WorkspaceAuthDomainAuditResult): @@ -62,6 +77,16 @@ class AddMember(WorkspaceAuthDomainAuditResult): def __str__(self): return f"Add member: {self.note}" + def _handle(self): + membership = GroupGroupMembership( + parent_group=self.workspace.authorization_domains.first(), + child_group=self.managed_group, + role=GroupGroupMembership.MEMBER, + ) + membership.full_clean() + membership.save() + membership.anvil_create() + @dataclass class AddAdmin(WorkspaceAuthDomainAuditResult): @@ -72,6 +97,16 @@ class AddAdmin(WorkspaceAuthDomainAuditResult): def __str__(self): return f"Add admin: {self.note}" + def _handle(self): + membership = GroupGroupMembership( + parent_group=self.workspace.authorization_domains.first(), + child_group=self.managed_group, + role=GroupGroupMembership.ADMIN, + ) + membership.full_clean() + membership.save() + membership.anvil_create() + @dataclass class ChangeToMember(WorkspaceAuthDomainAuditResult): @@ -82,6 +117,13 @@ class ChangeToMember(WorkspaceAuthDomainAuditResult): def __str__(self): return f"Change to member: {self.note}" + def _handle(self): + self.current_membership_instance.anvil_delete() + self.current_membership_instance.role = GroupGroupMembership.MEMBER + self.current_membership_instance.full_clean() + self.current_membership_instance.save() + self.current_membership_instance.anvil_create() + @dataclass class ChangeToAdmin(WorkspaceAuthDomainAuditResult): @@ -92,6 +134,13 @@ class ChangeToAdmin(WorkspaceAuthDomainAuditResult): def __str__(self): return f"Change to admin: {self.note}" + def _handle(self): + self.current_membership_instance.anvil_delete() + self.current_membership_instance.role = GroupGroupMembership.ADMIN + self.current_membership_instance.full_clean() + self.current_membership_instance.save() + self.current_membership_instance.anvil_create() + @dataclass class Remove(WorkspaceAuthDomainAuditResult): @@ -101,3 +150,7 @@ class Remove(WorkspaceAuthDomainAuditResult): def __str__(self): return f"Share as owner: {self.note}" + + def _handle(self): + self.current_membership_instance.anvil_delete() + self.current_membership_instance.delete() diff --git a/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py b/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py index 7d9b93f6..42cc6398 100644 --- a/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py +++ b/gregor_django/gregor_anvil/audit/workspace_sharing_audit_results.py @@ -18,6 +18,7 @@ class WorkspaceSharingAuditResult(GREGoRAuditResult): managed_group: ManagedGroup action: str = None current_sharing_instance: WorkspaceGroupSharing = None + handled: bool = False def get_table_dictionary(self): """Return a dictionary that can be used to populate an instance of `dbGaPDataSharingSnapshotAuditTable`.""" @@ -34,6 +35,13 @@ def get_table_dictionary(self): } return row + def _handle(self): + raise NotImplementedError("Subclasses must implement this method.") + + def handle(self): + self._handle() + self.handled = True + @dataclass class VerifiedShared(WorkspaceSharingAuditResult): @@ -42,6 +50,9 @@ class VerifiedShared(WorkspaceSharingAuditResult): def __str__(self): return f"Verified sharing: {self.note}" + def _handle(self): + pass + @dataclass class VerifiedNotShared(WorkspaceSharingAuditResult): @@ -50,6 +61,9 @@ class VerifiedNotShared(WorkspaceSharingAuditResult): def __str__(self): return f"Verified not shared: {self.note}" + def _handle(self): + pass + @dataclass class ShareAsReader(WorkspaceSharingAuditResult): @@ -60,6 +74,21 @@ class ShareAsReader(WorkspaceSharingAuditResult): def __str__(self): return f"Share as reader: {self.note}" + def _handle(self): + # Create or update the sharing record. + if self.current_sharing_instance: + sharing = self.current_sharing_instance + else: + sharing = WorkspaceGroupSharing( + workspace=self.workspace, + group=self.managed_group, + ) + sharing.access = WorkspaceGroupSharing.READER + sharing.can_compute = False + sharing.full_clean() + sharing.save() + sharing.anvil_create_or_update() + @dataclass class ShareAsWriter(WorkspaceSharingAuditResult): @@ -70,6 +99,21 @@ class ShareAsWriter(WorkspaceSharingAuditResult): def __str__(self): return f"Share as writer: {self.note}" + def _handle(self): + # Create or update the sharing record. + if self.current_sharing_instance: + sharing = self.current_sharing_instance + else: + sharing = WorkspaceGroupSharing( + workspace=self.workspace, + group=self.managed_group, + ) + sharing.access = WorkspaceGroupSharing.WRITER + sharing.can_compute = False + sharing.full_clean() + sharing.save() + sharing.anvil_create_or_update() + @dataclass class ShareAsOwner(WorkspaceSharingAuditResult): @@ -80,6 +124,21 @@ class ShareAsOwner(WorkspaceSharingAuditResult): def __str__(self): return f"Share as owner: {self.note}" + def _handle(self): + # Create or update the sharing record. + if self.current_sharing_instance: + sharing = self.current_sharing_instance + else: + sharing = WorkspaceGroupSharing( + workspace=self.workspace, + group=self.managed_group, + ) + sharing.access = WorkspaceGroupSharing.OWNER + sharing.can_compute = True + sharing.full_clean() + sharing.save() + sharing.anvil_create_or_update() + @dataclass class ShareWithCompute(WorkspaceSharingAuditResult): @@ -90,6 +149,21 @@ class ShareWithCompute(WorkspaceSharingAuditResult): def __str__(self): return f"Share with compute: {self.note}" + def _handle(self): + # Create or update the sharing record. + if self.current_sharing_instance: + sharing = self.current_sharing_instance + else: + sharing = WorkspaceGroupSharing( + workspace=self.workspace, + group=self.managed_group, + ) + sharing.access = WorkspaceGroupSharing.WRITER + sharing.can_compute = True + sharing.full_clean() + sharing.save() + sharing.anvil_create_or_update() + @dataclass class StopSharing(WorkspaceSharingAuditResult): @@ -100,6 +174,11 @@ class StopSharing(WorkspaceSharingAuditResult): def __str__(self): return f"Stop sharing: {self.note}" + def _handle(self): + # Remove the sharing record. + self.current_sharing_instance.anvil_delete() + self.current_sharing_instance.delete() + @dataclass class Error(WorkspaceSharingAuditResult): diff --git a/gregor_django/gregor_anvil/tests/test_audit.py b/gregor_django/gregor_anvil/tests/test_audit.py index 8f8125eb..dae1fd63 100644 --- a/gregor_django/gregor_anvil/tests/test_audit.py +++ b/gregor_django/gregor_anvil/tests/test_audit.py @@ -1,17 +1,24 @@ """Tests for the `py` module.""" from dataclasses import dataclass +from datetime import timedelta import django_tables2 as tables +import responses from anvil_consortium_manager.models import GroupGroupMembership, WorkspaceGroupSharing from anvil_consortium_manager.tests.factories import ( GroupGroupMembershipFactory, ManagedGroupFactory, + WorkspaceAuthorizationDomainFactory, + WorkspaceFactory, WorkspaceGroupSharingFactory, ) +from anvil_consortium_manager.tests.utils import AnVILAPIMockTestMixin from django.conf import settings from django.test import TestCase, override_settings +from django.utils import timezone from faker import Faker +from freezegun import freeze_time from .. import models from ..audit import ( @@ -167,17 +174,17 @@ def test_get_errors_table(self): self.assertEqual(table.rows[0].get_cell("value"), "c") -class UploadWorkspaceSharingAuditResultTest(TestCase): +class WorkspaceSharingAuditResultTest(AnVILAPIMockTestMixin, TestCase): """General tests of the UploadWorkspaceSharingAuditResult dataclasses.""" def test_shared_as_owner(self): - upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + workspace = WorkspaceFactory.create() group = ManagedGroupFactory.create() sharing = WorkspaceGroupSharingFactory.create( - workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.OWNER, can_compute=True + workspace=workspace, group=group, access=WorkspaceGroupSharing.OWNER, can_compute=True ) instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( - workspace=upload_workspace.workspace, + workspace=workspace, managed_group=group, current_sharing_instance=sharing, note="foo", @@ -187,13 +194,13 @@ def test_shared_as_owner(self): self.assertEqual(table_dictionary["can_compute"], True) def test_shared_as_writer_with_compute(self): - upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + workspace = WorkspaceFactory.create() group = ManagedGroupFactory.create() sharing = WorkspaceGroupSharingFactory.create( - workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.WRITER, can_compute=True + workspace=workspace, group=group, access=WorkspaceGroupSharing.WRITER, can_compute=True ) instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( - workspace=upload_workspace.workspace, + workspace=workspace, managed_group=group, current_sharing_instance=sharing, note="foo", @@ -203,13 +210,13 @@ def test_shared_as_writer_with_compute(self): self.assertEqual(table_dictionary["can_compute"], True) def test_shared_as_writer_without_compute(self): - upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + workspace = WorkspaceFactory.create() group = ManagedGroupFactory.create() sharing = WorkspaceGroupSharingFactory.create( - workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.WRITER, can_compute=False + workspace=workspace, group=group, access=WorkspaceGroupSharing.WRITER, can_compute=False ) instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( - workspace=upload_workspace.workspace, + workspace=workspace, managed_group=group, current_sharing_instance=sharing, note="foo", @@ -219,13 +226,13 @@ def test_shared_as_writer_without_compute(self): self.assertEqual(table_dictionary["can_compute"], False) def test_shared_as_reader(self): - upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + workspace = WorkspaceFactory.create() group = ManagedGroupFactory.create() sharing = WorkspaceGroupSharingFactory.create( - workspace=upload_workspace.workspace, group=group, access=WorkspaceGroupSharing.READER + workspace=workspace, group=group, access=WorkspaceGroupSharing.READER ) instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( - workspace=upload_workspace.workspace, + workspace=workspace, managed_group=group, current_sharing_instance=sharing, note="foo", @@ -235,10 +242,10 @@ def test_shared_as_reader(self): self.assertIsNone(table_dictionary["can_compute"]) def test_not_shared(self): - upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + workspace = WorkspaceFactory.create() group = ManagedGroupFactory.create() instance = workspace_sharing_audit_results.WorkspaceSharingAuditResult( - workspace=upload_workspace.workspace, + workspace=workspace, managed_group=group, current_sharing_instance=None, note="foo", @@ -247,6 +254,681 @@ def test_not_shared(self): self.assertIsNone(table_dictionary["access"]) self.assertIsNone(table_dictionary["can_compute"]) + def test_handle_verified_shared(self): + workspace = WorkspaceFactory.create(name="test-ws") + group = ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(days=1) + with freeze_time(date_created): + sharing = WorkspaceGroupSharingFactory.create( + workspace=workspace, + group=group, + access=WorkspaceGroupSharing.READER, + ) + instance = workspace_sharing_audit_results.VerifiedShared( + workspace=workspace, + managed_group=group, + current_sharing_instance=sharing, + note="foo", + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.access, WorkspaceGroupSharing.READER) + self.assertEqual(sharing.created, date_created) + self.assertEqual(sharing.modified, date_created) + + def test_handle_verified_not_shared(self): + workspace = WorkspaceFactory.create(name="test-ws") + group = ManagedGroupFactory.create() + instance = workspace_sharing_audit_results.VerifiedNotShared( + workspace=workspace, + managed_group=group, + current_sharing_instance=None, + note="foo", + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 0) + + def test_handle_share_as_reader_new(self): + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") + group = ManagedGroupFactory.create() + instance = workspace_sharing_audit_results.ShareAsReader( + workspace=workspace, + managed_group=group, + current_sharing_instance=None, + note="foo", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "READER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 1) + sharing = WorkspaceGroupSharing.objects.first() + self.assertEqual(sharing.workspace, workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.access, WorkspaceGroupSharing.READER) + self.assertFalse(sharing.can_compute) + + def test_handle_share_as_reader_update(self): + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") + group = ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(days=1) + with freeze_time(date_created): + sharing = WorkspaceGroupSharingFactory.create( + workspace=workspace, + group=group, + access=WorkspaceGroupSharing.WRITER, + can_compute=True, + ) + instance = workspace_sharing_audit_results.ShareAsReader( + workspace=workspace, + managed_group=group, + current_sharing_instance=sharing, + note="foo", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "READER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.access, WorkspaceGroupSharing.READER) + self.assertFalse(sharing.can_compute) + self.assertEqual(sharing.created, date_created) + self.assertGreater(sharing.modified, date_created) + + def test_handle_share_as_writer_new(self): + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") + group = ManagedGroupFactory.create() + instance = workspace_sharing_audit_results.ShareAsWriter( + workspace=workspace, + managed_group=group, + current_sharing_instance=None, + note="foo", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 1) + sharing = WorkspaceGroupSharing.objects.first() + self.assertEqual(sharing.workspace, workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.access, WorkspaceGroupSharing.WRITER) + self.assertFalse(sharing.can_compute) + + def test_handle_share_as_writer_update(self): + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") + group = ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(days=1) + with freeze_time(date_created): + sharing = WorkspaceGroupSharingFactory.create( + workspace=workspace, + group=group, + access=WorkspaceGroupSharing.OWNER, + can_compute=True, + ) + instance = workspace_sharing_audit_results.ShareAsWriter( + workspace=workspace, + managed_group=group, + current_sharing_instance=sharing, + note="foo", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.access, WorkspaceGroupSharing.WRITER) + self.assertFalse(sharing.can_compute) + self.assertEqual(sharing.created, date_created) + self.assertGreater(sharing.modified, date_created) + + def test_handle_share_with_compute_new(self): + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") + group = ManagedGroupFactory.create() + instance = workspace_sharing_audit_results.ShareWithCompute( + workspace=workspace, + managed_group=group, + current_sharing_instance=None, + note="foo", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 1) + sharing = WorkspaceGroupSharing.objects.first() + self.assertEqual(sharing.workspace, workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.access, WorkspaceGroupSharing.WRITER) + self.assertTrue(sharing.can_compute) + + def test_handle_share_with_compute_update(self): + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") + group = ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(days=1) + with freeze_time(date_created): + sharing = WorkspaceGroupSharingFactory.create( + workspace=workspace, + group=group, + access=WorkspaceGroupSharing.READER, + can_compute=False, + ) + instance = workspace_sharing_audit_results.ShareWithCompute( + workspace=workspace, + managed_group=group, + current_sharing_instance=sharing, + note="foo", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "WRITER", + "canShare": False, + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.access, WorkspaceGroupSharing.WRITER) + self.assertTrue(sharing.can_compute) + self.assertEqual(sharing.created, date_created) + self.assertGreater(sharing.modified, date_created) + + def test_handle_share_as_owner_new(self): + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") + group = ManagedGroupFactory.create() + instance = workspace_sharing_audit_results.ShareAsOwner( + workspace=workspace, + managed_group=group, + current_sharing_instance=None, + note="foo", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "OWNER", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 1) + sharing = WorkspaceGroupSharing.objects.first() + self.assertEqual(sharing.workspace, workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.access, WorkspaceGroupSharing.OWNER) + self.assertTrue(sharing.can_compute) + + def test_handle_share_as_owner_update(self): + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") + group = ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(days=1) + with freeze_time(date_created): + sharing = WorkspaceGroupSharingFactory.create( + workspace=workspace, + group=group, + access=WorkspaceGroupSharing.READER, + can_compute=False, + ) + instance = workspace_sharing_audit_results.ShareAsOwner( + workspace=workspace, + managed_group=group, + current_sharing_instance=sharing, + note="foo", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "OWNER", + "canShare": False, # We're not tracking this in ACM so we always send False. + "canCompute": True, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 1) + sharing.refresh_from_db() + self.assertEqual(sharing.workspace, workspace) + self.assertEqual(sharing.group, group) + self.assertEqual(sharing.access, WorkspaceGroupSharing.OWNER) + self.assertTrue(sharing.can_compute) + self.assertEqual(sharing.created, date_created) + self.assertGreater(sharing.modified, date_created) + + def test_handle_stop_sharing(self): + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") + group = ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(days=1) + with freeze_time(date_created): + sharing = WorkspaceGroupSharingFactory.create( + workspace=workspace, + group=group, + access=WorkspaceGroupSharing.READER, + can_compute=False, + ) + instance = workspace_sharing_audit_results.StopSharing( + workspace=workspace, + managed_group=group, + current_sharing_instance=sharing, + note="foo", + ) + # Add the mocked API response. + acls = [ + { + "email": group.email, + "accessLevel": "NO ACCESS", + "canShare": False, + "canCompute": False, + } + ] + self.anvil_response_mock.add( + responses.PATCH, + self.api_client.rawls_entry_point + "/api/workspaces/test-bp/test-ws/acl?inviteUsersNotFound=false", + status=200, + match=[responses.matchers.json_params_matcher(acls)], + json={"invitesSent": {}, "usersNotFound": {}, "usersUpdated": acls}, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(WorkspaceGroupSharing.objects.count(), 0) + + +class WorkspaceAuthDomainAuditResultTest(AnVILAPIMockTestMixin, TestCase): + """General tests of the WorkspaceAuthDomainAuditResult dataclasses.""" + + def test_handle_verified_member(self): + workspace = WorkspaceFactory.create(name="test-ws") + WorkspaceAuthorizationDomainFactory.create(workspace=workspace, group__name="auth-test-ws") + group = ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(days=1) + with freeze_time(date_created): + membership = GroupGroupMembershipFactory.create( + parent_group=workspace.authorization_domains.first(), + child_group=group, + role=GroupGroupMembership.MEMBER, + ) + instance = workspace_auth_domain_audit_results.VerifiedMember( + workspace=workspace, + managed_group=group, + current_membership_instance=membership, + note="foo", + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.parent_group, workspace.authorization_domains.first()) + self.assertEqual(membership.child_group, group) + self.assertEqual(membership.role, GroupGroupMembership.MEMBER) + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + + def test_handle_verified_admin(self): + workspace = WorkspaceFactory.create(name="test-ws") + WorkspaceAuthorizationDomainFactory.create(workspace=workspace, group__name="auth-test-ws") + group = ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(days=1) + with freeze_time(date_created): + membership = GroupGroupMembershipFactory.create( + parent_group=workspace.authorization_domains.first(), child_group=group, role=GroupGroupMembership.ADMIN + ) + instance = workspace_auth_domain_audit_results.VerifiedAdmin( + workspace=workspace, + managed_group=group, + current_membership_instance=membership, + note="foo", + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(GroupGroupMembership.objects.count(), 1) + membership.refresh_from_db() + self.assertEqual(membership.parent_group, workspace.authorization_domains.first()) + self.assertEqual(membership.child_group, group) + self.assertEqual(membership.role, GroupGroupMembership.ADMIN) + self.assertEqual(membership.created, date_created) + self.assertEqual(membership.modified, date_created) + + def test_handle_verified_not_member(self): + workspace = WorkspaceFactory.create(name="test-ws") + WorkspaceAuthorizationDomainFactory.create(workspace=workspace, group__name="auth-test-ws") + group = ManagedGroupFactory.create() + instance = workspace_auth_domain_audit_results.VerifiedMember( + workspace=workspace, + managed_group=group, + current_membership_instance=None, + note="foo", + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(GroupGroupMembership.objects.count(), 0) + + def test_handle_add_member(self): + workspace = WorkspaceFactory.create(name="test-ws") + WorkspaceAuthorizationDomainFactory.create(workspace=workspace, group__name="auth-test-ws") + group = ManagedGroupFactory.create() + instance = workspace_auth_domain_audit_results.AddMember( + workspace=workspace, + managed_group=group, + current_membership_instance=None, + note="foo", + ) + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth-test-ws/member/{group.email}", + status=204, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(GroupGroupMembership.objects.count(), 1) + membership = GroupGroupMembership.objects.first() + self.assertEqual(membership.parent_group, workspace.authorization_domains.first()) + self.assertEqual(membership.child_group, group) + self.assertEqual(membership.role, GroupGroupMembership.MEMBER) + + def test_handle_add_admin(self): + workspace = WorkspaceFactory.create(name="test-ws") + WorkspaceAuthorizationDomainFactory.create(workspace=workspace, group__name="auth-test-ws") + group = ManagedGroupFactory.create() + instance = workspace_auth_domain_audit_results.AddAdmin( + workspace=workspace, + managed_group=group, + current_membership_instance=None, + note="foo", + ) + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth-test-ws/admin/{group.email}", + status=204, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(GroupGroupMembership.objects.count(), 1) + membership = GroupGroupMembership.objects.first() + self.assertEqual(membership.parent_group, workspace.authorization_domains.first()) + self.assertEqual(membership.child_group, group) + self.assertEqual(membership.role, GroupGroupMembership.ADMIN) + + def test_handle_change_to_member(self): + workspace = WorkspaceFactory.create(name="test-ws") + WorkspaceAuthorizationDomainFactory.create(workspace=workspace, group__name="auth-test-ws") + group = ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(days=1) + with freeze_time(date_created): + membership = GroupGroupMembershipFactory.create( + parent_group=workspace.authorization_domains.first(), + child_group=group, + role=GroupGroupMembership.ADMIN, + ) + instance = workspace_auth_domain_audit_results.ChangeToMember( + workspace=workspace, + managed_group=group, + current_membership_instance=membership, + note="foo", + ) + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth-test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth-test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(GroupGroupMembership.objects.count(), 1) + membership = GroupGroupMembership.objects.first() + self.assertEqual(membership.parent_group, workspace.authorization_domains.first()) + self.assertEqual(membership.child_group, group) + self.assertEqual(membership.role, GroupGroupMembership.MEMBER) + self.assertGreater(membership.modified, date_created) + + def test_handle_change_to_admin(self): + workspace = WorkspaceFactory.create(name="test-ws") + WorkspaceAuthorizationDomainFactory.create(workspace=workspace, group__name="auth-test-ws") + group = ManagedGroupFactory.create() + date_created = timezone.now() - timedelta(days=1) + with freeze_time(date_created): + membership = GroupGroupMembershipFactory.create( + parent_group=workspace.authorization_domains.first(), + child_group=group, + role=GroupGroupMembership.MEMBER, + ) + instance = workspace_auth_domain_audit_results.ChangeToAdmin( + workspace=workspace, + managed_group=group, + current_membership_instance=membership, + note="foo", + ) + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth-test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.anvil_response_mock.add( + responses.PUT, + self.api_client.sam_entry_point + f"/api/groups/v1/auth-test-ws/admin/{group.name}@firecloud.org", + status=204, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(GroupGroupMembership.objects.count(), 1) + membership = GroupGroupMembership.objects.first() + self.assertEqual(membership.parent_group, workspace.authorization_domains.first()) + self.assertEqual(membership.child_group, group) + self.assertEqual(membership.role, GroupGroupMembership.ADMIN) + self.assertGreater(membership.modified, date_created) + + def test_handle_remove(self): + workspace = WorkspaceFactory.create(name="test-ws") + WorkspaceAuthorizationDomainFactory.create(workspace=workspace, group__name="auth-test-ws") + group = ManagedGroupFactory.create() + membership = GroupGroupMembershipFactory.create( + parent_group=workspace.authorization_domains.first(), + child_group=group, + role=GroupGroupMembership.MEMBER, + ) + instance = workspace_auth_domain_audit_results.Remove( + workspace=workspace, + managed_group=group, + current_membership_instance=membership, + note="foo", + ) + # Add the mocked API response. + # Note that the auth domain group is created automatically by the factory using the workspace name. + self.anvil_response_mock.add( + responses.DELETE, + self.api_client.sam_entry_point + f"/api/groups/v1/auth-test-ws/member/{group.name}@firecloud.org", + status=204, + ) + self.assertFalse(instance.handled) + instance.handle() + self.assertTrue(instance.handled) + self.assertEqual(GroupGroupMembership.objects.count(), 0) + + def test_member_as_admin(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + membership = GroupGroupMembershipFactory.create( + parent_group=upload_workspace.workspace.authorization_domains.first(), + child_group=group, + role=GroupGroupMembership.ADMIN, + ) + instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( + workspace=upload_workspace.workspace, + managed_group=group, + current_membership_instance=membership, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertEqual(table_dictionary["role"], membership.ADMIN) + + def test_member_as_member(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + membership = GroupGroupMembershipFactory.create( + parent_group=upload_workspace.workspace.authorization_domains.first(), + child_group=group, + role=GroupGroupMembership.MEMBER, + ) + instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( + workspace=upload_workspace.workspace, + managed_group=group, + current_membership_instance=membership, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertEqual(table_dictionary["role"], membership.MEMBER) + + def test_not_member(self): + upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) + group = ManagedGroupFactory.create() + instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( + workspace=upload_workspace.workspace, + managed_group=group, + current_membership_instance=None, + note="foo", + ) + table_dictionary = instance.get_table_dictionary() + self.assertIsNone(table_dictionary["role"]) + class UploadWorkspaceSharingAuditTableTest(TestCase): """General tests of the UploadWorkspaceSharingAuditTable class.""" @@ -3967,56 +4649,6 @@ def test_other_group_shared_as_owner(self): self.assertEqual(record.note, upload_workspace_audit.UploadWorkspaceSharingAudit.OTHER_GROUP_NO_ACCESS) -class WorkspaceAuthDomainAuditResultTest(TestCase): - """General tests of the WorkspaceAuthDomainAuditResult dataclasses.""" - - def test_member_as_admin(self): - upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) - group = ManagedGroupFactory.create() - membership = GroupGroupMembershipFactory.create( - parent_group=upload_workspace.workspace.authorization_domains.first(), - child_group=group, - role=GroupGroupMembership.ADMIN, - ) - instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( - workspace=upload_workspace.workspace, - managed_group=group, - current_membership_instance=membership, - note="foo", - ) - table_dictionary = instance.get_table_dictionary() - self.assertEqual(table_dictionary["role"], membership.ADMIN) - - def test_member_as_member(self): - upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) - group = ManagedGroupFactory.create() - membership = GroupGroupMembershipFactory.create( - parent_group=upload_workspace.workspace.authorization_domains.first(), - child_group=group, - role=GroupGroupMembership.MEMBER, - ) - instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( - workspace=upload_workspace.workspace, - managed_group=group, - current_membership_instance=membership, - note="foo", - ) - table_dictionary = instance.get_table_dictionary() - self.assertEqual(table_dictionary["role"], membership.MEMBER) - - def test_not_member(self): - upload_workspace = factories.UploadWorkspaceFactory.create(upload_cycle__is_future=True) - group = ManagedGroupFactory.create() - instance = workspace_auth_domain_audit_results.WorkspaceAuthDomainAuditResult( - workspace=upload_workspace.workspace, - managed_group=group, - current_membership_instance=None, - note="foo", - ) - table_dictionary = instance.get_table_dictionary() - self.assertIsNone(table_dictionary["role"]) - - class UploadWorkspaceAuthDomainAuditTableTest(TestCase): """General tests of the UploadWorkspaceAuthDomainAuditTable class.""" diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index 343adf0b..f8c37741 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -6,10 +6,8 @@ from anvil_consortium_manager.exceptions import AnVILGroupNotFound from anvil_consortium_manager.models import ( Account, - GroupGroupMembership, ManagedGroup, Workspace, - WorkspaceGroupSharing, ) from django.contrib import messages from django.contrib.auth import get_user_model @@ -28,8 +26,6 @@ from .audit import ( combined_workspace_audit, upload_workspace_audit, - workspace_auth_domain_audit_results, - workspace_sharing_audit_results, ) User = get_user_model() @@ -336,40 +332,8 @@ def get_success_url(self): def form_valid(self, form): # Handle the result. try: - # Set up the sharing instance. - if self.audit_result.current_sharing_instance: - sharing = self.audit_result.current_sharing_instance - else: - sharing = WorkspaceGroupSharing( - workspace=self.upload_workspace.workspace, - group=self.managed_group, - ) with transaction.atomic(): - if isinstance(self.audit_result, workspace_sharing_audit_results.VerifiedShared): - # No changes needed. - pass - elif isinstance(self.audit_result, workspace_sharing_audit_results.VerifiedNotShared): - # No changes needed. - pass - elif isinstance(self.audit_result, workspace_sharing_audit_results.StopSharing): - sharing.anvil_delete() - sharing.delete() - else: - if isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsReader): - sharing.access = WorkspaceGroupSharing.READER - sharing.can_compute = False - elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsWriter): - sharing.access = WorkspaceGroupSharing.WRITER - sharing.can_compute = False - elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareWithCompute): - sharing.access = WorkspaceGroupSharing.WRITER - sharing.can_compute = True - elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsOwner): - sharing.access = WorkspaceGroupSharing.OWNER - sharing.can_compute = True - sharing.full_clean() - sharing.save() - sharing.anvil_create_or_update() + self.audit_result.handle() except (AnVILAPIError, AnVILGroupNotFound) as e: if self.request.htmx: return HttpResponse(self.htmx_error) @@ -526,39 +490,7 @@ def form_valid(self, form): # Handle the result. try: with transaction.atomic(): - # Set up the membership instance. - if self.audit_result.current_membership_instance: - membership = self.audit_result.current_membership_instance - else: - membership = GroupGroupMembership( - parent_group=self.upload_workspace.workspace.authorization_domains.first(), - child_group=self.managed_group, - ) - # Now process the result. - if isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedMember): - pass - elif isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedAdmin): - pass - elif isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedNotMember): - pass - elif isinstance(self.audit_result, workspace_auth_domain_audit_results.Remove): - membership.anvil_delete() - membership.delete() - else: - if isinstance(self.audit_result, workspace_auth_domain_audit_results.ChangeToMember): - membership.anvil_delete() - membership.role = GroupGroupMembership.MEMBER - elif isinstance(self.audit_result, workspace_auth_domain_audit_results.ChangeToAdmin): - membership.anvil_delete() - membership.role = GroupGroupMembership.ADMIN - else: - if isinstance(self.audit_result, workspace_auth_domain_audit_results.AddMember): - membership.role = GroupGroupMembership.MEMBER - elif isinstance(self.audit_result, workspace_auth_domain_audit_results.AddAdmin): - membership.role = GroupGroupMembership.ADMIN - membership.full_clean() - membership.save() - membership.anvil_create() + self.audit_result.handle() except (AnVILAPIError, AnVILGroupNotFound) as e: if self.request.htmx: return HttpResponse(self.htmx_error) @@ -686,40 +618,8 @@ def get_success_url(self): def form_valid(self, form): # Handle the result. try: - # Set up the sharing instance. - if self.audit_result.current_sharing_instance: - sharing = self.audit_result.current_sharing_instance - else: - sharing = WorkspaceGroupSharing( - workspace=self.combined_workspace.workspace, - group=self.managed_group, - ) with transaction.atomic(): - if isinstance(self.audit_result, workspace_sharing_audit_results.VerifiedShared): - # No changes needed. - pass - elif isinstance(self.audit_result, workspace_sharing_audit_results.VerifiedNotShared): - # No changes needed. - pass - elif isinstance(self.audit_result, workspace_sharing_audit_results.StopSharing): - sharing.anvil_delete() - sharing.delete() - else: - if isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsReader): - sharing.access = WorkspaceGroupSharing.READER - sharing.can_compute = False - elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsWriter): - sharing.access = WorkspaceGroupSharing.WRITER - sharing.can_compute = False - elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareWithCompute): - sharing.access = WorkspaceGroupSharing.WRITER - sharing.can_compute = True - elif isinstance(self.audit_result, workspace_sharing_audit_results.ShareAsOwner): - sharing.access = WorkspaceGroupSharing.OWNER - sharing.can_compute = True - sharing.full_clean() - sharing.save() - sharing.anvil_create_or_update() + self.audit_result.handle() except (AnVILAPIError, AnVILGroupNotFound) as e: if self.request.htmx: return HttpResponse(self.htmx_error) @@ -849,39 +749,7 @@ def form_valid(self, form): # Handle the result. try: with transaction.atomic(): - # Set up the membership instance. - if self.audit_result.current_membership_instance: - membership = self.audit_result.current_membership_instance - else: - membership = GroupGroupMembership( - parent_group=self.workspace.workspace.authorization_domains.first(), - child_group=self.managed_group, - ) - # Now process the result. - if isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedMember): - pass - elif isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedAdmin): - pass - elif isinstance(self.audit_result, workspace_auth_domain_audit_results.VerifiedNotMember): - pass - elif isinstance(self.audit_result, workspace_auth_domain_audit_results.Remove): - membership.anvil_delete() - membership.delete() - else: - if isinstance(self.audit_result, workspace_auth_domain_audit_results.ChangeToMember): - membership.anvil_delete() - membership.role = GroupGroupMembership.MEMBER - elif isinstance(self.audit_result, workspace_auth_domain_audit_results.ChangeToAdmin): - membership.anvil_delete() - membership.role = GroupGroupMembership.ADMIN - else: - if isinstance(self.audit_result, workspace_auth_domain_audit_results.AddMember): - membership.role = GroupGroupMembership.MEMBER - elif isinstance(self.audit_result, workspace_auth_domain_audit_results.AddAdmin): - membership.role = GroupGroupMembership.ADMIN - membership.full_clean() - membership.save() - membership.anvil_create() + self.audit_result.handle() except (AnVILAPIError, AnVILGroupNotFound) as e: if self.request.htmx: return HttpResponse(self.htmx_error) From 23ff9b206b677c6cdf18a73e3759461f9a48e4aa Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 15 Oct 2024 11:26:09 -0700 Subject: [PATCH 68/97] Add a view mixin for audit resolve views Use the new mixin in the existing views. --- gregor_django/gregor_anvil/viewmixins.py | 64 +++++++ gregor_django/gregor_anvil/views.py | 227 +++-------------------- 2 files changed, 85 insertions(+), 206 deletions(-) diff --git a/gregor_django/gregor_anvil/viewmixins.py b/gregor_django/gregor_anvil/viewmixins.py index 4eba88f8..37d2c48b 100644 --- a/gregor_django/gregor_anvil/viewmixins.py +++ b/gregor_django/gregor_anvil/viewmixins.py @@ -1,3 +1,13 @@ +from anvil_consortium_manager.anvil_api import AnVILAPIError +from anvil_consortium_manager.exceptions import AnVILGroupNotFound +from anvil_consortium_manager.models import ( + ManagedGroup, +) +from django.contrib import messages +from django.db import transaction +from django.http import Http404, HttpResponse + + class AuditMixin: """Mixin to assist with auditing views.""" @@ -14,3 +24,57 @@ def get_context_data(self, **kwargs): context["needs_action_table"] = audit_results.get_needs_action_table() context["audit_results"] = audit_results return context + + +class AuditResolveMixin: + """Mixin to assist with audit resolution views.""" + + def get_workspace_data_object(self): + raise NotImplementedError("AuditResolveMixin.get_workspace_data_object() must be implemented in a subclass") + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["workspace_data_object"] = self.workspace_data_object + context["managed_group"] = self.managed_group + context["audit_result"] = self.audit_result + return context + + def get_managed_group(self, queryset=None): + """Look up the ManagedGroup by name.""" + try: + obj = ManagedGroup.objects.get(name=self.kwargs.get("managed_group_slug", None)) + except ManagedGroup.DoesNotExist: + raise Http404("No ManagedGroups found matching the query") + return obj + + def get(self, request, *args, **kwargs): + self.workspace_data_object = self.get_workspace_data_object() + self.managed_group = self.get_managed_group() + self.audit_result = self.get_audit_result() + return super().get(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + self.workspace_data_object = self.get_workspace_data_object() + self.managed_group = self.get_managed_group() + self.audit_result = self.get_audit_result() + return super().post(request, *args, **kwargs) + + def form_valid(self, form): + # Handle the result. + try: + with transaction.atomic(): + self.audit_result.handle() + except (AnVILAPIError, AnVILGroupNotFound) as e: + if self.request.htmx: + return HttpResponse(self.htmx_error) + else: + messages.error(self.request, "AnVIL API Error: " + str(e)) + return super().form_invalid(form) + # Otherwise, the audit resolution succeeded. + if self.request.htmx: + return HttpResponse(self.htmx_success) + else: + return super().form_valid(form) + + def get_success_url(self): + return self.workspace_data_object.get_absolute_url() diff --git a/gregor_django/gregor_anvil/views.py b/gregor_django/gregor_anvil/views.py index f8c37741..0b138be3 100644 --- a/gregor_django/gregor_anvil/views.py +++ b/gregor_django/gregor_anvil/views.py @@ -1,21 +1,16 @@ -from anvil_consortium_manager.anvil_api import AnVILAPIError from anvil_consortium_manager.auth import ( AnVILConsortiumManagerStaffEditRequired, AnVILConsortiumManagerStaffViewRequired, ) -from anvil_consortium_manager.exceptions import AnVILGroupNotFound from anvil_consortium_manager.models import ( Account, - ManagedGroup, Workspace, ) -from django.contrib import messages from django.contrib.auth import get_user_model from django.contrib.messages.views import SuccessMessageMixin -from django.db import transaction from django.db.models import Count, Q from django.forms import Form -from django.http import Http404, HttpResponse +from django.http import Http404 from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView, DetailView, FormView, TemplateView, UpdateView from django_tables2 import MultiTableMixin, SingleTableView @@ -265,7 +260,9 @@ def run_audit(self, **kwargs): return audit -class UploadWorkspaceSharingAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): +class UploadWorkspaceSharingAuditResolve( + AnVILConsortiumManagerStaffEditRequired, viewmixins.AuditResolveMixin, FormView +): """View to resolve UploadWorkspace audit results.""" form_class = Form @@ -273,7 +270,7 @@ class UploadWorkspaceSharingAuditResolve(AnVILConsortiumManagerStaffEditRequired htmx_success = """ Handled!""" htmx_error = """ Error!""" - def get_upload_workspace(self): + def get_workspace_data_object(self): """Look up the UploadWorkspace by billing project and name.""" # Filter the queryset based on kwargs. billing_project_slug = self.kwargs.get("billing_project_slug", None) @@ -291,61 +288,14 @@ def get_upload_workspace(self): ) return obj - def get_managed_group(self, queryset=None): - """Look up the ManagedGroup by name.""" - try: - obj = ManagedGroup.objects.get(name=self.kwargs.get("managed_group_slug", None)) - except ManagedGroup.DoesNotExist: - raise Http404("No ManagedGroups found matching the query") - return obj - def get_audit_result(self): audit = upload_workspace_audit.UploadWorkspaceSharingAudit() # No way to set the group queryset, since it is dynamically determined by the workspace. - audit.audit_workspace_and_group(self.upload_workspace, self.managed_group) + audit.audit_workspace_and_group(self.workspace_data_object, self.managed_group) # Set to completed, because we are just running this one specific check. audit.completed = True return audit.get_all_results()[0] - def get(self, request, *args, **kwargs): - self.upload_workspace = self.get_upload_workspace() - self.managed_group = self.get_managed_group() - self.audit_result = self.get_audit_result() - return super().get(request, *args, **kwargs) - - def post(self, request, *args, **kwargs): - self.upload_workspace = self.get_upload_workspace() - self.managed_group = self.get_managed_group() - self.audit_result = self.get_audit_result() - return super().post(request, *args, **kwargs) - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context["upload_workspace"] = self.upload_workspace - context["managed_group"] = self.managed_group - context["audit_result"] = self.audit_result - return context - - def get_success_url(self): - return self.upload_workspace.get_absolute_url() - - def form_valid(self, form): - # Handle the result. - try: - with transaction.atomic(): - self.audit_result.handle() - except (AnVILAPIError, AnVILGroupNotFound) as e: - if self.request.htmx: - return HttpResponse(self.htmx_error) - else: - messages.error(self.request, "AnVIL API Error: " + str(e)) - return super().form_invalid(form) - # Otherwise, the audit resolution succeeded. - if self.request.htmx: - return HttpResponse(self.htmx_success) - else: - return super().form_valid(form) - class UploadWorkspaceAuthDomainAudit(AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, TemplateView): """View to audit UploadWorkspace auth domain membership for all UploadWorkspaces.""" @@ -422,7 +372,9 @@ def run_audit(self, **kwargs): return audit -class UploadWorkspaceAuthDomainAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): +class UploadWorkspaceAuthDomainAuditResolve( + AnVILConsortiumManagerStaffEditRequired, viewmixins.AuditResolveMixin, FormView +): """View to resolve UploadWorkspace auth domain audit results.""" form_class = Form @@ -430,7 +382,7 @@ class UploadWorkspaceAuthDomainAuditResolve(AnVILConsortiumManagerStaffEditRequi htmx_success = """ Handled!""" htmx_error = """ Error!""" - def get_upload_workspace(self): + def get_workspace_data_object(self): """Look up the UploadWorkspace by billing project and name.""" # Filter the queryset based on kwargs. billing_project_slug = self.kwargs.get("billing_project_slug", None) @@ -448,61 +400,14 @@ def get_upload_workspace(self): ) return obj - def get_managed_group(self, queryset=None): - """Look up the ManagedGroup by name.""" - try: - obj = ManagedGroup.objects.get(name=self.kwargs.get("managed_group_slug", None)) - except ManagedGroup.DoesNotExist: - raise Http404("No ManagedGroups found matching the query") - return obj - def get_audit_result(self): audit = upload_workspace_audit.UploadWorkspaceAuthDomainAudit() # No way to set the group queryset, since it is dynamically determined by the workspace. - audit.audit_workspace_and_group(self.upload_workspace, self.managed_group) + audit.audit_workspace_and_group(self.workspace_data_object, self.managed_group) # Set to completed, because we are just running this one specific check. audit.completed = True return audit.get_all_results()[0] - def get(self, request, *args, **kwargs): - self.upload_workspace = self.get_upload_workspace() - self.managed_group = self.get_managed_group() - self.audit_result = self.get_audit_result() - return super().get(request, *args, **kwargs) - - def post(self, request, *args, **kwargs): - self.upload_workspace = self.get_upload_workspace() - self.managed_group = self.get_managed_group() - self.audit_result = self.get_audit_result() - return super().post(request, *args, **kwargs) - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context["upload_workspace"] = self.upload_workspace - context["managed_group"] = self.managed_group - context["audit_result"] = self.audit_result - return context - - def get_success_url(self): - return self.upload_workspace.get_absolute_url() - - def form_valid(self, form): - # Handle the result. - try: - with transaction.atomic(): - self.audit_result.handle() - except (AnVILAPIError, AnVILGroupNotFound) as e: - if self.request.htmx: - return HttpResponse(self.htmx_error) - else: - messages.error(self.request, "AnVIL API Error: " + str(e)) - return super().form_invalid(form) - # Otherwise, the audit resolution succeeded. - if self.request.htmx: - return HttpResponse(self.htmx_success) - else: - return super().form_valid(form) - class CombinedConsortiumDataWorkspaceSharingAudit( AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, TemplateView @@ -551,7 +456,9 @@ def run_audit(self, **kwargs): return audit -class CombinedConsortiumDataWorkspaceSharingAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): +class CombinedConsortiumDataWorkspaceSharingAuditResolve( + AnVILConsortiumManagerStaffEditRequired, viewmixins.AuditResolveMixin, FormView +): """View to resolve CombinedConsortiumDataWorkspace audit results.""" form_class = Form @@ -559,7 +466,7 @@ class CombinedConsortiumDataWorkspaceSharingAuditResolve(AnVILConsortiumManagerS htmx_success = """ Handled!""" htmx_error = """ Error!""" - def get_combined_workspace(self): + def get_workspace_data_object(self): """Look up the CombinedConsortiumDataWorkspace by billing project and name.""" # Filter the queryset based on kwargs. billing_project_slug = self.kwargs.get("billing_project_slug", None) @@ -577,61 +484,14 @@ def get_combined_workspace(self): ) return obj - def get_managed_group(self, queryset=None): - """Look up the ManagedGroup by name.""" - try: - obj = ManagedGroup.objects.get(name=self.kwargs.get("managed_group_slug", None)) - except ManagedGroup.DoesNotExist: - raise Http404("No ManagedGroups found matching the query") - return obj - def get_audit_result(self): audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit() # No way to set the group queryset, since it is dynamically determined by the workspace. - audit.audit_workspace_and_group(self.combined_workspace, self.managed_group) + audit.audit_workspace_and_group(self.workspace_data_object, self.managed_group) # Set to completed, because we are just running this one specific check. audit.completed = True return audit.get_all_results()[0] - def get(self, request, *args, **kwargs): - self.combined_workspace = self.get_combined_workspace() - self.managed_group = self.get_managed_group() - self.audit_result = self.get_audit_result() - return super().get(request, *args, **kwargs) - - def post(self, request, *args, **kwargs): - self.combined_workspace = self.get_combined_workspace() - self.managed_group = self.get_managed_group() - self.audit_result = self.get_audit_result() - return super().post(request, *args, **kwargs) - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context["combined_workspace"] = self.combined_workspace - context["managed_group"] = self.managed_group - context["audit_result"] = self.audit_result - return context - - def get_success_url(self): - return self.combined_workspace.get_absolute_url() - - def form_valid(self, form): - # Handle the result. - try: - with transaction.atomic(): - self.audit_result.handle() - except (AnVILAPIError, AnVILGroupNotFound) as e: - if self.request.htmx: - return HttpResponse(self.htmx_error) - else: - messages.error(self.request, "AnVIL API Error: " + str(e)) - return super().form_invalid(form) - # Otherwise, the audit resolution succeeded. - if self.request.htmx: - return HttpResponse(self.htmx_success) - else: - return super().form_valid(form) - class CombinedConsortiumDataWorkspaceAuthDomainAudit( AnVILConsortiumManagerStaffViewRequired, viewmixins.AuditMixin, TemplateView @@ -681,7 +541,9 @@ def run_audit(self, **kwargs): return audit -class CombinedConsortiumDataWorkspaceAuthDomainAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): +class CombinedConsortiumDataWorkspaceAuthDomainAuditResolve( + AnVILConsortiumManagerStaffEditRequired, viewmixins.AuditResolveMixin, FormView +): """View to resolve UploadWorkspace auth domain audit results.""" form_class = Form @@ -689,7 +551,7 @@ class CombinedConsortiumDataWorkspaceAuthDomainAuditResolve(AnVILConsortiumManag htmx_success = """ Handled!""" htmx_error = """ Error!""" - def get_workspace(self): + def get_workspace_data_object(self): """Look up the CombinedConsortiumDataWorkspace by billing project and name.""" # Filter the queryset based on kwargs. billing_project_slug = self.kwargs.get("billing_project_slug", None) @@ -707,57 +569,10 @@ def get_workspace(self): ) return obj - def get_managed_group(self, queryset=None): - """Look up the ManagedGroup by name.""" - try: - obj = ManagedGroup.objects.get(name=self.kwargs.get("managed_group_slug", None)) - except ManagedGroup.DoesNotExist: - raise Http404("No ManagedGroups found matching the query") - return obj - def get_audit_result(self): audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit() # No way to set the group queryset, since it is dynamically determined by the workspace. - audit.audit_workspace_and_group(self.workspace, self.managed_group) + audit.audit_workspace_and_group(self.workspace_data_object, self.managed_group) # Set to completed, because we are just running this one specific check. audit.completed = True return audit.get_all_results()[0] - - def get(self, request, *args, **kwargs): - self.workspace = self.get_workspace() - self.managed_group = self.get_managed_group() - self.audit_result = self.get_audit_result() - return super().get(request, *args, **kwargs) - - def post(self, request, *args, **kwargs): - self.workspace = self.get_workspace() - self.managed_group = self.get_managed_group() - self.audit_result = self.get_audit_result() - return super().post(request, *args, **kwargs) - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context["workspace"] = self.workspace - context["managed_group"] = self.managed_group - context["audit_result"] = self.audit_result - return context - - def get_success_url(self): - return self.workspace.get_absolute_url() - - def form_valid(self, form): - # Handle the result. - try: - with transaction.atomic(): - self.audit_result.handle() - except (AnVILAPIError, AnVILGroupNotFound) as e: - if self.request.htmx: - return HttpResponse(self.htmx_error) - else: - messages.error(self.request, "AnVIL API Error: " + str(e)) - return super().form_invalid(form) - # Otherwise, the audit resolution succeeded. - if self.request.htmx: - return HttpResponse(self.htmx_success) - else: - return super().form_valid(form) From 94058f98796cb7e8478b0550b1b0a57083235c80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 19:50:08 +0000 Subject: [PATCH 69/97] Bump sphinx from 8.0.2 to 8.1.3 Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 8.0.2 to 8.1.3. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES.rst) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v8.0.2...v8.1.3) --- updated-dependencies: - dependency-name: sphinx dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 132223a6..fcd7f3c7 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -161,21 +161,21 @@ sniffio==1.3.1 # via anyio snowballstemmer==2.2.0 # via sphinx -sphinx==8.0.2 +sphinx==8.1.3 # via # -r requirements/dev-requirements.in # sphinx-autobuild sphinx-autobuild==2024.10.3 # via -r requirements/dev-requirements.in -sphinxcontrib-applehelp==1.0.4 +sphinxcontrib-applehelp==2.0.0 # via sphinx -sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-devhelp==2.0.0 # via sphinx -sphinxcontrib-htmlhelp==2.0.1 +sphinxcontrib-htmlhelp==2.1.0 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-qthelp==2.0.0 # via sphinx sphinxcontrib-serializinghtml==2.0.0 # via sphinx From 61eabea281a8f6ec4c29fcc3188bb1b65f4958f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 19:50:10 +0000 Subject: [PATCH 70/97] Bump starlette from 0.38.2 to 0.40.0 in /requirements Bumps [starlette](https://github.com/encode/starlette) from 0.38.2 to 0.40.0. - [Release notes](https://github.com/encode/starlette/releases) - [Changelog](https://github.com/encode/starlette/blob/master/docs/release-notes.md) - [Commits](https://github.com/encode/starlette/compare/0.38.2...0.40.0) --- updated-dependencies: - dependency-name: starlette dependency-type: indirect ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 70 +++++++++++++++---------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 132223a6..3927dc49 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -12,7 +12,7 @@ anyio==4.4.0 # watchfiles asgiref==3.8.1 # via - # -c requirements/requirements.txt + # -c requirements.txt # django astroid==3.1.0 # via pylint @@ -24,19 +24,19 @@ backcall==0.2.0 # via ipython certifi==2024.7.4 # via - # -c requirements/requirements.txt - # -c requirements/test-requirements.txt + # -c requirements.txt + # -c test-requirements.txt # requests cfgv==3.4.0 # via pre-commit charset-normalizer==3.3.2 # via - # -c requirements/requirements.txt - # -c requirements/test-requirements.txt + # -c requirements.txt + # -c test-requirements.txt # requests click==8.1.7 # via - # -c requirements/requirements.txt + # -c requirements.txt # uvicorn colorama==0.4.6 # via sphinx-autobuild @@ -50,21 +50,21 @@ distlib==0.3.8 # via virtualenv django==4.2.16 # via - # -c requirements/requirements.txt + # -c requirements.txt # django-debug-toolbar # django-stubs # django-stubs-ext django-debug-toolbar==4.4.6 - # via -r requirements/dev-requirements.in + # via -r dev-requirements.in django-stubs==4.2.7 - # via -r requirements/dev-requirements.in + # via -r dev-requirements.in django-stubs-ext==5.0.0 # via django-stubs docutils==0.20.1 # via sphinx exceptiongroup==1.2.0 # via - # -c requirements/test-requirements.txt + # -c test-requirements.txt # anyio executing==2.0.1 # via stack-data @@ -76,14 +76,14 @@ identify==2.5.35 # via pre-commit idna==3.7 # via - # -c requirements/requirements.txt - # -c requirements/test-requirements.txt + # -c requirements.txt + # -c test-requirements.txt # anyio # requests imagesize==1.4.1 # via sphinx ipdb==0.13.13 - # via -r requirements/dev-requirements.in + # via -r dev-requirements.in ipython==8.12.3 # via ipdb isort==5.13.2 @@ -101,15 +101,15 @@ matplotlib-inline==0.1.6 mccabe==0.7.0 # via pylint mypy==1.11.2 - # via -r requirements/dev-requirements.in + # via -r dev-requirements.in mypy-extensions==1.0.0 # via mypy nodeenv==1.8.0 # via pre-commit packaging==23.2 # via - # -c requirements/requirements.txt - # -c requirements/test-requirements.txt + # -c requirements.txt + # -c test-requirements.txt # sphinx parso==0.8.3 # via jedi @@ -122,7 +122,7 @@ platformdirs==4.2.0 # pylint # virtualenv pre-commit==3.8.0 - # via -r requirements/dev-requirements.in + # via -r dev-requirements.in prompt-toolkit==3.0.43 # via ipython ptyprocess==0.7.0 @@ -138,24 +138,24 @@ pylint==3.1.0 # pylint-django # pylint-plugin-utils pylint-django==2.5.5 - # via -r requirements/dev-requirements.in + # via -r dev-requirements.in pylint-plugin-utils==0.8.2 # via pylint-django pyyaml==6.0.1 # via - # -c requirements/test-requirements.txt + # -c test-requirements.txt # pre-commit requests==2.32.3 # via - # -c requirements/requirements.txt - # -c requirements/test-requirements.txt + # -c requirements.txt + # -c test-requirements.txt # sphinx ruff==0.6.9 - # via -r requirements/dev-requirements.in + # via -r dev-requirements.in six==1.16.0 # via - # -c requirements/requirements.txt - # -c requirements/test-requirements.txt + # -c requirements.txt + # -c test-requirements.txt # asttokens sniffio==1.3.1 # via anyio @@ -163,10 +163,10 @@ snowballstemmer==2.2.0 # via sphinx sphinx==8.0.2 # via - # -r requirements/dev-requirements.in + # -r dev-requirements.in # sphinx-autobuild sphinx-autobuild==2024.10.3 - # via -r requirements/dev-requirements.in + # via -r dev-requirements.in sphinxcontrib-applehelp==1.0.4 # via sphinx sphinxcontrib-devhelp==1.0.2 @@ -181,17 +181,17 @@ sphinxcontrib-serializinghtml==2.0.0 # via sphinx sqlparse==0.5.1 # via - # -c requirements/requirements.txt + # -c requirements.txt # django # django-debug-toolbar stack-data==0.6.3 # via ipython -starlette==0.38.2 +starlette==0.40.0 # via sphinx-autobuild tomli==2.0.1 # via - # -c requirements/requirements.txt - # -c requirements/test-requirements.txt + # -c requirements.txt + # -c test-requirements.txt # django-stubs # ipdb # mypy @@ -209,8 +209,8 @@ types-pyyaml==6.0.12.12 # via django-stubs typing-extensions==4.8.0 # via - # -c requirements/requirements.txt - # -c requirements/test-requirements.txt + # -c requirements.txt + # -c test-requirements.txt # anyio # asgiref # astroid @@ -220,8 +220,8 @@ typing-extensions==4.8.0 # uvicorn urllib3==2.2.2 # via - # -c requirements/requirements.txt - # -c requirements/test-requirements.txt + # -c requirements.txt + # -c test-requirements.txt # requests uvicorn==0.30.5 # via sphinx-autobuild @@ -234,7 +234,7 @@ wcwidth==0.2.13 websockets==12.0 # via sphinx-autobuild werkzeug==3.0.4 - # via -r requirements/dev-requirements.in + # via -r dev-requirements.in # The following packages are considered to be unsafe in a requirements file: # setuptools From c42b072484ae738eeb7d535a6be1a5b2ec260dc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 19:50:14 +0000 Subject: [PATCH 71/97] Bump mypy from 1.11.2 to 1.12.0 Bumps [mypy](https://github.com/python/mypy) from 1.11.2 to 1.12.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.11.2...v1.12.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 132223a6..fc40dd21 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -100,7 +100,7 @@ matplotlib-inline==0.1.6 # via ipython mccabe==0.7.0 # via pylint -mypy==1.11.2 +mypy==1.12.0 # via -r requirements/dev-requirements.in mypy-extensions==1.0.0 # via mypy From c4361287401226f33ddda025c9a0ece60e2f4836 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 19:50:54 +0000 Subject: [PATCH 72/97] Compile requirements files --- requirements/dev-requirements.txt | 68 +++++++++++++++---------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 3927dc49..83a40d48 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -12,7 +12,7 @@ anyio==4.4.0 # watchfiles asgiref==3.8.1 # via - # -c requirements.txt + # -c requirements/requirements.txt # django astroid==3.1.0 # via pylint @@ -24,19 +24,19 @@ backcall==0.2.0 # via ipython certifi==2024.7.4 # via - # -c requirements.txt - # -c test-requirements.txt + # -c requirements/requirements.txt + # -c requirements/test-requirements.txt # requests cfgv==3.4.0 # via pre-commit charset-normalizer==3.3.2 # via - # -c requirements.txt - # -c test-requirements.txt + # -c requirements/requirements.txt + # -c requirements/test-requirements.txt # requests click==8.1.7 # via - # -c requirements.txt + # -c requirements/requirements.txt # uvicorn colorama==0.4.6 # via sphinx-autobuild @@ -50,21 +50,21 @@ distlib==0.3.8 # via virtualenv django==4.2.16 # via - # -c requirements.txt + # -c requirements/requirements.txt # django-debug-toolbar # django-stubs # django-stubs-ext django-debug-toolbar==4.4.6 - # via -r dev-requirements.in + # via -r requirements/dev-requirements.in django-stubs==4.2.7 - # via -r dev-requirements.in + # via -r requirements/dev-requirements.in django-stubs-ext==5.0.0 # via django-stubs docutils==0.20.1 # via sphinx exceptiongroup==1.2.0 # via - # -c test-requirements.txt + # -c requirements/test-requirements.txt # anyio executing==2.0.1 # via stack-data @@ -76,14 +76,14 @@ identify==2.5.35 # via pre-commit idna==3.7 # via - # -c requirements.txt - # -c test-requirements.txt + # -c requirements/requirements.txt + # -c requirements/test-requirements.txt # anyio # requests imagesize==1.4.1 # via sphinx ipdb==0.13.13 - # via -r dev-requirements.in + # via -r requirements/dev-requirements.in ipython==8.12.3 # via ipdb isort==5.13.2 @@ -101,15 +101,15 @@ matplotlib-inline==0.1.6 mccabe==0.7.0 # via pylint mypy==1.11.2 - # via -r dev-requirements.in + # via -r requirements/dev-requirements.in mypy-extensions==1.0.0 # via mypy nodeenv==1.8.0 # via pre-commit packaging==23.2 # via - # -c requirements.txt - # -c test-requirements.txt + # -c requirements/requirements.txt + # -c requirements/test-requirements.txt # sphinx parso==0.8.3 # via jedi @@ -122,7 +122,7 @@ platformdirs==4.2.0 # pylint # virtualenv pre-commit==3.8.0 - # via -r dev-requirements.in + # via -r requirements/dev-requirements.in prompt-toolkit==3.0.43 # via ipython ptyprocess==0.7.0 @@ -138,24 +138,24 @@ pylint==3.1.0 # pylint-django # pylint-plugin-utils pylint-django==2.5.5 - # via -r dev-requirements.in + # via -r requirements/dev-requirements.in pylint-plugin-utils==0.8.2 # via pylint-django pyyaml==6.0.1 # via - # -c test-requirements.txt + # -c requirements/test-requirements.txt # pre-commit requests==2.32.3 # via - # -c requirements.txt - # -c test-requirements.txt + # -c requirements/requirements.txt + # -c requirements/test-requirements.txt # sphinx ruff==0.6.9 - # via -r dev-requirements.in + # via -r requirements/dev-requirements.in six==1.16.0 # via - # -c requirements.txt - # -c test-requirements.txt + # -c requirements/requirements.txt + # -c requirements/test-requirements.txt # asttokens sniffio==1.3.1 # via anyio @@ -163,10 +163,10 @@ snowballstemmer==2.2.0 # via sphinx sphinx==8.0.2 # via - # -r dev-requirements.in + # -r requirements/dev-requirements.in # sphinx-autobuild sphinx-autobuild==2024.10.3 - # via -r dev-requirements.in + # via -r requirements/dev-requirements.in sphinxcontrib-applehelp==1.0.4 # via sphinx sphinxcontrib-devhelp==1.0.2 @@ -181,7 +181,7 @@ sphinxcontrib-serializinghtml==2.0.0 # via sphinx sqlparse==0.5.1 # via - # -c requirements.txt + # -c requirements/requirements.txt # django # django-debug-toolbar stack-data==0.6.3 @@ -190,8 +190,8 @@ starlette==0.40.0 # via sphinx-autobuild tomli==2.0.1 # via - # -c requirements.txt - # -c test-requirements.txt + # -c requirements/requirements.txt + # -c requirements/test-requirements.txt # django-stubs # ipdb # mypy @@ -209,8 +209,8 @@ types-pyyaml==6.0.12.12 # via django-stubs typing-extensions==4.8.0 # via - # -c requirements.txt - # -c test-requirements.txt + # -c requirements/requirements.txt + # -c requirements/test-requirements.txt # anyio # asgiref # astroid @@ -220,8 +220,8 @@ typing-extensions==4.8.0 # uvicorn urllib3==2.2.2 # via - # -c requirements.txt - # -c test-requirements.txt + # -c requirements/requirements.txt + # -c requirements/test-requirements.txt # requests uvicorn==0.30.5 # via sphinx-autobuild @@ -234,7 +234,7 @@ wcwidth==0.2.13 websockets==12.0 # via sphinx-autobuild werkzeug==3.0.4 - # via -r dev-requirements.in + # via -r requirements/dev-requirements.in # The following packages are considered to be unsafe in a requirements file: # setuptools From f06f15d8cf9f2dcd904bc88cd490d707041f1bf5 Mon Sep 17 00:00:00 2001 From: Jonas Carson Date: Wed, 16 Oct 2024 08:22:18 -0700 Subject: [PATCH 73/97] Fix issue where id token was changing when test past second boundary. Use same time variable. --- gregor_django/drupal_oauth_provider/tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gregor_django/drupal_oauth_provider/tests.py b/gregor_django/drupal_oauth_provider/tests.py index 214787e6..ca2b598d 100644 --- a/gregor_django/drupal_oauth_provider/tests.py +++ b/gregor_django/drupal_oauth_provider/tests.py @@ -102,6 +102,7 @@ def setUp(self): User = get_user_model() User.objects.create_user("testuser", "testuser@testuser.com", "testpw") self.client.login(username="testuser", password="testpw") + self.setup_time = datetime.datetime.now(datetime.timezone.utc) # Provide two mocked responses, first is to the public key request # second is used for the profile request for extra data @@ -175,13 +176,12 @@ def login(self, resp_mock=None, process="login", with_refresh_token=True): return resp def get_id_token(self): - now = datetime.datetime.now(datetime.timezone.utc) app = get_adapter().get_app(request=None, provider=self.provider_id) allowed_audience = app.client_id return sign_id_token( { - "exp": now + datetime.timedelta(hours=1), - "iat": now, + "exp": self.setup_time + datetime.timedelta(hours=1), + "iat": self.setup_time, "aud": allowed_audience, "scope": ["authenticated", "oauth_client_user"], "sub": 20122, From dde4051a893f79881acc5e0f419261806a191e31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 20:03:11 +0000 Subject: [PATCH 74/97] Bump types-requests from 2.32.0.20240914 to 2.32.0.20241016 Bumps [types-requests](https://github.com/python/typeshed) from 2.32.0.20240914 to 2.32.0.20241016. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/test-requirements.txt b/requirements/test-requirements.txt index 0256c88b..795d352d 100644 --- a/requirements/test-requirements.txt +++ b/requirements/test-requirements.txt @@ -87,7 +87,7 @@ tomli==2.0.1 # -c requirements/requirements.txt # coverage # pytest -types-requests==2.32.0.20240914 +types-requests==2.32.0.20241016 # via -r requirements/test-requirements.in typing-extensions==4.8.0 # via From 5633de6d4574667a6fcf6ecfaaf42f3c1135ee14 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Wed, 16 Oct 2024 13:36:23 -0700 Subject: [PATCH 75/97] Add a management command to audit combined workspaces --- .../commands/run_combined_workspace_audit.py | 72 +++++ .../gregor_anvil/tests/test_commands.py | 300 ++++++++++++++++++ 2 files changed, 372 insertions(+) create mode 100644 gregor_django/gregor_anvil/management/commands/run_combined_workspace_audit.py diff --git a/gregor_django/gregor_anvil/management/commands/run_combined_workspace_audit.py b/gregor_django/gregor_anvil/management/commands/run_combined_workspace_audit.py new file mode 100644 index 00000000..f010052f --- /dev/null +++ b/gregor_django/gregor_anvil/management/commands/run_combined_workspace_audit.py @@ -0,0 +1,72 @@ +from django.contrib.sites.models import Site +from django.core.mail import send_mail +from django.core.management.base import BaseCommand +from django.template.loader import render_to_string +from django.urls import reverse + +from ...audit import combined_workspace_audit + + +class Command(BaseCommand): + help = "Run access audits on CombinedConsortiumDataWorkspaces." + + def add_arguments(self, parser): + email_group = parser.add_argument_group(title="Email reports") + email_group.add_argument( + "--email", + help="""Email to which to send audit reports that need action or have errors.""", + ) + + def run_sharing_audit(self, *args, **options): + self.stdout.write("Running CombinedConsortiumDataWorkspace sharing audit... ", ending="") + audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceSharingAudit() + audit.run_audit() + self._handle_audit_results(audit, reverse("gregor_anvil:audit:combined_workspaces:sharing:all"), **options) + + def run_auth_domain_audit(self, *args, **options): + self.stdout.write("Running CombinedConsortiumDataWorkspace auth domain audit... ", ending="") + audit = combined_workspace_audit.CombinedConsortiumDataWorkspaceAuthDomainAudit() + audit.run_audit() + self._handle_audit_results(audit, reverse("gregor_anvil:audit:combined_workspaces:auth_domains:all"), **options) + + def _handle_audit_results(self, audit, url, **options): + # Report errors and needs access. + audit_ok = audit.ok() + # Construct the url for handling errors. + url = "https://" + Site.objects.get_current().domain + url + if audit_ok: + self.stdout.write(self.style.SUCCESS("ok!")) + else: + self.stdout.write(self.style.ERROR("problems found.")) + + # Print results + self.stdout.write("* Verified: {}".format(len(audit.verified))) + self.stdout.write("* Needs action: {}".format(len(audit.needs_action))) + self.stdout.write("* Errors: {}".format(len(audit.errors))) + + if not audit_ok: + self.stdout.write(self.style.ERROR(f"Please visit {url} to resolve these issues.")) + + # Send email if requested and there are problems. + email = options["email"] + subject = "{} - problems found".format(audit.__class__.__name__) + html_body = render_to_string( + "gregor_anvil/email_audit_report.html", + context={ + "title": "Combined workspace audit", + "audit_results": audit, + "url": url, + }, + ) + send_mail( + subject, + "Audit problems found. Please see attached report.", + None, + [email], + fail_silently=False, + html_message=html_body, + ) + + def handle(self, *args, **options): + self.run_sharing_audit(*args, **options) + self.run_auth_domain_audit(*args, **options) diff --git a/gregor_django/gregor_anvil/tests/test_commands.py b/gregor_django/gregor_anvil/tests/test_commands.py index b39cbfbe..33568383 100644 --- a/gregor_django/gregor_anvil/tests/test_commands.py +++ b/gregor_django/gregor_anvil/tests/test_commands.py @@ -1,5 +1,6 @@ """Tests for management commands in the `gregor_anvil` app.""" +from datetime import timedelta from io import StringIO from anvil_consortium_manager.models import GroupGroupMembership, WorkspaceGroupSharing @@ -14,6 +15,7 @@ from django.core.management import call_command from django.test import TestCase from django.urls import reverse +from django.utils import timezone from . import factories @@ -364,3 +366,301 @@ def test_auth_domain_audit_one_instance_needs_action_link_in_output(self): self.assertIn(url, out.getvalue()) # Zero messages have been sent by default. self.assertEqual(len(mail.outbox), 0) + + +class RunCombinedWorkspaceAuditTestCase(TestCase): + def test_no_workspaces(self): + """Test command output.""" + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace sharing audit... ok!", + "* Verified: 0", + "* Needs action: 0", + "* Errors: 0", + ] + ) + self.assertIn(expected_string, out.getvalue()) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace auth domain audit... ok!", + "* Verified: 0", + "* Needs action: 0", + "* Errors: 0", + ] + ) + self.assertIn(expected_string, out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) + + def test_sharing_audit_one_instance_verified(self): + """Test command output with one verified instance.""" + factories.CombinedConsortiumDataWorkspaceFactory.create() + # Verified not shared with auth domain. + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace sharing audit... ok!", + "* Verified: 1", + "* Needs action: 0", + "* Errors: 0", + ] + ) + self.assertIn(expected_string, out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) + + def test_sharing_audit_one_instance_needs_action(self): + """Test command output with one needs_action instance.""" + # Create a workspace and matching DAR. + factories.CombinedConsortiumDataWorkspaceFactory.create(date_completed=timezone.now() - timedelta(days=1)) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace sharing audit... problems found.", + "* Verified: 0", + "* Needs action: 1", + "* Errors: 0", + ] + ) + self.assertIn(expected_string, out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) + + def test_sharing_audit_one_instance_error(self): + """Test command output with one error instance.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=workspace.workspace.authorization_domains.first(), + access=WorkspaceGroupSharing.OWNER, + ) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace sharing audit... problems found.", + "* Verified: 0", + "* Needs action: 0", + "* Errors: 1", + ] + ) + self.assertIn(expected_string, out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) + + def test_sharing_audit_one_instance_verified_email(self): + """No email is sent when there are no errors.""" + factories.CombinedConsortiumDataWorkspaceFactory.create() + # Verified not shared with auth domain. + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", email="test@example.com", stdout=out) + self.assertIn("Running CombinedConsortiumDataWorkspace sharing audit... ok!", out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) + + def test_sharing_audit_one_instance_needs_action_email(self): + """Email is sent for one needs_action instance.""" + # Create a workspace and matching DAR. + factories.CombinedConsortiumDataWorkspaceFactory.create(date_completed=timezone.now() - timedelta(days=1)) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", email="test@example.com", stdout=out) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace sharing audit... problems found.", + "* Verified: 0", + "* Needs action: 1", + "* Errors: 0", + ] + ) + self.assertIn(expected_string, out.getvalue()) + # One message has been sent by default. + self.assertEqual(len(mail.outbox), 1) + email = mail.outbox[0] + self.assertEqual(email.to, ["test@example.com"]) + self.assertEqual(email.subject, "CombinedConsortiumDataWorkspaceSharingAudit - problems found") + + def test_sharing_audit_one_instance_error_email(self): + """Test command output with one error instance.""" + # Create a workspace and matching DAR. + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + WorkspaceGroupSharingFactory.create( + workspace=workspace.workspace, + group=workspace.workspace.authorization_domains.first(), + access=WorkspaceGroupSharing.OWNER, + ) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", email="test@example.com", stdout=out) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace sharing audit... problems found.", + "* Verified: 0", + "* Needs action: 0", + "* Errors: 1", + ] + ) + self.assertIn(expected_string, out.getvalue()) + # One message has been sent by default. + self.assertEqual(len(mail.outbox), 1) + email = mail.outbox[0] + self.assertEqual(email.to, ["test@example.com"]) + self.assertEqual(email.subject, "CombinedConsortiumDataWorkspaceSharingAudit - problems found") + + def test_sharing_audit_one_instance_needs_action_link_in_output(self): + factories.CombinedConsortiumDataWorkspaceFactory.create(date_completed=timezone.now() - timedelta(days=1)) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + url = reverse("gregor_anvil:audit:combined_workspaces:sharing:all") + self.assertIn(url, out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) + + def test_sharing_audit_different_domain(self): + """Test command output when a different domain is specified.""" + site = Site.objects.create(domain="foobar.com", name="test") + site.save() + with self.settings(SITE_ID=site.id): + factories.CombinedConsortiumDataWorkspaceFactory.create(date_completed=timezone.now() - timedelta(days=1)) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + self.assertIn("Running CombinedConsortiumDataWorkspace sharing audit... problems found.", out.getvalue()) + self.assertIn("https://foobar.com", out.getvalue()) + + def test_auth_domain_audit_one_instance_verified(self): + """Test command output with one verified instance.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group__name=settings.ANVIL_DCC_ADMINS_GROUP_NAME, + role=GroupGroupMembership.ADMIN, + ) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace auth domain audit... ok!", + "* Verified: 1", + "* Needs action: 0", + "* Errors: 0", + ] + ) + self.assertIn(expected_string, out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) + + def test_auth_domain_audit_one_instance_needs_action(self): + """Test command output with one needs_action instance.""" + factories.CombinedConsortiumDataWorkspaceFactory.create() + ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace auth domain audit... problems found.", + "* Verified: 0", + "* Needs action: 1", + "* Errors: 0", + ] + ) + self.assertIn(expected_string, out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) + + def test_auth_domain_audit_one_instance_error(self): + """Test command output with one error instance.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + role=GroupGroupMembership.ADMIN, + ) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace auth domain audit... problems found.", + "* Verified: 0", + "* Needs action: 0", + "* Errors: 1", + ] + ) + self.assertIn(expected_string, out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) + + def test_auth_domain_audit_one_instance_verified_email(self): + """No email is sent when there are no errors.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + child_group__name="GREGOR_ALL", + role=GroupGroupMembership.MEMBER, + ) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", email="test@example.com", stdout=out) + self.assertIn("Running CombinedConsortiumDataWorkspace auth domain audit... ok!", out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) + + def test_auth_domain_audit_one_instance_needs_action_email(self): + """Email is sent for one needs_action instance.""" + # Create a workspace and matching DAR. + factories.CombinedConsortiumDataWorkspaceFactory.create() + factories.ManagedGroupFactory.create(name="GREGOR_ALL") + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", email="test@example.com", stdout=out) + # One message has been sent by default. + self.assertEqual(len(mail.outbox), 1) + email = mail.outbox[0] + self.assertEqual(email.to, ["test@example.com"]) + self.assertEqual(email.subject, "CombinedConsortiumDataWorkspaceAuthDomainAudit - problems found") + + def test_auth_domain_audit_one_instance_error_email(self): + """Test command output with one error instance.""" + workspace = factories.CombinedConsortiumDataWorkspaceFactory.create() + GroupGroupMembershipFactory.create( + parent_group=workspace.workspace.authorization_domains.first(), + role=GroupGroupMembership.ADMIN, + ) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", email="test@example.com", stdout=out) + expected_string = "\n".join( + [ + "Running CombinedConsortiumDataWorkspace auth domain audit... problems found.", + "* Verified: 0", + "* Needs action: 0", + "* Errors: 1", + ] + ) + self.assertIn(expected_string, out.getvalue()) + # One message has been sent by default. + self.assertEqual(len(mail.outbox), 1) + email = mail.outbox[0] + self.assertEqual(email.to, ["test@example.com"]) + self.assertEqual(email.subject, "CombinedConsortiumDataWorkspaceAuthDomainAudit - problems found") + + def test_auth_domain_audit_different_domain(self): + """Test command output when a different domain is specified.""" + site = Site.objects.create(domain="foobar.com", name="test") + site.save() + with self.settings(SITE_ID=site.id): + factories.CombinedConsortiumDataWorkspaceFactory.create() + ManagedGroupFactory.create(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME) + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + self.assertIn( + "Running CombinedConsortiumDataWorkspace auth domain audit... problems found.", out.getvalue() + ) + self.assertIn("https://foobar.com", out.getvalue()) + + def test_auth_domain_audit_one_instance_needs_action_link_in_output(self): + factories.CombinedConsortiumDataWorkspaceFactory.create() + ManagedGroupFactory.create(name="GREGOR_ALL") + out = StringIO() + call_command("run_combined_workspace_audit", "--no-color", stdout=out) + url = reverse("gregor_anvil:audit:combined_workspaces:auth_domains:all") + self.assertIn(url, out.getvalue()) + # Zero messages have been sent by default. + self.assertEqual(len(mail.outbox), 0) From ca9a0fbbca8205d8bad03112c4a21dee0cabf630 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Wed, 16 Oct 2024 14:57:20 -0700 Subject: [PATCH 76/97] Clean up test coverage --- .../audit/combined_workspace_audit.py | 38 +------------------ 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/gregor_django/gregor_anvil/audit/combined_workspace_audit.py b/gregor_django/gregor_anvil/audit/combined_workspace_audit.py index 0885a4c6..05a8e7fc 100644 --- a/gregor_django/gregor_anvil/audit/combined_workspace_audit.py +++ b/gregor_django/gregor_anvil/audit/combined_workspace_audit.py @@ -18,7 +18,7 @@ class CombinedConsortiumDataWorkspaceAuthDomainAuditTable(tables.Table): note = tables.Column() action = tables.TemplateColumn( # Temporarily use this button template, until we have the resolve view working for this workspace type. - template_name="gregor_anvil/snippets/upload_workspace_auth_domain_audit_action_button.html" + template_name="gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_action_button.html" ) class Meta: @@ -101,42 +101,6 @@ def _audit_workspace_and_dcc_admin_group(self, combined_workspace, managed_group else: self.needs_action.append(workspace_auth_domain_audit_results.AddAdmin(**audit_result_args)) - def _audit_workspace_and_dcc_group(self, combined_workspace, managed_group): - """Audit the auth domain membership for a specific workspace and the DCC writers/members groups. - - Expectations: - - Member before the workspace is completed. - - Not a member after the workspace is completed. - """ - current_membership = self._get_current_membership(combined_workspace, managed_group) - audit_result_args = { - "workspace": combined_workspace.workspace, - "managed_group": managed_group, - "current_membership_instance": current_membership, - } - - if not combined_workspace.date_completed: - note = self.DCC_BEFORE_COMPLETE - if not current_membership: - self.needs_action.append(workspace_auth_domain_audit_results.AddMember(note=note, **audit_result_args)) - elif current_membership and current_membership.role == GroupGroupMembership.MEMBER: - self.verified.append(workspace_auth_domain_audit_results.VerifiedMember(note=note, **audit_result_args)) - else: - self.errors.append(workspace_auth_domain_audit_results.ChangeToMember(note=note, **audit_result_args)) - else: - note = self.DCC_AFTER_COMPLETE - if not current_membership: - self.verified.append( - workspace_auth_domain_audit_results.VerifiedNotMember(note=note, **audit_result_args) - ) - elif current_membership and current_membership.role == GroupGroupMembership.MEMBER: - self.needs_action.append(workspace_auth_domain_audit_results.Remove(note=note, **audit_result_args)) - else: - self.errors.append(workspace_auth_domain_audit_results.Remove(note=note, **audit_result_args)) - - def _audit_workspace_and_dcc_member_group(self, combined_workspace, managed_group): - pass - def _audit_workspace_and_gregor_all_group(self, combined_workspace, managed_group): """Audit the auth domain membership for a specific workspace and the GREGOR_ALL group. From 2841a97aad96a4cdb689a1bfb29b4aca3f143a88 Mon Sep 17 00:00:00 2001 From: Jonas Carson Date: Thu, 17 Oct 2024 11:04:23 -0700 Subject: [PATCH 77/97] Add some missing coverage --- gregor_django/users/tests/test_views.py | 56 ++++++++++++++++++++++++- gregor_django/users/views.py | 1 - 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/gregor_django/users/tests/test_views.py b/gregor_django/users/tests/test_views.py index e0d8431a..e1611657 100644 --- a/gregor_django/users/tests/test_views.py +++ b/gregor_django/users/tests/test_views.py @@ -1,19 +1,26 @@ import json import pytest +from allauth.socialaccount.models import SocialApp from anvil_consortium_manager.models import AnVILProjectManagerAccess -from anvil_consortium_manager.tests.factories import AccountFactory +from anvil_consortium_manager.tests.factories import AccountFactory, UserEmailEntryFactory from django.conf import settings from django.contrib import messages from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser, Permission from django.contrib.messages.middleware import MessageMiddleware from django.contrib.sessions.middleware import SessionMiddleware +from django.contrib.sites.models import Site from django.http import HttpRequest from django.shortcuts import resolve_url from django.test import RequestFactory, TestCase from django.urls import reverse +from gregor_django.drupal_oauth_provider.provider import CustomProvider +from gregor_django.gregor_anvil.tests.factories import ( + PartnerGroupFactory, + ResearchCenterFactory, +) from gregor_django.users.forms import UserChangeForm, UserLookupForm from gregor_django.users.tests.factories import UserFactory from gregor_django.users.views import UserRedirectView, UserUpdateView, user_detail_view @@ -92,13 +99,42 @@ def test_get_redirect_url(self, user: User, rf: RequestFactory): class TestUserDetailView: - def test_authenticated(self, client, user: User, rf: RequestFactory): + def test_authenticated(self, client, user: User): client.force_login(user) user_detail_url = reverse("users:detail", kwargs=dict(username=user.username)) response = client.get(user_detail_url) assert response.status_code == 200 + def test_configured_user_with_anvil_account(self, client): + account = AccountFactory.create(verified=True) + account_user = account.user + client.force_login(account_user) + pg1 = PartnerGroupFactory(short_name="pg1") + rc1 = ResearchCenterFactory(short_name="rc1") + + account.save() + account_user.partner_groups.add(pg1) + account_user.research_centers.add(rc1) + user_detail_url = reverse("users:detail", kwargs=dict(username=account_user.username)) + response = client.get(user_detail_url) + + assert response.status_code == 200 + + def test_configured_users_no_anvil_account(self, client, user: User): + client.force_login(user) + pg1 = PartnerGroupFactory(short_name="pg1") + rc1 = ResearchCenterFactory(short_name="rc1") + UserEmailEntryFactory.create(user=user) + + user.partner_groups.add(pg1) + user.research_centers.add(rc1) + user_detail_url = reverse("users:detail", kwargs=dict(username=user.username)) + + response = client.get(user_detail_url) + + assert response.status_code == 200 + def test_not_authenticated(self, user: User, rf: RequestFactory): request = rf.get("/fake-url/") request.user = AnonymousUser() @@ -129,6 +165,22 @@ def test_unlinked_accounts(self): self.assertContains(response, "Previously-linked accounts") +class LoginViewTest(TestCase): + def setUp(self): + current_site = Site.objects.get_current() + self.social_app = SocialApp.objects.create( + provider=CustomProvider.id, + name="DOA", + client_id="test-client-id", + secret="test-client-secret", + ) + self.social_app.sites.add(current_site) + + def test_basic_login_view_render(self): + response = self.client.get(reverse("account_login")) + assert response.status_code == 200 + + class UserAutocompleteViewTest(TestCase): def setUp(self): """Set up test class.""" diff --git a/gregor_django/users/views.py b/gregor_django/users/views.py index e27834ab..ef0dc927 100644 --- a/gregor_django/users/views.py +++ b/gregor_django/users/views.py @@ -20,7 +20,6 @@ class UserDetailView(LoginRequiredMixin, DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["unlinked_accounts"] = self.object.unlinked_accounts.all() - print(context["unlinked_accounts"]) context["user_email_entries"] = self.object.useremailentry_set.filter(date_verified=None) context["is_me"] = self.request.user == self.object return context From 5e0ef303b197674f8e22b30f65ed8a166f02afa6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 19:43:35 +0000 Subject: [PATCH 78/97] Bump ruff from 0.6.9 to 0.7.0 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.9 to 0.7.0. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.9...0.7.0) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index eada11bd..0c856314 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -150,7 +150,7 @@ requests==2.32.3 # -c requirements/requirements.txt # -c requirements/test-requirements.txt # sphinx -ruff==0.6.9 +ruff==0.7.0 # via -r requirements/dev-requirements.in six==1.16.0 # via From 63a1030b0864161820339246cde795517ca8e816 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:50:13 +0000 Subject: [PATCH 79/97] Bump pyjwt from 2.8.0 to 2.9.0 Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.8.0 to 2.9.0. - [Release notes](https://github.com/jpadilla/pyjwt/releases) - [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst) - [Commits](https://github.com/jpadilla/pyjwt/compare/2.8.0...2.9.0) --- updated-dependencies: - dependency-name: pyjwt dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index d0e752c3..710fda88 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -122,7 +122,7 @@ pyasn1-modules==0.3.0 # via google-auth pycparser==2.21 # via cffi -pyjwt==2.8.0 +pyjwt==2.9.0 # via -r requirements/requirements.in pyproject-hooks==1.0.0 # via From 257e946f041bab9da0f8c5b9cc5a6135bb012529 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:51:53 +0000 Subject: [PATCH 80/97] Bump cryptography from 43.0.1 to 43.0.3 Bumps [cryptography](https://github.com/pyca/cryptography) from 43.0.1 to 43.0.3. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/43.0.1...43.0.3) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index d0e752c3..2e7ea700 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -31,7 +31,7 @@ crispy-bootstrap5==2024.10 # via # -r requirements/requirements.in # django-anvil-consortium-manager -cryptography==43.0.1 +cryptography==43.0.3 # via -r requirements/requirements.in django==4.2.16 # via From da15adb7fee165913ccfd5db48ab880f23b5c493 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:25:52 +0000 Subject: [PATCH 81/97] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.6.9 → v0.7.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.9...v0.7.0) - [github.com/gitleaks/gitleaks: v8.20.0 → v8.21.1](https://github.com/gitleaks/gitleaks/compare/v8.20.0...v8.21.1) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 808e8b7b..34714409 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.6.9 + rev: v0.7.0 hooks: # Run the linter. - id: ruff @@ -21,7 +21,7 @@ repos: - id: ruff-format - repo: https://github.com/gitleaks/gitleaks - rev: v8.20.0 + rev: v8.21.1 hooks: - id: gitleaks From 41a09d854b4ce82db5911a2ed2aaece0b04abef1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:04:54 +0000 Subject: [PATCH 82/97] Bump mypy from 1.12.0 to 1.12.1 Bumps [mypy](https://github.com/python/mypy) from 1.12.0 to 1.12.1. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.12.0...v1.12.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index eada11bd..f02685ac 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -100,7 +100,7 @@ matplotlib-inline==0.1.6 # via ipython mccabe==0.7.0 # via pylint -mypy==1.12.0 +mypy==1.12.1 # via -r requirements/dev-requirements.in mypy-extensions==1.0.0 # via mypy From 9bec7d1d4246a1d3e569bd814b3e71aee1cd8b62 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:06:19 +0000 Subject: [PATCH 83/97] Bump mysqlclient from 2.2.4 to 2.2.5 Bumps [mysqlclient](https://github.com/PyMySQL/mysqlclient) from 2.2.4 to 2.2.5. - [Release notes](https://github.com/PyMySQL/mysqlclient/releases) - [Changelog](https://github.com/PyMySQL/mysqlclient/blob/main/HISTORY.rst) - [Commits](https://github.com/PyMySQL/mysqlclient/compare/v2.2.4...v2.2.5) --- updated-dependencies: - dependency-name: mysqlclient dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index d0e752c3..15d51bd6 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -96,7 +96,7 @@ idna==3.7 # via requests jsonapi-requests==0.8.0 # via -r requirements/requirements.in -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/requirements.in networkx==3.1 # via django-anvil-consortium-manager From 13fa73b66a6e0fa5a02e150dcc220ce330e85320 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 21 Oct 2024 15:38:57 -0700 Subject: [PATCH 84/97] Bump gitleaks version Handled in main branch, but I want CI to run in this branch. --- .github/workflows/gitleaks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml index f6cca493..00a67cc8 100644 --- a/.github/workflows/gitleaks.yml +++ b/.github/workflows/gitleaks.yml @@ -10,10 +10,10 @@ jobs: name: gitleaks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.1 with: fetch-depth: 0 - - uses: gitleaks/gitleaks-action@v2.3.6 + - uses: gitleaks/gitleaks-action@v2.3.7 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE}} # Only required for Organizations, not personal accounts. From 5422e5f20bd0c7e71820e518b7279511f0d8cad3 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 21 Oct 2024 15:51:34 -0700 Subject: [PATCH 85/97] Add nightly combined workspace audit to cron file --- gregor_apps.cron | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gregor_apps.cron b/gregor_apps.cron index d857f24c..2be3d68f 100644 --- a/gregor_apps.cron +++ b/gregor_apps.cron @@ -13,3 +13,6 @@ MAILTO="gregorweb@uw.edu" # Nightly upload workspace audit 0 3 * * * . /var/www/django/gregor_apps/gregor-apps-activate.sh; python manage.py run_upload_workspace_audit --email gregorweb@uw.edu >> cron.log + +# Nightly combined workspace audit +0 3 * * * . /var/www/django/gregor_apps/gregor-apps-activate.sh; python manage.py run_combined_workspace_audit --email gregorweb@uw.edu >> cron.log From 475245d08f8bfded89ebe5f08e65ac10d98e1054 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 22 Oct 2024 10:45:05 -0700 Subject: [PATCH 86/97] Clean up audit templates for consistency --- ...nedconsortiumdataworkspace_auth_domain_audit_explanation.html | 1 + ...ombinedconsortiumdataworkspace_sharing_audit_explanation.html | 1 + .../snippets/upload_workspace_sharing_audit_explanation.html | 1 + 3 files changed, 3 insertions(+) diff --git a/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_explanation.html b/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_explanation.html index f2785a71..32c7632d 100644 --- a/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_explanation.html +++ b/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_auth_domain_audit_explanation.html @@ -17,6 +17,7 @@

    Note that groups associated with AnVIL (e.g., anvil-admins, anvil-devs) are ignored by the audit.

    +

    Any errors should be reported!

    diff --git a/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_explanation.html b/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_explanation.html index 3cfa15e2..5c1b9f0e 100644 --- a/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_explanation.html +++ b/gregor_django/templates/gregor_anvil/snippets/combinedconsortiumdataworkspace_sharing_audit_explanation.html @@ -37,6 +37,7 @@

  • Errors
    • The workspace has been shared with an unexpected group.
    • +
    • A group other than the DCC admins group is an owner of the workspace.

    diff --git a/gregor_django/templates/gregor_anvil/snippets/upload_workspace_sharing_audit_explanation.html b/gregor_django/templates/gregor_anvil/snippets/upload_workspace_sharing_audit_explanation.html index cdf2a379..f86cafc6 100644 --- a/gregor_django/templates/gregor_anvil/snippets/upload_workspace_sharing_audit_explanation.html +++ b/gregor_django/templates/gregor_anvil/snippets/upload_workspace_sharing_audit_explanation.html @@ -37,6 +37,7 @@

  • Errors
    • The workspace has been shared with an unexpected group.
    • +
    • A group other than the DCC admins group is an owner of the workspace.

    From 05c632faf89a0a2d8755d78fbd0ac08ac9e58531 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 19:39:43 +0000 Subject: [PATCH 87/97] Bump mypy from 1.12.1 to 1.13.0 Bumps [mypy](https://github.com/python/mypy) from 1.12.1 to 1.13.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.12.1...v1.13.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 9096c9c6..4446b498 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -100,7 +100,7 @@ matplotlib-inline==0.1.6 # via ipython mccabe==0.7.0 # via pylint -mypy==1.12.1 +mypy==1.13.0 # via -r requirements/dev-requirements.in mypy-extensions==1.0.0 # via mypy From a2a785bc802a6b5e17563f1648d12a8bd8171d4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 19:46:07 +0000 Subject: [PATCH 88/97] Bump actions/checkout from 4.2.1 to 4.2.2 Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.1 to 4.2.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.2.1...v4.2.2) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- .github/workflows/gitleaks.yml | 2 +- .github/workflows/pip-compile.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26e7b012..70379dd4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,7 @@ jobs: steps: - name: Checkout Code Repository - uses: actions/checkout@v4.2.1 + uses: actions/checkout@v4.2.2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5.2.0 @@ -111,7 +111,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repo - uses: actions/checkout@v4.2.1 + uses: actions/checkout@v4.2.2 - name: Set up Python uses: actions/setup-python@v5.2.0 diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml index 00a67cc8..5c7d8e73 100644 --- a/.github/workflows/gitleaks.yml +++ b/.github/workflows/gitleaks.yml @@ -10,7 +10,7 @@ jobs: name: gitleaks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.1 + - uses: actions/checkout@v4.2.2 with: fetch-depth: 0 - uses: gitleaks/gitleaks-action@v2.3.7 diff --git a/.github/workflows/pip-compile.yml b/.github/workflows/pip-compile.yml index 9f906bd1..c64f510e 100644 --- a/.github/workflows/pip-compile.yml +++ b/.github/workflows/pip-compile.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout Code Repository - uses: actions/checkout@v4.2.1 + uses: actions/checkout@v4.2.2 with: ref: ${{ github.head_ref }} From 7e9e68b6f7a3f6edd84574ef103ef0965d045397 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 19:35:38 +0000 Subject: [PATCH 89/97] Bump django-allauth from 65.0.2 to 65.1.0 Bumps [django-allauth](https://github.com/sponsors/pennersr) from 65.0.2 to 65.1.0. - [Commits](https://github.com/sponsors/pennersr/commits) --- updated-dependencies: - dependency-name: django-allauth dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index a5ca25ce..cdf7ef7c 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -12,6 +12,7 @@ asgiref==3.8.1 # via # -r requirements/requirements.in # django + # django-allauth # django-htmx build==1.0.3 # via pip-tools @@ -49,7 +50,7 @@ django==4.2.16 # django-picklefield # django-simple-history # django-tables2 -django-allauth==65.0.2 +django-allauth==65.1.0 # via -r requirements/requirements.in django-anvil-consortium-manager @ git+https://github.com/UW-GAC/django-anvil-consortium-manager.git@v0.25 # via -r requirements/requirements.in From 6e50dbec870caa9618c647e45d9f75f1e1916187 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 19:55:42 +0000 Subject: [PATCH 90/97] Bump actions/setup-python from 5.2.0 to 5.3.0 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.2.0 to 5.3.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v5.2.0...v5.3.0) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- .github/workflows/pip-compile.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26e7b012..af91a982 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: uses: actions/checkout@v4.2.1 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5.2.0 + uses: actions/setup-python@v5.3.0 with: python-version: ${{ matrix.python-version }} cache: pip @@ -114,7 +114,7 @@ jobs: uses: actions/checkout@v4.2.1 - name: Set up Python - uses: actions/setup-python@v5.2.0 + uses: actions/setup-python@v5.3.0 with: python-version: '3.10' diff --git a/.github/workflows/pip-compile.yml b/.github/workflows/pip-compile.yml index 9f906bd1..1b04610d 100644 --- a/.github/workflows/pip-compile.yml +++ b/.github/workflows/pip-compile.yml @@ -18,7 +18,7 @@ jobs: ref: ${{ github.head_ref }} - name: Set up Python - uses: actions/setup-python@v5.2.0 + uses: actions/setup-python@v5.3.0 with: python-version: "3.10" From 59c6b82ade4470c773d9f56e8f3a3a82c909b975 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Thu, 7 Nov 2024 13:37:33 -0800 Subject: [PATCH 91/97] Use new version of update-requirements-files action This fixes an issue with pip-tools and pip versions, where pip-copmile was adding absolute paths when run with a pip version of >=24.3. --- .github/workflows/pip-compile.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pip-compile.yml b/.github/workflows/pip-compile.yml index 9f906bd1..72bd62a0 100644 --- a/.github/workflows/pip-compile.yml +++ b/.github/workflows/pip-compile.yml @@ -23,7 +23,7 @@ jobs: python-version: "3.10" - name: Update requirements files - uses: UW-GAC/pip-tools-actions/update-requirements-files@v0.1 + uses: UW-GAC/pip-tools-actions/update-requirements-files@v0.2 with: requirements_files: |- requirements/requirements.in From 7834d986d0d62f7a73570899e18c0bcf02bc76db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 22:04:00 +0000 Subject: [PATCH 92/97] Bump pytest-cov from 5.0.0 to 6.0.0 Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 5.0.0 to 6.0.0. - [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-cov/compare/v5.0.0...v6.0.0) --- updated-dependencies: - dependency-name: pytest-cov dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements/test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/test-requirements.txt b/requirements/test-requirements.txt index 795d352d..2f6f4a10 100644 --- a/requirements/test-requirements.txt +++ b/requirements/test-requirements.txt @@ -56,7 +56,7 @@ pytest==8.3.3 # pytest-django # pytest-sugar # pytest-xdist -pytest-cov==5.0.0 +pytest-cov==6.0.0 # via -r requirements/test-requirements.in pytest-django==4.9.0 # via -r requirements/test-requirements.in From 7092be91950d1f5d09f8139d6904fb9551537a1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 22:04:27 +0000 Subject: [PATCH 93/97] Bump ruff from 0.7.0 to 0.7.2 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.0 to 0.7.2. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.7.0...0.7.2) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 9096c9c6..eb7ff9b6 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -150,7 +150,7 @@ requests==2.32.3 # -c requirements/requirements.txt # -c requirements/test-requirements.txt # sphinx -ruff==0.7.0 +ruff==0.7.2 # via -r requirements/dev-requirements.in six==1.16.0 # via From 5a7bf8f4e0dea4538ceb1017917a07f4fd716aa4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 22:04:34 +0000 Subject: [PATCH 94/97] Bump django-htmx from 1.19.0 to 1.21.0 Bumps [django-htmx](https://github.com/adamchainz/django-htmx) from 1.19.0 to 1.21.0. - [Changelog](https://github.com/adamchainz/django-htmx/blob/main/docs/changelog.rst) - [Commits](https://github.com/adamchainz/django-htmx/compare/1.19.0...1.21.0) --- updated-dependencies: - dependency-name: django-htmx dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index a5ca25ce..10b517ce 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -72,7 +72,7 @@ django-extensions==3.2.1 # django-anvil-consortium-manager django-filter==23.5 # via django-anvil-consortium-manager -django-htmx==1.19.0 +django-htmx==1.21.0 # via -r requirements/requirements.in django-login-required-middleware==0.9.0 # via -r requirements/requirements.in From 8a054636bd35848fbae173217b8c5ae55ffe8cef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 22:04:37 +0000 Subject: [PATCH 95/97] Bump werkzeug from 3.0.4 to 3.1.2 Bumps [werkzeug](https://github.com/pallets/werkzeug) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/pallets/werkzeug/releases) - [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/werkzeug/compare/3.0.4...3.1.2) --- updated-dependencies: - dependency-name: werkzeug dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 9096c9c6..6bc075bf 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -233,7 +233,7 @@ wcwidth==0.2.13 # via prompt-toolkit websockets==12.0 # via sphinx-autobuild -werkzeug==3.0.4 +werkzeug==3.1.2 # via -r requirements/dev-requirements.in # The following packages are considered to be unsafe in a requirements file: From 09af3b9428c466cfe36f1a4989d9a483a458a1f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 22:04:40 +0000 Subject: [PATCH 96/97] Bump whitenoise from 6.7.0 to 6.8.2 Bumps [whitenoise](https://github.com/evansd/whitenoise) from 6.7.0 to 6.8.2. - [Changelog](https://github.com/evansd/whitenoise/blob/main/docs/changelog.rst) - [Commits](https://github.com/evansd/whitenoise/compare/6.7.0...6.8.2) --- updated-dependencies: - dependency-name: whitenoise dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index a5ca25ce..bfc2d19b 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -164,7 +164,7 @@ urllib3==2.2.2 # via requests wheel==0.42.0 # via pip-tools -whitenoise==6.7.0 +whitenoise==6.8.2 # via -r requirements/requirements.in # The following packages are considered to be unsafe in a requirements file: From 85a0f0dc2d0d21e1cfbf921b124a9808d7ca23ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 22:04:45 +0000 Subject: [PATCH 97/97] Bump django-constance from 4.1.2 to 4.1.3 Bumps [django-constance](https://github.com/jazzband/django-constance) from 4.1.2 to 4.1.3. - [Release notes](https://github.com/jazzband/django-constance/releases) - [Changelog](https://github.com/jazzband/django-constance/blob/master/docs/changes.rst) - [Commits](https://github.com/jazzband/django-constance/compare/4.1.2...4.1.3) --- updated-dependencies: - dependency-name: django-constance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index a5ca25ce..a899dde9 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -55,7 +55,7 @@ django-anvil-consortium-manager @ git+https://github.com/UW-GAC/django-anvil-con # via -r requirements/requirements.in django-autocomplete-light==3.11.0 # via django-anvil-consortium-manager -django-constance==4.1.2 +django-constance==4.1.3 # via -r requirements/requirements.in django-crispy-forms==2.3 # via