from django.contrib import admin from django.utils.html import format_html from .models import AuditEvent, BackfillRun class ActorTypeFilter(admin.SimpleListFilter): title = "Actor type" parameter_name = "actor_type" def lookups(self, request, model_admin): return ( ("named", "Named actor"), ("programmatic", "Programmatic"), ) def queryset(self, request, queryset): if self.value() == "named": return queryset.filter(actor__isnull=False) if self.value() == "programmatic": return queryset.filter(actor__isnull=True) return queryset @admin.register(AuditEvent) class AuditEventAdmin(admin.ModelAdmin): list_display = ( "event_time", "actor_display", "action_detail_display", "target_summary", "evidence_display", "reconstructed_display", "message_display", ) list_filter = ( "action", ActorTypeFilter, "evidence_category", "source", "is_reconstructed", "actor", "event_time", "target_type", ) search_fields = ( 'actor__username', 'actor__email', 'target_repr', 'target_id', 'message', "source_id", ) readonly_fields = ( "id", "timestamp", "event_time", "actor", "action", "evidence_category", "control_family", "target_type", "target_id", "target_repr", "old_values_display", "new_values_display", "old_values", "new_values", "message", "source", "source_id", "is_reconstructed", "request_path", "ip_address", ) date_hierarchy = "event_time" def message_display(self, obj): return obj.message or "" message_display.short_description = "Message" def actor_display(self, obj): return obj.actor_display actor_display.short_description = "Actor" actor_display.admin_order_field = "actor" def action_display(self, obj): return obj.action_display action_display.short_description = "Action" action_display.admin_order_field = "action" def action_detail_display(self, obj): return obj.action_detail_display action_detail_display.short_description = "Action" action_detail_display.admin_order_field = "action" def transition_display(self, obj): return obj.transition_display transition_display.short_description = "Transition" def target_summary(self, obj): return obj.target_summary target_summary.short_description = "Target" target_summary.admin_order_field = "target_repr" def evidence_summary(self, obj): return obj.evidence_summary evidence_summary.short_description = "Evidence" evidence_summary.admin_order_field = "evidence_category" def evidence_display(self, obj): return format_html("{}
{}", obj.evidence_area_display, f"Source: {obj.source_display}") evidence_display.short_description = "Evidence" evidence_display.admin_order_field = "evidence_category" def reconstructed_display(self, obj): return obj.reconstructed_display reconstructed_display.short_description = "Reconstructed" reconstructed_display.admin_order_field = "is_reconstructed" def old_values_display(self, obj): return obj.old_values_display old_values_display.short_description = "Old values (resolved)" def new_values_display(self, obj): return obj.new_values_display new_values_display.short_description = "New values (resolved)" def has_add_permission(self, request): return False def has_change_permission(self, request, obj=None): return False def has_delete_permission(self, request, obj=None): return False def log_addition(self, request, obj, message): return None def log_change(self, request, obj, message): return None def log_deletion(self, request, obj, object_repr): return None def log_deletions(self, request, queryset): return [] @admin.register(BackfillRun) class BackfillRunAdmin(admin.ModelAdmin): list_display = ("name", "started", "completed", "created_events", "dry_run") readonly_fields = ("name", "started", "completed", "created_events", "dry_run", "notes") search_fields = ("name", "notes") list_filter = ("dry_run", "started", "completed") def has_add_permission(self, request): return False def has_change_permission(self, request, obj=None): return False def has_delete_permission(self, request, obj=None): return False