Repository navigation
Conversation
- Introduced a new package structure for views, splitting them into separate files for enrollment, management, and verification. - Implemented `enroll_factor`, `security_settings`, `recovery_codes`, `manage_factors`, and `verify` views to handle MFA functionalities. - Removed the `configure.html` template and U2F-related JavaScript from the login template. - Updated the login view to utilize Django MFA's session management for pending verification. - Adjusted settings to support Django 4.2 and 5.2, including changes to the storage backend for static files. - Updated the test runner and tox configuration to reflect the new Django versions and removed deprecated dependencies.
… removed redundant code blocks and optimized functions.
| var options = decodeOptions(JSON.parse(optionsEl.textContent)); | ||
| var ceremony = | ||
| mode === "create" | ||
| ? navigator.credentials.create(options) |
There was a problem hiding this comment.
Misleading line break before '?'; readers may interpret this as an expression boundary.
| out.response.authenticatorData = bufToB64url(response.authenticatorData); | ||
| out.response.signature = bufToB64url(response.signature); | ||
| out.response.userHandle = response.userHandle | ||
| ? bufToB64url(response.userHandle) |
There was a problem hiding this comment.
Misleading line break before '?'; readers may interpret this as an expression boundary.
There was a problem hiding this comment.
Pull request overview
This PR modernizes django-mfa into a Django 4.2+/Python 3.10+ package with a new factor architecture (registry + polymorphic Authenticator model), removes legacy U2F codepaths, and replaces legacy packaging/CI/docs tooling with a pyproject.toml + GitHub Actions + Markdown docs setup.
Changes:
- Replaces legacy MFA/U2F implementation with registry-driven factor flows (TOTP, WebAuthn/passkeys, recovery codes), plus startup checks, session helpers, and new templates/tests.
- Migrates packaging from
setup.py/MANIFEST.in/requirements.txttopyproject.toml(hatchling) and adds CI jobs for tests/docs/packaging smoke. - Converts docs from reStructuredText to Markdown (MyST/Sphinx) and adds upgrade + security documentation.
Reviewed changes
Copilot reviewed 119 out of 123 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tox.ini | Removes legacy tox matrix (replaced by GitHub Actions + uv). |
| test_runner.py | Updates test harness settings and allows optional test labels. |
| setup.py | Removes legacy setuptools packaging entrypoint. |
| sandbox/test_django_mfa/wsgi.py | Removes deprecated WhiteNoise WSGI wrapper and documents modern setup. |
| sandbox/test_django_mfa/urls.py | Removes debug-toolbar routing and legacy imports. |
| sandbox/test_django_mfa/settings.py | Updates sandbox to new backends/STORAGES guidance and WebAuthn settings. |
| sandbox/templates/login.html | Removes argonauts and legacy U2F JS includes. |
| sandbox/templates/configure.html | Removes legacy MFA configure template. |
| sandbox/sample/views.py | Removes legacy U2F session pre-verify logic; relies on signal stamping. |
| sandbox/requirements.txt | Removes sandbox requirements pin file. |
| requirements.txt | Removes legacy root requirements pins. |
| README.rst | Removes legacy reStructuredText README. |
| pyproject.toml | Adds hatchling/PEP 621 packaging + dependency groups + ruff config. |
| MANIFEST.in | Removes legacy manifest now handled by hatchling inclusion rules. |
| docs/upgrading.md | Adds detailed breaking-change upgrade guide for 2.x/3.x → 4.x. |
| docs/security.md | Adds explicit security model and production checklist. |
| docs/recipes.md | Adds integration recipes and troubleshooting guidance. |
| docs/mfa_flow.rst | Removes legacy flow documentation (RST). |
| docs/mfa_flow.md | Adds new Markdown flow + URL reference. |
| docs/installation_setup.rst | Removes legacy installation/setup documentation (RST). |
| docs/installation_setup.md | Adds new Markdown installation/setup guide. |
| docs/index.rst | Removes legacy docs index (RST). |
| docs/index.md | Adds new Markdown docs index with toctrees. |
| docs/contributing.rst | Removes legacy contributing guide (RST). |
| docs/contributing.md | Adds new contributing guide aligned with uv/pyproject workflow. |
| docs/api.md | Adds public API reference for host projects. |
| django_mfa/views/picker.py | Adds factor picker view (registry-driven). |
| django_mfa/views/manage.py | Adds security settings / recovery codes / factor removal views. |
| django_mfa/views/enroll.py | Adds registry-driven enrollment view with uniform error handling. |
| django_mfa/views/init.py | Converts views into a package and preserves import compatibility. |
| django_mfa/utils.py | Modernizes string comparison and URI building; removes Python 2 fallback paths. |
| django_mfa/urls.py | Replaces legacy URL set with new namespaced registry-driven URL set. |
| django_mfa/totp.py | Modernizes Python 3 style and minor formatting. |
| django_mfa/tests/test_u2f_removal.py | Adds regression tests ensuring U2F artifacts are removed. |
| django_mfa/tests/test_templatetags.py | Adds QR template tag tests (SVG data URI). |
| django_mfa/tests/test_templates.py | Adds template contract tests (WebAuthn hooks, base template rules). |
| django_mfa/tests/test_support_authenticator.py | Adds tests for the software WebAuthn authenticator harness. |
| django_mfa/tests/test_session.py | Adds tests for session MFA state helper module. |
| django_mfa/tests/test_registry.py | Adds tests for adapter registry behavior and availability rules. |
| django_mfa/tests/test_ratelimit.py | Adds tests for per-user/per-factor throttling and parser validation. |
| django_mfa/tests/test_packaging.py | Adds wheel-content tests to prevent missing subpackages/assets. |
| django_mfa/tests/test_models.py | Replaces legacy model tests with Authenticator + legacy-removal tests. |
| django_mfa/tests/test_handles.py | Adds tests for stored WebAuthn user handle behavior and invariants. |
| django_mfa/tests/test_forms.py | Removes legacy U2F form tests. |
| django_mfa/tests/test_docs.py | Adds tests guarding MyST/Sphinx config and doc reachability. |
| django_mfa/tests/test_crypto.py | Adds tests for optional secret encryption round-trips/rotation. |
| django_mfa/tests/test_conf.py | Adds tests for conf defaults and WebAuthn-related system checks. |
| django_mfa/tests/test_compat.py | Adds tests preventing imports of symbols removed in Django 4.0+. |
| django_mfa/tests/test_adapter_totp.py | Adds TOTP adapter enrollment/verify tests including window tolerance. |
| django_mfa/tests/test_adapter_recovery.py | Adds recovery-code generation and verification behavior tests. |
| django_mfa/tests/support/authenticator.py | Adds in-process WebAuthn authenticator for end-to-end ceremony tests. |
| django_mfa/tests/support/init.py | Adds support package marker for test utilities. |
| django_mfa/templatetags/webauthn_tags.py | Adds tag to safely embed WebAuthn ceremony options as JSON script. |
| django_mfa/templatetags/otp_tags.py | Replaces Google Charts QR generation with server-rendered inline SVG QR. |
| django_mfa/templates/u2f/verify_second_factor_u2f.html | Removes legacy U2F verification template. |
| django_mfa/templates/u2f/key_list.html | Removes legacy U2F key list template. |
| django_mfa/templates/u2f/base.html | Removes legacy U2F base template. |
| django_mfa/templates/u2f/add_key.html | Removes legacy U2F enrollment template. |
| django_mfa/templates/u2f_base.html | Removes legacy U2F standalone base page template. |
| django_mfa/templates/django_mfa/verify_webauthn.html | Adds WebAuthn verification template (JS contract-based). |
| django_mfa/templates/django_mfa/verify_totp.html | Adds TOTP verification template. |
| django_mfa/templates/django_mfa/verify_recovery_codes.html | Adds recovery-code verification template. |
| django_mfa/templates/django_mfa/security.html | Reworks security settings UI around adapters/authenticators. |
| django_mfa/templates/django_mfa/recovery_codes.html | Reworks recovery codes page + client-side download behavior. |
| django_mfa/templates/django_mfa/picker.html | Adds factor picker template. |
| django_mfa/templates/django_mfa/enroll_webauthn.html | Adds WebAuthn enrollment template. |
| django_mfa/templates/django_mfa/enroll_totp.html | Adds TOTP enrollment template using new QR tag. |
| django_mfa/templates/django_mfa/base.html | Reworks MFA base layout and static asset namespacing. |
| django_mfa/static/style.css | Removes legacy un-namespaced static stylesheet. |
| django_mfa/static/django_u2f/django_u2f.js | Removes legacy U2F browser JS. |
| django_mfa/signals.py | Adds login/logout signal receivers (pending stamping + quicklogin hint). |
| django_mfa/session.py | Adds session MFA state read/write helpers. |
| django_mfa/registry.py | Adds adapter base class + registry implementation. |
| django_mfa/ratelimit.py | Adds cache-based per-user/per-factor throttling. |
| django_mfa/quicklogin.py | Adds optional “quicklogin hint cookie” feature for passkey UX. |
| django_mfa/otp.py | Modernizes OTP base class for Python 3. |
| django_mfa/models.py | Replaces legacy models with Authenticator + constraints + helpers. |
| django_mfa/migrations/0007_drop_legacy_models.py | Drops legacy tables with deliberate irreversibility guard. |
| django_mfa/migrations/0006_mfa_user_handle.py | Adds stored WebAuthn user-handle model. |
| django_mfa/migrations/0005_migrate_to_authenticator.py | Migrates legacy OTP/recovery data into Authenticator. |
| django_mfa/migrations/0004_authenticator.py | Introduces Authenticator schema and singleton constraints. |
| django_mfa/migrations/_helpers.py | Adds forward/reverse helpers for migration 0005. |
| django_mfa/middleware.py | Replaces legacy middleware logic with session/registry-driven enforcement and quicklogin cookie handling. |
| django_mfa/handles.py | Adds stored opaque user handle for passwordless WebAuthn login. |
| django_mfa/forms.py | Removes legacy U2F forms module. |
| django_mfa/crypto.py | Adds optional signing-based secret encryption/decryption helpers. |
| django_mfa/conf.py | Adds resolved settings wrapper with defaults and strict key validation. |
| django_mfa/checks.py | Adds WebAuthn-gated system checks (RP ID + backend presence). |
| django_mfa/backends.py | Adds authentication backend for passwordless passkey login. |
| django_mfa/apps.py | Registers checks and imports adapters/signals at app startup. |
| django_mfa/admin.py | Updates admin registration to new Authenticator model. |
| django_mfa/adapters/totp.py | Adds TOTP adapter with enrollment + verify implementation. |
| django_mfa/adapters/recovery_codes.py | Adds recovery code adapter with hashed-at-rest semantics. |
| django_mfa/adapters/init.py | Registers built-in adapters based on MFA_FACTORS. |
| django_mfa/init.py | Adds package version lookup; removes deprecated default_app_config. |
| .travis.yml | Removes legacy Travis CI config. |
| .readthedocs.yaml | Adds explicit Read the Docs build config using uv + MyST. |
| .gitignore | Updates ignores for uv/packaging artifacts and documents uv.lock intent. |
| .github/workflows/ci.yml | Adds GitHub Actions CI matrix (tests/coverage/docs/package smoke). |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| def record_failure(user, factor_type): | ||
| _limit, window = parse(mfa_settings.MFA_VERIFY_RATE_LIMIT) | ||
| key = _key(user, factor_type) | ||
| cache.set(key, cache.get(key, 0) + 1, window) |
No description provided.