]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Fix: check permissions for all documents via bulk download (#8631)
authorshamoon <4887959+shamoon@users.noreply.github.com>
Tue, 7 Jan 2025 08:10:11 +0000 (00:10 -0800)
committerGitHub <noreply@github.com>
Tue, 7 Jan 2025 08:10:11 +0000 (00:10 -0800)
src/documents/tests/test_api_bulk_download.py
src/documents/views.py

index 43299b77da99383189c07280dcd6b1beb80d330c..31bf182b571985fe681da80862ffbff84dc4c396 100644 (file)
@@ -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")
index be2343b90b05a04d785ecab8cfd6e2078c4036f5..d88105ea718c71ff3632dda3beae821c06ce9119 100644 (file)
@@ -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