114 lines
3.6 KiB
Python
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)
|