changes
This commit is contained in:
388
app/models/audit_enhanced.py
Normal file
388
app/models/audit_enhanced.py
Normal file
@@ -0,0 +1,388 @@
|
||||
"""
|
||||
Enhanced audit logging models for P2 security features
|
||||
"""
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional, Dict, Any
|
||||
from enum import Enum
|
||||
import json
|
||||
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, Text, Index
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
|
||||
from app.models.base import BaseModel
|
||||
|
||||
|
||||
class SecurityEventType(str, Enum):
|
||||
"""Security event types for classification"""
|
||||
# Authentication events
|
||||
LOGIN_SUCCESS = "login_success"
|
||||
LOGIN_FAILURE = "login_failure"
|
||||
LOGOUT = "logout"
|
||||
SESSION_EXPIRED = "session_expired"
|
||||
PASSWORD_CHANGE = "password_change"
|
||||
ACCOUNT_LOCKED = "account_locked"
|
||||
|
||||
# Authorization events
|
||||
ACCESS_DENIED = "access_denied"
|
||||
PRIVILEGE_ESCALATION = "privilege_escalation"
|
||||
UNAUTHORIZED_ACCESS = "unauthorized_access"
|
||||
|
||||
# Data access events
|
||||
DATA_READ = "data_read"
|
||||
DATA_WRITE = "data_write"
|
||||
DATA_DELETE = "data_delete"
|
||||
DATA_EXPORT = "data_export"
|
||||
BULK_OPERATION = "bulk_operation"
|
||||
|
||||
# System events
|
||||
CONFIGURATION_CHANGE = "configuration_change"
|
||||
USER_CREATION = "user_creation"
|
||||
USER_MODIFICATION = "user_modification"
|
||||
USER_DELETION = "user_deletion"
|
||||
|
||||
# Security events
|
||||
SUSPICIOUS_ACTIVITY = "suspicious_activity"
|
||||
ATTACK_DETECTED = "attack_detected"
|
||||
SECURITY_VIOLATION = "security_violation"
|
||||
IP_BLOCKED = "ip_blocked"
|
||||
|
||||
# File events
|
||||
FILE_UPLOAD = "file_upload"
|
||||
FILE_DOWNLOAD = "file_download"
|
||||
FILE_DELETION = "file_deletion"
|
||||
FILE_MODIFICATION = "file_modification"
|
||||
|
||||
# Integration events
|
||||
API_ACCESS = "api_access"
|
||||
EXTERNAL_SERVICE = "external_service"
|
||||
IMPORT_OPERATION = "import_operation"
|
||||
|
||||
|
||||
class SecurityEventSeverity(str, Enum):
|
||||
"""Security event severity levels"""
|
||||
CRITICAL = "critical"
|
||||
HIGH = "high"
|
||||
MEDIUM = "medium"
|
||||
LOW = "low"
|
||||
INFO = "info"
|
||||
|
||||
|
||||
class ComplianceStandard(str, Enum):
|
||||
"""Compliance standards for reporting"""
|
||||
SOX = "sox" # Sarbanes-Oxley
|
||||
HIPAA = "hipaa" # Health Insurance Portability and Accountability Act
|
||||
GDPR = "gdpr" # General Data Protection Regulation
|
||||
SOC2 = "soc2" # Service Organization Control 2
|
||||
ISO27001 = "iso27001" # Information Security Management
|
||||
NIST = "nist" # National Institute of Standards and Technology
|
||||
|
||||
|
||||
class EnhancedAuditLog(BaseModel):
|
||||
"""
|
||||
Enhanced audit logging for comprehensive security monitoring
|
||||
"""
|
||||
__tablename__ = "enhanced_audit_logs"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
|
||||
|
||||
# Event identification
|
||||
event_id = Column(String(64), nullable=False, unique=True, index=True)
|
||||
event_type = Column(String(50), nullable=False, index=True)
|
||||
event_category = Column(String(30), nullable=False, index=True) # security, audit, compliance, system
|
||||
severity = Column(String(20), nullable=False, index=True)
|
||||
|
||||
# Event details
|
||||
title = Column(String(255), nullable=False)
|
||||
description = Column(Text, nullable=False)
|
||||
outcome = Column(String(20), nullable=False, index=True) # success, failure, error, blocked
|
||||
|
||||
# User and session context
|
||||
user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True)
|
||||
session_id = Column(String(128), nullable=True, index=True)
|
||||
impersonated_user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
|
||||
|
||||
# Network context
|
||||
source_ip = Column(String(45), nullable=True, index=True)
|
||||
user_agent = Column(Text, nullable=True)
|
||||
request_id = Column(String(64), nullable=True, index=True)
|
||||
|
||||
# Geographic context
|
||||
country = Column(String(5), nullable=True)
|
||||
region = Column(String(100), nullable=True)
|
||||
city = Column(String(100), nullable=True)
|
||||
|
||||
# Technical context
|
||||
endpoint = Column(String(255), nullable=True, index=True)
|
||||
http_method = Column(String(10), nullable=True)
|
||||
status_code = Column(Integer, nullable=True)
|
||||
response_time_ms = Column(Integer, nullable=True)
|
||||
|
||||
# Resource context
|
||||
resource_type = Column(String(50), nullable=True, index=True) # file, customer, document, etc.
|
||||
resource_id = Column(String(100), nullable=True, index=True)
|
||||
resource_name = Column(String(255), nullable=True)
|
||||
|
||||
# Data context
|
||||
data_before = Column(Text, nullable=True) # JSON string of previous state
|
||||
data_after = Column(Text, nullable=True) # JSON string of new state
|
||||
data_volume = Column(Integer, nullable=True) # Bytes processed
|
||||
record_count = Column(Integer, nullable=True) # Number of records affected
|
||||
|
||||
# Risk assessment
|
||||
risk_score = Column(Integer, default=0, nullable=False, index=True) # 0-100
|
||||
risk_factors = Column(Text, nullable=True) # JSON array of risk indicators
|
||||
threat_indicators = Column(Text, nullable=True) # JSON array of threat patterns
|
||||
|
||||
# Compliance tracking
|
||||
compliance_standards = Column(Text, nullable=True) # JSON array of applicable standards
|
||||
retention_period_days = Column(Integer, default=2555, nullable=False) # 7 years default
|
||||
|
||||
# Timestamp and tracking
|
||||
timestamp = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False, index=True)
|
||||
processed_at = Column(DateTime(timezone=True), nullable=True)
|
||||
correlation_id = Column(String(64), nullable=True, index=True) # For related events
|
||||
|
||||
# Additional metadata
|
||||
tags = Column(Text, nullable=True) # JSON array of tags for categorization
|
||||
custom_fields = Column(Text, nullable=True) # JSON object for custom data
|
||||
|
||||
# Relationships
|
||||
user = relationship("User", foreign_keys=[user_id])
|
||||
impersonated_user = relationship("User", foreign_keys=[impersonated_user_id])
|
||||
|
||||
def set_data_before(self, data: Dict[str, Any]) -> None:
|
||||
"""Set data before change as JSON"""
|
||||
self.data_before = json.dumps(data, default=str) if data else None
|
||||
|
||||
def set_data_after(self, data: Dict[str, Any]) -> None:
|
||||
"""Set data after change as JSON"""
|
||||
self.data_after = json.dumps(data, default=str) if data else None
|
||||
|
||||
def get_data_before(self) -> Optional[Dict[str, Any]]:
|
||||
"""Get data before change from JSON"""
|
||||
return json.loads(self.data_before) if self.data_before else None
|
||||
|
||||
def get_data_after(self) -> Optional[Dict[str, Any]]:
|
||||
"""Get data after change from JSON"""
|
||||
return json.loads(self.data_after) if self.data_after else None
|
||||
|
||||
def set_risk_factors(self, factors: list) -> None:
|
||||
"""Set risk factors as JSON"""
|
||||
self.risk_factors = json.dumps(factors) if factors else None
|
||||
|
||||
def get_risk_factors(self) -> list:
|
||||
"""Get risk factors from JSON"""
|
||||
return json.loads(self.risk_factors) if self.risk_factors else []
|
||||
|
||||
def set_threat_indicators(self, indicators: list) -> None:
|
||||
"""Set threat indicators as JSON"""
|
||||
self.threat_indicators = json.dumps(indicators) if indicators else None
|
||||
|
||||
def get_threat_indicators(self) -> list:
|
||||
"""Get threat indicators from JSON"""
|
||||
return json.loads(self.threat_indicators) if self.threat_indicators else []
|
||||
|
||||
def set_compliance_standards(self, standards: list) -> None:
|
||||
"""Set compliance standards as JSON"""
|
||||
self.compliance_standards = json.dumps(standards) if standards else None
|
||||
|
||||
def get_compliance_standards(self) -> list:
|
||||
"""Get compliance standards from JSON"""
|
||||
return json.loads(self.compliance_standards) if self.compliance_standards else []
|
||||
|
||||
def set_tags(self, tags: list) -> None:
|
||||
"""Set tags as JSON"""
|
||||
self.tags = json.dumps(tags) if tags else None
|
||||
|
||||
def get_tags(self) -> list:
|
||||
"""Get tags from JSON"""
|
||||
return json.loads(self.tags) if self.tags else []
|
||||
|
||||
def set_custom_fields(self, fields: Dict[str, Any]) -> None:
|
||||
"""Set custom fields as JSON"""
|
||||
self.custom_fields = json.dumps(fields, default=str) if fields else None
|
||||
|
||||
def get_custom_fields(self) -> Optional[Dict[str, Any]]:
|
||||
"""Get custom fields from JSON"""
|
||||
return json.loads(self.custom_fields) if self.custom_fields else None
|
||||
|
||||
# Add indexes for performance
|
||||
__table_args__ = (
|
||||
Index('idx_enhanced_audit_user_timestamp', 'user_id', 'timestamp'),
|
||||
Index('idx_enhanced_audit_event_severity', 'event_type', 'severity'),
|
||||
Index('idx_enhanced_audit_resource', 'resource_type', 'resource_id'),
|
||||
Index('idx_enhanced_audit_ip_timestamp', 'source_ip', 'timestamp'),
|
||||
Index('idx_enhanced_audit_correlation', 'correlation_id'),
|
||||
Index('idx_enhanced_audit_risk_score', 'risk_score'),
|
||||
Index('idx_enhanced_audit_compliance', 'compliance_standards'),
|
||||
)
|
||||
|
||||
|
||||
class SecurityAlert(BaseModel):
|
||||
"""
|
||||
Security alerts for real-time monitoring and incident response
|
||||
"""
|
||||
__tablename__ = "security_alerts"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
|
||||
|
||||
# Alert identification
|
||||
alert_id = Column(String(64), nullable=False, unique=True, index=True)
|
||||
rule_id = Column(String(64), nullable=False, index=True)
|
||||
rule_name = Column(String(255), nullable=False)
|
||||
|
||||
# Alert details
|
||||
title = Column(String(255), nullable=False)
|
||||
description = Column(Text, nullable=False)
|
||||
severity = Column(String(20), nullable=False, index=True)
|
||||
confidence = Column(Integer, default=100, nullable=False) # 0-100 confidence score
|
||||
|
||||
# Context
|
||||
event_count = Column(Integer, default=1, nullable=False) # Number of triggering events
|
||||
time_window_minutes = Column(Integer, nullable=True) # Time window for correlation
|
||||
affected_users = Column(Text, nullable=True) # JSON array of user IDs
|
||||
affected_resources = Column(Text, nullable=True) # JSON array of resource identifiers
|
||||
|
||||
# Response tracking
|
||||
status = Column(String(20), default="open", nullable=False, index=True) # open, investigating, resolved, false_positive
|
||||
assigned_to = Column(Integer, ForeignKey("users.id"), nullable=True)
|
||||
resolved_by = Column(Integer, ForeignKey("users.id"), nullable=True)
|
||||
resolution_notes = Column(Text, nullable=True)
|
||||
|
||||
# Timestamps
|
||||
first_seen = Column(DateTime(timezone=True), nullable=False, index=True)
|
||||
last_seen = Column(DateTime(timezone=True), nullable=False, index=True)
|
||||
acknowledged_at = Column(DateTime(timezone=True), nullable=True)
|
||||
resolved_at = Column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
# Related audit logs
|
||||
triggering_events = Column(Text, nullable=True) # JSON array of audit log IDs
|
||||
|
||||
# Additional metadata
|
||||
tags = Column(Text, nullable=True) # JSON array of tags
|
||||
custom_fields = Column(Text, nullable=True) # JSON object for custom data
|
||||
|
||||
# Relationships
|
||||
assignee = relationship("User", foreign_keys=[assigned_to])
|
||||
resolver = relationship("User", foreign_keys=[resolved_by])
|
||||
|
||||
|
||||
class ComplianceReport(BaseModel):
|
||||
"""
|
||||
Compliance reporting for various standards
|
||||
"""
|
||||
__tablename__ = "compliance_reports"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
|
||||
|
||||
# Report identification
|
||||
report_id = Column(String(64), nullable=False, unique=True, index=True)
|
||||
standard = Column(String(50), nullable=False, index=True)
|
||||
report_type = Column(String(50), nullable=False, index=True) # periodic, on_demand, incident
|
||||
|
||||
# Report details
|
||||
title = Column(String(255), nullable=False)
|
||||
description = Column(Text, nullable=True)
|
||||
|
||||
# Time range
|
||||
start_date = Column(DateTime(timezone=True), nullable=False, index=True)
|
||||
end_date = Column(DateTime(timezone=True), nullable=False, index=True)
|
||||
|
||||
# Report content
|
||||
summary = Column(Text, nullable=True) # JSON summary of findings
|
||||
details = Column(Text, nullable=True) # JSON detailed findings
|
||||
recommendations = Column(Text, nullable=True) # JSON recommendations
|
||||
|
||||
# Metrics
|
||||
total_events = Column(Integer, default=0, nullable=False)
|
||||
security_events = Column(Integer, default=0, nullable=False)
|
||||
violations = Column(Integer, default=0, nullable=False)
|
||||
high_risk_events = Column(Integer, default=0, nullable=False)
|
||||
|
||||
# Status
|
||||
status = Column(String(20), default="generating", nullable=False, index=True) # generating, ready, delivered, archived
|
||||
generated_by = Column(Integer, ForeignKey("users.id"), nullable=False)
|
||||
generated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
|
||||
|
||||
# Delivery
|
||||
recipients = Column(Text, nullable=True) # JSON array of recipient emails
|
||||
delivered_at = Column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
# File storage
|
||||
file_path = Column(String(500), nullable=True) # Path to generated report file
|
||||
file_size = Column(Integer, nullable=True) # File size in bytes
|
||||
|
||||
# Relationships
|
||||
generator = relationship("User", foreign_keys=[generated_by])
|
||||
|
||||
|
||||
class AuditRetentionPolicy(BaseModel):
|
||||
"""
|
||||
Audit log retention policies for compliance
|
||||
"""
|
||||
__tablename__ = "audit_retention_policies"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
|
||||
|
||||
# Policy identification
|
||||
policy_name = Column(String(255), nullable=False, unique=True, index=True)
|
||||
event_types = Column(Text, nullable=True) # JSON array of event types to apply to
|
||||
compliance_standards = Column(Text, nullable=True) # JSON array of applicable standards
|
||||
|
||||
# Retention settings
|
||||
retention_days = Column(Integer, nullable=False) # Days to retain
|
||||
archive_after_days = Column(Integer, nullable=True) # Days before archiving
|
||||
|
||||
# Policy details
|
||||
description = Column(Text, nullable=True)
|
||||
is_active = Column(Boolean, default=True, nullable=False)
|
||||
priority = Column(Integer, default=100, nullable=False) # Higher priority = more specific
|
||||
|
||||
# Timestamps
|
||||
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
|
||||
updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
|
||||
created_by = Column(Integer, ForeignKey("users.id"), nullable=False)
|
||||
|
||||
# Relationships
|
||||
creator = relationship("User")
|
||||
|
||||
|
||||
class SIEMIntegration(BaseModel):
|
||||
"""
|
||||
SIEM integration configuration and status
|
||||
"""
|
||||
__tablename__ = "siem_integrations"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
|
||||
|
||||
# Integration identification
|
||||
integration_name = Column(String(255), nullable=False, unique=True, index=True)
|
||||
siem_type = Column(String(50), nullable=False, index=True) # splunk, elk, qradar, etc.
|
||||
|
||||
# Configuration
|
||||
endpoint_url = Column(String(500), nullable=True)
|
||||
api_key_hash = Column(String(255), nullable=True) # Hashed API key
|
||||
configuration = Column(Text, nullable=True) # JSON configuration
|
||||
|
||||
# Event filtering
|
||||
event_types = Column(Text, nullable=True) # JSON array of event types to send
|
||||
severity_threshold = Column(String(20), default="medium", nullable=False)
|
||||
|
||||
# Status
|
||||
is_active = Column(Boolean, default=True, nullable=False)
|
||||
is_healthy = Column(Boolean, default=True, nullable=False)
|
||||
last_sync = Column(DateTime(timezone=True), nullable=True)
|
||||
last_error = Column(Text, nullable=True)
|
||||
|
||||
# Statistics
|
||||
events_sent = Column(Integer, default=0, nullable=False)
|
||||
errors_count = Column(Integer, default=0, nullable=False)
|
||||
|
||||
# Timestamps
|
||||
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
|
||||
updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
|
||||
created_by = Column(Integer, ForeignKey("users.id"), nullable=False)
|
||||
|
||||
# Relationships
|
||||
creator = relationship("User")
|
||||
Reference in New Issue
Block a user