user-detail: display planned alert & deletion dates (#74464)

This commit is contained in:
Paul Marillonnet 2023-02-13 14:49:19 +01:00
parent 909ae86d2c
commit 947c325cdb
3 changed files with 96 additions and 1 deletions

View File

@ -85,6 +85,23 @@
</p>
{% endif %}
{% if alert_date and deletion_date %}
<p class="a2-manager-user-date-alert">
{% if alert_date > now %}
{% blocktrans %}Deletion alert email planned for {{ alert_date }}.{% endblocktrans %}
{% else %}
{% blocktrans %}Deletion alert email sent on {{ alert_date }}.{% endblocktrans %}
{% endif %}
</p>
<p class="a2-manager-user-date-deletion">
{% if deletion_date > now %}
{% blocktrans %}Account deletion planned for {{ deletion_date }}.{% endblocktrans %}
{% else %}
{% blocktrans %}Account deletion pending (should have been performed on {{ deletion_date }}).{% endblocktrans %}
{% endif %}
</p>
{% endif %}
{% for data in user_data %}
{{ data }}
{% endfor %}

View File

@ -16,6 +16,7 @@
import base64
import collections
import datetime
import operator
from django.contrib import messages
@ -30,6 +31,7 @@ from django.urls import reverse, reverse_lazy
from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.html import format_html
from django.utils.timezone import now
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _
from django.utils.translation import pgettext_lazy
@ -40,6 +42,7 @@ from django.views.generic.edit import BaseFormView
from authentic2.a2_rbac.models import OrganizationalUnit, Role, RoleParenting
from authentic2.a2_rbac.utils import get_default_ou
from authentic2.apps.journal.views import JournalViewWithContext
from authentic2.backends.ldap_backend import LDAPBackend
from authentic2.models import Attribute, PasswordReset
from authentic2.utils import hooks, spooler, switch_user
from authentic2.utils.misc import is_ajax, make_url, redirect, select_next_url, send_password_reset_mail
@ -437,6 +440,37 @@ class UserDetailView(OtherActionsMixin, BaseDetailView):
data for datas in hooks.call_hooks('manager_user_data', self, self.object) for data in datas
]
kwargs['user_data'] = user_data
realms = [block['realm'] for block in LDAPBackend.get_config() if block.get('realm')]
# user is active and belongs to an OU that defines deletion delays
if (
self.object.is_active
and self.object.email
and self.object.ou
and self.object.ou.clean_unused_accounts_alert
and self.object.ou.clean_unused_accounts_deletion
):
# user does not have any external identifier that would prohibit automated deletion
if not (
getattr(self.object, 'oidc_account', None)
or (
getattr(self.object, 'userexternalid', None)
and getattr(self.object.userexternalid, 'source', None)
and self.object.userexternalid.source in realms
)
):
# base value for computing alert & deletion is user's last login or creation date
start = self.object.last_login or self.object.date_joined
# but the keepalive alert date is more relevant if more recent
if self.object.keepalive and self.object.keepalive > start:
start = self.object.keepalive
kwargs['now'] = now().date()
kwargs['alert_date'] = start.date() + datetime.timedelta(
days=self.object.ou.clean_unused_accounts_alert
)
kwargs['deletion_date'] = start.date() + datetime.timedelta(
days=self.object.ou.clean_unused_accounts_deletion
)
ctx = super().get_context_data(**kwargs)
return ctx

View File

@ -756,7 +756,7 @@ def test_user_import_attributes(transactional_db, app, admin):
assert et.attributes.values['phone'].content == '+3281123456'
def test_detail_view(app, admin, simple_user):
def test_detail_view(app, admin, simple_user, freezer, user_ou1, ou1):
url = f'/manage/users/{simple_user.pk}/'
resp = login(app, admin, url)
assert str(simple_user.uuid) in resp.text
@ -766,6 +766,50 @@ def test_detail_view(app, admin, simple_user):
simple_user.save()
resp = app.get(url)
assert "Last activity on Feb. 1, 2023" in resp.pyquery('.a2-manager-user-last-activity')[0].text
logout(app)
ou1.clean_unused_accounts_alert = 700
ou1.clean_unused_accounts_deletion = 730
ou1.save()
user_ou1.date_joined = user_ou1.last_login = datetime.datetime(2023, 1, 1, 3)
user_ou1.save()
url = f'/manage/users/{user_ou1.pk}/'
freezer.move_to('2023-01-01')
resp = login(app, admin, url)
assert (
"Deletion alert email planned for Dec. 1, 2024."
in resp.pyquery('.a2-manager-user-date-alert')[0].text
)
assert (
"Account deletion planned for Dec. 31, 2024."
in resp.pyquery('.a2-manager-user-date-deletion')[0].text
)
logout(app)
freezer.move_to('2024-12-10')
resp = login(app, admin, url)
assert "Deletion alert email sent on Dec. 1, 2024." in resp.pyquery('.a2-manager-user-date-alert')[0].text
assert (
"Account deletion planned for Dec. 31, 2024."
in resp.pyquery('.a2-manager-user-date-deletion')[0].text
)
logout(app)
freezer.move_to('2025-01-01')
resp = login(app, admin, url)
assert "Deletion alert email sent on Dec. 1, 2024." in resp.pyquery('.a2-manager-user-date-alert')[0].text
assert (
"Account deletion pending (should have been performed on Dec. 31, 2024)."
in resp.pyquery('.a2-manager-user-date-deletion')[0].text
)
ou1.clean_unused_accounts_alert = ou1.clean_unused_accounts_deletion = None
ou1.save()
resp = app.get(url)
assert not resp.pyquery('.a2-manager-user-date-alert')
assert not resp.pyquery('.a2-manager-user-date-deletion')
def test_detail_view_user_deleted(app, admin, simple_user):