diff --git a/mayan/apps/documents/tests/test_api.py b/mayan/apps/documents/tests/test_api.py index b58e398cef..a0debe937e 100644 --- a/mayan/apps/documents/tests/test_api.py +++ b/mayan/apps/documents/tests/test_api.py @@ -4,20 +4,13 @@ from __future__ import unicode_literals import time -from json import loads - -from django.contrib.auth import get_user_model from django.test import override_settings -from django.urls import reverse from django.utils.encoding import force_text from django_downloadview import assert_download_response from rest_framework import status from rest_api.tests import BaseAPITestCase -from user_management.tests.literals import ( - TEST_ADMIN_EMAIL, TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME -) from .literals import ( TEST_DOCUMENT_DESCRIPTION_EDITED, TEST_DOCUMENT_FILENAME, @@ -26,6 +19,15 @@ from .literals import ( TEST_SMALL_DOCUMENT_FILENAME, TEST_SMALL_DOCUMENT_PATH ) from ..models import Document, DocumentType +from ..permissions import ( + permission_document_create, permission_document_download, + permission_document_delete, permission_document_edit, + permission_document_new_version, permission_document_properties_edit, + permission_document_restore, permission_document_trash, + permission_document_view, permission_document_type_create, + permission_document_type_delete, permission_document_type_edit, + permission_document_version_revert, permission_document_version_view +) class DocumentTypeAPITestCase(BaseAPITestCase): @@ -63,23 +65,43 @@ class DocumentTypeAPITestCase(BaseAPITestCase): document_type = DocumentType.objects.create( label=TEST_DOCUMENT_TYPE_LABEL ) + response = self._request_document_type_put() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - self.client.put( - reverse('rest_api:documenttype-detail', args=(document_type.pk,)), - {'label': TEST_DOCUMENT_TYPE_LABEL_EDITED} + def test_document_type_edit_via_put_with_access(self): + self.document_type = DocumentType.objects.create( + label=TEST_DOCUMENT_TYPE_LABEL + ) + self.grant_access( + permission=permission_document_type_edit, obj=self.document_type + ) + response = self._request_document_type_put() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.document_type.refresh_from_db() + self.assertEqual( + self.document_type.label, TEST_DOCUMENT_TYPE_LABEL_EDITED ) - document_type = DocumentType.objects.get(pk=document_type.pk) - self.assertEqual(document_type.label, TEST_DOCUMENT_TYPE_LABEL_EDITED) + def _request_document_type_patch(self): + return self.patch( + viewname='rest_api:documenttype-detail', args=( + self.document_type.pk, + ), data={'label': TEST_DOCUMENT_TYPE_LABEL_EDITED} + ) + + def test_document_type_edit_via_patch_no_permission(self): + self.document_type = DocumentType.objects.create( + label=TEST_DOCUMENT_TYPE_LABEL + ) + response = self._request_document_type_patch() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_document_type_edit_via_patch(self): document_type = DocumentType.objects.create( label=TEST_DOCUMENT_TYPE_LABEL ) - - self.client.patch( - reverse('rest_api:documenttype-detail', args=(document_type.pk,)), - {'label': TEST_DOCUMENT_TYPE_LABEL_EDITED} + self.grant_access( + permission=permission_document_type_edit, obj=self.document_type ) document_type = DocumentType.objects.get(pk=document_type.pk) @@ -90,10 +112,18 @@ class DocumentTypeAPITestCase(BaseAPITestCase): label=TEST_DOCUMENT_TYPE_LABEL ) - self.client.delete( - reverse('rest_api:documenttype-detail', args=(document_type.pk,)) - ) + response = self._request_document_type_delete() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + def test_document_type_delete_with_access(self): + self.document_type = DocumentType.objects.create( + label=TEST_DOCUMENT_TYPE_LABEL + ) + self.grant_access( + permission=permission_document_type_delete, obj=self.document_type + ) + response = self._request_document_type_delete() + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(DocumentType.objects.all().count(), 0) @@ -138,11 +168,16 @@ class DocumentAPITestCase(BaseAPITestCase): } ) - document_data = loads(response.content) + def test_document_upload_no_permission(self): + response = self._request_document_upload() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - self.assertEqual( - response.status_code, status.HTTP_201_CREATED + def test_document_upload_with_access(self): + self.grant_access( + permission=permission_document_create, obj=self.document_type ) + response = self._request_document_upload() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Document.objects.count(), 1) document = Document.objects.first() @@ -180,6 +215,17 @@ class DocumentAPITestCase(BaseAPITestCase): } ) + def test_document_new_version_upload_no_permission(self): + self._create_document() + response = self._request_document_new_version_upload() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_document_new_version_upload_with_access(self): + self._create_document() + self.grant_access( + permission=permission_document_new_version, obj=self.document + ) + response = self._request_document_new_version_upload() self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(document.versions.count(), 2) @@ -204,51 +250,62 @@ class DocumentAPITestCase(BaseAPITestCase): self.assertEqual(document.versions.count(), 2) - last_version = document.versions.last() + def test_document_version_revert_no_permission(self): + self._create_document() + self._create_new_version() + response = self._request_document_version_revert() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - self.client.delete( - reverse( - 'rest_api:documentversion-detail', - args=(document.pk, last_version.pk,) - ) + def test_document_version_revert_with_access(self): + self._create_document() + self._create_new_version() + self.grant_access( + permission=permission_document_version_revert, obj=self.document + ) + response = self._request_document_version_revert() + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + self.assertEqual(self.document.versions.count(), 1) + self.assertEqual( + self.document.versions.first(), self.document.latest_version ) - - self.assertEqual(document.versions.count(), 1) - - self.assertEqual(document.versions.first(), document.latest_version) - - def test_document_version_list(self): - document = self._create_document() # Needed by MySQL as milliseconds value is not store in timestamp field time.sleep(1) - with open(TEST_DOCUMENT_PATH) as file_object: - document.new_version(file_object=file_object) + def test_document_version_list_no_permission(self): + self._create_document() + self._create_new_version() + response = self._request_document_version_list() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['count'], 0) - document.refresh_from_db() - - self.assertEqual(document.versions.count(), 2) - - response = self.client.get( - reverse( - 'rest_api:document-version-list', - args=(document.pk,) - ) + def test_document_version_list_with_access(self): + self._create_document() + self._create_new_version() + self.grant_access( + permission=permission_document_version_view, obj=self.document ) - + response = self._request_document_version_list() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( response.data['results'][1]['checksum'], document.latest_version.checksum ) - def test_document_download(self): - document = self._create_document() + def _request_document_download(self): + return self.get( + viewname='rest_api:document-download', args=(self.document.pk,) + ) - response = self.client.get( - reverse( - 'rest_api:document-download', args=(document.pk,) - ) + def test_document_download_no_permission(self): + self._create_document() + response = self._request_document_download() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_document_download_with_access(self): + self._create_document() + self.grant_access( + permission=permission_document_download, obj=self.document ) with document.open() as file_object: @@ -258,17 +315,24 @@ class DocumentAPITestCase(BaseAPITestCase): mime_type='{}; charset=utf-8'.format(document.file_mimetype) ) - def test_document_version_download(self): - document = self._create_document() - - latest_version = document.latest_version - response = self.client.get( - reverse( - 'rest_api:documentversion-download', - args=(document.pk, latest_version.pk,) + def _request_document_version_download(self): + return self.get( + viewname='rest_api:documentversion-download', args=( + self.document.pk, self.document.latest_version.pk, ) ) + def test_document_version_download_no_permission(self): + self._create_document() + response = self._request_document_version_download() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_document_version_download_with_access(self): + self._create_document() + self.grant_access( + permission=permission_document_download, obj=self.document + ) + with latest_version.open() as file_object: assert_download_response( self, response, content=file_object.read(), @@ -299,14 +363,11 @@ class DocumentAPITestCase(BaseAPITestCase): def test_document_version_edit_via_patch(self): self._create_document() - response = self.client.patch( - reverse( - 'rest_api:documentversion-detail', - args=(self.document.pk, self.document.latest_version.pk,) - ), data={'comment': TEST_DOCUMENT_VERSION_COMMENT_EDITED} + self.grant_access( + permission=permission_document_edit, obj=self.document ) - - self.assertEqual(response.status_code, 200) + response = self._request_document_version_edit_via_patch() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.document.latest_version.refresh_from_db() self.assertEqual(self.document.versions.count(), 1) self.assertEqual( @@ -316,14 +377,16 @@ class DocumentAPITestCase(BaseAPITestCase): def test_document_version_edit_via_put(self): self._create_document() - response = self.client.put( - reverse( - 'rest_api:documentversion-detail', - args=(self.document.pk, self.document.latest_version.pk,) - ), data={'comment': TEST_DOCUMENT_VERSION_COMMENT_EDITED} - ) + response = self._request_document_version_edit_via_put() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - self.assertEqual(response.status_code, 200) + def test_document_version_edit_via_put_with_access(self): + self._create_document() + self.grant_access( + permission=permission_document_edit, obj=self.document + ) + response = self._request_document_version_edit_via_put() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.document.latest_version.refresh_from_db() self.assertEqual(self.document.versions.count(), 1) self.assertEqual( @@ -331,7 +394,18 @@ class DocumentAPITestCase(BaseAPITestCase): TEST_DOCUMENT_VERSION_COMMENT_EDITED ) - def test_document_comment_edit_via_patch(self): + def _request_document_description_edit_via_patch(self): + return self.patch( + viewname='rest_api:document-detail', args=(self.document.pk,), + data={'description': TEST_DOCUMENT_DESCRIPTION_EDITED} + ) + + def test_document_description_edit_via_patch_no_permission(self): + self._create_document() + response = self._request_document_description_edit_via_patch() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_document_description_edit_via_patch_with_access(self): self._create_document() response = self.client.patch( reverse( @@ -339,8 +413,8 @@ class DocumentAPITestCase(BaseAPITestCase): args=(self.document.pk,) ), data={'description': TEST_DOCUMENT_DESCRIPTION_EDITED} ) - - self.assertEqual(response.status_code, 200) + response = self._request_document_description_edit_via_patch() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.document.refresh_from_db() self.assertEqual( self.document.description, @@ -349,13 +423,16 @@ class DocumentAPITestCase(BaseAPITestCase): def test_document_comment_edit_via_put(self): self._create_document() - response = self.client.put( - reverse( - 'rest_api:document-detail', - args=(self.document.pk,) - ), data={'description': TEST_DOCUMENT_DESCRIPTION_EDITED} + response = self._request_document_description_edit_via_put() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_document_description_edit_via_put_with_access(self): + self._create_document() + self.grant_access( + permission=permission_document_properties_edit, obj=self.document ) - self.assertEqual(response.status_code, 200) + response = self._request_document_description_edit_via_put() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.document.refresh_from_db() self.assertEqual( self.document.description, @@ -391,58 +468,109 @@ class TrashedDocumentAPITestCase(BaseAPITestCase): file_object=file_object, ) - return document + def _request_document_move_to_trash(self): + return self.delete( + viewname='rest_api:document-detail', args=(self.document.pk,) + ) - def test_document_move_to_trash(self): - document = self._create_document() + def test_document_move_to_trash_no_permission(self): + self._create_document() + response = self._request_document_move_to_trash() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - self.client.delete( - reverse('rest_api:document-detail', args=(document.pk,)) + def test_document_move_to_trash_with_access(self): + self._create_document() + self.grant_access( + permission=permission_document_trash, obj=self.document ) self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.trash.count(), 1) - def test_trashed_document_delete_from_trash(self): - document = self._create_document() - document.delete() + def _request_trashed_document_delete_view(self): + return self.delete( + viewname='rest_api:trasheddocument-detail', args=(self.document.pk,) + ) + def test_trashed_document_delete_from_trash_no_access(self): + self._create_document() + self.document.delete() + response = self._request_trashed_document_delete_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.trash.count(), 1) - self.client.delete( - reverse('rest_api:trasheddocument-detail', args=(document.pk,)) - ) - + def test_trashed_document_delete_from_trash_with_access(self): + self._create_document() + self.document.delete() + self.grant_access(permission=permission_document_delete, obj=self.document) + response = self._request_trashed_document_delete_view() + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.trash.count(), 0) - def test_trashed_document_detail_view(self): - document = self._create_document() - document.delete() - - response = self.client.get( - reverse('rest_api:trasheddocument-detail', args=(document.pk,)) + def _request_trashed_document_detail_view(self): + return self.get( + viewname='rest_api:trasheddocument-detail', args=(self.document.pk,) ) - self.assertEqual(response.data['uuid'], force_text(document.uuid)) + def test_trashed_document_detail_view_no_access(self): + self._create_document() + self.document.delete() + response = self._request_trashed_document_detail_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('uuid' in response.data) - def test_trashed_document_list_view(self): - document = self._create_document() - document.delete() + def test_trashed_document_detail_view_with_access(self): + self._create_document() + self.document.delete() + self.grant_access(permission=permission_document_view, obj=self.document) + response = self._request_trashed_document_detail_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['uuid'], force_text(self.document.uuid)) - response = self.client.get( - reverse('rest_api:trasheddocument-list') + def _request_trashed_document_list_view(self): + return self.get( + viewname='rest_api:trasheddocument-list' ) - self.assertEqual(response.data['results'][0]['uuid'], force_text(document.uuid)) + def test_trashed_document_list_view_no_access(self): + self._create_document() + self.document.delete() + response = self._request_trashed_document_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['count'], 0) - def test_trashed_document_restore(self): - document = self._create_document() - document.delete() - - self.client.post( - reverse('rest_api:trasheddocument-restore', args=(document.pk,)) + def test_trashed_document_list_view_with_access(self): + self._create_document() + self.document.delete() + self.grant_access( + permission=permission_document_view, obj=self.document + ) + response = self._request_trashed_document_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual( + response.data['results'][0]['uuid'], force_text(self.document.uuid) ) + def _request_trashed_document_restore_view(self): + return self.post( + viewname='rest_api:trasheddocument-restore', args=(self.document.pk,) + ) + + def test_trashed_document_restore_no_access(self): + self._create_document() + self.document.delete() + response = self._request_trashed_document_restore_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertEqual(Document.trash.count(), 1) + self.assertEqual(Document.objects.count(), 0) + + def test_trashed_document_restore_with_access(self): + self._create_document() + self.document.delete() + self.grant_access(permission=permission_document_restore, obj=self.document) + response = self._request_trashed_document_restore_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(Document.trash.count(), 0) self.assertEqual(Document.objects.count(), 1)