Skip to content

Comments

Add MFA/2FA support via standalone sub-package#728

Open
iMerica wants to merge 24 commits intomasterfrom
feature/mfa
Open

Add MFA/2FA support via standalone sub-package#728
iMerica wants to merge 24 commits intomasterfrom
feature/mfa

Conversation

@iMerica
Copy link
Owner

@iMerica iMerica commented Feb 15, 2026

Background

Adds TOTP-based multi-factor authentication as an opt-in sub-package (dj_rest_auth.mfa). Existing core behavior remains unchanged unless MFA is enabled for a user.

Users add dj_rest_auth.mfa to INSTALLED_APPS and swap LoginView for MFALoginView. MFA is per-user - users without TOTP configured see no behavior change.

How it works

  • MFALoginView subclasses LoginView and checks whether TOTP is enabled
  • MFA users get an ephemeral token (signed, 5-minute TTL) instead of a real auth token
  • Client sends ephemeral_token + TOTP/recovery code to /mfa/verify/ to complete login
  • Recovery codes are supported as fallback
  • TOTP activation is now validated with a signed, user-bound activation_token (instead of trusting raw secret submission)

Endpoints

  • POST /mfa/verify/ — exchange ephemeral token + code for real token
  • GET /mfa/totp/activate/ — generate setup payload (secret, totp_url, optional qr_code_data_uri, activation_token)
  • POST /mfa/totp/activate/ — confirm activation with activation_token + code
  • POST /mfa/totp/deactivate/ — disable TOTP (requires valid code)
  • GET /mfa/status/ — check MFA status
  • GET /mfa/recovery-codes/ — view unused codes
  • POST /mfa/recovery-codes/regenerate/ — regenerate codes

Security hardening and UX updates

  • Added MFA audit logging for sensitive events (activation/deactivation, failed verifications, recovery-code use)
  • Prevents silent TOTP replacement by rejecting activation when MFA is already enabled
  • Returns explicit MFA is not enabled. on deactivate attempts when MFA is disabled
  • Fixes recovery code race condition using atomic transaction + select_for_update()

Dependencies

  • with-mfa extra now installs pyotp>=2.9.0
  • qrcode is optional for server-side QR convenience; headless clients can generate QR from totp_url

Docs

  • Migrated MFA docs to MkDocs (docs/guides/mfa.md)
  • Removed legacy docs/mfa.rst
  • Added MFA references in mkdocs.yml nav and API endpoints docs

Tests

Expanded MFA coverage, including:

  • activation token validation and user binding
  • already-enabled activation guard
  • disabled deactivation behavior
  • audit logging assertions
  • concurrency-safe recovery code validation behavior

MFA test module currently runs with 33 passing tests.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds comprehensive TOTP-based Multi-Factor Authentication (MFA) support to dj-rest-auth as an optional sub-package (dj_rest_auth.mfa). The implementation is opt-in and backward compatible - existing code is unaffected except for new settings defaults in app_settings.py and optional extras in setup.py.

Changes:

  • Adds dj_rest_auth.mfa sub-package with models, views, serializers, and URLs for TOTP and recovery code authentication
  • Implements ephemeral token flow: users with MFA enabled receive a temporary signed token instead of immediate authentication, which must be exchanged with a valid TOTP/recovery code at /mfa/verify/
  • Includes comprehensive documentation in RST format and README with setup instructions, API endpoint descriptions, and usage examples

Reviewed changes

Copilot reviewed 18 out of 20 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
setup.py Adds with-mfa extras requiring pyotp>=2.9.0 and qrcode>=8.0
docs/mfa.rst Complete 304-line MFA documentation covering installation, endpoints, configuration, and examples
docs/index.rst Adds MFA documentation link to main index
docs/configuration.rst Documents all MFA-related configuration settings
dj_rest_auth/tests/test_mfa.py Comprehensive test suite with 28 tests including 19-step end-to-end flow
dj_rest_auth/tests/requirements.txt Adds pyotp test dependency
dj_rest_auth/tests/mfa_urls.py URL configuration for MFA tests
dj_rest_auth/mfa/views.py Implements MFALoginView, MFAVerifyView, TOTPActivateView, TOTPDeactivateView, MFAStatusView, and recovery code management views
dj_rest_auth/mfa/utils.py Ephemeral token creation/verification and MFA status checking utilities
dj_rest_auth/mfa/urls.py URL patterns for all MFA endpoints
dj_rest_auth/mfa/totp.py TOTP secret generation, validation, and management logic
dj_rest_auth/mfa/serializers.py Serializers for MFA verification, TOTP activation/deactivation, status, and recovery codes
dj_rest_auth/mfa/recovery_codes.py Recovery code generation, validation, and management with seed-based deterministic generation
dj_rest_auth/mfa/models.py Authenticator model storing TOTP secrets and recovery code data in JSONField
dj_rest_auth/mfa/migrations/0001_initial.py Initial migration creating Authenticator model with unique constraint on (user, type)
dj_rest_auth/mfa/apps.py AppConfig for the MFA sub-package
dj_rest_auth/mfa/init.py Empty init file for MFA package
dj_rest_auth/mfa/migrations/init.py Empty init file for migrations
dj_rest_auth/app_settings.py Adds MFA-related default settings and serializer import strings
README.md Adds Quick MFA Setup section with installation instructions and login flow diagram

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 20 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

iMerica and others added 3 commits February 15, 2026 20:58
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 20 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@iMerica iMerica requested a review from Copilot February 16, 2026 03:17
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 21 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants