From dc5905e580eb3b02bdaccdd683f15eae4f604782 Mon Sep 17 00:00:00 2001 From: Yuhuai Liu Date: Fri, 30 Oct 2026 13:33:57 -0400 Subject: [PATCH] Make Django admin login page use custom LoginView to enfore 2FA --- admin/base/urls.py | 4 ++++ admin_tests/common_auth/test_views.py | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/admin/base/urls.py b/admin/base/urls.py index 1eb840bc362..2cd35b755c3 100644 --- a/admin/base/urls.py +++ b/admin/base/urls.py @@ -3,9 +3,13 @@ from django.contrib import admin from admin.base.settings import ADMIN_BASE, DEBUG from admin.base import views +from admin.common_auth.views import LoginView base_pattern = f'^{ADMIN_BASE}' +# Route Django admin's login through our LoginView so it enforces two-factor auth +admin.site.login = LoginView.as_view() + urlpatterns = [ ### ADMIN ### re_path( diff --git a/admin_tests/common_auth/test_views.py b/admin_tests/common_auth/test_views.py index b0a02b84f0e..8621eb96df8 100644 --- a/admin_tests/common_auth/test_views.py +++ b/admin_tests/common_auth/test_views.py @@ -3,6 +3,7 @@ from django.utils import timezone from django.test import RequestFactory +from django.urls import resolve, reverse from django.http import Http404 from admin.nodes.views import NodeSearchView from tests.base import AdminTestCase @@ -243,3 +244,7 @@ def custom_login(request, user, *args, **kwargs): mock_redirect.assert_called() mocked_login.assert_not_called() assert not hasattr(request, 'user') + + def test_django_admin_login_uses_login_view(self): + match = resolve(reverse('admin:login')) + assert match.func.view_class is LoginView