Skip to content

Commit

Permalink
Add accessor audits to the run_cdsa_audit management command
Browse files Browse the repository at this point in the history
  • Loading branch information
amstilp committed Jun 24, 2024
1 parent c134e86 commit ded77d2
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 33 deletions.
13 changes: 12 additions & 1 deletion primed/cdsa/management/commands/run_cdsa_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.template.loader import render_to_string
from django.urls import reverse

from ...audit import signed_agreement_audit, workspace_audit
from ...audit import accessor_audit, signed_agreement_audit, workspace_audit


class Command(BaseCommand):
Expand Down Expand Up @@ -37,6 +37,16 @@ def _audit_workspaces(self):
self._report_results(data_access_audit, url)
self._send_email(data_access_audit, url)

def _audit_accessors(self):
self.stdout.write("Running Accessor audit... ", ending="")
data_access_audit = accessor_audit.AccessorAudit()
data_access_audit.run_audit()

# Construct the url for handling errors.
url = "https://" + Site.objects.get_current().domain + reverse("cdsa:audit:signed_agreements:accessors:all")
self._report_results(data_access_audit, url)
self._send_email(data_access_audit, url)

def _report_results(self, data_access_audit, resolve_url):
# Report errors and needs access.
audit_ok = data_access_audit.ok()
Expand Down Expand Up @@ -78,3 +88,4 @@ def handle(self, *args, **options):
self.email = options["email"]
self._audit_signed_agreements()
self._audit_workspaces()
self._audit_accessors()
165 changes: 133 additions & 32 deletions primed/cdsa/tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from os.path import isdir, isfile

from anvil_consortium_manager.tests.factories import (
AccountFactory,
GroupGroupMembershipFactory,
ManagedGroupFactory,
)
Expand All @@ -16,6 +17,8 @@
from django.test import TestCase
from django.urls import reverse

from primed.users.tests.factories import UserFactory

from ..tests import factories


Expand Down Expand Up @@ -118,10 +121,15 @@ def test_command_output_no_records(self):
"Running CDSAWorkspace access audit... ok!\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
self.assertIn(expected_output, out.getvalue())
expected_output = "Running accessor audit... ok!\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 0\n"
expected_output = "Running uploader audit... ok!\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 0\n"
self.assertIn(expected_output, out.getvalue())
self.assertIn(expected_output, out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_run_audit_one_agreement_verified(self):
def test_command_agreements_one_agreement_verified(self):
"""Test command output with one verified instance."""
factories.MemberAgreementFactory.create(is_primary=False)
out = StringIO()
Expand All @@ -130,14 +138,10 @@ def test_command_run_audit_one_agreement_verified(self):
"Running SignedAgreement access audit... ok!\n" "* Verified: 1\n" "* Needs action: 0\n" "* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
expected_output = (
"Running CDSAWorkspace access audit... ok!\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_run_audit_one_agreement_needs_action(self):
def test_command_agreements_one_agreement_needs_action(self):
"""Test command output with one needs_action instance."""
factories.MemberAgreementFactory.create()
out = StringIO()
Expand All @@ -150,11 +154,10 @@ def test_command_run_audit_one_agreement_needs_action(self):
)
self.assertIn(expected_output, out.getvalue())
self.assertIn(reverse("cdsa:audit:signed_agreements:sag:all"), out.getvalue())
self.assertIn("Running CDSAWorkspace access audit... ok!", out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_run_audit_one_agreement_error(self):
def test_command_agreements_one_agreement_error(self):
"""Test command output with one error instance."""
agreement = factories.MemberAgreementFactory.create(is_primary=False)
GroupGroupMembershipFactory.create(
Expand All @@ -171,21 +174,19 @@ def test_command_run_audit_one_agreement_error(self):
)
self.assertIn(expected_output, out.getvalue())
self.assertIn(reverse("cdsa:audit:signed_agreements:sag:all"), out.getvalue())
self.assertIn("Running CDSAWorkspace access audit... ok!", out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_run_audit_one_agreement_verified_email(self):
def test_command_agreements_one_agreement_verified_email(self):
"""No email is sent when there are no errors."""
factories.MemberAgreementFactory.create(is_primary=False)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
self.assertIn("Running CDSAWorkspace access audit... ok!", out.getvalue())
self.assertIn("Running SignedAgreement access audit... ok!", out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_run_audit_one_agreement_needs_action_email(self):
def test_command_agreements_one_agreement_needs_action_email(self):
"""Email is sent for one needs_action instance."""
factories.MemberAgreementFactory.create()
out = StringIO()
Expand All @@ -197,15 +198,14 @@ def test_command_run_audit_one_agreement_needs_action_email(self):
"* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
self.assertIn("Running CDSAWorkspace access audit... ok!", out.getvalue())
# One message has been sent by default.
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
self.assertEqual(email.to, ["[email protected]"])
self.assertEqual(email.subject, "CDSA SignedAgreementAccessAudit errors")
self.assertIn(reverse("cdsa:audit:signed_agreements:sag:all"), email.alternatives[0][0])

def test_command_run_audit_one_agreement_error_email(self):
def test_command_agreements_one_agreement_error_email(self):
"""Test command output with one error instance."""
agreement = factories.MemberAgreementFactory.create(is_primary=False)
GroupGroupMembershipFactory.create(
Expand All @@ -222,31 +222,26 @@ def test_command_run_audit_one_agreement_error_email(self):
)
self.assertIn(expected_output, out.getvalue())
self.assertIn(reverse("cdsa:audit:signed_agreements:sag:all"), out.getvalue())
self.assertIn("Running CDSAWorkspace access audit... ok!", out.getvalue())
# One message has been sent by default.
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
self.assertEqual(email.to, ["[email protected]"])
self.assertEqual(email.subject, "CDSA SignedAgreementAccessAudit errors")
self.assertIn(reverse("cdsa:audit:signed_agreements:sag:all"), email.alternatives[0][0])

def test_command_run_audit_one_workspace_verified(self):
def test_command_workspaces_one_workspace_verified(self):
"""Test command output with one verified instance."""
factories.CDSAWorkspaceFactory.create()
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = (
"Running SignedAgreement access audit... ok!\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
expected_output = (
"Running CDSAWorkspace access audit... ok!\n" "* Verified: 1\n" "* Needs action: 0\n" "* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_run_audit_one_workspace_needs_action(self):
def test_command_workspaces_one_workspace_needs_action(self):
"""Test command output with one needs_action instance."""
agreement = factories.DataAffiliateAgreementFactory.create()
GroupGroupMembershipFactory.create(
Expand All @@ -264,11 +259,10 @@ def test_command_run_audit_one_workspace_needs_action(self):
)
self.assertIn(expected_output, out.getvalue())
self.assertIn(reverse("cdsa:audit:workspaces:all"), out.getvalue())
self.assertIn("Running SignedAgreement access audit... ok!", out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_run_audit_one_workspace_error(self):
def test_command_workspaces_one_workspace_error(self):
"""Test command output with one error instance."""
workspace = factories.CDSAWorkspaceFactory.create()
GroupGroupMembershipFactory.create(
Expand All @@ -285,21 +279,19 @@ def test_command_run_audit_one_workspace_error(self):
)
self.assertIn(expected_output, out.getvalue())
self.assertIn(reverse("cdsa:audit:workspaces:all"), out.getvalue())
self.assertIn("Running SignedAgreement access audit... ok!", out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_run_audit_one_workspace_verified_email(self):
def test_command_workspaces_one_workspace_verified_email(self):
"""No email is sent when there are no errors."""
factories.CDSAWorkspaceFactory.create()
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
self.assertIn("Running CDSAWorkspace access audit... ok!", out.getvalue())
self.assertIn("Running SignedAgreement access audit... ok!", out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_run_audit_one_workspace_needs_action_email(self):
def test_command_workspaces_one_workspace_needs_action_email(self):
"""Email is sent for one needs_action instance."""
agreement = factories.DataAffiliateAgreementFactory.create()
GroupGroupMembershipFactory.create(
Expand All @@ -316,15 +308,14 @@ def test_command_run_audit_one_workspace_needs_action_email(self):
"* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
self.assertIn("Running SignedAgreement access audit... ok!", out.getvalue())
# One message has been sent by default.
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
self.assertEqual(email.to, ["[email protected]"])
self.assertEqual(email.subject, "CDSA WorkspaceAccessAudit errors")
self.assertIn(reverse("cdsa:audit:workspaces:all"), email.alternatives[0][0])

def test_command_run_audit_one_workspace_error_email(self):
def test_command_workspaces_one_workspace_error_email(self):
"""Test command output with one error instance."""
workspace = factories.CDSAWorkspaceFactory.create()
GroupGroupMembershipFactory.create(
Expand All @@ -341,17 +332,121 @@ def test_command_run_audit_one_workspace_error_email(self):
)
self.assertIn(expected_output, out.getvalue())
self.assertIn(reverse("cdsa:audit:workspaces:all"), out.getvalue())
self.assertIn("Running SignedAgreement access audit... ok!", out.getvalue())
# One message has been sent by default.
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
self.assertEqual(email.to, ["[email protected]"])
self.assertEqual(email.subject, "CDSA WorkspaceAccessAudit errors")
self.assertIn(reverse("cdsa:audit:workspaces:all"), email.alternatives[0][0])

def test_signed_agreement_and_workspace_needs_action(self):
def test_accessors_no_accessors(self):
"""Test command output with no accessors."""
factories.MemberAgreementFactory.create(is_primary=False)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = "Running Accessor audit... ok!\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 0\n"
self.assertIn(expected_output, out.getvalue())
self.assertIn(expected_output, out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_accessors_verified(self):
"""Test command output with one verified instance."""
agreement = factories.MemberAgreementFactory.create(is_primary=False)
agreement.signed_agreement.accessors.add(UserFactory.create())
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = "Running Accessor audit... ok!\n" "* Verified: 1\n" "* Needs action: 0\n" "* Errors: 0\n"
self.assertIn(expected_output, out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_accessors_needs_action(self):
"""Test command output with one needs_action instance."""
agreement = factories.MemberAgreementFactory.create()
account = AccountFactory.create(verified=True)
agreement.signed_agreement.accessors.add(account.user)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = (
"Running Accessor audit... problems found.\n" "* Verified: 0\n" "* Needs action: 1\n" "* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
self.assertIn(reverse("cdsa:audit:signed_agreements:accessors:all"), out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_accessors_error(self):
"""Test command output with one error instance."""
agreement = factories.MemberAgreementFactory.create(is_primary=False)
GroupGroupMembershipFactory.create(
parent_group=agreement.signed_agreement.anvil_access_group,
)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = (
"Running Accessor audit... problems found.\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 1\n"
)
self.assertIn(expected_output, out.getvalue())
self.assertIn(reverse("cdsa:audit:signed_agreements:accessors:all"), out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_accessors_verified_email(self):
"""No email is sent when there are no errors."""
factories.MemberAgreementFactory.create(is_primary=False)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
self.assertIn("Running Accessor audit... ok!", out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_accessors_needs_action_email(self):
"""Email is sent for one needs_action instance."""
agreement = factories.MemberAgreementFactory.create()
GroupGroupMembershipFactory.create(
parent_group=self.cdsa_group,
child_group=agreement.signed_agreement.anvil_access_group,
)
account = AccountFactory.create(verified=True)
agreement.signed_agreement.accessors.add(account.user)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
expected_output = (
"Running Accessor audit... problems found.\n" "* Verified: 0\n" "* Needs action: 1\n" "* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
# One message has been sent by default.
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
self.assertEqual(email.to, ["[email protected]"])
self.assertEqual(email.subject, "CDSA AccessorAudit errors")
self.assertIn(reverse("cdsa:audit:signed_agreements:accessors:all"), email.alternatives[0][0])

def test_command_accessors_error_email(self):
"""Test command output with one error instance."""
agreement = factories.MemberAgreementFactory.create(is_primary=False)
GroupGroupMembershipFactory.create(
parent_group=agreement.signed_agreement.anvil_access_group,
)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
expected_output = (
"Running Accessor audit... problems found.\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 1\n"
)
self.assertIn(expected_output, out.getvalue())
self.assertIn(reverse("cdsa:audit:signed_agreements:accessors:all"), out.getvalue())
# One message has been sent by default.
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
self.assertEqual(email.to, ["[email protected]"])
self.assertEqual(email.subject, "CDSA AccessorAudit errors")
self.assertIn(reverse("cdsa:audit:signed_agreements:accessors:all"), email.alternatives[0][0])

def test_needs_action(self):
agreement = factories.DataAffiliateAgreementFactory.create()
factories.CDSAWorkspaceFactory.create(study=agreement.study)
agreement.signed_agreement.accessors.add(AccountFactory.create(verified=True).user)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = (
Expand All @@ -368,10 +463,15 @@ def test_signed_agreement_and_workspace_needs_action(self):
"* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
expected_output = (
"Running Accessor audit... problems found.\n" "* Verified: 0\n" "* Needs action: 1\n" "* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
# No messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)
self.fail("include accessor and uploader audits")

def test_signed_agreement_and_workspace_needs_action_email(self):
def test_needs_action_email(self):
agreement = factories.DataAffiliateAgreementFactory.create()
factories.CDSAWorkspaceFactory.create(study=agreement.study)
out = StringIO()
Expand Down Expand Up @@ -400,6 +500,7 @@ def test_signed_agreement_and_workspace_needs_action_email(self):
self.assertEqual(email.to, ["[email protected]"])
self.assertEqual(email.subject, "CDSA WorkspaceAccessAudit errors")
self.assertIn(reverse("cdsa:audit:workspaces:all"), email.alternatives[0][0])
self.fail("include accessor and uploader audits")

def test_different_domain(self):
"""Test command output when a different domain is specified."""
Expand Down

0 comments on commit ded77d2

Please sign in to comment.