Skip to content

Commit

Permalink
fixup: Redirect to setup
Browse files Browse the repository at this point in the history
  • Loading branch information
dopry committed May 7, 2022
1 parent 76f6705 commit 4cfcee7
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 55 deletions.
79 changes: 46 additions & 33 deletions tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,74 @@


@override_settings(ROOT_URLCONF='tests.urls_admin')
class AdminSiteTest(UserMixin, TestCase):

def setUp(self):
super().setUp()
self.user = self.create_superuser()
self.login_user()

def test_default_admin(self):
response = self.client.get('/admin/')
self.assertEqual(response.status_code, 200)


@override_settings(ROOT_URLCONF='tests.urls_otp_admin')
class OTPAdminSiteTest(UserMixin, TestCase):
"""
otp_admin is admin console that needs OTP for access.
Only admin users (is_staff and is_active)
with OTP can access it.
"""

def test_admin_not_authenticated_with_otp_enabled(self):
response = self.client.get('/otp_admin/', follow=True)
redirect_to = '%s?next=/otp_admin/' % reverse('admin:login')
def test_anonymous_get_admin_index_redirects_to_admin_login(self):
index_url = reverse('admin:index')
login_url = reverse('admin:login')
response = self.client.get(index_url, follow=True)
redirect_to = '%s?next=%s' % (login_url, index_url)
self.assertRedirects(response, redirect_to)

def test_otp_admin_without_otp(self):
def test_anonymous_get_admin_logout_redirects_to_admin_index(self):
# see: django.tests.admin_views.test_client_logout_url_can_be_used_to_login
index_url = reverse('admin:index')
logout_url = reverse('admin:logout')
response = self.client.get(logout_url)
self.assertEqual(
response.status_code, 302
)
self.assertEqual(response.headers.get('Location'), index_url)

def test_anonymous_get_admin_login(self):
index_url = reverse('admin:index')
login_url = reverse('admin:login')

response = self.client.get(login_url, follow=True)
self.assertEqual(response.status_code, 200)
redirect_to = '%s?next=%s' % (login_url, index_url)
self.assertRedirects(response, redirect_to)

def test_is_staff_not_verified_not_setup_get_admin_index_redirects_to_setup(self):
"""
admins without MFA setup should be redirected to the setup page.
"""
index_url = reverse('admin:index')
setup_url = reverse('two_factor:setup')
self.user = self.create_superuser()
self.login_user()
response = self.client.get('/otp_admin/', follow=True)
redirect_to = '%s?next=/admin/' % reverse('two_factor:setup')
response = self.client.get(index_url, follow=True)
redirect_to = '%s?next=%s' % (setup_url, index_url)
self.assertRedirects(response, redirect_to)

def test_otp_admin_without_otp_named_url(self):
def test_is_staff_not_verified_not_setup_get_admin_login_redirects_to_setup(self):
index_url = reverse('admin:index')
login_url = reverse('admin:login')
setup_url = reverse('two_factor:setup')
self.user = self.create_superuser()
self.login_user()
response = self.client.get('/otp_admin/', follow=True)
redirect_to = '%s?next=/admin/' % reverse('two_factor:setup')
response = self.client.get(login_url, follow=True)
redirect_to = '%s?next=%s' % (setup_url, index_url)
self.assertRedirects(response, redirect_to)

def test_otp_admin_with_otp(self):
def test_is_staff_is_verified_get_admin_index(self):
index_url = reverse('admin:index')
self.user = self.create_superuser()
self.enable_otp(self.user)
self.login_user()
response = self.client.get('/otp_admin/')
response = self.client.get(index_url)
self.assertEqual(response.status_code, 200)

def test_client_logout_url_can_be_used_to_login(self):
# see: django.tests.admin_views.test_client_logout_url_can_be_used_to_login
admin_logout_url = reverse('admin:logout')
response = self.client.get(admin_logout_url)
self.assertEqual(
response.status_code, 302
)
admin_index_url = reverse('admin:index')
self.assertEqual(response.headers.get('Location'), admin_index_url)
def test_is_staff_is_verified_get_admin_login_redirects_to_admin_index(self):
login_url = reverse('admin:login')
index_url = reverse('admin:index')
self.user = self.create_superuser()
self.enable_otp(self.user)
self.login_user()
response = self.client.get(login_url)
self.assertEqual(response.headers.get('Location'), index_url)
4 changes: 2 additions & 2 deletions tests/urls_admin.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from django.contrib import admin
from django.urls import path
from two_factor.admin import TwoFactorAdminSite

from .urls import urlpatterns

urlpatterns += [
path('admin/', admin.site.urls),
path('admin/', TwoFactorAdminSite().urls),
]
11 changes: 0 additions & 11 deletions tests/urls_otp_admin.py

This file was deleted.

13 changes: 4 additions & 9 deletions two_factor/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,6 @@ def login(self, request, extra_context=None):
if self.has_admin_permission(request):
if not self.has_mfa_setup(request):
return self.redirect_to_mfa_setup(request)
else:
# A user can get here if they logged in through the site
# in a way that didn't require OTP. This can happen when sites
# require MFA for only some pages. At his point a user should be
# prompted for MFA verification.
# TODO: Determine if OTP verification needs to be implemented or
# if the login form will happily go straight to
pass

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

request.current_app = self.name
return LoginView.as_view()(request)
return LoginView.as_view(**defaults)(request, context)

def admin_view(self, view, cacheable=False):
"""
Expand Down

0 comments on commit 4cfcee7

Please sign in to comment.