Files
hive-manage-v3/backend/app/middleware/audit.py
T
2026-07-22 16:52:09 +08:00

64 lines
2.2 KiB
Python

"""Audit middleware: log all mutating requests to AuditLog."""
import json
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response
from app.database import async_session
from app.models.audit import AuditLog
from app.services.auth_service import decode_access_token, get_user_by_id
class AuditMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next) -> Response:
if request.method in ("POST", "PUT", "PATCH", "DELETE"):
response = await call_next(request)
await self._log(request, response)
return response
return await call_next(request)
async def _log(self, request: Request, response: Response):
try:
user_id = "anonymous"
username = "anonymous"
auth_header = request.headers.get("authorization")
if auth_header and auth_header.startswith("Bearer "):
try:
payload = decode_access_token(auth_header[7:])
async with async_session() as db:
user = await get_user_by_id(db, payload["sub"])
if user:
user_id = user.id
username = user.username
except Exception:
pass
path = request.url.path
action = f"{request.method} {path}"
detail = {}
if response.status_code >= 400:
body = b""
try:
body = await request.body()
if body:
detail["request_body"] = json.loads(body)
except Exception:
pass
async with async_session() as db:
log = AuditLog(
user_id=user_id,
username=username,
action=action,
target=path,
detail=json.dumps(detail) if detail else None,
ip_address=request.client.host if request.client else None,
)
db.add(log)
await db.commit()
except Exception:
pass