Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display message in GUI when accessing embargoed dandiset #2060

Merged
merged 2 commits into from
Oct 29, 2024
Merged
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
15 changes: 15 additions & 0 deletions dandiapi/api/tests/test_dandiset.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,21 @@ def test_dandiset_rest_retrieve(api_client, dandiset):
}


@pytest.mark.django_db
def test_dandiset_rest_retrieve_embargoed(api_client, dandiset_factory, user):
dandiset: Dandiset = dandiset_factory(embargo_status=Dandiset.EmbargoStatus.EMBARGOED)
resp = api_client.get(f'/api/dandisets/{dandiset.identifier}/')
assert resp.status_code == 401

api_client.force_authenticate(user=user)
resp = api_client.get(f'/api/dandisets/{dandiset.identifier}/')
assert resp.status_code == 403

dandiset.set_owners([user])
resp = api_client.get(f'/api/dandisets/{dandiset.identifier}/')
assert resp.status_code == 200


@pytest.mark.parametrize(
('embargo_status'),
[choice[0] for choice in Dandiset.EmbargoStatus.choices],
Expand Down
55 changes: 49 additions & 6 deletions web/src/views/DandisetLandingView/DandisetLandingView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,30 @@
:total-visible="0"
/>
</v-toolbar>
<v-container v-if="embargoedOrUnauthenticated" class="d-flex justify-center align-center" style="height: 50vh;">
<div class="d-block blue-grey lighten-5 pa-4 rounded-lg">
<span class="text-h5">
<v-icon class="mb-1">
mdi-alert-circle
</v-icon>
This Dandiset is Embargoed
</span>
<br><br>
<span class="text-body-2">
If you are an owner of this Dandiset, please log in to enable access.
</span>
<br>
<span class="text-body-2">
If you are a member of this project, contact the Dandiset owners to enable access.
</span>
<br><br>
<span class="text-body-2">
For further assistance, please contact <a href="mailto:help@dandiarchive.org">help@dandiarchive.org</a>.
</span>
</div>
</v-container>
<v-container
v-if="dandisetDoesNotExist"
v-else-if="dandisetDoesNotExist"
class="d-flex justify-center align-center"
style="height: 50vh;"
>
Expand Down Expand Up @@ -92,6 +114,7 @@ import {
import type { Ref } from 'vue';
import { onBeforeRouteLeave, useRoute, useRouter } from 'vue-router/composables';
import type { NavigationGuardNext, RawLocation, Route } from 'vue-router';
import axios from 'axios';

import DandisetSearchField from '@/components/DandisetSearchField.vue';
import Meditor from '@/components/Meditor/Meditor.vue';
Expand Down Expand Up @@ -121,7 +144,7 @@ const props = defineProps({
onBeforeRouteLeave((to: Route, from: Route, next: NavigationGuardNext) => {
// Prompt user if they try to leave the DLP with unsaved changes in the meditor
if (!editorInterface.value?.transactionTracker?.isModified()
// eslint-disable-next-line no-alert
// eslint-disable-next-line no-alert
|| window.confirm('You have unsaved changes, are you sure you want to leave?')) {
next();
return true;
Expand All @@ -139,6 +162,10 @@ const loading = ref(false);
// If loading is finished and currentDandiset is still null, the dandiset doesn't exist.
const dandisetDoesNotExist = computed(() => !loading.value && !currentDandiset.value);

// This is set if the request to retrieve the dandiset fails
// due to it being embargoed, or the user being unauthenticated
const embargoedOrUnauthenticated = ref(false);

const schema = computed(() => store.schema);
const userCanModifyDandiset = computed(() => store.userCanModifyDandiset);

Expand All @@ -161,11 +188,27 @@ function navigateToVersion(versionToNavigateTo: string) {
// https://stackoverflow.com/a/59127059
watch(() => props.identifier, async () => {
const { identifier, version } = props;
if (identifier) {
loading.value = true;
if (!identifier) {
return;
}

// Set default values
embargoedOrUnauthenticated.value = false;
loading.value = true;

// Catch error to check if response is 401, for embargoed dandisets
try {
await store.initializeDandisets({ identifier, version });
loading.value = false;

} catch (e) {
if (axios.isAxiosError(e) && (e.response?.status === 401 || e.response?.status === 403)) {
embargoedOrUnauthenticated.value = true
} else {
throw e
}
}

loading.value = false;
}, { immediate: true });

watch([() => props.identifier, () => props.version], async () => {
Expand Down Expand Up @@ -194,7 +237,7 @@ watch([() => props.identifier, () => props.version], async () => {

const page = ref(Number(route.query.pos) || 1);
const pages = ref(1);
const nextDandiset : Ref<any[]> = ref([]);
const nextDandiset: Ref<any[]> = ref([]);

async function fetchNextPage() {
const sortOption = Number(route.query.sortOption) || 0;
Expand Down