58 lines
1.8 KiB
Python
58 lines
1.8 KiB
Python
"""Kleine auditlog-helper voor gevoelige acties."""
|
|
import logging
|
|
|
|
from rest_framework import viewsets
|
|
|
|
logger = logging.getLogger("roosterwijs.audit")
|
|
|
|
|
|
def audit_log(request, action, target="", extra=None):
|
|
"""Log wie wat deed, zonder request bodies of wachtwoorden te loggen."""
|
|
user = getattr(request, "user", None)
|
|
username = user.get_username() if user and user.is_authenticated else "anonymous"
|
|
ip = None
|
|
if request is not None:
|
|
forwarded = request.META.get("HTTP_X_FORWARDED_FOR", "")
|
|
ip = (forwarded.split(",", 1)[0].strip() or request.META.get("REMOTE_ADDR") or None)
|
|
logger.info(
|
|
"actor=%r action=%s target=%s extra=%s",
|
|
username,
|
|
action,
|
|
target or "-",
|
|
extra or {},
|
|
)
|
|
try:
|
|
from plugins.models import AuditEvent
|
|
|
|
AuditEvent.objects.create(
|
|
actor=username,
|
|
action=action,
|
|
target=target or "",
|
|
ip_address=ip,
|
|
extra=extra or {},
|
|
)
|
|
except Exception:
|
|
logger.exception("Kon audit-event niet opslaan")
|
|
|
|
|
|
class AuditedModelViewSet(viewsets.ModelViewSet):
|
|
"""ModelViewSet die create/update/delete-acties auditbaar maakt."""
|
|
|
|
audit_name = None
|
|
|
|
def _audit_target(self, obj):
|
|
name = self.audit_name or obj.__class__.__name__
|
|
return f"{name}:{getattr(obj, 'pk', '-')}"
|
|
|
|
def perform_create(self, serializer):
|
|
obj = serializer.save()
|
|
audit_log(self.request, "create", self._audit_target(obj))
|
|
|
|
def perform_update(self, serializer):
|
|
obj = serializer.save()
|
|
audit_log(self.request, "update", self._audit_target(obj))
|
|
|
|
def perform_destroy(self, instance):
|
|
target = self._audit_target(instance)
|
|
super().perform_destroy(instance)
|
|
audit_log(self.request, "delete", target)
|