Commit bd6de05d authored by Mickaël Desfrênes's avatar Mickaël Desfrênes
Browse files

ARK manifests and IIIF annotations require public status

parent b0132db8
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -78,8 +78,10 @@ def serialize_jama_resource(
        height = file_instance.image_height()
    metadata = []  # @todo
    annotation_page_id = f"{settings.JAMA_SITE}iiif/annotations/page/{resource_id}"
    if annotations is None:
        annotations = _annotations_for_resource(resource_instance.pk)
    serialized_annotations = _serialize_jama_resource_annotations(
        annotations or _annotations_for_resource(resource_instance.pk), canvas_id
        annotations, canvas_id
    )
    resource_label = resource_instance.title
    return {
@@ -132,6 +134,8 @@ def _serialize_jama_resource_annotations(
) -> list[dict]:
    annotations_list = []
    for annotation in annotations:
        if not annotation.public:
            continue
        annotation_id = f"{settings.JAMA_SITE}iiif/annotation/{annotation.id}"
        creator = _annotation_creator(annotation)
        annotations_list.append(
@@ -162,7 +166,7 @@ def _annotations_by_resource_id(
        return annotations_by_resource_id

    for annotation in (
        Annotation.objects.filter(resource_id__in=resource_ids)
        Annotation.objects.filter(resource_id__in=resource_ids, public=True)
        .select_related("owner")
        .order_by("created_at")
    ):
@@ -173,7 +177,7 @@ def _annotations_by_resource_id(

def _annotations_for_resource(resource_id: int) -> list[Annotation]:
    return list(
        Annotation.objects.filter(resource_id=resource_id)
        Annotation.objects.filter(resource_id=resource_id, public=True)
        .select_related("owner")
        .order_by("created_at")
    )
+70 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ from unittest.mock import patch

from django.contrib.auth.models import User
from django.db import connection
from django.http import Http404
from django.test import (
    Client,
    RequestFactory,
@@ -25,6 +26,7 @@ from jama.admin_services import tasks as task_services
from jama import settings as jama_settings
from annotations.models import Annotation
from jama.iiif import serialize_jama_collection
from jama.views import ark_resource_or_collection_iiif_manifest
from resources import acl
from resources.models import (
    APIKey,
@@ -814,6 +816,7 @@ class IiifSerializationTestCase(TestCase):
        Annotation.objects.create(
            resource=first_file,
            owner=self.owner,
            public=True,
            data={
                "svg": '<rect x="1" y="2" width="3" height="4" />',
                "bodies": [{"title": "Note", "contents": "Alpha"}],
@@ -822,8 +825,18 @@ class IiifSerializationTestCase(TestCase):
        Annotation.objects.create(
            resource=second_file,
            owner=self.owner,
            public=True,
            data={"svg": "", "bodies": [{"motivation": "tagging", "contents": {}}]},
        )
        Annotation.objects.create(
            resource=first_file,
            owner=self.owner,
            public=False,
            data={
                "svg": "",
                "bodies": [{"title": "Private note", "contents": "Secret"}],
            },
        )

        request = self.factory.get("/iiif/manifest/")

@@ -842,4 +855,61 @@ class IiifSerializationTestCase(TestCase):
            payload["items"][0]["annotations"][0]["items"][0]["creator"],
            "Ada Lovelace",
        )
        self.assertEqual(len(payload["items"][0]["annotations"][0]["items"]), 1)
        self.assertNotIn("Secret", response.content.decode())
        self.assertLessEqual(len(queries), 5)

    def test_ark_manifest_stops_serving_collection_after_unpublish(self):
        self.collection.ark = "12345/collection"
        self.collection.public_access = True
        self.collection.save(update_fields=["ark", "public_access"])
        request = self.factory.get("/ark/12345/collection/iiif/manifest/")

        response = ark_resource_or_collection_iiif_manifest(
            request, "12345", "collection"
        )
        self.assertEqual(response.status_code, 200)

        self.collection.public_access = False
        self.collection.save(update_fields=["public_access"])

        with self.assertRaises(Http404):
            ark_resource_or_collection_iiif_manifest(request, "12345", "collection")

    def test_ark_manifest_stops_serving_annotation_after_making_it_private(self):
        self.collection.ark = "12345/annotated-collection"
        self.collection.public_access = True
        self.collection.save(update_fields=["ark", "public_access"])
        file_instance = File.objects.create(
            title="annotated page",
            original_name="annotated-page.jpg",
            project=self.project,
            hash="ee" * 32,
            file_type=self.file_type,
            size=100,
            denormalized_image_width=1200,
            denormalized_image_height=800,
        )
        CollectionMembership.objects.create(
            collection=self.collection, resource=file_instance
        )
        annotation = Annotation.objects.create(
            resource=file_instance,
            owner=self.owner,
            public=True,
            data={"bodies": [{"title": "Public note", "contents": "Sensitive"}]},
        )
        request = self.factory.get("/ark/12345/annotated-collection/iiif/manifest/")

        response = ark_resource_or_collection_iiif_manifest(
            request, "12345", "annotated-collection"
        )
        self.assertContains(response, "Sensitive")

        annotation.public = False
        annotation.save(update_fields=["public"])

        response = ark_resource_or_collection_iiif_manifest(
            request, "12345", "annotated-collection"
        )
        self.assertNotContains(response, "Sensitive")
+2 −2
Original line number Diff line number Diff line
@@ -5,7 +5,6 @@ from django.contrib.auth.models import User
from resources.models import Resource, Collection, Project
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
from .iiif import serialize_jama_collection
from django.views.decorators.cache import cache_page


def merge_query_string_to_url(url: str, qs: str) -> str:
@@ -64,7 +63,6 @@ def status(request: HttpRequest) -> HttpResponse:
    return HttpResponse("ok")


@cache_page(60 * 60 * 24)
def ark_collection_iiif_manifest(
    request: HttpRequest, naan: str, assigned_name: str
) -> HttpResponse:
@@ -72,6 +70,7 @@ def ark_collection_iiif_manifest(
    collection = Collection.objects.filter(
        deleted_at__isnull=True,
        ark=ark_name,
        public_access=True,
        project__restore_state=Project.RESTORE_STATE_READY,
    ).first()
    if collection:
@@ -93,6 +92,7 @@ def ark_resource_or_collection_iiif_manifest(
    collection = Collection.objects.filter(
        deleted_at__isnull=True,
        ark=ark_name,
        public_access=True,
        project__restore_state=Project.RESTORE_STATE_READY,
    ).first()
    if collection: