From ea741698e78d7b74187b92f09056eee4d1816fc7 Mon Sep 17 00:00:00 2001 From: Valentin Rigal <rigal@teklia.com> Date: Fri, 30 Jun 2023 10:58:21 +0000 Subject: [PATCH] Restrict thumbnail S3 PUT URL --- arkindex/documents/serializers/elements.py | 16 ++++++++-- .../documents/tests/test_retrieve_elements.py | 29 +++++++++++++++++-- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/arkindex/documents/serializers/elements.py b/arkindex/documents/serializers/elements.py index fdcaff8144..e125a4f395 100644 --- a/arkindex/documents/serializers/elements.py +++ b/arkindex/documents/serializers/elements.py @@ -23,7 +23,7 @@ from arkindex.documents.serializers.light import ( from arkindex.documents.serializers.ml import ClassificationSerializer, WorkerRunSummarySerializer from arkindex.images.models import Image from arkindex.images.serializers import ZoneSerializer -from arkindex.ponos.utils import is_admin_or_ponos_task +from arkindex.ponos.models import Task from arkindex.process.models import WorkerVersion from arkindex.project.fields import Array from arkindex.project.mixins import SelectionMixin @@ -437,7 +437,19 @@ class ElementSlimSerializer(ElementTinySerializer): @extend_schema_field(serializers.CharField(allow_null=True)) def get_thumbnail_put_url(self, element): - if is_admin_or_ponos_task(self.context['request']) and element.type.folder: + """ + Only set the Thumbnail PUT URL for Ponos tasks that + are running the thumbnails generation on a folder. + """ + # TODO: This check would be simplified to process.thumbnails once that attribute + # is available, allowing to use the get_process_from_ponos_auth helper directly. + task = self.context.get('request') and self.context['request'].auth + if ( + isinstance(task, Task) + and element.type.folder + and task.image == settings.ARKINDEX_TASKS_IMAGE + and "generate_thumbnails" in task.command + ): return element.thumbnail.s3_put_url class Meta(ElementTinySerializer.Meta): diff --git a/arkindex/documents/tests/test_retrieve_elements.py b/arkindex/documents/tests/test_retrieve_elements.py index 1433be4a4a..aacf31f7cf 100644 --- a/arkindex/documents/tests/test_retrieve_elements.py +++ b/arkindex/documents/tests/test_retrieve_elements.py @@ -1,3 +1,4 @@ +from django.test import override_settings from django.urls import reverse from rest_framework import status @@ -110,9 +111,11 @@ class TestRetrieveElements(FixtureAPITestCase): self.assertIsNone(response.json()['thumbnail_url']) self.assertIsNone(response.json()['thumbnail_put_url']) + @override_settings(ARKINDEX_TASKS_IMAGE='task_image') def test_get_element_thumbnail_put_ponos_task(self): """ - Check getting an element only gives a thumbnail PUT URL to bots for folders + Check getting an element only gives a thumbnail PUT URL Ponos tasks + running the thumbnails generation command on a folder element """ process = Process.objects.create( mode=ProcessMode.Repository, @@ -121,8 +124,10 @@ class TestRetrieveElements(FixtureAPITestCase): ) process.start() task = process.tasks.get() + task.image = 'task_image' + task.command = 'python generate_thumbnails' - self.assertTrue(self.vol.type.folder) + task.save() response = self.client.get( reverse('api:element-retrieve', kwargs={'pk': str(self.vol.id)}), HTTP_AUTHORIZATION=f'Ponos {task.token}', @@ -138,6 +143,26 @@ class TestRetrieveElements(FixtureAPITestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsNone(response.json()['thumbnail_put_url']) + def test_get_element_thumbnail_put_requires_thumbnails_task(self): + """ + Only tasks that are intended to generate thumbnails (ARKINDEX_TASKS_IMAGE + thumbnails_generation command) + can retrieve the thumbnails PUT URL. + """ + process = Process.objects.create( + mode=ProcessMode.Repository, + revision=self.worker_version.revision, + creator=self.user, + ) + process.start() + task = process.tasks.get() + self.assertTrue(self.vol.type.folder) + response = self.client.get( + reverse('api:element-retrieve', kwargs={'pk': str(self.vol.id)}), + HTTP_AUTHORIZATION=f'Ponos {task.token}', + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIsNone(response.json()['thumbnail_put_url']) + def test_get_element_creator(self): self.vol.creator = self.user self.vol.save() -- GitLab