mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Fix: include global perms for bulk edit endpoint (#8468)
This commit is contained in:
parent
dafb0b1f21
commit
9e4bc05a24
@ -2,6 +2,7 @@ import json
|
|||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from auditlog.models import LogEntry
|
from auditlog.models import LogEntry
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.test import override_settings
|
from django.test import override_settings
|
||||||
from guardian.shortcuts import assign_perm
|
from guardian.shortcuts import assign_perm
|
||||||
@ -858,6 +859,74 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
|
|||||||
args, kwargs = m.call_args
|
args, kwargs = m.call_args
|
||||||
self.assertEqual(kwargs["merge"], True)
|
self.assertEqual(kwargs["merge"], True)
|
||||||
|
|
||||||
|
@mock.patch("documents.serialisers.bulk_edit.set_storage_path")
|
||||||
|
@mock.patch("documents.serialisers.bulk_edit.merge")
|
||||||
|
def test_insufficient_global_perms(self, mock_merge, mock_set_storage):
|
||||||
|
"""
|
||||||
|
GIVEN:
|
||||||
|
- User has no global permissions to change a document
|
||||||
|
- User has no global permissions to add a document
|
||||||
|
- User has no global permissions to delete a document
|
||||||
|
WHEN:
|
||||||
|
- API is called to set storage path
|
||||||
|
- API is called to merge documents
|
||||||
|
- API is called to merge with delete
|
||||||
|
THEN:
|
||||||
|
- API returns HTTP 403 for all calls unless global permissions are granted
|
||||||
|
"""
|
||||||
|
user1 = User.objects.create(username="user1")
|
||||||
|
user1.save()
|
||||||
|
self.client.force_authenticate(user=user1)
|
||||||
|
self.setup_mock(mock_set_storage, "set_storage_path")
|
||||||
|
self.setup_mock(mock_merge, "merge")
|
||||||
|
response = self.client.post(
|
||||||
|
"/api/documents/bulk_edit/",
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"documents": [self.doc1.id],
|
||||||
|
"method": "set_storage_path",
|
||||||
|
"parameters": {"storage_path": self.sp1.id},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
content_type="application/json",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
mock_set_storage.assert_not_called()
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
"/api/documents/bulk_edit/",
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"documents": [self.doc1.id],
|
||||||
|
"method": "merge",
|
||||||
|
"parameters": {"metadata_document_id": self.doc1.id},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
content_type="application/json",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
mock_merge.assert_not_called()
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
"/api/documents/bulk_edit/",
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"documents": [self.doc1.id],
|
||||||
|
"method": "merge",
|
||||||
|
"parameters": {
|
||||||
|
"metadata_document_id": self.doc1.id,
|
||||||
|
"delete_originals": True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
content_type="application/json",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
mock_merge.assert_not_called()
|
||||||
|
|
||||||
@mock.patch("documents.serialisers.bulk_edit.set_permissions")
|
@mock.patch("documents.serialisers.bulk_edit.set_permissions")
|
||||||
def test_insufficient_permissions_ownership(self, m):
|
def test_insufficient_permissions_ownership(self, m):
|
||||||
"""
|
"""
|
||||||
@ -872,6 +941,8 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
|
|||||||
self.doc1.owner = User.objects.get(username="temp_admin")
|
self.doc1.owner = User.objects.get(username="temp_admin")
|
||||||
self.doc1.save()
|
self.doc1.save()
|
||||||
user1 = User.objects.create(username="user1")
|
user1 = User.objects.create(username="user1")
|
||||||
|
user1.user_permissions.add(*Permission.objects.all())
|
||||||
|
user1.save()
|
||||||
self.client.force_authenticate(user=user1)
|
self.client.force_authenticate(user=user1)
|
||||||
|
|
||||||
permissions = {
|
permissions = {
|
||||||
@ -925,6 +996,8 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
|
|||||||
self.doc1.save()
|
self.doc1.save()
|
||||||
user1 = User.objects.create(username="user1")
|
user1 = User.objects.create(username="user1")
|
||||||
assign_perm("view_document", user1, self.doc1)
|
assign_perm("view_document", user1, self.doc1)
|
||||||
|
user1.user_permissions.add(*Permission.objects.all())
|
||||||
|
user1.save()
|
||||||
self.client.force_authenticate(user=user1)
|
self.client.force_authenticate(user=user1)
|
||||||
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
@ -1044,6 +1117,8 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
|
|||||||
self.doc1.owner = User.objects.get(username="temp_admin")
|
self.doc1.owner = User.objects.get(username="temp_admin")
|
||||||
self.doc1.save()
|
self.doc1.save()
|
||||||
user1 = User.objects.create(username="user1")
|
user1 = User.objects.create(username="user1")
|
||||||
|
user1.user_permissions.add(*Permission.objects.all())
|
||||||
|
user1.save()
|
||||||
self.client.force_authenticate(user=user1)
|
self.client.force_authenticate(user=user1)
|
||||||
|
|
||||||
self.setup_mock(m, "merge")
|
self.setup_mock(m, "merge")
|
||||||
|
@ -1005,25 +1005,49 @@ class BulkEditView(PassUserMixin):
|
|||||||
(doc.owner == user or doc.owner is None) for doc in document_objs
|
(doc.owner == user or doc.owner is None) for doc in document_objs
|
||||||
)
|
)
|
||||||
|
|
||||||
has_perms = (
|
# check global and object permissions for all documents
|
||||||
user_is_owner_of_all_documents
|
has_perms = user.has_perm("documents.change_document") and all(
|
||||||
if method
|
has_perms_owner_aware(user, "change_document", doc)
|
||||||
|
for doc in document_objs
|
||||||
|
)
|
||||||
|
|
||||||
|
# check ownership for methods that change original document
|
||||||
|
if (
|
||||||
|
has_perms
|
||||||
|
and method
|
||||||
in [
|
in [
|
||||||
bulk_edit.set_permissions,
|
bulk_edit.set_permissions,
|
||||||
bulk_edit.delete,
|
bulk_edit.delete,
|
||||||
bulk_edit.rotate,
|
bulk_edit.rotate,
|
||||||
bulk_edit.delete_pages,
|
bulk_edit.delete_pages,
|
||||||
]
|
]
|
||||||
else all(
|
) or (
|
||||||
has_perms_owner_aware(user, "change_document", doc)
|
|
||||||
for doc in document_objs
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (
|
|
||||||
method in [bulk_edit.merge, bulk_edit.split]
|
method in [bulk_edit.merge, bulk_edit.split]
|
||||||
and parameters["delete_originals"]
|
and parameters["delete_originals"]
|
||||||
and not user_is_owner_of_all_documents
|
):
|
||||||
|
has_perms = user_is_owner_of_all_documents
|
||||||
|
|
||||||
|
# check global add permissions for methods that create documents
|
||||||
|
if (
|
||||||
|
has_perms
|
||||||
|
and method in [bulk_edit.split, bulk_edit.merge]
|
||||||
|
and not user.has_perm(
|
||||||
|
"documents.add_document",
|
||||||
|
)
|
||||||
|
):
|
||||||
|
has_perms = False
|
||||||
|
|
||||||
|
# check global delete permissions for methods that delete documents
|
||||||
|
if (
|
||||||
|
has_perms
|
||||||
|
and (
|
||||||
|
method == bulk_edit.delete
|
||||||
|
or (
|
||||||
|
method in [bulk_edit.merge, bulk_edit.split]
|
||||||
|
and parameters["delete_originals"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
and not user.has_perm("documents.delete_document")
|
||||||
):
|
):
|
||||||
has_perms = False
|
has_perms = False
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user