CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-allauth

Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication.

Pending
Overview
Eval results
Files

mfa.mddocs/

Multi-Factor Authentication

TOTP authenticators, WebAuthn hardware keys, recovery codes, and MFA management flows. Provides enterprise-grade security with support for multiple authentication factors including time-based codes, hardware security keys, and backup recovery codes.

Capabilities

Models

Core models for managing MFA authenticators, recovery codes, and authentication sessions.

class Authenticator(models.Model):
    """
    Base model for MFA authenticators (TOTP, WebAuthn, etc.).
    """
    user: User = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    type: str = models.CharField(max_length=20)
    data: dict = models.JSONField(default=dict)
    created_at: datetime = models.DateTimeField(auto_now_add=True)
    last_used_at: Optional[datetime] = models.DateTimeField(null=True, blank=True)
    
    def __str__(self) -> str: ...
    def record_usage(self) -> None: ...

class RecoveryCode(models.Model):
    """
    Recovery codes for MFA account recovery.
    """
    user: User = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    code: str = models.CharField(max_length=16)
    used_at: Optional[datetime] = models.DateTimeField(null=True, blank=True)
    
    def is_used(self) -> bool: ...
    def use_code(self) -> None: ...

class AuthenticationSession(models.Model):
    """
    Track MFA authentication sessions.
    """
    user: User = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    created_at: datetime = models.DateTimeField(auto_now_add=True)
    expires_at: datetime = models.DateTimeField()
    token: str = models.CharField(max_length=255)
    
    def is_expired(self) -> bool: ...

TOTP (Time-based One-Time Passwords)

TOTP authenticator implementation using standard RFC 6238.

class TOTPAuthenticator:
    """
    Time-based One-Time Password authenticator.
    """
    
    def __init__(self, authenticator: Authenticator): ...
    
    def generate_qr_code(self, name: str = None) -> str:
        """
        Generate QR code URL for TOTP setup.
        
        Parameters:
        - name: Optional name for the account
        
        Returns:
        QR code data URL
        """
    
    def get_secret_key(self) -> str:
        """
        Get the secret key for manual entry.
        
        Returns:
        Base32-encoded secret key
        """
    
    def validate_token(self, token: str) -> bool:
        """
        Validate TOTP token.
        
        Parameters:
        - token: 6-digit TOTP code
        
        Returns:
        True if token is valid
        """
    
    @classmethod
    def generate_secret(cls) -> str:
        """
        Generate new TOTP secret.
        
        Returns:
        Base32-encoded secret
        """

def get_totp_key(user: User) -> str:
    """
    Get or generate TOTP secret key for user.
    
    Parameters:
    - user: User instance
    
    Returns:
    TOTP secret key
    """

def validate_totp_token(user: User, token: str) -> bool:
    """
    Validate TOTP token for user.
    
    Parameters:
    - user: User instance
    - token: TOTP token to validate
    
    Returns:
    True if token is valid
    """

WebAuthn (Hardware Security Keys)

WebAuthn implementation for hardware security keys and platform authenticators.

class WebAuthnAuthenticator:
    """
    WebAuthn hardware security key authenticator.
    """
    
    def __init__(self, authenticator: Authenticator): ...
    
    def get_credential_creation_options(self, request: HttpRequest) -> Dict[str, Any]:
        """
        Get options for WebAuthn credential creation.
        
        Parameters:
        - request: HTTP request object
        
        Returns:
        WebAuthn creation options dictionary
        """
    
    def verify_registration(self, request: HttpRequest, credential: Dict[str, Any]) -> bool:
        """
        Verify WebAuthn registration.
        
        Parameters:
        - request: HTTP request object  
        - credential: WebAuthn credential data
        
        Returns:
        True if registration is valid
        """
    
    def get_credential_request_options(self, request: HttpRequest) -> Dict[str, Any]:
        """
        Get options for WebAuthn authentication.
        
        Parameters:
        - request: HTTP request object
        
        Returns:
        WebAuthn request options dictionary
        """
    
    def verify_authentication(self, request: HttpRequest, credential: Dict[str, Any]) -> bool:
        """
        Verify WebAuthn authentication.
        
        Parameters:
        - request: HTTP request object
        - credential: WebAuthn credential data
        
        Returns:
        True if authentication is valid
        """

def get_webauthn_rp_id(request: HttpRequest) -> str:
    """
    Get WebAuthn Relying Party ID from request.
    
    Parameters:
    - request: HTTP request object
    
    Returns:
    RP ID string
    """

def get_webauthn_origin(request: HttpRequest) -> str:
    """
    Get WebAuthn origin from request.
    
    Parameters:
    - request: HTTP request object
    
    Returns:
    Origin URL string
    """

Recovery Codes

Recovery code generation and management for MFA account recovery.

def generate_recovery_codes(user: User, count: int = 10) -> List[str]:
    """
    Generate recovery codes for user.
    
    Parameters:
    - user: User instance
    - count: Number of codes to generate
    
    Returns:
    List of recovery code strings
    """

def validate_recovery_code(user: User, code: str) -> bool:
    """
    Validate and consume recovery code.
    
    Parameters:
    - user: User instance
    - code: Recovery code to validate
    
    Returns:
    True if code is valid and unused
    """

def get_unused_recovery_codes(user: User) -> List[RecoveryCode]:
    """
    Get unused recovery codes for user.
    
    Parameters:
    - user: User instance
    
    Returns:
    List of unused RecoveryCode instances
    """

def regenerate_recovery_codes(user: User) -> List[str]:
    """
    Regenerate all recovery codes for user.
    
    Parameters:
    - user: User instance
    
    Returns:
    List of new recovery code strings
    """

Views

Django views for MFA setup, authentication, and management.

class AuthenticateView(FormView):
    """
    MFA authentication view.
    """
    template_name: str = "mfa/authenticate.html"
    form_class: type = AuthenticateForm
    
    def get_form_kwargs(self) -> Dict[str, Any]: ...
    def form_valid(self, form: AuthenticateForm) -> HttpResponse: ...

class TOTPAddView(FormView):
    """
    Add TOTP authenticator view.
    """
    template_name: str = "mfa/totp/add.html"
    form_class: type = TOTPAddForm
    
    def get_context_data(self, **kwargs) -> Dict[str, Any]: ...
    def form_valid(self, form: TOTPAddForm) -> HttpResponse: ...

class TOTPRemoveView(FormView):
    """
    Remove TOTP authenticator view.
    """
    template_name: str = "mfa/totp/remove.html"
    form_class: type = TOTPRemoveForm

class WebAuthnAddView(FormView):
    """
    Add WebAuthn authenticator view.
    """
    template_name: str = "mfa/webauthn/add.html"
    form_class: type = WebAuthnAddForm
    
    def get_context_data(self, **kwargs) -> Dict[str, Any]: ...

class RecoveryCodesView(TemplateView):
    """
    Recovery codes management view.
    """
    template_name: str = "mfa/recovery_codes/index.html"
    
    def get_context_data(self, **kwargs) -> Dict[str, Any]: ...

class RecoveryCodesGenerateView(FormView):
    """
    Generate new recovery codes view.
    """
    template_name: str = "mfa/recovery_codes/generate.html"
    form_class: type = GenerateRecoveryCodesForm
    
    def form_valid(self, form: GenerateRecoveryCodesForm) -> HttpResponse: ...

Forms

Django forms for MFA setup and authentication.

class AuthenticateForm(forms.Form):
    """
    MFA authentication form.
    """
    code: str = forms.CharField(max_length=16)
    
    def __init__(self, user: User, request: HttpRequest, *args, **kwargs): ...
    def clean_code(self) -> str: ...

class TOTPAddForm(forms.Form):
    """
    TOTP setup form.
    """
    secret: str = forms.CharField(widget=forms.HiddenInput)
    code: str = forms.CharField(max_length=6)
    
    def __init__(self, user: User, *args, **kwargs): ...
    def clean_code(self) -> str: ...
    def save(self) -> Authenticator: ...

class TOTPRemoveForm(forms.Form):
    """
    TOTP removal form.
    """
    authenticator: int = forms.ModelChoiceField(queryset=None)
    
    def __init__(self, user: User, *args, **kwargs): ...
    def save(self) -> None: ...

class WebAuthnAddForm(forms.Form):
    """
    WebAuthn setup form.
    """
    name: str = forms.CharField(max_length=100)
    credential: str = forms.CharField(widget=forms.HiddenInput)
    
    def __init__(self, user: User, request: HttpRequest, *args, **kwargs): ...
    def save(self) -> Authenticator: ...

class GenerateRecoveryCodesForm(forms.Form):
    """
    Recovery code generation form.
    """
    
    def __init__(self, user: User, *args, **kwargs): ...
    def save(self) -> List[str]: ...

Utilities

MFA utility functions and helpers.

def is_mfa_enabled(user: User) -> bool:
    """
    Check if user has MFA enabled.
    
    Parameters:
    - user: User instance
    
    Returns:
    True if user has any MFA authenticators
    """

def get_user_authenticators(user: User, authenticator_type: str = None) -> QuerySet:
    """
    Get user's MFA authenticators.
    
    Parameters:
    - user: User instance
    - authenticator_type: Optional filter by authenticator type
    
    Returns:
    QuerySet of Authenticator instances
    """

def create_authentication_session(user: User) -> AuthenticationSession:
    """
    Create MFA authentication session.
    
    Parameters:
    - user: User instance
    
    Returns:
    AuthenticationSession instance
    """

def verify_authentication_session(token: str) -> Optional[AuthenticationSession]:
    """
    Verify MFA authentication session token.
    
    Parameters:
    - token: Session token
    
    Returns:
    AuthenticationSession instance if valid, None otherwise
    """

Usage Examples

TOTP Setup

from allauth.mfa.totp import TOTPAuthenticator, get_totp_key
from allauth.mfa.models import Authenticator

# Generate TOTP secret for user
secret = get_totp_key(user)

# Create authenticator
authenticator = Authenticator.objects.create(
    user=user,
    type='totp',
    data={'secret': secret}
)

# Generate QR code for setup
totp_auth = TOTPAuthenticator(authenticator)
qr_code_url = totp_auth.generate_qr_code(f"{user.username}@example.com")

# Validate TOTP token
is_valid = totp_auth.validate_token('123456')

WebAuthn Setup

from allauth.mfa.webauthn import WebAuthnAuthenticator
from allauth.mfa.models import Authenticator

# Create WebAuthn authenticator
authenticator = Authenticator.objects.create(
    user=user,
    type='webauthn',
    data={}
)

webauthn_auth = WebAuthnAuthenticator(authenticator)

# Get registration options (send to frontend)
creation_options = webauthn_auth.get_credential_creation_options(request)

# Verify registration (after credential creation)
credential_data = {
    'id': 'credential_id',
    'rawId': 'raw_credential_id',
    'response': {
        'attestationObject': 'attestation_data',
        'clientDataJSON': 'client_data'
    }
}

is_valid = webauthn_auth.verify_registration(request, credential_data)

Recovery Codes

from allauth.mfa.recovery_codes import (
    generate_recovery_codes, 
    validate_recovery_code,
    get_unused_recovery_codes
)

# Generate recovery codes
codes = generate_recovery_codes(user, count=10)
print("Recovery codes:", codes)

# Validate and use recovery code
is_valid = validate_recovery_code(user, 'ABC123DEF')

# Check remaining codes
remaining_codes = get_unused_recovery_codes(user)
print(f"Remaining codes: {len(remaining_codes)}")

MFA Authentication Flow

from allauth.mfa.utils import is_mfa_enabled, create_authentication_session

# Check if user has MFA enabled
if is_mfa_enabled(user):
    # Create authentication session
    session = create_authentication_session(user)
    
    # Store session token (e.g., in session or redirect parameter)
    request.session['mfa_session_token'] = session.token
    
    # Redirect to MFA authentication page
    return redirect('mfa_authenticate')

Template Usage

<!-- MFA status in user profile -->
{% if user.is_authenticated %}
    {% load mfa_tags %}
    
    <h3>Multi-Factor Authentication</h3>
    {% if user|is_mfa_enabled %}
        <p class="text-success">✓ MFA is enabled</p>
        
        <!-- Show authenticators -->
        {% for auth in user.authenticator_set.all %}
            <div class="authenticator">
                <strong>{{ auth.get_type_display }}</strong>
                <small>Added {{ auth.created_at|date }}</small>
            </div>
        {% endfor %}
        
        <a href="{% url 'mfa_recovery_codes' %}">View Recovery Codes</a>
    {% else %}
        <p class="text-warning">⚠ MFA is not enabled</p>
        <a href="{% url 'mfa_add_totp' %}" class="btn btn-primary">Enable TOTP</a>
        <a href="{% url 'mfa_add_webauthn' %}" class="btn btn-secondary">Add Security Key</a>
    {% endif %}
{% endif %}

Settings Configuration

# In Django settings.py

# Enable MFA
INSTALLED_APPS = [
    # ...
    'allauth.mfa',
]

# MFA settings
MFA_TOTP_ISSUER = 'My Application'
MFA_RECOVERY_CODE_COUNT = 10
MFA_WEBAUTHN_RP_NAME = 'My Application'

# Require MFA for certain views
MFA_REQUIRED_FOR_STAFF = True
MFA_GRACE_PERIOD_SECONDS = 300  # 5 minutes

Install with Tessl CLI

npx tessl i tessl/pypi-django-allauth

docs

account-management.md

core-config.md

headless-api.md

index.md

mfa.md

social-authentication.md

template-system.md

user-sessions.md

tile.json