Add MFA/2FA support via standalone sub-package#728
Conversation
1a0d03b to
f5755c1
Compare
There was a problem hiding this comment.
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.mfasub-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.
There was a problem hiding this comment.
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.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
# Conflicts: # dj_rest_auth/__version__.py
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.mfatoINSTALLED_APPSand swapLoginViewforMFALoginView. MFA is per-user - users without TOTP configured see no behavior change.How it works
MFALoginViewsubclassesLoginViewand checks whether TOTP is enabledephemeral_token+ TOTP/recovery code to/mfa/verify/to complete loginactivation_token(instead of trusting raw secret submission)Endpoints
POST /mfa/verify/— exchange ephemeral token + code for real tokenGET /mfa/totp/activate/— generate setup payload (secret,totp_url, optionalqr_code_data_uri,activation_token)POST /mfa/totp/activate/— confirm activation withactivation_token+ codePOST /mfa/totp/deactivate/— disable TOTP (requires valid code)GET /mfa/status/— check MFA statusGET /mfa/recovery-codes/— view unused codesPOST /mfa/recovery-codes/regenerate/— regenerate codesSecurity hardening and UX updates
MFA is not enabled.on deactivate attempts when MFA is disabledselect_for_update()Dependencies
with-mfaextra now installspyotp>=2.9.0qrcodeis optional for server-side QR convenience; headless clients can generate QR fromtotp_urlDocs
docs/guides/mfa.md)docs/mfa.rstmkdocs.ymlnav and API endpoints docsTests
Expanded MFA coverage, including:
MFA test module currently runs with 33 passing tests.