diff --git a/src/documents/tests/test_api_bulk_download.py b/src/documents/tests/test_api_bulk_download.py index 43299b77d..31bf182b5 100644 --- a/src/documents/tests/test_api_bulk_download.py +++ b/src/documents/tests/test_api_bulk_download.py @@ -23,8 +23,8 @@ class TestBulkDownload(DirectoriesMixin, APITestCase): def setUp(self): super().setUp() - user = User.objects.create_superuser(username="temp_admin") - self.client.force_authenticate(user=user) + self.user = User.objects.create_superuser(username="temp_admin") + self.client.force_authenticate(user=self.user) self.doc1 = Document.objects.create(title="unrelated", checksum="A") self.doc2 = Document.objects.create( @@ -333,3 +333,19 @@ class TestBulkDownload(DirectoriesMixin, APITestCase): f.read(), zipf.read("originals/statement/Title 2 - Doc 3.jpg"), ) + + def test_download_insufficient_permissions(self): + user = User.objects.create_user(username="temp_user") + self.client.force_authenticate(user=user) + + self.doc2.owner = self.user + self.doc2.save() + + response = self.client.post( + self.ENDPOINT, + json.dumps({"documents": [self.doc2.id, self.doc3.id]}), + content_type="application/json", + ) + + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertEqual(response.content, b"Insufficient permissions") diff --git a/src/documents/views.py b/src/documents/views.py index be2343b90..d88105ea7 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -1584,10 +1584,15 @@ class BulkDownloadView(GenericAPIView): serializer.is_valid(raise_exception=True) ids = serializer.validated_data.get("documents") + documents = Document.objects.filter(pk__in=ids) compression = serializer.validated_data.get("compression") content = serializer.validated_data.get("content") follow_filename_format = serializer.validated_data.get("follow_formatting") + for document in documents: + if not has_perms_owner_aware(request.user, "view_document", document): + return HttpResponseForbidden("Insufficient permissions") + settings.SCRATCH_DIR.mkdir(parents=True, exist_ok=True) temp = tempfile.NamedTemporaryFile( # noqa: SIM115 dir=settings.SCRATCH_DIR, @@ -1604,7 +1609,7 @@ class BulkDownloadView(GenericAPIView): with zipfile.ZipFile(temp.name, "w", compression) as zipf: strategy = strategy_class(zipf, follow_filename_format) - for document in Document.objects.filter(pk__in=ids): + for document in documents: strategy.add_document(document) # TODO(stumpylog): Investigate using FileResponse here