From 32273a89621f6fa7315592a6d1b5acf4969e8e65 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Tue, 27 Sep 2022 12:54:55 +0200 Subject: [PATCH 1/3] manager: search journal by uuid of deleted accounts (#69591) Search by a queryset of DeletedUser is extracted from search_by_email() to be shared with search_by_uuid(). --- src/authentic2/manager/journal_views.py | 18 ++++++++++++++---- tests/test_manager_journal.py | 23 +++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/authentic2/manager/journal_views.py b/src/authentic2/manager/journal_views.py index ed87f237..4308a583 100644 --- a/src/authentic2/manager/journal_views.py +++ b/src/authentic2/manager/journal_views.py @@ -47,8 +47,14 @@ class JournalSearchEngine(BaseJournalSearchEngine): user_uuid = uuid.UUID(lexem) except ValueError: yield self.q_false - else: + return + # check if uuid exists to go on the fast path + # searching in DeletedUser is expensive + if User.objects.filter(uuid=user_uuid.hex).exists(): yield Q(user__uuid=user_uuid.hex) + else: + deleted_user_qs = DeletedUser.objects.filter(old_uuid=user_uuid.hex) + yield from self._search_by_deleted_user(deleted_user_qs) @classmethod def search_by_uuid_documentation(cls): @@ -78,14 +84,18 @@ class JournalSearchEngine(BaseJournalSearchEngine): users = User.objects.find_duplicates(fullname=fullname, threshold=app_settings.A2_FTS_THRESHOLD) return self.query_for_users(users) - def search_by_email(self, email): - yield from super().search_by_email(email) - pks = list(DeletedUser.objects.filter(old_email=email).values_list('old_user_id', flat=True)) + def _search_by_deleted_user(self, deleted_user_qs): + pks = list(deleted_user_qs.values_list('old_user_id', flat=True)) if pks: yield Q(user_id__in=pks) user_ct = ContentType.objects.get_for_model(User) yield Q(reference_ids__contains=[n_2_pairing(user_ct.id, pk) for pk in pks]) + def search_by_email(self, email): + yield from super().search_by_email(email) + deleted_user_qs = DeletedUser.objects.filter(old_email=email) + yield from self._search_by_deleted_user(deleted_user_qs) + @classmethod def search_by_event_documentation(cls): return '%s %s' % ( diff --git a/tests/test_manager_journal.py b/tests/test_manager_journal.py index c21fddf9..d89cacca 100644 --- a/tests/test_manager_journal.py +++ b/tests/test_manager_journal.py @@ -1340,3 +1340,26 @@ def test_empty_event_types(app, superuser, events): response.form['event_type'].select(text='User deletions') response = response.form.submit() assert len(response.pyquery('tbody tr[data-event-type]')) == 0 + + +def test_search_by_uuid(app, superuser, events): + from authentic2.custom_user.models import DeletedUser + + login(app, user=superuser) + response = app.get('/manage/journal/') + + response.form.set('search', 'uuid:%s' % events['user'].uuid) + response = response.form.submit() + assert len(response.pyquery('tbody tr')) > 0 + + events['user'].delete() + + response.form.set('search', 'uuid:%s' % events['user'].uuid) + response = response.form.submit() + assert len(response.pyquery('tbody tr')) > 0 + + DeletedUser.objects.all().delete() + + response.form.set('search', 'uuid:%s' % events['user'].uuid) + response = response.form.submit() + assert len(response.pyquery('tbody tr')) == 0 -- 2.37.2