""" MFAFactor model — stores TOTP/OTP configuration per user. Maps to AGENT.md DBML: `mfa_factors` table (Lines 228-235). """ from django.conf import settings from django.db import models from core.models import BaseModel class MFAFactor(BaseModel): """ Multi-factor authentication factor for a user. Stores the encrypted TOTP secret. The `enabled` flag allows users to set up MFA before activating it (verify first, then enable). """ class FactorType(models.TextChoices): TOTP = "totp", "Time-based OTP" SMS = "sms", "SMS OTP" EMAIL = "email", "Email OTP" user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="mfa_factors", ) type = models.CharField( max_length=20, choices=FactorType.choices, default=FactorType.TOTP, ) secret = models.TextField( help_text="Encrypted TOTP secret. Use core.services.encryption to encrypt/decrypt.", ) enabled = models.BooleanField(default=False) class Meta: db_table = "mfa_factors" constraints = [ models.UniqueConstraint( fields=["user", "type"], name="unique_mfa_factor_per_user_type", ), ] def __str__(self) -> str: status = "enabled" if self.enabled else "disabled" return f"MFA ({self.type}) for {self.user_id} [{status}]"