HH/apps/core/services.py
2025-12-24 12:42:31 +03:00

114 lines
3.6 KiB
Python

"""
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)