diff --git a/src/open_inwoner/utils/admin.py b/src/open_inwoner/utils/admin.py index 48c4cbf189..c872e44275 100644 --- a/src/open_inwoner/utils/admin.py +++ b/src/open_inwoner/utils/admin.py @@ -1,5 +1,7 @@ from django.contrib import admin from django.contrib.admin.models import ADDITION, CHANGE, DELETION +from django.urls import NoReverseMatch, reverse +from django.utils.html import escape, format_html from django.utils.translation import gettext as _ from import_export.admin import ExportMixin @@ -10,9 +12,24 @@ class CustomTimelineLogAdmin(ExportMixin, TimelineLogAdmin): - list_display = ["get_object_title", "timestamp", "get_action_flag", "user"] + show_full_result_count = False + fields = ["content_type", "timestamp", "extra_data", "user"] + list_display = [ + "timestamp", + "user", + "content_type", + "object_link", + "object_id", + "get_action_flag", + "message", + ] list_filter = ["timestamp", "content_type"] list_select_related = ["content_type"] + search_fields = [ + "user__email", + "extra_data", + ] + date_hierarchy = "timestamp" # export resource_class = TimelineLogResource @@ -26,8 +43,6 @@ def get_object_title(self, obj): return f"{obj.content_type.name} - {obj.object_id}" return _("System - anonymous user") - get_object_title.short_description = _("Logboekvermelding") - def get_action_flag(self, obj): if obj.extra_data: if obj.extra_data.get("action_flag")[0] == ADDITION: @@ -42,19 +57,45 @@ def get_action_flag(self, obj): return _("System action") return "" + def message(self, obj): + return obj.extra_data.get("message") if obj.extra_data else "" + + def object_link(self, obj): + if not obj.extra_data: + return "" + + if obj.extra_data.get("action_flag") == DELETION: + link = escape(obj.extra_data.get("content_object_repr")) or "" + else: + ct = obj.content_type + try: + url = reverse( + ("admin:{app_label}_{model}_change").format( + app_label=ct.app_label, model=ct.model + ), + args=[obj.object_id], + ) + link = format_html( + '{}', + url, + escape(obj.extra_data.get("content_object_repr")), + ) + except NoReverseMatch: + link = escape(obj.extra_data.get("content_object_repr")) + except Exception: + link = "" + + return link + get_action_flag.short_description = _("Actie") + message.short_description = _("Bericht") + object_link.short_description = _("Object") def has_add_permission(self, request): return False def has_change_permission(self, request, obj=None): - """ - Show the audit log both to superusers and the users with 'change' - permissions. - """ - return ( - request.user.is_superuser or request.user.has_perm("admin.change_logentry") - ) and request.method != "POST" + return False def has_delete_permission(self, request, obj=None): return False diff --git a/src/open_inwoner/utils/tests/test_timeline_logger.py b/src/open_inwoner/utils/tests/test_timeline_logger.py index 8c2f0964cf..52ee96f0e7 100644 --- a/src/open_inwoner/utils/tests/test_timeline_logger.py +++ b/src/open_inwoner/utils/tests/test_timeline_logger.py @@ -97,7 +97,12 @@ def test_user_does_not_have_add_permission(self): response = self.app.get(url, user=self.user, expect_errors=True) self.assertEquals(response.status_code, 403) - def test_user_does_not_have_change_permission(self): + def test_superuser_does_not_have_add_permission(self): + log_url = reverse("admin:timeline_logger_timelinelog_add") + response = self.app.get(log_url, user=self.user, expect_errors=True) + self.assertEquals(response.status_code, 403) + + def test_superuser_does_not_have_change_permission(self): add_url = reverse("admin:accounts_contact_add") add_form = self.app.get(add_url, user=self.user).forms.get("contact_form") add_form["first_name"] = self.contact.first_name @@ -110,12 +115,10 @@ def test_user_does_not_have_change_permission(self): "admin:timeline_logger_timelinelog_change", kwargs={"object_id": log_entry.id}, ) - log_form = self.app.get(log_url, user=self.user).forms["timelinelog_form"] - log_form["object_id"] = 29 - response = log_form.submit(expect_errors=True) + response = self.app.post(log_url, user=self.user, expect_errors=True) self.assertEquals(response.status_code, 403) - def test_user_does_not_have_delete_permission(self): + def test_superuser_does_not_have_delete_permission(self): add_url = reverse("admin:accounts_contact_add") add_form = self.app.get(add_url, user=self.user).forms.get("contact_form") add_form["first_name"] = self.contact.first_name @@ -181,6 +184,16 @@ def test_get_action_returns_empty_string_when_no_extra_data_exists(self): ) self.assertEquals(action, "") + def test_object_link_returns_right_link(self): + self.add_instance() + url = reverse("admin:timeline_logger_timelinelog_changelist") + response = self.app.get(url, user=self.user) + contact = Contact.objects.first() + obj_link = reverse( + "admin:accounts_contact_change", kwargs={"object_id": contact.id} + ) + self.assertContains(response, obj_link) + class TestTimelineLogExport(WebTest): @freeze_time("2021-10-18 13:00:00")