from unittest import mock
from auditlog.models import LogEntry
+from django.contrib.auth.models import Permission
from django.contrib.auth.models import User
from django.test import override_settings
from guardian.shortcuts import assign_perm
args, kwargs = m.call_args
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")
def test_insufficient_permissions_ownership(self, m):
"""
self.doc1.owner = User.objects.get(username="temp_admin")
self.doc1.save()
user1 = User.objects.create(username="user1")
+ user1.user_permissions.add(*Permission.objects.all())
+ user1.save()
self.client.force_authenticate(user=user1)
permissions = {
self.doc1.save()
user1 = User.objects.create(username="user1")
assign_perm("view_document", user1, self.doc1)
+ user1.user_permissions.add(*Permission.objects.all())
+ user1.save()
self.client.force_authenticate(user=user1)
response = self.client.post(
self.doc1.owner = User.objects.get(username="temp_admin")
self.doc1.save()
user1 = User.objects.create(username="user1")
+ user1.user_permissions.add(*Permission.objects.all())
+ user1.save()
self.client.force_authenticate(user=user1)
self.setup_mock(m, "merge")
(doc.owner == user or doc.owner is None) for doc in document_objs
)
- has_perms = (
- user_is_owner_of_all_documents
- if method
+ # check global and object permissions for all documents
+ has_perms = user.has_perm("documents.change_document") and all(
+ 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 [
bulk_edit.set_permissions,
bulk_edit.delete,
bulk_edit.rotate,
bulk_edit.delete_pages,
]
- else all(
- has_perms_owner_aware(user, "change_document", doc)
- for doc in document_objs
+ ) or (
+ method in [bulk_edit.merge, bulk_edit.split]
+ and parameters["delete_originals"]
+ ):
+ 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 (
- method in [bulk_edit.merge, bulk_edit.split]
- and parameters["delete_originals"]
- and not user_is_owner_of_all_documents
+ 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