From 54100f75388cdb3231baf5bc198b08ecf629f340 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 25 Feb 2019 21:08:56 -0400 Subject: [PATCH] Role permissions API: Add permission checking and tests Signed-off-by: Roberto Rosario --- mayan/apps/permissions/api_views.py | 3 + mayan/apps/permissions/serializers.py | 33 +++++++-- mayan/apps/permissions/tests/test_api.py | 92 ++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 5 deletions(-) diff --git a/mayan/apps/permissions/api_views.py b/mayan/apps/permissions/api_views.py index 80829f1680..02e6882e80 100644 --- a/mayan/apps/permissions/api_views.py +++ b/mayan/apps/permissions/api_views.py @@ -72,6 +72,9 @@ class RoleAPIViewSet(MayanAPIModelViewSet): 'group_remove': permission_role_edit, 'list': permission_role_view, 'partial_update': permission_role_edit, + 'permission_add': permission_role_edit, + 'permission_list': permission_role_view, + 'permission_remove': permission_role_edit, 'retrieve': permission_role_view, 'update': permission_role_edit, } diff --git a/mayan/apps/permissions/serializers.py b/mayan/apps/permissions/serializers.py index aed71a51c5..90fdf5cec8 100644 --- a/mayan/apps/permissions/serializers.py +++ b/mayan/apps/permissions/serializers.py @@ -4,6 +4,7 @@ from django.contrib.auth.models import Group from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers +from rest_framework.exceptions import ValidationError from mayan.apps.rest_api.mixins import ExternalObjectListSerializerMixin from mayan.apps.rest_api.relations import MultiKwargHyperlinkedIdentityField @@ -86,21 +87,43 @@ class RolePermissionAddRemoveSerializer(ExternalObjectListSerializerMixin, seria help_text=_( 'Comma separated list of permission primary keys that will be added or ' 'removed.' - ), required=False, write_only=True + ), label=_('Permission ID list'), required=False, write_only=True ) class Meta: external_object_list_model = Permission external_object_list_pk_list_field = 'permission_id_list' + external_object_list_pk_type = None + + def filter_queryset(self, id_list, queryset): + result = [] + for pk in id_list: + try: + result.append(Permission.get(pk=pk)) + except KeyError: + raise ValidationError( + { + 'permission_id_list': [ + 'Permission "{}" not found.'.format(pk) + ] + }, code='invalid' + ) + + return result + + def get_external_object_list_queryset(self): + return Permission.all() def permissions_add(self, instance): - instance.permissions.add( - *self.get_external_object_list() + instance.permissions_add( + queryset=self.get_external_object_list(), + _user=self.context['request'].user ) def permissions_remove(self, instance): - instance.permissions.remove( - *self.get_external_object_list() + instance.permissions_remove( + queryset=self.get_external_object_list(), + _user=self.context['request'].user ) diff --git a/mayan/apps/permissions/tests/test_api.py b/mayan/apps/permissions/tests/test_api.py index 54e7c0f292..5e59d1487c 100644 --- a/mayan/apps/permissions/tests/test_api.py +++ b/mayan/apps/permissions/tests/test_api.py @@ -326,3 +326,95 @@ class RoleGroupAPITestCase(GroupTestMixin, RoleTestMixin, BaseAPITestCase): self.test_role.refresh_from_db() self.assertTrue(self.test_group not in self.test_role.groups.all()) + + +class RolePermissionAPITestCase(PermissionTestMixin, RoleTestMixin, BaseAPITestCase): + def _request_role_permission_list_api_view(self): + return self.get( + viewname='rest_api:role-permission-list', + kwargs={'role_id': self.test_role.pk} + ) + + def _request_role_permission_add_api_view(self): + return self.post( + viewname='rest_api:role-permission-add', + kwargs={'role_id': self.test_role.pk}, + data={'permission_id_list': '{}'.format(self.test_permission.pk)} + ) + + def _request_role_permission_remove_api_view(self): + return self.post( + viewname='rest_api:role-permission-remove', + kwargs={'role_id': self.test_role.pk}, + data={'permission_id_list': '{}'.format(self.test_permission.pk)} + ) + + def _setup_role_permission_list(self): + self._create_test_permission() + self._create_test_role() + self.test_role.grant(permission=self.test_permission) + + def test_role_permission_list_api_view_no_permission(self): + self._setup_role_permission_list() + + response = self._request_role_permission_list_api_view() + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + def test_role_permission_list_api_view_with_access(self): + self._setup_role_permission_list() + + self.grant_access(obj=self.test_role, permission=permission_role_view) + response = self._request_role_permission_list_api_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['count'], 1) + + def _setup_role_permission_add(self): + self._create_test_permission() + self._create_test_role() + + def test_role_permission_add_api_view_no_permission(self): + self._setup_role_permission_add() + + response = self._request_role_permission_add_api_view() + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + self.test_role.refresh_from_db() + self.assertTrue(self.test_permission not in self.test_role.permissions.all()) + + def test_role_permission_add_api_view_with_access(self): + self._setup_role_permission_add() + + self.grant_access(obj=self.test_role, permission=permission_role_edit) + response = self._request_role_permission_add_api_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + + self.test_role.refresh_from_db() + self.assertTrue( + self.test_permission.stored_permission in self.test_role.permissions.all() + ) + + def _setup_role_permission_remove(self): + self._create_test_permission() + self._create_test_role() + self.test_role.grant(permission=self.test_permission) + + def test_role_permission_remove_api_view_no_permission(self): + self._setup_role_permission_remove() + + response = self._request_role_permission_remove_api_view() + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + self.test_role.refresh_from_db() + self.assertTrue( + self.test_permission.stored_permission in self.test_role.permissions.all() + ) + + def test_role_permission_remove_api_view_with_access(self): + self._setup_role_permission_remove() + + self.grant_access(obj=self.test_role, permission=permission_role_edit) + response = self._request_role_permission_remove_api_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + + self.test_role.refresh_from_db() + self.assertTrue(self.test_permission not in self.test_role.permissions.all())