]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Fix: remove unnecessary permission requirements for new email endpoint (#11215)
authorshamoon <4887959+shamoon@users.noreply.github.com>
Wed, 29 Oct 2025 14:14:51 +0000 (07:14 -0700)
committerGitHub <noreply@github.com>
Wed, 29 Oct 2025 14:14:51 +0000 (07:14 -0700)
src/documents/permissions.py
src/documents/tests/test_api_email.py
src/documents/views.py

index a2b165fd8f73c042334243a10e82c4e45e9b24c7..cf6a9aa35c09198d885aed26792354e2aea1fb4d 100644 (file)
@@ -164,6 +164,24 @@ def has_perms_owner_aware(user, perms, obj):
     return obj.owner is None or obj.owner == user or checker.has_perm(perms, obj)
 
 
+class ViewDocumentsPermissions(BasePermission):
+    """
+    Permissions class that checks for model permissions for only viewing Documents.
+    """
+
+    perms_map = {
+        "OPTIONS": ["documents.view_document"],
+        "GET": ["documents.view_document"],
+        "POST": ["documents.view_document"],
+    }
+
+    def has_permission(self, request, view):
+        if not request.user or (not request.user.is_authenticated):  # pragma: no cover
+            return False
+
+        return request.user.has_perms(self.perms_map.get(request.method, []))
+
+
 class PaperlessNotePermissions(BasePermission):
     """
     Permissions class that checks for model permissions for Notes.
index 0f9bd969588c46cda1e569ceb9b7ae0ec1b1bbf4..884553dba77363142e2a1ba20d72dfe25aea746e 100644 (file)
@@ -329,6 +329,34 @@ class TestEmail(DirectoriesMixin, SampleDirMixin, APITestCase):
         )
         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
 
+    def test_email_only_requires_view_permission(self):
+        """
+        GIVEN:
+            - User having only view documents permission
+        WHEN:
+            - API request is made to bulk email documents
+        THEN:
+            - Request succeeds
+        """
+        user1 = User.objects.create_user(username="test1")
+        user1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
+
+        self.client.force_authenticate(user1)
+
+        response = self.client.post(
+            self.ENDPOINT,
+            json.dumps(
+                {
+                    "documents": [self.doc1.pk],
+                    "addresses": "test@example.com",
+                    "subject": "Test",
+                    "message": "Test message",
+                },
+            ),
+            content_type="application/json",
+        )
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+
     @override_settings(
         EMAIL_ENABLED=True,
         EMAIL_BACKEND="django.core.mail.backends.locmem.EmailBackend",
index 696311a7ab947be76a01ecdf25ef53e22af4edb2..9365a82c2d1a11a2edb375820fc71e4f5267aac4 100644 (file)
@@ -141,6 +141,7 @@ from documents.permissions import AcknowledgeTasksPermissions
 from documents.permissions import PaperlessAdminPermissions
 from documents.permissions import PaperlessNotePermissions
 from documents.permissions import PaperlessObjectPermissions
+from documents.permissions import ViewDocumentsPermissions
 from documents.permissions import get_document_count_filter_for_user
 from documents.permissions import get_objects_for_user_owner_aware
 from documents.permissions import has_perms_owner_aware
@@ -1171,7 +1172,12 @@ class DocumentViewSet(
 
         return Response(sorted(entries, key=lambda x: x["timestamp"], reverse=True))
 
-    @action(methods=["post"], detail=True, url_path="email")
+    @action(
+        methods=["post"],
+        detail=True,
+        url_path="email",
+        permission_classes=[IsAuthenticated, ViewDocumentsPermissions],
+    )
     # TODO: deprecated as of 2.19, remove in future release
     def email_document(self, request, pk=None):
         request_data = request.data.copy()
@@ -1183,6 +1189,7 @@ class DocumentViewSet(
         detail=False,
         url_path="email",
         serializer_class=EmailSerializer,
+        permission_classes=[IsAuthenticated, ViewDocumentsPermissions],
     )
     def email_documents(self, request, data=None):
         serializer = EmailSerializer(data=data or request.data)