trash api tests, respect permissions
This commit is contained in:
parent
26d7d19a98
commit
0a6234bf6f
95
src/documents/tests/test_api_trash.py
Normal file
95
src/documents/tests/test_api_trash.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.core.cache import cache
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
|
from documents.models import Document
|
||||||
|
|
||||||
|
|
||||||
|
class TestTrashAPI(APITestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
self.user = User.objects.create_superuser(username="temp_admin")
|
||||||
|
self.client.force_authenticate(user=self.user)
|
||||||
|
cache.clear()
|
||||||
|
|
||||||
|
def test_api_trash(self):
|
||||||
|
"""
|
||||||
|
GIVEN:
|
||||||
|
- Existing document
|
||||||
|
WHEN:
|
||||||
|
- API request to delete document
|
||||||
|
- API request to restore document
|
||||||
|
- API request to empty trash
|
||||||
|
THEN:
|
||||||
|
- Document is moved to trash
|
||||||
|
- Document is restored from trash
|
||||||
|
- Trash is emptied
|
||||||
|
"""
|
||||||
|
|
||||||
|
document = Document.objects.create(
|
||||||
|
title="Title",
|
||||||
|
content="content",
|
||||||
|
checksum="checksum",
|
||||||
|
mime_type="application/pdf",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.client.force_login(user=self.user)
|
||||||
|
self.client.delete(f"/api/documents/{document.pk}/")
|
||||||
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
self.assertEqual(Document.global_objects.count(), 1)
|
||||||
|
self.assertEqual(Document.deleted_objects.count(), 1)
|
||||||
|
|
||||||
|
resp = self.client.get("/api/trash/")
|
||||||
|
self.assertEqual(resp.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(resp.data["count"], 1)
|
||||||
|
|
||||||
|
resp = self.client.post(
|
||||||
|
"/api/trash/",
|
||||||
|
{"action": "restore", "documents": [document.pk]},
|
||||||
|
)
|
||||||
|
self.assertEqual(resp.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(Document.objects.count(), 1)
|
||||||
|
|
||||||
|
resp = self.client.get("/api/trash/")
|
||||||
|
self.assertEqual(resp.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(resp.data["count"], 0)
|
||||||
|
|
||||||
|
self.client.delete(f"/api/documents/{document.pk}/")
|
||||||
|
resp = self.client.post(
|
||||||
|
"/api/trash/",
|
||||||
|
{"action": "empty", "documents": [document.pk]},
|
||||||
|
)
|
||||||
|
self.assertEqual(resp.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(Document.global_objects.count(), 0)
|
||||||
|
|
||||||
|
def test_api_trash_insufficient_permissions(self):
|
||||||
|
"""
|
||||||
|
GIVEN:
|
||||||
|
- Existing document with owner in trash
|
||||||
|
WHEN:
|
||||||
|
- API request to empty trash
|
||||||
|
THEN:
|
||||||
|
- 403 Forbidden
|
||||||
|
"""
|
||||||
|
|
||||||
|
user1 = User.objects.create_user(username="user1")
|
||||||
|
self.client.force_authenticate(user=user1)
|
||||||
|
self.client.force_login(user=user1)
|
||||||
|
user2 = User.objects.create_user(username="user2")
|
||||||
|
document = Document.objects.create(
|
||||||
|
title="Title",
|
||||||
|
content="content",
|
||||||
|
checksum="checksum",
|
||||||
|
mime_type="application/pdf",
|
||||||
|
owner=user2,
|
||||||
|
)
|
||||||
|
document.delete()
|
||||||
|
|
||||||
|
resp = self.client.post(
|
||||||
|
"/api/trash/",
|
||||||
|
{"action": "empty", "documents": [document.pk]},
|
||||||
|
)
|
||||||
|
self.assertEqual(resp.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
self.assertEqual(Document.global_objects.count(), 1)
|
@ -47,6 +47,7 @@ from django.views.decorators.http import condition
|
|||||||
from django.views.decorators.http import last_modified
|
from django.views.decorators.http import last_modified
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
from django_filters.rest_framework import DjangoFilterBackend
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
|
from guardian.core import ObjectPermissionChecker
|
||||||
from langdetect import detect
|
from langdetect import detect
|
||||||
from packaging import version as packaging_version
|
from packaging import version as packaging_version
|
||||||
from redis import Redis
|
from redis import Redis
|
||||||
@ -2075,6 +2076,12 @@ class TrashView(ListModelMixin, PassUserMixin):
|
|||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
doc_ids = serializer.validated_data.get("documents")
|
doc_ids = serializer.validated_data.get("documents")
|
||||||
|
docs = Document.global_objects.filter(id__in=doc_ids)
|
||||||
|
checker = ObjectPermissionChecker(request.user)
|
||||||
|
checker.prefetch_perms(docs)
|
||||||
|
for doc in docs:
|
||||||
|
if not checker.has_perm("delete_document", doc):
|
||||||
|
return HttpResponseForbidden("Insufficient permissions")
|
||||||
action = serializer.validated_data.get("action")
|
action = serializer.validated_data.get("action")
|
||||||
if action == "restore":
|
if action == "restore":
|
||||||
for doc in Document.deleted_objects.filter(id__in=doc_ids).all():
|
for doc in Document.deleted_objects.filter(id__in=doc_ids).all():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user