Spaces:
Sleeping
Sleeping
| import time | |
| from typing import Any | |
| from django.utils.deprecation import MiddlewareMixin | |
| from django.http import HttpRequest, HttpResponse | |
| from .models import AuditLog | |
| class SecurityHeadersMiddleware(MiddlewareMixin): | |
| def process_response(self, request: HttpRequest, response: HttpResponse): | |
| response.headers.setdefault("X-Content-Type-Options", "nosniff") | |
| response.headers.setdefault("Referrer-Policy", "no-referrer-when-downgrade") | |
| response.headers.setdefault("X-Frame-Options", "SAMEORIGIN") | |
| # CSP tối giản; mở rộng khi cần | |
| response.headers.setdefault("Content-Security-Policy", "default-src 'self'; img-src 'self' data:;") | |
| return response | |
| class AuditLogMiddleware(MiddlewareMixin): | |
| def process_request(self, request: HttpRequest): | |
| request._audit_start = time.perf_counter() | |
| def process_response(self, request: HttpRequest, response: HttpResponse): | |
| try: | |
| path = request.path[:300] | |
| query = request.META.get("QUERY_STRING", "")[:500] | |
| ua = request.META.get("HTTP_USER_AGENT", "")[:300] | |
| ip = request.META.get("REMOTE_ADDR") | |
| latency_ms = None | |
| start = getattr(request, "_audit_start", None) | |
| if start is not None: | |
| latency_ms = (time.perf_counter() - start) * 1000 | |
| intent = "" | |
| confidence = None | |
| data: Any = getattr(response, "data", None) | |
| if isinstance(data, dict): | |
| intent = str(data.get("intent") or "")[:50] | |
| confidence_value = data.get("confidence") | |
| try: | |
| confidence = float(confidence_value) if confidence_value is not None else None | |
| except (TypeError, ValueError): | |
| confidence = None | |
| AuditLog.objects.create( | |
| path=path, | |
| query=query, | |
| user_agent=ua, | |
| ip=ip, | |
| status=response.status_code, | |
| intent=intent, | |
| confidence=confidence, | |
| latency_ms=latency_ms, | |
| ) | |
| except Exception: | |
| # Không làm hỏng request nếu ghi log lỗi | |
| pass | |
| return response | |