diff --git a/src/openforms/logging/admin.py b/src/openforms/logging/admin.py index 3946212a01..066288bcf2 100644 --- a/src/openforms/logging/admin.py +++ b/src/openforms/logging/admin.py @@ -1,4 +1,9 @@ +from typing import Any + from django.contrib import admin +from django.http import Http404 +from django.http.request import HttpRequest +from django.http.response import HttpResponse from import_export import resources from import_export.admin import ExportActionModelAdmin @@ -7,6 +12,8 @@ from openforms.logging.models import AVGTimelineLogProxy, TimelineLogProxy +from .logevent import timelinelog_details_view_admin + class TimelineLogProxyResource(resources.ModelResource): user = Field(attribute="user") @@ -68,6 +75,19 @@ def has_change_permission(self, request, obj=None): def has_delete_permission(self, request, obj=None): return False + def change_view( + self, + request: HttpRequest, + object_id: str, + form_url: str = "", + extra_context: dict[str, Any] | None = None, + ) -> HttpResponse: + timelinelog = self.get_object(request, object_id) + if timelinelog is None: + raise Http404(f"No {self.model._meta.object_name} matches the given query.") + timelinelog_details_view_admin(timelinelog, request.user) + return super().change_view(request, object_id, form_url, extra_context) + @admin.register(AVGTimelineLogProxy) class AVGTimelineLogProxyAdmin(TimelineLogProxyAdmin): diff --git a/src/openforms/logging/logevent.py b/src/openforms/logging/logevent.py index 616a67a4e4..848bd4aa9b 100644 --- a/src/openforms/logging/logevent.py +++ b/src/openforms/logging/logevent.py @@ -71,6 +71,18 @@ def _create_log( return log_entry +def timelinelog_details_view_admin(timelinelog_proxy: TimelineLogProxy, user: User): + _create_log( + timelinelog_proxy, + "timelinelog_details_view_admin", + tags=[TimelineLogTags.AVG], + user=user, + ) + + +# - - - + + def enabling_analytics_tool( analytics_tools_configuration: AnalyticsToolsConfiguration, analytics_tool: str ): diff --git a/src/openforms/logging/models.py b/src/openforms/logging/models.py index 54c9e33e50..d4a78b3788 100644 --- a/src/openforms/logging/models.py +++ b/src/openforms/logging/models.py @@ -126,7 +126,7 @@ def fmt_url(self) -> str: def content_admin_url(self) -> str: if not (self.object_id and self.content_type_id): return "" - + breakpoint() ct = self.content_type return reverse( f"admin:{ct.app_label}_{ct.model}_change", args=(self.object_id,) diff --git a/src/openforms/logging/templates/logging/events/timelinelog_details_view_admin.txt b/src/openforms/logging/templates/logging/events/timelinelog_details_view_admin.txt new file mode 100644 index 0000000000..b237b47148 --- /dev/null +++ b/src/openforms/logging/templates/logging/events/timelinelog_details_view_admin.txt @@ -0,0 +1,4 @@ +{% load i18n %} +{% blocktrans trimmed with lead=log.fmt_lead user=log.fmt_user timelinelog=log.pk %} + {{ lead }}: User {{ user }} viewed timelinelog {{ timelinelog }} in the admin +{% endblocktrans %} diff --git a/src/openforms/logging/tests/test_admin.py b/src/openforms/logging/tests/test_admin.py index 17157edf7a..f5b8f5219d 100644 --- a/src/openforms/logging/tests/test_admin.py +++ b/src/openforms/logging/tests/test_admin.py @@ -8,7 +8,11 @@ from django_webtest import WebTest from maykin_2fa.test import disable_admin_mfa -from openforms.accounts.tests.factories import StaffUserFactory, SuperUserFactory +from openforms.accounts.tests.factories import ( + StaffUserFactory, + SuperUserFactory, + UserFactory, +) from openforms.logging import logevent from openforms.logging.models import TimelineLogProxy from openforms.logging.tests.factories import TimelineLogProxyFactory @@ -98,6 +102,28 @@ def test_deleted_submission_doesnt_crash_logs(self): self.assertEqual(200, response.status_code) +@disable_admin_mfa() +class TimelineLogAdminTests(WebTest): + def test_viewing_timelinelog_details_in_admin_creates_log(self): + user = UserFactory.create(is_superuser=True, is_staff=True) + timeline_log = TimelineLogProxyFactory.create(user=user) + + self.app.get( + reverse( + "admin:logging_timelinelogproxy_change", + kwargs={"object_id": timeline_log.id}, + ), + user=user, + ) + + self.assertEqual( + TimelineLogProxy.objects.filter( + template="logging/events/timelinelog_details_view_admin.txt" + ).count(), + 1, + ) + + class TimelineLogExportsTest(TestCase): def test_bare_timelinelog_export(self): user = StaffUserFactory.create()