Skip to content

Commit

Permalink
Send email to admins when un-embargo requested
Browse files Browse the repository at this point in the history
  • Loading branch information
jjnesbitt committed Apr 1, 2024
1 parent 8aa46d1 commit 4633632
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 2 deletions.
27 changes: 27 additions & 0 deletions dandiapi/api/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from allauth.socialaccount.models import SocialAccount
from django.contrib.auth.models import User

from dandiapi.api.models.dandiset import Dandiset

logger = logging.getLogger(__name__)

BASE_RENDER_CONTEXT = {
Expand Down Expand Up @@ -177,3 +179,28 @@ def send_pending_users_message(users: Iterable[User]):
messages = [build_pending_users_message(users)]
with mail.get_connection() as connection:
connection.send_messages(messages)


def build_dandisets_to_unembargo_message(dandisets: Iterable[Dandiset]):
dandiset_context = [
{
'identifier': ds.identifier,
'owners': [user.username for user in ds.owners],
'asset_count': ds.draft_version.asset_count,
'size': ds.draft_version.size,
}
for ds in dandisets
]
render_context = {**BASE_RENDER_CONTEXT, 'dandisets': dandiset_context}
return build_message(
subject='DANDI: new dandisets to un-embargo',
message=render_to_string('api/mail/dandisets_to_unembargo.txt', render_context),
to=[ADMIN_EMAIL],
)


def send_dandisets_to_unembargo_message(dandisets: Iterable[Dandiset]):
logger.info('Sending dandisets to un-embargo message to admins at %s', ADMIN_EMAIL)
messages = [build_dandisets_to_unembargo_message(dandisets)]
with mail.get_connection() as connection:
connection.send_messages(messages)
5 changes: 4 additions & 1 deletion dandiapi/api/services/embargo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ def unembargo_dandiset(*, user: User, dandiset: Dandiset):
if not user.has_perm('owner', dandiset):
raise DandisetOwnerRequiredError

# TODO: Send email to admins?
# A scheduled task will pick up any new dandisets with this status and email the admins to
# initiate the un-embargo process
dandiset.embargo_status = Dandiset.EmbargoStatus.UNEMBARGOING
dandiset.save()
14 changes: 13 additions & 1 deletion dandiapi/api/tasks/scheduled.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
from django.db.models.query_utils import Q

from dandiapi.analytics.tasks import collect_s3_log_records_task
from dandiapi.api.mail import send_pending_users_message
from dandiapi.api.mail import send_dandisets_to_unembargo_message, send_pending_users_message
from dandiapi.api.models import UserMetadata, Version
from dandiapi.api.models.asset import Asset
from dandiapi.api.models.dandiset import Dandiset
from dandiapi.api.services.metadata import version_aggregate_assets_summary
from dandiapi.api.services.metadata.exceptions import VersionMetadataConcurrentlyModifiedError
from dandiapi.api.tasks import (
Expand Down Expand Up @@ -111,6 +112,14 @@ def send_pending_users_email() -> None:
send_pending_users_message(pending_users)


@shared_task(soft_time_limit=20)
def send_dandisets_to_unembargo_email() -> None:
"""Send an email to admins listing dandisets that have requested un-embargo."""
dandisets = Dandiset.objects.filter(embargo_status=Dandiset.EmbargoStatus.UNEMBARGOING)
if dandisets.exists():
send_dandisets_to_unembargo_message(dandisets)


@shared_task(soft_time_limit=60)
def refresh_materialized_view_search() -> None:
"""
Expand Down Expand Up @@ -139,6 +148,9 @@ def register_scheduled_tasks(sender: Celery, **kwargs):
# Send daily email to admins containing a list of users awaiting approval
sender.add_periodic_task(crontab(hour=0, minute=0), send_pending_users_email.s())

# Send daily email to admins containing a list of dandisets to un-embargo
sender.add_periodic_task(crontab(hour=0, minute=0), send_dandisets_to_unembargo_email.s())

# Refresh the materialized view used by asset search every 10 mins.
sender.add_periodic_task(timedelta(minutes=10), refresh_materialized_view_search.s())

Expand Down
10 changes: 10 additions & 0 deletions dandiapi/api/templates/api/mail/dandisets_to_unembargo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% autoescape off %}
The following new dandisets are awaiting un-embargo:

{% for ds in dandisets %}
Dandiset ID: {{ ds.identifier }}
Owners: {{ ds.owners }}
Number of Assets: {{ ds.asset_count }}
Total data size: {{ ds.size }}
{% endfor %}
{% endautoescape %}
41 changes: 41 additions & 0 deletions dandiapi/api/tests/test_unembargo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from __future__ import annotations

from guardian.shortcuts import assign_perm
import pytest

from dandiapi.api.models.dandiset import Dandiset
from dandiapi.api.services.embargo import AssetBlobEmbargoedError, remove_asset_blob_embargoed_tag
from dandiapi.api.tasks.scheduled import send_dandisets_to_unembargo_email


@pytest.mark.django_db()
def test_remove_asset_blob_embargoed_tag_fails_on_embargod(embargoed_asset_blob, asset_blob):
with pytest.raises(AssetBlobEmbargoedError):
remove_asset_blob_embargoed_tag(embargoed_asset_blob)

# Test that error not raised on non-embargoed asset blob
remove_asset_blob_embargoed_tag(asset_blob)


@pytest.mark.django_db()
def test_unembargo_dandiset_sends_emails(
api_client, user, dandiset, draft_version_factory, mailoutbox
):
draft_version_factory(dandiset=dandiset)

assign_perm('owner', user, dandiset)
api_client.force_authenticate(user=user)

dandiset.embargo_status = Dandiset.EmbargoStatus.EMBARGOED
dandiset.save()

resp = api_client.post(f'/api/dandisets/{dandiset.identifier}/unembargo/')
assert resp.status_code == 200

# Simulate the scheduled task calling this function
send_dandisets_to_unembargo_email()

assert mailoutbox
assert 'un-embargo' in mailoutbox[0].subject
assert dandiset.identifier in mailoutbox[0].message().get_payload()
assert user.username in mailoutbox[0].message().get_payload()

0 comments on commit 4633632

Please sign in to comment.