feat: JWT auth, user management, audit logging system
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user