Skip to content

Commit

Permalink
Merge pull request #700 from UW-GAC/feature/managed-group-adapter
Browse files Browse the repository at this point in the history
Add a custom ManagedGroupAdapter
  • Loading branch information
amstilp authored Aug 7, 2024
2 parents f742923 + f328677 commit 3ca24c9
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 0 deletions.
1 change: 1 addition & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@
"primed.miscellaneous_workspaces.adapters.DataPrepWorkspaceAdapter",
]
ANVIL_ACCOUNT_ADAPTER = "primed.primed_anvil.adapters.AccountAdapter"
ANVIL_MANAGED_GROUP_ADAPTER = "primed.primed_anvil.adapters.ManagedGroupAdapter"

# Specify the URL name that AccountLink and AccountLinkVerify redirect to.
ANVIL_ACCOUNT_LINK_REDIRECT = "users:redirect"
Expand Down
22 changes: 22 additions & 0 deletions primed/primed_anvil/adapters.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from anvil_consortium_manager.adapters.account import BaseAccountAdapter
from anvil_consortium_manager.adapters.managed_group import BaseManagedGroupAdapter
from anvil_consortium_manager.models import (
GroupGroupMembership,
ManagedGroup,
WorkspaceGroupSharing,
)
from anvil_consortium_manager.tables import ManagedGroupStaffTable
from django.conf import settings
from django.db.models import Q

Expand Down Expand Up @@ -77,3 +79,23 @@ def after_anvil_create(self, workspace):
can_compute=True,
)
sharing.anvil_create_or_update()


class ManagedGroupAdapter(BaseManagedGroupAdapter):
"""Adapter for ManagedGroups."""

list_table_class = ManagedGroupStaffTable

def after_anvil_create(self, managed_group):
super().after_anvil_create(managed_group)
# Add the ADMINs group as an admin of the auth domain.
try:
admins_group = ManagedGroup.objects.get(name=settings.ANVIL_CC_ADMINS_GROUP_NAME)
except ManagedGroup.DoesNotExist:
return
membership = GroupGroupMembership.objects.create(
parent_group=managed_group,
child_group=admins_group,
role=GroupGroupMembership.ADMIN,
)
membership.anvil_create()
52 changes: 52 additions & 0 deletions primed/primed_anvil/tests/test_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,55 @@ def test_after_anvil_create_no_admins_group(self):
self.adapter.after_anvil_create(workspace)
# No WorkspaceGroupSharing objects were created.
self.assertEqual(WorkspaceGroupSharing.objects.count(), 0)


class ManagedGroupAdapterTest(AnVILAPIMockTestMixin, TestCase):
"""Tests for the custom PRIMED ManagedGroupAdapter."""

def setUp(self):
super().setUp()
self.adapter = adapters.ManagedGroupAdapter()

def test_after_anvil_create(self):
admins_group = ManagedGroupFactory.create(name="TEST_PRIMED_CC_ADMINS")
managed_group = ManagedGroupFactory.create(name="test-group")
# API response for PRIMED_ADMINS membership.
self.anvil_response_mock.add(
responses.PUT,
self.api_client.sam_entry_point + "/api/groups/v1/test-group/admin/[email protected]",
status=204,
)
# Run the adapter method.
self.adapter.after_anvil_create(managed_group)
# Check for GroupGroupMembership.
self.assertEqual(GroupGroupMembership.objects.count(), 1)
membership = GroupGroupMembership.objects.first()
self.assertEqual(membership.parent_group, managed_group)
self.assertEqual(membership.child_group, admins_group)
self.assertEqual(membership.role, GroupGroupMembership.ADMIN)

@override_settings(ANVIL_CC_ADMINS_GROUP_NAME="foobar")
def test_after_anvil_create_different_admins_group(self):
admins_group = ManagedGroupFactory.create(name="foobar")
managed_group = ManagedGroupFactory.create(name="test-group")
# API response for PRIMED_ADMINS membership.
self.anvil_response_mock.add(
responses.PUT,
self.api_client.sam_entry_point + "/api/groups/v1/test-group/admin/[email protected]",
status=204,
)
# Run the adapter method.
self.adapter.after_anvil_create(managed_group)
# Check for GroupGroupMembership.
self.assertEqual(GroupGroupMembership.objects.count(), 1)
membership = GroupGroupMembership.objects.first()
self.assertEqual(membership.parent_group, managed_group)
self.assertEqual(membership.child_group, admins_group)
self.assertEqual(membership.role, GroupGroupMembership.ADMIN)

def test_after_anvil_create_no_admins_group(self):
managed_group = ManagedGroupFactory.create(name="test-group")
# Run the adapter method.
self.adapter.after_anvil_create(managed_group)
# No WorkspaceGroupSharing objects were created.
self.assertEqual(GroupGroupMembership.objects.count(), 0)
49 changes: 49 additions & 0 deletions primed/primed_anvil/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import json

import responses
from anvil_consortium_manager import models as acm_models
from anvil_consortium_manager.tests.factories import (
AccountFactory,
GroupAccountMembershipFactory,
ManagedGroupFactory,
WorkspaceGroupSharingFactory,
)
from anvil_consortium_manager.tests.utils import AnVILAPIMockTestMixin
from anvil_consortium_manager.views import AccountList
from constance.test import override_config
from django.conf import settings
Expand Down Expand Up @@ -1313,3 +1315,50 @@ def test_context_workspaces_input_one_workspace(self):
response.context_data["workspaces_input"],
"""{\n "test-bp/test-ws": ""\n}""",
)


class ManagedGroupCreateTest(AnVILAPIMockTestMixin, TestCase):
"""Tests for custom ManagedGroup behavior."""

def get_url(self, *args):
"""Get the url for the view being tested."""
return reverse("anvil_consortium_manager:managed_groups:new", args=args)

def setUp(self):
"""Set up test class."""
# The superclass uses the responses package to mock API responses.
super().setUp()
self.factory = RequestFactory()
# Create a user with both view and edit permissions.
self.user = User.objects.create_user(username="test", password="test")
self.user.user_permissions.add(
Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME)
)
self.user.user_permissions.add(
Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME)
)
# Create the admins group.
self.admins_group = ManagedGroupFactory.create(name="TEST_PRIMED_CC_ADMINS")

def test_cc_admins_membership(self):
"""The after_anvil_create method is run after a managed group is created."""
# API response for group creation.
api_url = self.api_client.sam_entry_point + "/api/groups/v1/test-group"
self.anvil_response_mock.add(responses.POST, api_url, status=201)
# API response for auth domain PRIMED_ADMINS membership.
self.anvil_response_mock.add(
responses.PUT,
self.api_client.sam_entry_point + "/api/groups/v1/test-group/admin/[email protected]",
status=204,
)
# Submit the form to django.
self.client.force_login(self.user)
response = self.client.post(self.get_url(), {"name": "test-group"})
self.assertEqual(response.status_code, 302)
# Check that the admin group was added.
new_group = acm_models.ManagedGroup.objects.latest("pk")
self.assertEqual(acm_models.GroupGroupMembership.objects.count(), 1)
membership = acm_models.GroupGroupMembership.objects.first()
self.assertEqual(membership.parent_group, new_group)
self.assertEqual(membership.child_group, self.admins_group)
self.assertEqual(membership.role, acm_models.GroupGroupMembership.ADMIN)

0 comments on commit 3ca24c9

Please sign in to comment.