From 5574aaec9e7c865d915183f1a1236c139a92d18c Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 24 Apr 2019 23:19:04 -0400 Subject: [PATCH] Add role create and edit events Signed-off-by: Roberto Rosario --- HISTORY.rst | 1 + docs/releases/3.2.rst | 1 + mayan/apps/permissions/apps.py | 9 ++++ mayan/apps/permissions/events.py | 16 ++++++ mayan/apps/permissions/methods.py | 9 ++++ mayan/apps/permissions/models.py | 18 ++++++- mayan/apps/permissions/tests/mixins.py | 9 +++- mayan/apps/permissions/tests/test_events.py | 56 +++++++++++++++++++++ mayan/apps/permissions/views.py | 6 +++ 9 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 mayan/apps/permissions/events.py create mode 100644 mayan/apps/permissions/tests/test_events.py diff --git a/HISTORY.rst b/HISTORY.rst index a387c953f2..f11298a934 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -149,6 +149,7 @@ * Update ChoiceForm to be full height. * Add AddRemoveView to replace AssignRemoveView * Update the group roles view to use the new AddRemoveView. +* Add role create and edit events. 3.1.11 (2019-04-XX) =================== diff --git a/docs/releases/3.2.rst b/docs/releases/3.2.rst index 98522885f0..882c4a02be 100644 --- a/docs/releases/3.2.rst +++ b/docs/releases/3.2.rst @@ -181,6 +181,7 @@ Other changes * Update ChoiceForm to be full height. * Add AddRemoveView to replace AssignRemoveView * Update the group roles view to use the new AddRemoveView. +* Add role create and edit events. Removals -------- diff --git a/mayan/apps/permissions/apps.py b/mayan/apps/permissions/apps.py index 80cf2c7f9e..24479a8a38 100644 --- a/mayan/apps/permissions/apps.py +++ b/mayan/apps/permissions/apps.py @@ -12,7 +12,9 @@ from mayan.apps.common.menus import ( menu_list_facet, menu_object, menu_secondary, menu_setup ) from mayan.apps.common.signals import perform_upgrade +from mayan.apps.events import ModelEventType +from .events import event_role_created, event_role_edited from .handlers import purge_permissions from .links import ( link_group_roles, link_role_create, link_role_delete, link_role_edit, @@ -35,6 +37,7 @@ class PermissionsApp(MayanAppConfig): def ready(self): super(PermissionsApp, self).ready() + from actstream import registry Role = self.get_model('Role') Group = apps.get_model(app_label='auth', model_name='Group') @@ -42,6 +45,10 @@ class PermissionsApp(MayanAppConfig): Group.add_to_class(name='roles_add', value=method_group_roles_add) Group.add_to_class(name='roles_remove', value=method_group_roles_remove) + ModelEventType.register( + event_types=(event_role_created, event_role_edited), model=Role + ) + ModelPermission.register( model=Role, permissions=( permission_acl_edit, permission_acl_view, @@ -72,3 +79,5 @@ class PermissionsApp(MayanAppConfig): perform_upgrade.connect( purge_permissions, dispatch_uid='purge_permissions' ) + + registry.register(Role) diff --git a/mayan/apps/permissions/events.py b/mayan/apps/permissions/events.py new file mode 100644 index 0000000000..9b6d20ba96 --- /dev/null +++ b/mayan/apps/permissions/events.py @@ -0,0 +1,16 @@ +from __future__ import absolute_import, unicode_literals + +from django.utils.translation import ugettext_lazy as _ + +from mayan.apps.events import EventTypeNamespace + +namespace = EventTypeNamespace( + label=_('Permissions'), name='permissions' +) + +event_role_created = namespace.add_event_type( + label=_('Role created'), name='role_created' +) +event_role_edited = namespace.add_event_type( + label=_('Role edited'), name='role_edited' +) diff --git a/mayan/apps/permissions/methods.py b/mayan/apps/permissions/methods.py index e3ea0c70d5..6e9204c5a9 100644 --- a/mayan/apps/permissions/methods.py +++ b/mayan/apps/permissions/methods.py @@ -4,6 +4,8 @@ from django.db import transaction from mayan.apps.user_management.events import event_group_edited +from .events import event_role_edited + def method_group_roles_add(self, queryset, _user): with transaction.atomic(): @@ -12,6 +14,9 @@ def method_group_roles_add(self, queryset, _user): ) for role in queryset: self.roles.add(role) + event_role_edited.commit( + actor=_user, action_object=self, target=role + ) def method_group_roles_remove(self, queryset, _user): @@ -21,3 +26,7 @@ def method_group_roles_remove(self, queryset, _user): ) for role in queryset: self.roles.remove(role) + event_role_edited.commit( + actor=_user, action_object=self, target=role + ) + diff --git a/mayan/apps/permissions/models.py b/mayan/apps/permissions/models.py index aeb4c246dd..c00435e01c 100644 --- a/mayan/apps/permissions/models.py +++ b/mayan/apps/permissions/models.py @@ -3,12 +3,13 @@ from __future__ import unicode_literals import logging from django.contrib.auth.models import Group -from django.db import models +from django.db import models, transaction from django.urls import reverse from django.utils.encoding import force_text, python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from .classes import Permission +from .events import event_role_created, event_role_edited from .managers import RoleManager, StoredPermissionManager logger = logging.getLogger(__name__) @@ -121,3 +122,18 @@ class Role(models.Model): def natural_key(self): return (self.label,) natural_key.dependencies = ['auth.Group', 'permissions.StoredPermission'] + + def save(self, *args, **kwargs): + _user = kwargs.pop('_user', None) + + with transaction.atomic(): + is_new = not self.pk + super(Role, self).save(*args, **kwargs) + if is_new: + event_role_created.commit( + actor=_user, target=self + ) + else: + event_role_edited.commit( + actor=_user, target=self + ) diff --git a/mayan/apps/permissions/tests/mixins.py b/mayan/apps/permissions/tests/mixins.py index a32e092c5c..146746e44a 100644 --- a/mayan/apps/permissions/tests/mixins.py +++ b/mayan/apps/permissions/tests/mixins.py @@ -100,12 +100,19 @@ class RoleTestMixin(object): class RoleViewTestMixin(object): def _request_test_role_create_view(self): - return self.post( + # Typecast to list to force queryset evaluation + values = list(Role.objects.values_list('pk', flat=True)) + + response = self.post( viewname='permissions:role_create', data={ 'label': TEST_ROLE_LABEL, } ) + self.test_role = Role.objects.exclude(pk__in=values).first() + + return response + def _request_test_role_delete_view(self): return self.post( viewname='permissions:role_delete', kwargs={'pk': self.test_role.pk} diff --git a/mayan/apps/permissions/tests/test_events.py b/mayan/apps/permissions/tests/test_events.py new file mode 100644 index 0000000000..f2bb8563c5 --- /dev/null +++ b/mayan/apps/permissions/tests/test_events.py @@ -0,0 +1,56 @@ +from __future__ import unicode_literals + +from actstream.models import Action + +from mayan.apps.common.tests import GenericViewTestCase + +from ..events import event_role_created, event_role_edited +from ..permissions import permission_role_create, permission_role_edit + +from .mixins import RoleTestMixin, RoleViewTestMixin + + +class RoleEventsTestCase(RoleTestMixin, RoleViewTestMixin, GenericViewTestCase): + def test_role_created_event_no_permissions(self): + Action.objects.all().delete() + + response = self._request_test_role_create_view() + self.assertEqual(response.status_code, 403) + self.assertEqual(Action.objects.count(), 0) + + def test_role_created_event_with_permissions(self): + Action.objects.all().delete() + + self.grant_permission(permission=permission_role_create) + response = self._request_test_role_create_view() + self.assertEqual(response.status_code, 302) + + event = Action.objects.first() + + self.assertEqual(event.verb, event_role_created.id) + self.assertEqual(event.target, self.test_role) + self.assertEqual(event.actor, self._test_case_user) + + def test_role_edited_event_no_permissions(self): + self._create_test_role() + Action.objects.all().delete() + + response = self._request_test_role_edit_view() + self.assertEqual(response.status_code, 403) + self.assertEqual(Action.objects.count(), 0) + + def test_role_edited_event_with_access(self): + self._create_test_role() + Action.objects.all().delete() + + self.grant_access( + obj=self.test_role, permission=permission_role_edit + ) + + response = self._request_test_role_edit_view() + self.assertEqual(response.status_code, 302) + event = Action.objects.first() + + self.assertEqual(event.verb, event_role_edited.id) + self.assertEqual(event.target, self.test_role) + self.assertEqual(event.actor, self._test_case_user) diff --git a/mayan/apps/permissions/views.py b/mayan/apps/permissions/views.py index 54952b7c6b..9d9448c28f 100644 --- a/mayan/apps/permissions/views.py +++ b/mayan/apps/permissions/views.py @@ -55,6 +55,9 @@ class RoleCreateView(SingleObjectCreateView): view_permission = permission_role_create post_action_redirect = reverse_lazy('permissions:role_list') + def get_save_extra_data(self): + return {'_user': self.request.user} + class RoleDeleteView(SingleObjectDeleteView): model = Role @@ -67,6 +70,9 @@ class RoleEditView(SingleObjectEditView): model = Role object_permission = permission_role_edit + def get_save_extra_data(self): + return {'_user': self.request.user} + class SetupRoleMembersView(AssignRemoveView): grouped = False