89 lines
2.8 KiB
Python
89 lines
2.8 KiB
Python
import json
|
|
|
|
from django.contrib import admin
|
|
|
|
from .models import AuditEvent
|
|
from .utils import log_event
|
|
|
|
|
|
PATCH_MARKER = "_cmmc_audit_admin_log_patch_installed"
|
|
|
|
|
|
def _message_to_text(message):
|
|
if isinstance(message, str):
|
|
return message
|
|
return json.dumps(message, default=str)
|
|
|
|
|
|
def _admin_change_message(obj, message):
|
|
details = _message_to_text(message)
|
|
if details:
|
|
return f"Admin changed {obj}: {details}"
|
|
return f"Admin changed {obj}"
|
|
|
|
|
|
def install_admin_audit_patch():
|
|
if getattr(admin.ModelAdmin, PATCH_MARKER, False):
|
|
return
|
|
|
|
original_log_addition = admin.ModelAdmin.log_addition
|
|
original_log_change = admin.ModelAdmin.log_change
|
|
original_log_deletion = admin.ModelAdmin.log_deletion
|
|
original_log_deletions = admin.ModelAdmin.log_deletions
|
|
|
|
def log_addition(self, request, obj, message):
|
|
result = original_log_addition(self, request, obj, message)
|
|
log_event(
|
|
AuditEvent.Action.ADMIN_ADDITION,
|
|
obj,
|
|
message=f"Admin added {obj}",
|
|
actor=getattr(request, "user", None),
|
|
request=request,
|
|
source=AuditEvent.Source.DJANGO_ADMIN,
|
|
)
|
|
return result
|
|
|
|
def log_change(self, request, obj, message):
|
|
result = original_log_change(self, request, obj, message)
|
|
log_event(
|
|
AuditEvent.Action.ADMIN_CHANGE,
|
|
obj,
|
|
message=_admin_change_message(obj, message),
|
|
actor=getattr(request, "user", None),
|
|
request=request,
|
|
source=AuditEvent.Source.DJANGO_ADMIN,
|
|
)
|
|
return result
|
|
|
|
def log_deletion(self, request, obj, object_repr):
|
|
result = original_log_deletion(self, request, obj, object_repr)
|
|
log_event(
|
|
AuditEvent.Action.ADMIN_DELETION,
|
|
obj,
|
|
message=f"Admin deleted {object_repr}",
|
|
actor=getattr(request, "user", None),
|
|
request=request,
|
|
source=AuditEvent.Source.DJANGO_ADMIN,
|
|
target_repr=object_repr,
|
|
)
|
|
return result
|
|
|
|
def log_deletions(self, request, queryset):
|
|
objects = list(queryset)
|
|
result = original_log_deletions(self, request, queryset)
|
|
for obj in objects:
|
|
log_event(
|
|
AuditEvent.Action.ADMIN_DELETION,
|
|
obj,
|
|
message=f"Admin deleted {obj}",
|
|
actor=getattr(request, "user", None),
|
|
request=request,
|
|
source=AuditEvent.Source.DJANGO_ADMIN,
|
|
)
|
|
return result
|
|
|
|
admin.ModelAdmin.log_addition = log_addition
|
|
admin.ModelAdmin.log_change = log_change
|
|
admin.ModelAdmin.log_deletion = log_deletion
|
|
admin.ModelAdmin.log_deletions = log_deletions
|
|
setattr(admin.ModelAdmin, PATCH_MARKER, True)
|