From cb541705370c3bb22836e98a31f6609e6c484fad Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Wed, 17 Aug 2022 17:08:44 +0200 Subject: [PATCH] authenticators: keep readable journal log even if deleted (#68184) --- .../authenticators/journal_event_types.py | 41 +++++++++---------- tests/test_manager_journal.py | 9 ++++ 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/authentic2/apps/authenticators/journal_event_types.py b/src/authentic2/apps/authenticators/journal_event_types.py index e2e7de2d..ef1feb79 100644 --- a/src/authentic2/apps/authenticators/journal_event_types.py +++ b/src/authentic2/apps/authenticators/journal_event_types.py @@ -22,34 +22,40 @@ from authentic2.apps.journal.utils import form_to_old_new from .models import BaseAuthenticator -class AuthenticatorCreation(EventTypeDefinition): +class AuthenticatorEvents(EventTypeDefinition): + @classmethod + def record(cls, *, user, session, authenticator, data=None): + data = data or {} + data.update({'authenticator_name': str(authenticator), 'authenticator_uuid': str(authenticator.uuid)}) + super().record(user=user, session=session, references=[authenticator], data=data) + + +class AuthenticatorCreation(AuthenticatorEvents): name = 'authenticator.creation' label = _('authenticator creation') - @classmethod - def record(cls, *, user, session, authenticator): - super().record(user=user, session=session, references=[authenticator]) - @classmethod def get_message(cls, event, context): (authenticator,) = event.get_typed_references(BaseAuthenticator) + authenticator = authenticator or event.get_data('authenticator_name') if context != authenticator: return _('creation of authenticator "%s"') % authenticator else: return _('creation') -class AuthenticatorEdit(EventTypeDefinition): +class AuthenticatorEdit(AuthenticatorEvents): name = 'authenticator.edit' label = _('authenticator edit') @classmethod def record(cls, *, user, session, form): - super().record(user=user, session=session, references=[form.instance], data=form_to_old_new(form)) + super().record(user=user, session=session, authenticator=form.instance, data=form_to_old_new(form)) @classmethod def get_message(cls, event, context): (authenticator,) = event.get_typed_references(BaseAuthenticator) + authenticator = authenticator or event.get_data('authenticator_name') new = event.get_data('new') or {} edited_attributes = ', '.join(new) or '' if context != authenticator: @@ -60,49 +66,40 @@ class AuthenticatorEdit(EventTypeDefinition): return _('edit ({change})').format(change=edited_attributes) -class AuthenticatorEnable(EventTypeDefinition): +class AuthenticatorEnable(AuthenticatorEvents): name = 'authenticator.enable' label = _('authenticator enable') - @classmethod - def record(cls, *, user, session, authenticator): - super().record(user=user, session=session, references=[authenticator]) - @classmethod def get_message(cls, event, context): (authenticator,) = event.get_typed_references(BaseAuthenticator) + authenticator = authenticator or event.get_data('authenticator_name') if context != authenticator: return _('enable of authenticator "%s"') % authenticator else: return _('enable') -class AuthenticatorDisable(EventTypeDefinition): +class AuthenticatorDisable(AuthenticatorEvents): name = 'authenticator.disable' label = _('authenticator disable') - @classmethod - def record(cls, *, user, session, authenticator): - super().record(user=user, session=session, references=[authenticator]) - @classmethod def get_message(cls, event, context): (authenticator,) = event.get_typed_references(BaseAuthenticator) + authenticator = authenticator or event.get_data('authenticator_name') if context != authenticator: return _('disable of authenticator "%s"') % authenticator else: return _('disable') -class AuthenticatorDeletion(EventTypeDefinition): +class AuthenticatorDeletion(AuthenticatorEvents): name = 'authenticator.deletion' label = _('authenticator deletion') - @classmethod - def record(cls, *, user, session, authenticator): - super().record(user=user, session=session, references=[authenticator]) - @classmethod def get_message(cls, event, context): (authenticator,) = event.get_typed_references(BaseAuthenticator) + authenticator = authenticator or event.get_data('authenticator_name') return _('deletion of authenticator "%s"') % authenticator diff --git a/tests/test_manager_journal.py b/tests/test_manager_journal.py index 66990dc4..1de1ab04 100644 --- a/tests/test_manager_journal.py +++ b/tests/test_manager_journal.py @@ -1318,3 +1318,12 @@ def test_event_type_list(app, superuser, events): for e in Event.objects.all(): assert '%s (%s)' % (e.type.name, e.type.definition.label) in response.text + + +def test_delete_authenticator(app, superuser, events): + events['authenticator'].delete() + response = login(app, superuser, path="/manage/journal/") + response.form.set('search', 'event:authenticator.creation') + response = response.form.submit() + assert len(response.pyquery('tbody tr')) == 1 + assert 'creation of authenticator "Password"' in response.pyquery('tbody tr').text() -- 2.30.2