From 074585337be3d0e3c09d1c33a4aeb0de6b80e8a2 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 21 May 2025 15:09:40 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F(back)=20return=20the=20media?= =?UTF-8?q?-check=20url=20on=20the=20attachment=5Fupload=20response?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to have the media-check url returned on the attachment-upload response instead of the media url directly. The front will know the endpoint to use to check the media status. --- src/backend/core/api/viewsets.py | 13 +++++- .../test_api_documents_attachment_upload.py | 43 ++++++++++++++----- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index f8b6a56e..cc90dcb2 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -4,7 +4,7 @@ import json import logging import uuid -from urllib.parse import unquote, urlparse +from urllib.parse import unquote, urlencode, urlparse from django.conf import settings from django.contrib.postgres.aggregates import ArrayAgg @@ -18,6 +18,7 @@ from django.db import models as db from django.db.models.expressions import RawSQL from django.db.models.functions import Left, Length from django.http import Http404, StreamingHttpResponse +from django.urls import reverse from django.utils.text import capfirst, slugify from django.utils.translation import gettext_lazy as _ @@ -1193,8 +1194,16 @@ class DocumentViewSet( malware_detection.analyse_file(key, document_id=document.id) + url = reverse( + "documents-media-check", + kwargs={"pk": document.id}, + ) + parameters = urlencode({"key": key}) + return drf.response.Response( - {"file": f"{settings.MEDIA_URL:s}{key:s}"}, + { + "file": f"{url:s}?{parameters:s}", + }, status=drf.status.HTTP_201_CREATED, ) diff --git a/src/backend/core/tests/documents/test_api_documents_attachment_upload.py b/src/backend/core/tests/documents/test_api_documents_attachment_upload.py index 94fd9771..05fb5757 100644 --- a/src/backend/core/tests/documents/test_api_documents_attachment_upload.py +++ b/src/backend/core/tests/documents/test_api_documents_attachment_upload.py @@ -5,6 +5,7 @@ Test file uploads API endpoint for users in impress's core app. import re import uuid from unittest import mock +from urllib.parse import parse_qs, urlparse from django.core.files.storage import default_storage from django.core.files.uploadedfile import SimpleUploadedFile @@ -66,8 +67,12 @@ def test_api_documents_attachment_upload_anonymous_success(): assert response.status_code == 201 - pattern = re.compile(rf"^/media/{document.id!s}/attachments/(.*)\.png") - file_path = response.json()["file"] + pattern = re.compile(rf"^{document.id!s}/attachments/(.*)\.png") + url_parsed = urlparse(response.json()["file"]) + assert url_parsed.path == f"/api/v1.0/documents/{document.id!s}/media-check/" + query = parse_qs(url_parsed.query) + assert query["key"][0] is not None + file_path = query["key"][0] match = pattern.search(file_path) file_id = match.group(1) # Validate that file_id is a valid UUID @@ -148,8 +153,13 @@ def test_api_documents_attachment_upload_authenticated_success(reach, role): assert response.status_code == 201 - pattern = re.compile(rf"^/media/{document.id!s}/attachments/(.*)\.png") - match = pattern.search(response.json()["file"]) + pattern = re.compile(rf"^{document.id!s}/attachments/(.*)\.png") + url_parsed = urlparse(response.json()["file"]) + assert url_parsed.path == f"/api/v1.0/documents/{document.id!s}/media-check/" + query = parse_qs(url_parsed.query) + assert query["key"][0] is not None + file_path = query["key"][0] + match = pattern.search(file_path) file_id = match.group(1) mock_analyse_file.assert_called_once_with( @@ -224,8 +234,12 @@ def test_api_documents_attachment_upload_success(via, role, mock_user_teams): assert response.status_code == 201 - file_path = response.json()["file"] - pattern = re.compile(rf"^/media/{document.id!s}/attachments/(.*)\.png") + pattern = re.compile(rf"^{document.id!s}/attachments/(.*)\.png") + url_parsed = urlparse(response.json()["file"]) + assert url_parsed.path == f"/api/v1.0/documents/{document.id!s}/media-check/" + query = parse_qs(url_parsed.query) + assert query["key"][0] is not None + file_path = query["key"][0] match = pattern.search(file_path) file_id = match.group(1) @@ -320,8 +334,13 @@ def test_api_documents_attachment_upload_fix_extension( assert response.status_code == 201 - file_path = response.json()["file"] - pattern = re.compile(rf"^/media/{document.id!s}/attachments/(.*)\.{extension:s}") + pattern = re.compile(rf"^{document.id!s}/attachments/(.*)\.{extension:s}") + url_parsed = urlparse(response.json()["file"]) + assert url_parsed.path == f"/api/v1.0/documents/{document.id!s}/media-check/" + query = parse_qs(url_parsed.query) + assert query["key"][0] is not None + file_path = query["key"][0] + match = pattern.search(file_path) file_id = match.group(1) @@ -386,8 +405,12 @@ def test_api_documents_attachment_upload_unsafe(): assert response.status_code == 201 - file_path = response.json()["file"] - pattern = re.compile(rf"^/media/{document.id!s}/attachments/(.*)\.exe") + pattern = re.compile(rf"^{document.id!s}/attachments/(.*)\.exe") + url_parsed = urlparse(response.json()["file"]) + assert url_parsed.path == f"/api/v1.0/documents/{document.id!s}/media-check/" + query = parse_qs(url_parsed.query) + assert query["key"][0] is not None + file_path = query["key"][0] match = pattern.search(file_path) file_id = match.group(1)