From bbb3f18181a576e70939251c8005e04352cf7788 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Tue, 25 May 2021 15:31:27 +0200 Subject: [PATCH] ldap: record user reactivation in journal (#54170) --- src/authentic2/backends/ldap_backend.py | 4 ++++ src/authentic2/manager/journal_event_types.py | 19 +++++++++++++++---- tests/test_ldap.py | 16 +++++++++++----- tests/test_manager_journal.py | 17 +++++++++++++++++ 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/authentic2/backends/ldap_backend.py b/src/authentic2/backends/ldap_backend.py index dde2e758..092b584a 100644 --- a/src/authentic2/backends/ldap_backend.py +++ b/src/authentic2/backends/ldap_backend.py @@ -1468,6 +1468,8 @@ class LDAPBackend(object): return self._return_django_user(dn, username, password, conn, block, attributes) def _return_django_user(self, dn, username, password, conn, block, attributes): + from authentic2.manager.journal_event_types import ManagerUserActivation + user = self.lookup_existing_user(username, block, attributes) if user: log.debug('found existing user %r', user) @@ -1485,6 +1487,8 @@ class LDAPBackend(object): if not user.is_active and user.deactivation_reason and user.deactivation_reason.startswith('ldap-'): user.mark_as_active() + ldap_uri = conn.get_option(ldap.OPT_URI) + ManagerUserActivation.record(target_user=user, reason='ldap-reactivation', origin=ldap_uri) user_login_success(user.get_username()) return user diff --git a/src/authentic2/manager/journal_event_types.py b/src/authentic2/manager/journal_event_types.py index 6f137c1d..5c59bf86 100644 --- a/src/authentic2/manager/journal_event_types.py +++ b/src/authentic2/manager/journal_event_types.py @@ -187,16 +187,27 @@ class ManagerUserActivation(EventTypeDefinition): label = _('user activation') @classmethod - def record(cls, user, session, target_user): - super().record(user=user, session=session, references=[target_user]) + def record(cls, target_user, user=None, session=None, origin=None, reason=None): + data = {'origin': origin, 'reason': reason} + super().record(user=user, session=session, references=[target_user], data=data) @classmethod def get_message(cls, event, context): (user,) = event.get_typed_references(User) + reason = event.get_data('reason') if context and context == user: - return _('activation by administrator') + if reason == 'ldap-reactivation': + return _('automatic activation because the associated LDAP account reappeared') + else: + return _('activation by administrator') elif user: - return _('activation of user "%s"') % user.get_full_name() + if reason == 'ldap-reactivation': + return ( + _('automatic activation of user "%s" because the associated LDAP account reappeared') + % user.get_full_name() + ) + else: + return _('activation of user "%s"') % user.get_full_name() return super().get_message(event, context) diff --git a/tests/test_ldap.py b/tests/test_ldap.py index bf79fb1e..e425b857 100644 --- a/tests/test_ldap.py +++ b/tests/test_ldap.py @@ -312,15 +312,21 @@ def test_deactivate_orphaned_users(slapd, settings, client, db): ).count() == 1 ) - assert ( - User.objects.filter( - is_active=True, deactivation_reason__isnull=True, deactivation__isnull=True - ).count() - == 4 + reactivated_users = User.objects.filter( + is_active=True, deactivation_reason__isnull=True, deactivation__isnull=True ) + assert reactivated_users.count() == 4 assert User.objects.filter(is_active=False).count() == 2 assert User.objects.count() == 6 + for user in reactivated_users: + utils.assert_event( + 'manager.user.activation', + target_user=user, + reason='ldap-reactivation', + origin=slapd.ldap_url, + ) + @pytest.mark.django_db def test_simple_with_binddn(slapd, settings, client): diff --git a/tests/test_manager_journal.py b/tests/test_manager_journal.py index 2211ff87..098c33e3 100644 --- a/tests/test_manager_journal.py +++ b/tests/test_manager_journal.py @@ -261,6 +261,11 @@ def events(db, freezer): target_user=user, reason='ldap-old-source', ) + make( + 'manager.user.activation', + target_user=user, + reason='ldap-reactivation', + ) # verify we created at least one event for each type assert set(Event.objects.values_list("type__name", flat=True)) == set(_registry) @@ -564,6 +569,12 @@ def test_global_journal(app, superuser, events): 'user': '-', 'message': 'automatic deactivation of user "Johnny doe" because the associated LDAP source has been deleted', }, + { + 'message': 'automatic activation of user "Johnny doe" because the associated LDAP account reappeared', + 'timestamp': 'Jan. 2, 2020, 7 p.m.', + 'type': 'manager.user.activation', + 'user': '-', + }, ] @@ -761,6 +772,12 @@ def test_user_journal(app, superuser, events): 'user': '-', 'message': 'automatic deactivation because the associated LDAP source has been deleted', }, + { + 'message': 'automatic activation because the associated LDAP account reappeared', + 'timestamp': 'Jan. 2, 2020, 7 p.m.', + 'type': 'manager.user.activation', + 'user': '-', + }, ] -- 2.20.1