ISO-27001-Risk-Management/risks/views.py
Kevin Heyer 686030e4cb feat: Enhance risk management application with user auditing and improved incident handling
- Added AuditUserMiddleware to track the current user for auditing purposes.
- Introduced audit_context for managing the current user in thread-local storage.
- Updated Control and Incident models to include created_at and updated_at timestamps.
- Refactored Control and Incident serializers to handle related risks and timestamps.
- Modified views to set the _changed_by attribute for user actions.
- Enhanced incident listing and detail views to display related risks and user actions.
- Updated templates for better presentation of risks and incidents.
- Added migrations for new fields and relationships in the database.
- Improved filtering options in the incident list view.
2025-09-09 12:00:29 +02:00

214 lines
No EOL
6.8 KiB
Python

from django.contrib.admin.models import LogEntry
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from django.shortcuts import render, get_object_or_404
from .models import Risk, Control, ResidualRisk, AuditLog, Incident
from .serializers import ControlSerializer, RiskSerializer, ResidualRiskSerializer, UserSerializer, AuditSerializer, IncidentSerializer
User = get_user_model()
# ---------------------------------------------------------------------------
# API
# ---------------------------------------------------------------------------
class RiskViewSet(viewsets.ModelViewSet):
"""
API endpoint for managing Risks.
Provides CRUD operations.
"""
queryset = Risk.objects.all()
serializer_class = RiskSerializer
permission_classes = [IsAuthenticated]
def perform_create(self, serializer):
instance = serializer.save()
instance._changed_by = self.request.user
def perform_update(self, serializer):
instance = serializer.save()
instance._changed_by = self.request.user
class ControlViewSet(viewsets.ModelViewSet):
"""
API endpoint for managing Controls.
Provides CRUD operations.
"""
queryset = Control.objects.all()
serializer_class = ControlSerializer
permission_classes = [IsAuthenticated]
def perform_create(self, serializer):
instance = serializer.save()
instance._changed_by = self.request.user
def perform_update(self, serializer):
instance = serializer.save()
instance._changed_by = self.request.user
class ResidualRiskViewSet(viewsets.ModelViewSet):
queryset = ResidualRisk.objects.all()
serializer_class = ResidualRiskSerializer
permission_classes = [IsAuthenticated]
class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
API endpoint for listing users and their responsibilities.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [IsAuthenticated]
def perform_create(self, serializer):
instance = serializer.save()
instance._changed_by = self.request.user
def perform_update(self, serializer):
instance = serializer.save()
instance._changed_by = self.request.user
class AuditViewSet(viewsets.ReadOnlyModelViewSet):
"""
API endpoint for view audit logging.
"""
queryset = AuditLog.objects.all()
serializer_class = AuditSerializer
permission_classes = [IsAuthenticated]
class IncidentViewSet(viewsets.ModelViewSet):
"""
API endpoint for listing incidents and its related risks.
"""
queryset = Incident.objects.all()
serializer_class = IncidentSerializer
permission_classes = [IsAuthenticated]
def perform_create(self, serializer):
instance = serializer.save(reported_by=self.request.user)
instance._changed_by = self.request.user
def perform_update(self, serializer):
instance = serializer.save()
instance._changed_by = self.request.user
# ---------------------------------------------------------------------------
# Web
# ---------------------------------------------------------------------------
def dashboard(request):
return render(request, "risks/dashboard.html")
def stats(request):
return render(request, "risks/statistics.html")
def list_risks(request):
qs = Risk.objects.all().select_related("owner")
# GET-Parameter lesen
risk_id = request.GET.get("risk")
control_id = request.GET.get("control")
owner_id = request.GET.get("owner")
if risk_id:
qs = qs.filter(id=risk_id)
if control_id:
qs = qs.filter(controls__id=control_id)
if owner_id:
qs = qs.filter(owner_id=owner_id)
risks = qs.order_by("title").distinct()
controls = Control.objects.all().order_by("title")
owners = User.objects.filter(owned_risks__isnull=False).distinct().order_by("username")
return render(request, "risks/list_risks.html", {
"risks": risks,
"controls": controls,
"owners": owners,
})
def show_risk(request, id):
risk = get_object_or_404(Risk, pk=id)
ct = ContentType.objects.get_for_model(Risk)
logs = LogEntry.objects.filter(
content_type=ct,
object_id=risk.pk
).order_by("-action_time")
return render(request, "risks/item_risk.html", {"risk": risk, "logs": logs})
def list_controls(request):
qs = Control.objects.all().select_related("responsible")
control_id = request.GET.get("control")
risk_id = request.GET.get("risk")
status = request.GET.get("status")
responsible_id = request.GET.get("responsible")
if control_id:
qs = qs.filter(id=control_id)
if risk_id:
qs = qs.filter(risks__id=risk_id) # FIX
if status:
qs = qs.filter(status=status)
if responsible_id:
qs = qs.filter(responsible_id=responsible_id)
controls = qs.order_by("title").distinct()
risks = Risk.objects.all().order_by("title")
users = User.objects.filter(responsible_controls__isnull=False).distinct().order_by("username")
return render(request, "risks/list_controls.html", {
"controls": controls,
"risks": risks,
"users": users,
"status_choices": Control.STATUS_CHOICES,
})
def show_control(request, id):
control = get_object_or_404(Control, pk=id)
ct = ContentType.objects.get_for_model(Control)
logs = LogEntry.objects.filter(
content_type=ct,
object_id=control.pk
).order_by("-action_time")
return render(request, "risks/item_control.html", {"control": control, "logs": logs})
def list_incidents(request):
qs = Incident.objects.all().select_related("reported_by").prefetch_related("related_risks")
risk_id = request.GET.get("risk")
status = request.GET.get("status")
reported_by = request.GET.get("reported_by")
if risk_id:
qs = qs.filter(related_risks__id=risk_id) # FIX
if status:
qs = qs.filter(status=status)
if reported_by:
qs = qs.filter(reported_by=reported_by)
incidents = qs.order_by("title").distinct()
risks = Risk.objects.all().order_by("title")
users = User.objects.filter(incidents__isnull=False).distinct().order_by("username") # sinnvoller
return render(request, "risks/list_incidents.html", {
"incidents": incidents,
"risks": risks,
"users": users,
"status_choices": Incident.STATUS_CHOICES,
})
def show_incident(request, id):
incident = get_object_or_404(Incident, pk=id)
ct = ContentType.objects.get_for_model(Incident)
logs = LogEntry.objects.filter(
content_type=ct,
object_id=incident.pk
).order_by("-action_time")
return render(request, "risks/item_incident.html", {"incident": incident, "logs": logs})