import logging import traceback from django.utils.deprecation import MiddlewareMixin from django.http.request import RawPostDataException from pingcap_sso.utils.requests import get_client_ip, get_client_agent from pingcap_sso.admin_audit_log.models import AdminAuditLog logger = logging.getLogger(__name__) class AdminAuditLogMiddleware(MiddlewareMixin): """ """ PATH_PREFIX = '/api/admin/' def _enable_audit_log(self, request, user): if not request.path.startswith(self.PATH_PREFIX): return False if not (user.is_authenticated and (user.is_staff or user.is_superuser)): return False if getattr(request, 'admin_audit_log_exempt', False): return False return True def process_request(self, request): if self._enable_audit_log(request, request.user): request.raw_body = request.body[:] def process_view(self, request, view_func, view_args, view_kwargs): if getattr(view_func, 'admin_audit_log_exempt', False): request.admin_audit_log_exempt = True def process_response(self, request, response): user = request.user if self._enable_audit_log(request, user): if response.get('content-type') == 'application/json': if getattr(response, 'streaming', False): response_body = '<<>>' else: response_body = response.content.decode('utf-8') else: response_body = '<<>>' try: if hasattr(request, 'raw_body'): request_body = request.raw_body.decode('utf-8') else: request_body = '' except RawPostDataException: request_body = '<<>>' except Exception: logger.error(traceback.format_exc()) request_body = '<<>>' try: AdminAuditLog.objects.create( user=user, referrer=(request.META.get('HTTP_REFERER') or '')[:255], path=request.get_full_path()[:255], request_method=request.method, request_body=request_body, response_code=response.status_code, response_body=response_body, ip=get_client_ip(request), ua=get_client_agent(request)[:255] ) except Exception: logger.error(traceback.format_exc()) return response