Saas-Base / apps /security /models /security_event.py
rsnarsna
first commit
667aacd
Raw
History Blame Contribute Delete
1.86 kB
"""
SecurityEvent model β€” structured security event log.
Maps to AGENT.md DBML: `security_events` table (Lines 254-260).
"""
from django.conf import settings
from django.db import models
from core.models import BaseModel
class SecurityEvent(BaseModel):
"""
Records security-relevant events for a user.
Used for security alerts and anomaly detection.
Events are append-only β€” never updated or deleted.
"""
class EventType(models.TextChoices):
PASSWORD_CHANGE = "password_change", "Password Changed"
PASSWORD_RESET = "password_reset", "Password Reset"
EMAIL_CHANGE = "email_change", "Email Changed"
MFA_ENABLE = "mfa_enable", "MFA Enabled"
MFA_DISABLE = "mfa_disable", "MFA Disabled"
LOGIN_SUCCESS = "login_success", "Login Success"
LOGIN_FAILURE = "login_failure", "Login Failure"
DEVICE_NEW = "device_new", "New Device Detected"
SESSION_REVOKE = "session_revoke", "Session Revoked"
ACCOUNT_LOCKED = "account_locked", "Account Locked"
ACCOUNT_SUSPENDED = "account_suspended", "Account Suspended"
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="security_events",
)
event_type = models.CharField(
max_length=50,
choices=EventType.choices,
)
metadata = models.JSONField(
default=dict,
blank=True,
help_text="Additional event-specific data (IP, device info, etc.).",
)
class Meta:
db_table = "security_events"
ordering = ["-created_at"]
indexes = [
models.Index(fields=["user", "-created_at"]),
models.Index(fields=["event_type", "-created_at"]),
]
def __str__(self) -> str:
return f"{self.get_event_type_display()} β€” {self.user_id}"