Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions dandiapi/api/models/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from django.core.validators import RegexValidator
from django.db import models
from django.db.models.query_utils import Q
from django.utils import timezone
from django_extensions.db.models import TimeStampedModel

from dandiapi.api.asset_paths import get_root_paths
Expand Down Expand Up @@ -216,13 +217,26 @@ def _populate_access_metadata(self):
# Ensure that every item in access is a dict
access = [x for x in access if isinstance(x, dict)] or default_access

new_status = (
AccessType.EmbargoedAccess.value
if self.dandiset.embargoed
else AccessType.OpenAccess.value
)

# When transitioning from embargoed to open access, record the actual
# unembargo timestamp in embargoedUntil.
# See https://github.com/dandi/dandi-schema/pull/143 for the field semantics.
if (
access[0].get('status') == AccessType.EmbargoedAccess.value
and new_status == AccessType.OpenAccess.value
):
access[0]['embargoedUntil'] = timezone.now().isoformat()

# Set first access item
access[0] = {
**access[0],
'schemaKey': 'AccessRequirements',
'status': AccessType.EmbargoedAccess.value
if self.dandiset.embargoed
else AccessType.OpenAccess.value,
'status': new_status,
}

return access
Expand Down
20 changes: 20 additions & 0 deletions dandiapi/api/tests/test_unembargo.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from __future__ import annotations

import datetime
from typing import TYPE_CHECKING

import dandischema
from django.core.files.storage import default_storage
from django.utils import timezone
import pytest

from dandiapi.api.manifests import all_manifest_filepaths
Expand Down Expand Up @@ -255,10 +257,22 @@ def test_unembargo_dandiset(

write_manifest_files(draft_version.id)

# Seed access metadata to match what would exist in reality: the version was
# created while EMBARGOED (with EmbargoedAccess status and a future embargoedUntil),
# then kickoff changed the dandiset to UNEMBARGOING without saving the version.
original_embargoed_until = '2099-01-01T00:00:00+00:00'
draft_version.metadata['access'][0]['status'] = (
dandischema.models.AccessType.EmbargoedAccess.value
)
draft_version.metadata['access'][0]['embargoedUntil'] = original_embargoed_until
draft_version.save()

assert all(asset.is_embargoed for asset in draft_version.assets.all())
assert all(asset.status == Asset.Status.VALID for asset in draft_version.assets.all())

before_unembargo = timezone.now()
unembargo_dandiset(dandiset, owners[0])
after_unembargo = timezone.now()

for zarr_file in zarr_files:
zarr_file_s3_path = zarr_archive.s3_path(str(zarr_file.path))
Expand All @@ -277,6 +291,12 @@ def test_unembargo_dandiset(
== dandischema.models.AccessType.OpenAccess.value
)

# Verify embargoedUntil was replaced with the actual unembargo timestamp
embargoed_until = draft_version.metadata['access'][0]['embargoedUntil']
assert embargoed_until != original_embargoed_until
embargoed_until_dt = datetime.datetime.fromisoformat(embargoed_until)
assert before_unembargo <= embargoed_until_dt <= after_unembargo

# Check that a correct email exists
assert mailoutbox
assert 'has been unembargoed' in mailoutbox[0].subject
Expand Down
Loading