Skip to content

Commit

Permalink
Merge pull request #680 from UW-GAC/feature/adapter-automation
Browse files Browse the repository at this point in the history
Automate adding DCC admins group to workspaces and managed groups
  • Loading branch information
amstilp authored Aug 8, 2024
2 parents 9831820 + ce07370 commit d43c139
Show file tree
Hide file tree
Showing 7 changed files with 523 additions and 12 deletions.
1 change: 1 addition & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@
"gregor_django.gregor_anvil.adapters.ExchangeWorkspaceAdapter",
]
ANVIL_ACCOUNT_ADAPTER = "gregor_django.gregor_anvil.adapters.AccountAdapter"
ANVIL_MANAGED_GROUP_ADAPTER = "gregor_django.gregor_anvil.adapters.ManagedGroupAdapter"

# Specify the URL name that AccountLink and AccountLinkVerify redirect to.
ANVIL_ACCOUNT_LINK_REDIRECT = "users:redirect"
Expand Down
1 change: 1 addition & 0 deletions config/settings/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@
# ------------------------------------------------------------------------------
# Specify the path to the service account to use for managing access on AnVIL.
ANVIL_API_SERVICE_ACCOUNT_FILE = env("ANVIL_API_SERVICE_ACCOUNT_FILE")
ANVIL_DCC_ADMINS_GROUP_NAME = env("ANVIL_DCC_ADMINS_GROUP_NAME", default="DEV_GREGOR_DCC_ADMINS")
1 change: 1 addition & 0 deletions config/settings/production.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,4 @@
# ------------------------------------------------------------------------------
# Specify the path to the service account to use for managing access on AnVIL.
ANVIL_API_SERVICE_ACCOUNT_FILE = env("ANVIL_API_SERVICE_ACCOUNT_FILE")
ANVIL_DCC_ADMINS_GROUP_NAME = "GREGOR_DCC_ADMINS"
1 change: 1 addition & 0 deletions config/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@
# template tests require debug to be set
# get the last templates entry and set debug option
TEMPLATES[-1]["OPTIONS"]["debug"] = True # noqa
ANVIL_DCC_ADMINS_GROUP_NAME = "TEST_GREGOR_DCC_ADMINS"
94 changes: 85 additions & 9 deletions gregor_django/gregor_anvil/adapters.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,67 @@
from anvil_consortium_manager.adapters.account import BaseAccountAdapter
from anvil_consortium_manager.adapters.managed_group import BaseManagedGroupAdapter
from anvil_consortium_manager.adapters.workspace import BaseWorkspaceAdapter
from anvil_consortium_manager.forms import WorkspaceForm
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

from . import filters, forms, models, tables


class WorkspaceAdminSharingAdapterMixin:
"""Helper class to share workspaces with the GREGOR_DCC_ADMINs group."""

def after_anvil_create(self, workspace):
super().after_anvil_create(workspace)
# Share the workspace with the ADMINs group as an owner.
try:
admins_group = ManagedGroup.objects.get(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME)
except ManagedGroup.DoesNotExist:
return
sharing = WorkspaceGroupSharing.objects.create(
workspace=workspace,
group=admins_group,
access=WorkspaceGroupSharing.OWNER,
can_compute=True,
)
sharing.anvil_create_or_update()

def after_anvil_import(self, workspace):
super().after_anvil_import(workspace)
# # Check if the workspace is already shared with the ADMINs group.
try:
admins_group = ManagedGroup.objects.get(name=settings.ANVIL_DCC_ADMINS_GROUP_NAME)
except ManagedGroup.DoesNotExist:
return
try:
sharing = WorkspaceGroupSharing.objects.get(
workspace=workspace,
group=admins_group,
)
except WorkspaceGroupSharing.DoesNotExist:
sharing = WorkspaceGroupSharing.objects.create(
workspace=workspace,
group=admins_group,
access=WorkspaceGroupSharing.OWNER,
can_compute=True,
)
sharing.save()
sharing.anvil_create_or_update()
else:
# If the existing sharing record exists, make sure it has the correct permissions.
if not sharing.can_compute or sharing.access != WorkspaceGroupSharing.OWNER:
sharing.can_compute = True
sharing.access = WorkspaceGroupSharing.OWNER
sharing.save()
sharing.anvil_create_or_update()


class AccountAdapter(BaseAccountAdapter):
"""Custom account adapter for PRIMED."""

Expand All @@ -27,7 +83,27 @@ def get_autocomplete_label(self, account):
return "{} ({})".format(name, account.email)


class UploadWorkspaceAdapter(BaseWorkspaceAdapter):
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_DCC_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()


class UploadWorkspaceAdapter(WorkspaceAdminSharingAdapterMixin, BaseWorkspaceAdapter):
"""Adapter for UploadWorkspaces."""

type = "upload"
Expand Down Expand Up @@ -56,7 +132,7 @@ def get_autocomplete_queryset(self, queryset, q, forwarded={}):
return queryset


class PartnerUploadWorkspaceAdapter(BaseWorkspaceAdapter):
class PartnerUploadWorkspaceAdapter(WorkspaceAdminSharingAdapterMixin, BaseWorkspaceAdapter):
"""Adapter for PartnerUploadWorkspaces."""

type = "partner_upload"
Expand All @@ -71,7 +147,7 @@ class PartnerUploadWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_detail_template_name = "gregor_anvil/partneruploadworkspace_detail.html"


class ResourceWorkspaceAdapter(BaseWorkspaceAdapter):
class ResourceWorkspaceAdapter(WorkspaceAdminSharingAdapterMixin, BaseWorkspaceAdapter):
"""Adapter for ResourceWorkspaces."""

type = "resource"
Expand All @@ -87,7 +163,7 @@ class ResourceWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_form_class = WorkspaceForm


class TemplateWorkspaceAdapter(BaseWorkspaceAdapter):
class TemplateWorkspaceAdapter(WorkspaceAdminSharingAdapterMixin, BaseWorkspaceAdapter):
"""Adapter for ExampleWorkspaces."""

type = "template"
Expand All @@ -101,7 +177,7 @@ class TemplateWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_form_class = WorkspaceForm


class CombinedConsortiumDataWorkspaceAdapter(BaseWorkspaceAdapter):
class CombinedConsortiumDataWorkspaceAdapter(WorkspaceAdminSharingAdapterMixin, BaseWorkspaceAdapter):
"""Adapter for CombinedConsortiumDataWorkspace."""

type = "combined_consortium"
Expand All @@ -115,7 +191,7 @@ class CombinedConsortiumDataWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_form_class = WorkspaceForm


class ReleaseWorkspaceAdapter(BaseWorkspaceAdapter):
class ReleaseWorkspaceAdapter(WorkspaceAdminSharingAdapterMixin, BaseWorkspaceAdapter):
"""Adapter for ReleaseWorkspace."""

type = "release"
Expand All @@ -129,7 +205,7 @@ class ReleaseWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_form_class = WorkspaceForm


class DCCProcessingWorkspaceAdapter(BaseWorkspaceAdapter):
class DCCProcessingWorkspaceAdapter(WorkspaceAdminSharingAdapterMixin, BaseWorkspaceAdapter):
"""Adapter for DCCProcessingWorkspace."""

type = "dcc_processing"
Expand All @@ -143,7 +219,7 @@ class DCCProcessingWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_form_class = WorkspaceForm


class DCCProcessedDataWorkspaceAdapter(BaseWorkspaceAdapter):
class DCCProcessedDataWorkspaceAdapter(WorkspaceAdminSharingAdapterMixin, BaseWorkspaceAdapter):
"""Adapter for DCCProcessedDataWorkspace."""

type = "dcc_processed_data"
Expand All @@ -157,7 +233,7 @@ class DCCProcessedDataWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_form_class = WorkspaceForm


class ExchangeWorkspaceAdapter(BaseWorkspaceAdapter):
class ExchangeWorkspaceAdapter(WorkspaceAdminSharingAdapterMixin, BaseWorkspaceAdapter):
"""Adapter for ExchangeWorkspaces."""

type = "exchange"
Expand Down
Loading

0 comments on commit d43c139

Please sign in to comment.