""" Core services - Utility services for audit logging and other common operations """ import logging from django.contrib.contenttypes.models import ContentType from .models import AuditEvent logger = logging.getLogger(__name__) class AuditService: """ Service for creating audit log entries. Centralizes audit logging logic across the application. """ @staticmethod def log_event( event_type, description, user=None, content_object=None, metadata=None, ip_address=None, user_agent=None ): """ Create an audit log entry. Args: event_type: Type of event (from AuditEvent.EVENT_TYPES) description: Human-readable description of the event user: User who triggered the event (optional) content_object: Related object (optional) metadata: Additional metadata as dict (optional) ip_address: IP address of the request (optional) user_agent: User agent string (optional) Returns: AuditEvent instance """ try: audit_data = { 'event_type': event_type, 'description': description, 'user': user, 'metadata': metadata or {}, 'ip_address': ip_address, 'user_agent': user_agent, } if content_object: audit_data['content_type'] = ContentType.objects.get_for_model(content_object) audit_data['object_id'] = content_object.id audit_event = AuditEvent.objects.create(**audit_data) logger.info(f"Audit event created: {event_type} - {description}") return audit_event except Exception as e: logger.error(f"Failed to create audit event: {str(e)}") # Don't raise exception - audit logging should not break the main flow return None @staticmethod def log_from_request(event_type, description, request, content_object=None, metadata=None): """ Create an audit log entry from a Django request object. Automatically extracts user, IP, and user agent from request. Args: event_type: Type of event description: Description of the event request: Django request object content_object: Related object (optional) metadata: Additional metadata (optional) Returns: AuditEvent instance """ user = request.user if request.user.is_authenticated else None ip_address = AuditService.get_client_ip(request) user_agent = request.META.get('HTTP_USER_AGENT', '') return AuditService.log_event( event_type=event_type, description=description, user=user, content_object=content_object, metadata=metadata, ip_address=ip_address, user_agent=user_agent ) @staticmethod def get_client_ip(request): """Extract client IP address from request.""" x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = request.META.get('REMOTE_ADDR') return ip def create_audit_log(event_type, description, **kwargs): """ Convenience function for creating audit logs. Wrapper around AuditService.log_event. """ return AuditService.log_event(event_type, description, **kwargs)