Skip to content

Commit edbb4b2

Browse files
committed
fixup: Redirect to setup
1 parent 76f6705 commit edbb4b2

File tree

4 files changed

+53
-55
lines changed

4 files changed

+53
-55
lines changed

tests/test_admin.py

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,61 +6,74 @@
66

77

88
@override_settings(ROOT_URLCONF='tests.urls_admin')
9-
class AdminSiteTest(UserMixin, TestCase):
10-
11-
def setUp(self):
12-
super().setUp()
13-
self.user = self.create_superuser()
14-
self.login_user()
15-
16-
def test_default_admin(self):
17-
response = self.client.get('/admin/')
18-
self.assertEqual(response.status_code, 200)
19-
20-
21-
@override_settings(ROOT_URLCONF='tests.urls_otp_admin')
229
class OTPAdminSiteTest(UserMixin, TestCase):
2310
"""
2411
otp_admin is admin console that needs OTP for access.
2512
Only admin users (is_staff and is_active)
2613
with OTP can access it.
2714
"""
2815

29-
def test_admin_not_authenticated_with_otp_enabled(self):
30-
response = self.client.get('/otp_admin/', follow=True)
31-
redirect_to = '%s?next=/otp_admin/' % reverse('admin:login')
16+
def test_anonymous_get_admin_index_redirects_to_admin_login(self):
17+
index_url = reverse('admin:index')
18+
login_url = reverse('admin:login')
19+
response = self.client.get(index_url, follow=True)
20+
redirect_to = '%s?next=%s' % (login_url, index_url)
3221
self.assertRedirects(response, redirect_to)
3322

34-
def test_otp_admin_without_otp(self):
23+
def test_anonymous_get_admin_logout_redirects_to_admin_index(self):
24+
# see: django.tests.admin_views.test_client_logout_url_can_be_used_to_login
25+
index_url = reverse('admin:index')
26+
logout_url = reverse('admin:logout')
27+
response = self.client.get(logout_url)
28+
self.assertEqual(
29+
response.status_code, 302
30+
)
31+
self.assertEqual(response.headers.get('Location'), index_url)
32+
33+
def test_anonymous_get_admin_login(self):
34+
index_url = reverse('admin:index')
35+
login_url = reverse('admin:login')
36+
37+
response = self.client.get(login_url, follow=True)
38+
self.assertEqual(response.status_code, 200)
39+
redirect_to = '%s?next=%s' % (login_url, index_url)
40+
self.assertRedirects(response, redirect_to)
41+
42+
def test_is_staff_not_verified_not_setup_get_admin_index_redirects_to_setup(self):
3543
"""
3644
admins without MFA setup should be redirected to the setup page.
3745
"""
46+
index_url = reverse('admin:index')
47+
setup_url = reverse('two_factor:setup')
3848
self.user = self.create_superuser()
3949
self.login_user()
40-
response = self.client.get('/otp_admin/', follow=True)
41-
redirect_to = '%s?next=/admin/' % reverse('two_factor:setup')
50+
response = self.client.get(index_url, follow=True)
51+
redirect_to = '%s?next=%s' % (setup_url, index_url)
4252
self.assertRedirects(response, redirect_to)
4353

44-
def test_otp_admin_without_otp_named_url(self):
54+
def test_is_staff_not_verified_not_setup_get_admin_login_redirects_to_setup(self):
55+
index_url = reverse('admin:index')
56+
login_url = reverse('admin:login')
57+
setup_url = reverse('two_factor:setup')
4558
self.user = self.create_superuser()
4659
self.login_user()
47-
response = self.client.get('/otp_admin/', follow=True)
48-
redirect_to = '%s?next=/admin/' % reverse('two_factor:setup')
60+
response = self.client.get(login_url, follow=True)
61+
redirect_to = '%s?next=%s' % (setup_url, index_url)
4962
self.assertRedirects(response, redirect_to)
5063

51-
def test_otp_admin_with_otp(self):
64+
def test_is_staff_is_verified_get_admin_index(self):
65+
index_url = reverse('admin:index')
5266
self.user = self.create_superuser()
5367
self.enable_otp(self.user)
5468
self.login_user()
55-
response = self.client.get('/otp_admin/')
69+
response = self.client.get(index_url)
5670
self.assertEqual(response.status_code, 200)
5771

58-
def test_client_logout_url_can_be_used_to_login(self):
59-
# see: django.tests.admin_views.test_client_logout_url_can_be_used_to_login
60-
admin_logout_url = reverse('admin:logout')
61-
response = self.client.get(admin_logout_url)
62-
self.assertEqual(
63-
response.status_code, 302
64-
)
65-
admin_index_url = reverse('admin:index')
66-
self.assertEqual(response.headers.get('Location'), admin_index_url)
72+
def test_is_staff_is_verified_get_admin_login_redirects_to_admin_index(self):
73+
login_url = reverse('admin:login')
74+
index_url = reverse('admin:index')
75+
self.user = self.create_superuser()
76+
self.enable_otp(self.user)
77+
self.login_user()
78+
response = self.client.get(login_url)
79+
self.assertEqual(response.headers.get('Location'), index_url)

tests/urls_admin.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
from django.contrib import admin
21
from django.urls import path
32

3+
from two_factor.admin import TwoFactorAdminSite
4+
45
from .urls import urlpatterns
56

67
urlpatterns += [
7-
path('admin/', admin.site.urls),
8+
path('admin/', TwoFactorAdminSite().urls),
89
]

tests/urls_otp_admin.py

Lines changed: 0 additions & 11 deletions
This file was deleted.

two_factor/admin.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,6 @@ def login(self, request, extra_context=None):
6767
if self.has_admin_permission(request):
6868
if not self.has_mfa_setup(request):
6969
return self.redirect_to_mfa_setup(request)
70-
else:
71-
# A user can get here if they logged in through the site
72-
# in a way that didn't require OTP. This can happen when sites
73-
# require MFA for only some pages. At his point a user should be
74-
# prompted for MFA verification.
75-
# TODO: Determine if OTP verification needs to be implemented or
76-
# if the login form will happily go straight to
77-
pass
7870

7971
# Since this module gets imported in the application's root package,
8072
# it cannot import models from other applications at the module level,
@@ -94,9 +86,12 @@ def login(self, request, extra_context=None):
9486
):
9587
context[REDIRECT_FIELD_NAME] = reverse("admin:index", current_app=self.name)
9688
context.update(extra_context or {})
89+
defaults = {
90+
'extra_context': context,
91+
}
9792

9893
request.current_app = self.name
99-
return LoginView.as_view()(request)
94+
return LoginView.as_view(**defaults)(request, context)
10095

10196
def admin_view(self, view, cacheable=False):
10297
"""

0 commit comments

Comments
 (0)