manager: do not include erroneous link to deleted users (#62204)
gitea/authentic/pipeline/head This commit looks good Details

This commit is contained in:
Frédéric Péters 2023-05-24 18:07:19 +02:00
parent c247eb1474
commit a89824213a
2 changed files with 20 additions and 5 deletions

View File

@ -15,7 +15,7 @@
{% endif %} {% endif %}
<tr data-event-id="{{ event.id }}" data-event-cursor="{{ event.cursor }}" data-event-type="{{ event.type.name }}"> <tr data-event-id="{{ event.id }}" data-event-cursor="{{ event.cursor }}" data-event-type="{{ event.type.name }}">
<td class="journal-list--timestamp-column">{% block event-timestamp %}{{ event.timestamp }}{% endblock %}</td> <td class="journal-list--timestamp-column">{% block event-timestamp %}{{ event.timestamp }}{% endblock %}</td>
<td class="journal-list--user-column" {% if event.user %}data-user-id="{{ event.user.id }}"{% endif %}>{% block event-user %}{% if event.user %}<a href="{% url 'a2-manager-user-detail' pk=event.user.pk %}">{{ event.user }}</a>{% else %}-{% endif %}{% endblock %}</td> <td class="journal-list--user-column" {% if event.user and not event.user.deleted %}data-user-id="{{ event.user.id }}"{% endif %}>{% block event-user %}{% if event.user and not event.user.deleted %}<a href="{% url 'a2-manager-user-detail' pk=event.user.pk %}">{{ event.user }}</a>{% elif event.user %}{{ event.user }}{% else %}-{% endif %}{% endblock %}</td>
<td class="journal-list--session-column">{% block event-session %}{% if event.api %}API{% else %}{{ event.session_id_shortened|default:"-" }}{% endif %}{% endblock %}</td> <td class="journal-list--session-column">{% block event-session %}{% if event.api %}API{% else %}{{ event.session_id_shortened|default:"-" }}{% endif %}{% endblock %}</td>
<td class="journal-list--message-column">{% block event-message %}{{ event.message|default:"-" }}{% endblock %}</td> <td class="journal-list--message-column">{% block event-message %}{{ event.message|default:"-" }}{% endblock %}</td>
</tr> </tr>

View File

@ -25,7 +25,7 @@ from authentic2.a2_rbac.models import Role
from authentic2.a2_rbac.utils import get_default_ou from authentic2.a2_rbac.utils import get_default_ou
from authentic2.apps.authenticators.models import LoginPasswordAuthenticator from authentic2.apps.authenticators.models import LoginPasswordAuthenticator
from authentic2.apps.journal.models import Event, EventType, _registry from authentic2.apps.journal.models import Event, EventType, _registry
from authentic2.custom_user.models import Profile, ProfileType, User from authentic2.custom_user.models import DeletedUser, Profile, ProfileType, User
from authentic2.journal import journal from authentic2.journal import journal
from authentic2.models import Service from authentic2.models import Service
from authentic2_auth_saml.models import SAMLAuthenticator, SetAttributeAction from authentic2_auth_saml.models import SAMLAuthenticator, SetAttributeAction
@ -62,6 +62,8 @@ def events(db, superuser, freezer):
saml_authenticator = SAMLAuthenticator.objects.create(slug='saml') saml_authenticator = SAMLAuthenticator.objects.create(slug='saml')
set_attribute_action = SetAttributeAction.objects.create(authenticator=saml_authenticator) set_attribute_action = SetAttributeAction.objects.create(authenticator=saml_authenticator)
deleted_user = User.objects.create(username="deleted", email="deleted@example.com", ou=ou, uuid="3" * 32)
class EventFactory: class EventFactory:
date = make_aware(datetime.datetime(2020, 1, 1)) date = make_aware(datetime.datetime(2020, 1, 1))
@ -325,6 +327,9 @@ def events(db, superuser, freezer):
make('user.notification.activity', actor=service, target_user=user) make('user.notification.activity', actor=service, target_user=user)
make('user.notification.activity', actor=superuser, target_user=user) make('user.notification.activity', actor=superuser, target_user=user)
make("user.password.reset", user=deleted_user)
deleted_user.delete()
# verify we created at least one event for each type # verify we created at least one event for each type
assert set(Event.objects.values_list("type__name", flat=True)) == set(_registry) assert set(Event.objects.values_list("type__name", flat=True)) == set(_registry)
@ -365,6 +370,9 @@ def test_global_journal(app, superuser, events):
# remove event about admin login # remove event about admin login
Event.objects.order_by('-id').filter(type__name='user.login', user=superuser)[0].delete() Event.objects.order_by('-id').filter(type__name='user.login', user=superuser)[0].delete()
# get deleted user
deleted_user = DeletedUser.objects.all().first()
response = response.click("Global journal") response = response.click("Global journal")
content = extract_journal(response) content = extract_journal(response)
@ -749,6 +757,12 @@ def test_global_journal(app, superuser, events):
'type': 'user.notification.activity', 'type': 'user.notification.activity',
'user': 'super user', 'user': 'super user',
}, },
{
'message': 'password reset',
'timestamp': 'Jan. 3, 2020, 1 p.m.',
'type': 'user.password.reset',
'user': f'deleted user (#{deleted_user.old_user_id}, deleted@example.com)',
},
] ]
agent_page = response.click('agent', index=1) agent_page = response.click('agent', index=1)
@ -756,6 +770,9 @@ def test_global_journal(app, superuser, events):
user_page = response.click('Johnny doe', index=1) user_page = response.click('Johnny doe', index=1)
assert 'Johnny doe' in user_page.text assert 'Johnny doe' in user_page.text
with pytest.raises(IndexError):
response.click('deleted user')
def test_user_journal(app, superuser, events): def test_user_journal(app, superuser, events):
response = login(app, user=superuser, path="/manage/") response = login(app, user=superuser, path="/manage/")
@ -1277,6 +1294,7 @@ def test_search(app, superuser, events):
table_content = [text_content(p) for p in response.pyquery('tbody td.journal-list--message-column')] table_content = [text_content(p) for p in response.pyquery('tbody td.journal-list--message-column')]
assert table_content == [ assert table_content == [
'password reset',
'user deletion after 140 days of inactivity, notification sent to "user@example.com".', 'user deletion after 140 days of inactivity, notification sent to "user@example.com".',
'profile "aaa" of type "One Type" deleted for user "Johnny doe"', 'profile "aaa" of type "One Type" deleted for user "Johnny doe"',
'profile "aaa" of type "One Type" updated for user "Johnny doe"', 'profile "aaa" of type "One Type" updated for user "Johnny doe"',
@ -1297,7 +1315,6 @@ def test_search(app, superuser, events):
'password reset', 'password reset',
'password reset failure with email "USER@example.com"', 'password reset failure with email "USER@example.com"',
'password reset request with email "user@example.com"', 'password reset request with email "user@example.com"',
'user deletion',
] ]
response = response.click('Previous') response = response.click('Previous')
table_content = [text_content(p) for p in response.pyquery('tbody td.journal-list--message-column')] table_content = [text_content(p) for p in response.pyquery('tbody td.journal-list--message-column')]
@ -1372,8 +1389,6 @@ def test_empty_event_types(app, superuser, events):
def test_search_by_uuid(app, superuser, events): def test_search_by_uuid(app, superuser, events):
from authentic2.custom_user.models import DeletedUser
login(app, user=superuser) login(app, user=superuser)
response = app.get('/manage/journal/') response = app.get('/manage/journal/')