diff --git a/HISTORY.rst b/HISTORY.rst index d462579126..e816e6afc0 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -206,6 +206,7 @@ * Add outline links CSS for facets. * Add a bottom margin to list links. * Use copyfileobj to save documents to files +* Add user logged in and logged out events. 3.1.11 (2019-04-XX) =================== diff --git a/docs/releases/3.2.rst b/docs/releases/3.2.rst index 8314a1b9e8..ee2156b6a9 100644 --- a/docs/releases/3.2.rst +++ b/docs/releases/3.2.rst @@ -238,6 +238,7 @@ Other changes * Add outline links CSS for facets. * Add a bottom margin to list links. * Use copyfileobj to save documents to files +* Add user logged in and logged out events. Removals -------- diff --git a/mayan/apps/user_management/apps.py b/mayan/apps/user_management/apps.py index 094f1c49b8..421e86a123 100644 --- a/mayan/apps/user_management/apps.py +++ b/mayan/apps/user_management/apps.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals from django.apps import apps from django.contrib.auth import get_user_model +from django.contrib.auth.signals import user_logged_in, user_logged_out from django.db.models.signals import post_save from django.utils import six from django.utils.translation import ugettext_lazy as _ @@ -28,7 +29,10 @@ from .events import ( event_group_created, event_group_edited, event_user_created, event_user_edited ) -from .handlers import handler_initialize_new_user_options +from .handlers import ( + handler_initialize_new_user_options, handler_user_logged_in, + handler_user_logged_out +) from .links import ( link_current_user_details, link_current_user_edit, link_group_create, link_group_delete, link_group_edit, link_group_list, link_group_user_list, @@ -261,5 +265,17 @@ class UserManagementApp(MayanAppConfig): receiver=handler_initialize_new_user_options, sender=User ) + + user_logged_in.connect( + dispatch_uid='user_management_handler_user_logged_in', + receiver=handler_user_logged_in, + sender=User + ) + user_logged_out.connect( + dispatch_uid='user_management_handler_user_logged_out', + receiver=handler_user_logged_out, + sender=User + ) + registry.register(Group) registry.register(User) diff --git a/mayan/apps/user_management/events.py b/mayan/apps/user_management/events.py index b4c0f49941..153cb5a529 100644 --- a/mayan/apps/user_management/events.py +++ b/mayan/apps/user_management/events.py @@ -21,3 +21,9 @@ event_user_created = namespace.add_event_type( event_user_edited = namespace.add_event_type( label=_('User edited'), name='user_edited' ) +event_user_logged_in = namespace.add_event_type( + label=_('User logged in'), name='user_logged_in' +) +event_user_logged_out = namespace.add_event_type( + label=_('User logged out'), name='user_logged_out' +) diff --git a/mayan/apps/user_management/handlers.py b/mayan/apps/user_management/handlers.py index 3cc3354cfc..83b5589b3a 100644 --- a/mayan/apps/user_management/handlers.py +++ b/mayan/apps/user_management/handlers.py @@ -2,6 +2,8 @@ from __future__ import unicode_literals from django.apps import apps +from .events import event_user_logged_in, event_user_logged_out + def handler_initialize_new_user_options(sender, instance, **kwargs): UserOptions = apps.get_model( @@ -10,3 +12,15 @@ def handler_initialize_new_user_options(sender, instance, **kwargs): if kwargs['created']: UserOptions.objects.create(user=instance) + + +def handler_user_logged_in(sender, **kwargs): + event_user_logged_in.commit( + actor=kwargs['user'], target=kwargs['user'] + ) + + +def handler_user_logged_out(sender, **kwargs): + event_user_logged_out.commit( + actor=kwargs['user'], target=kwargs['user'] + ) diff --git a/mayan/apps/user_management/tests/mixins.py b/mayan/apps/user_management/tests/mixins.py index fb5c91fada..5701a0e7b3 100644 --- a/mayan/apps/user_management/tests/mixins.py +++ b/mayan/apps/user_management/tests/mixins.py @@ -223,18 +223,16 @@ class UserTestCaseMixin(object): self._test_case_user.cleartext_password = TEST_CASE_USER_PASSWORD def login(self, *args, **kwargs): - logged_in = self.client.login(*args, **kwargs) - - return logged_in + return self.client.login(*args, **kwargs) def login_superuser(self): - self.login( + return self.login( username=TEST_CASE_SUPERUSER_USERNAME, password=TEST_CASE_SUPERUSER_PASSWORD ) def login_user(self): - self.login( + return self.login( username=TEST_CASE_USER_USERNAME, password=TEST_CASE_USER_PASSWORD ) diff --git a/mayan/apps/user_management/tests/test_events.py b/mayan/apps/user_management/tests/test_events.py index 4967578925..98446b3e61 100644 --- a/mayan/apps/user_management/tests/test_events.py +++ b/mayan/apps/user_management/tests/test_events.py @@ -12,7 +12,7 @@ from ..permissions import ( from ..events import ( event_group_created, event_group_edited, event_user_created, - event_user_edited + event_user_edited, event_user_logged_in, event_user_logged_out ) from .mixins import ( @@ -21,7 +21,7 @@ from .mixins import ( ) -class GroupEventsTestCase(GroupTestMixin, GroupViewTestMixin, UserTestMixin, GenericViewTestCase): +class GroupEventsViewTestCase(GroupTestMixin, GroupViewTestMixin, UserTestMixin, GenericViewTestCase): def test_group_create_event(self): self.grant_permission( permission=permission_group_create @@ -87,7 +87,46 @@ class GroupEventsAPITestCase(GroupAPITestMixin, GroupTestMixin, GroupViewTestMix self.assertEqual(action.verb, event_group_edited.id) -class UserEventsTestCase(UserAPITestMixin, UserTestMixin, UserViewTestMixin, GenericViewTestCase): +class UserEventsTestCase(UserTestMixin, GenericViewTestCase): + auto_login_user = False + create_test_case_user = False + + def test_user_logged_in_event_from_view(self): + self._create_test_user() + + Action.objects.all().delete() + + result = self.login( + username=self.test_user.username, + password=self.test_user.cleartext_password + ) + self.assertTrue(result) + + action = Action.objects.order_by('timestamp').last() + self.assertEqual(action.actor, self.test_user) + self.assertEqual(action.target, self.test_user) + self.assertEqual(action.verb, event_user_logged_in.id) + + def test_user_logged_out_event_from_view(self): + self._create_test_user() + + result = self.login( + username=self.test_user.username, + password=self.test_user.cleartext_password + ) + self.assertTrue(result) + + Action.objects.all().delete() + + self.logout() + + action = Action.objects.order_by('timestamp').last() + self.assertEqual(action.actor, self.test_user) + self.assertEqual(action.target, self.test_user) + self.assertEqual(action.verb, event_user_logged_out.id) + + +class UserEventsViewTestCase(UserAPITestMixin, UserTestMixin, UserViewTestMixin, GenericViewTestCase): def test_user_create_event_from_view(self): self.grant_permission( permission=permission_user_create