Skip to content

Commit

Permalink
Add uploader audits to 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 ded77d2 commit e87096a
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 21 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 accessor_audit, signed_agreement_audit, workspace_audit
from ...audit import accessor_audit, signed_agreement_audit, uploader_audit, workspace_audit


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

def _audit_uploaders(self):
self.stdout.write("Running Uploader audit... ", ending="")
data_access_audit = uploader_audit.UploaderAudit()
data_access_audit.run_audit()

# Construct the url for handling errors.
url = "https://" + Site.objects.get_current().domain + reverse("cdsa:audit:signed_agreements:uploaders: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 @@ -89,3 +99,4 @@ def handle(self, *args, **options):
self._audit_signed_agreements()
self._audit_workspaces()
self._audit_accessors()
self._audit_uploaders()
165 changes: 145 additions & 20 deletions primed/cdsa/tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def test_representative_records_zero(self):
self.assertEqual(len(lines), 1)

def test_representative_records_three(self):
factories.MemberAgreementFactory.create()
factories.DataAffiliateAgreementFactory.create()
factories.DataAffiliateAgreementFactory.create()
factories.NonDataAffiliateAgreementFactory.create()
out = StringIO()
Expand Down Expand Up @@ -122,16 +122,16 @@ def test_command_output_no_records(self):
)
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"
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_agreements_one_agreement_verified(self):
"""Test command output with one verified instance."""
factories.MemberAgreementFactory.create(is_primary=False)
factories.DataAffiliateAgreementFactory.create(is_primary=False)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = (
Expand All @@ -143,7 +143,7 @@ def test_command_agreements_one_agreement_verified(self):

def test_command_agreements_one_agreement_needs_action(self):
"""Test command output with one needs_action instance."""
factories.MemberAgreementFactory.create()
factories.DataAffiliateAgreementFactory.create()
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = (
Expand All @@ -159,7 +159,7 @@ def test_command_agreements_one_agreement_needs_action(self):

def test_command_agreements_one_agreement_error(self):
"""Test command output with one error instance."""
agreement = factories.MemberAgreementFactory.create(is_primary=False)
agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False)
GroupGroupMembershipFactory.create(
parent_group=self.cdsa_group,
child_group=agreement.signed_agreement.anvil_access_group,
Expand All @@ -179,7 +179,7 @@ def test_command_agreements_one_agreement_error(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)
factories.DataAffiliateAgreementFactory.create(is_primary=False)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
self.assertIn("Running SignedAgreement access audit... ok!", out.getvalue())
Expand All @@ -188,7 +188,7 @@ def test_command_agreements_one_agreement_verified_email(self):

def test_command_agreements_one_agreement_needs_action_email(self):
"""Email is sent for one needs_action instance."""
factories.MemberAgreementFactory.create()
factories.DataAffiliateAgreementFactory.create()
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
expected_output = (
Expand All @@ -207,7 +207,7 @@ def test_command_agreements_one_agreement_needs_action_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)
agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False)
GroupGroupMembershipFactory.create(
parent_group=self.cdsa_group,
child_group=agreement.signed_agreement.anvil_access_group,
Expand Down Expand Up @@ -341,7 +341,7 @@ def test_command_workspaces_one_workspace_error_email(self):

def test_accessors_no_accessors(self):
"""Test command output with no accessors."""
factories.MemberAgreementFactory.create(is_primary=False)
factories.DataAffiliateAgreementFactory.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"
Expand All @@ -352,7 +352,7 @@ def test_accessors_no_accessors(self):

def test_command_accessors_verified(self):
"""Test command output with one verified instance."""
agreement = factories.MemberAgreementFactory.create(is_primary=False)
agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False)
agreement.signed_agreement.accessors.add(UserFactory.create())
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
Expand All @@ -363,7 +363,7 @@ def test_command_accessors_verified(self):

def test_command_accessors_needs_action(self):
"""Test command output with one needs_action instance."""
agreement = factories.MemberAgreementFactory.create()
agreement = factories.DataAffiliateAgreementFactory.create()
account = AccountFactory.create(verified=True)
agreement.signed_agreement.accessors.add(account.user)
out = StringIO()
Expand All @@ -378,7 +378,7 @@ def test_command_accessors_needs_action(self):

def test_command_accessors_error(self):
"""Test command output with one error instance."""
agreement = factories.MemberAgreementFactory.create(is_primary=False)
agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False)
GroupGroupMembershipFactory.create(
parent_group=agreement.signed_agreement.anvil_access_group,
)
Expand All @@ -394,7 +394,7 @@ def test_command_accessors_error(self):

def test_command_accessors_verified_email(self):
"""No email is sent when there are no errors."""
factories.MemberAgreementFactory.create(is_primary=False)
factories.DataAffiliateAgreementFactory.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())
Expand All @@ -403,7 +403,7 @@ def test_command_accessors_verified_email(self):

def test_command_accessors_needs_action_email(self):
"""Email is sent for one needs_action instance."""
agreement = factories.MemberAgreementFactory.create()
agreement = factories.DataAffiliateAgreementFactory.create()
GroupGroupMembershipFactory.create(
parent_group=self.cdsa_group,
child_group=agreement.signed_agreement.anvil_access_group,
Expand All @@ -425,7 +425,7 @@ def test_command_accessors_needs_action_email(self):

def test_command_accessors_error_email(self):
"""Test command output with one error instance."""
agreement = factories.MemberAgreementFactory.create(is_primary=False)
agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False)
GroupGroupMembershipFactory.create(
parent_group=agreement.signed_agreement.anvil_access_group,
)
Expand All @@ -443,10 +443,115 @@ def test_command_accessors_error_email(self):
self.assertEqual(email.subject, "CDSA AccessorAudit errors")
self.assertIn(reverse("cdsa:audit:signed_agreements:accessors:all"), email.alternatives[0][0])

def test_uploaders_no_uploaders(self):
"""Test command output with no uploaders."""
factories.DataAffiliateAgreementFactory.create(is_primary=False)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
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_uploaders_verified(self):
"""Test command output with one verified instance."""
agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False)
agreement.uploaders.add(UserFactory.create())
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = "Running Uploader 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_uploaders_needs_action(self):
"""Test command output with one needs_action instance."""
agreement = factories.DataAffiliateAgreementFactory.create()
account = AccountFactory.create(verified=True)
agreement.uploaders.add(account.user)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = (
"Running Uploader 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:uploaders:all"), out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

def test_command_uploaders_error(self):
"""Test command output with one error instance."""
agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False)
GroupGroupMembershipFactory.create(
parent_group=agreement.anvil_upload_group,
)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = (
"Running Uploader 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:uploaders:all"), out.getvalue())
# Zero messages have been sent by default.
self.assertEqual(len(mail.outbox), 0)

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

def test_command_uploaders_needs_action_email(self):
"""Email is sent for one needs_action instance."""
agreement = factories.DataAffiliateAgreementFactory.create()
GroupGroupMembershipFactory.create(
parent_group=self.cdsa_group,
child_group=agreement.signed_agreement.anvil_access_group,
)
account = AccountFactory.create(verified=True)
agreement.uploaders.add(account.user)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
expected_output = (
"Running Uploader 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 UploaderAudit errors")
self.assertIn(reverse("cdsa:audit:signed_agreements:uploaders:all"), email.alternatives[0][0])

def test_command_uploaders_error_email(self):
"""Test command output with one error instance."""
agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False)
GroupGroupMembershipFactory.create(
parent_group=agreement.anvil_upload_group,
)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
expected_output = (
"Running Uploader 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:uploaders: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 UploaderAudit errors")
self.assertIn(reverse("cdsa:audit:signed_agreements:uploaders: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)
agreement.uploaders.add(AccountFactory.create(verified=True).user)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", stdout=out)
expected_output = (
Expand All @@ -467,13 +572,18 @@ def test_needs_action(self):
"Running Accessor audit... problems found.\n" "* Verified: 0\n" "* Needs action: 1\n" "* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
expected_output = (
"Running Uploader 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_needs_action_email(self):
agreement = factories.DataAffiliateAgreementFactory.create()
factories.CDSAWorkspaceFactory.create(study=agreement.study)
agreement.signed_agreement.accessors.add(AccountFactory.create(verified=True).user)
agreement.uploaders.add(AccountFactory.create(verified=True).user)
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
expected_output = (
Expand All @@ -490,8 +600,16 @@ def test_needs_action_email(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())
expected_output = (
"Running Uploader audit... problems found.\n" "* Verified: 0\n" "* Needs action: 1\n" "* Errors: 0\n"
)
self.assertIn(expected_output, out.getvalue())
# Two messages has been sent.
self.assertEqual(len(mail.outbox), 2)
self.assertEqual(len(mail.outbox), 4)
email = mail.outbox[0]
self.assertEqual(email.to, ["[email protected]"])
self.assertEqual(email.subject, "CDSA SignedAgreementAccessAudit errors")
Expand All @@ -500,13 +618,20 @@ def test_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")
email = mail.outbox[2]
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])
email = mail.outbox[3]
self.assertEqual(email.to, ["[email protected]"])
self.assertEqual(email.subject, "CDSA UploaderAudit errors")
self.assertIn(reverse("cdsa:audit:signed_agreements:uploaders:all"), email.alternatives[0][0])

def test_different_domain(self):
"""Test command output when a different domain is specified."""
site = Site.objects.create(domain="foobar.com", name="test")
site.save()
factories.MemberAgreementFactory.create()
factories.DataAffiliateAgreementFactory.create()
with self.settings(SITE_ID=site.id):
out = StringIO()
call_command("run_cdsa_audit", "--no-color", email="[email protected]", stdout=out)
Expand Down

0 comments on commit e87096a

Please sign in to comment.