audit_service.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import db
  2. import json
  3. from fastapi import Request
  4. from typing import Optional, Any
  5. class AuditService:
  6. async def log(
  7. self,
  8. user_id: int,
  9. action: str,
  10. target_type: Optional[str] = None,
  11. target_id: Optional[int] = None,
  12. details: Optional[Any] = None,
  13. request: Optional[Request] = None
  14. ):
  15. ip_address = None
  16. if request:
  17. # Try to get real IP if behind proxy
  18. ip_address = request.headers.get("X-Forwarded-For", request.client.host if request.client else None)
  19. details_str = None
  20. if details:
  21. if isinstance(details, (dict, list)):
  22. # Convert details to JSON string, handling Decimals and other types
  23. def decimal_default(obj):
  24. try:
  25. from decimal import Decimal
  26. if isinstance(obj, Decimal):
  27. return float(obj)
  28. except:
  29. pass
  30. return str(obj)
  31. details_str = json.dumps(details, ensure_ascii=False, default=decimal_default)
  32. else:
  33. details_str = str(details)
  34. query = """
  35. INSERT INTO audit_logs (user_id, action, target_type, target_id, details, ip_address)
  36. VALUES (%s, %s, %s, %s, %s, %s)
  37. """
  38. db.execute_commit(query, (user_id, action, target_type, target_id, details_str, ip_address))
  39. audit_service = AuditService()