Skip to content

Commit 6ed5a45

Browse files
committed
fix regression from PR jazzband#500
1 parent 8d1ecfe commit 6ed5a45

File tree

3 files changed

+19
-11
lines changed

3 files changed

+19
-11
lines changed

tests/test_views_login.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def test_valid_login(self, mock_signal):
3838
response = self._post({'auth-username': '[email protected]',
3939
'auth-password': 'secret',
4040
'login_view-current_step': 'auth'})
41-
self.assertRedirects(response, reverse('two_factor:setup'))
41+
self.assertRedirects(response, resolve_url(settings.LOGIN_REDIRECT_URL))
4242

4343
# No signal should be fired for non-verified user logins.
4444
self.assertFalse(mock_signal.called)
@@ -80,8 +80,7 @@ def test_valid_login_with_allowed_external_redirect(self):
8080
{'auth-username': '[email protected]',
8181
'auth-password': 'secret',
8282
'login_view-current_step': 'auth'})
83-
self.assertEqual(self.client.session.get('next'), redirect_url)
84-
self.assertRedirects(response, reverse('two_factor:setup'), fetch_redirect_response=False)
83+
self.assertRedirects(response, redirect_url, fetch_redirect_response=False)
8584

8685
def test_valid_login_with_disallowed_external_redirect(self):
8786
redirect_url = 'https://test.disallowed-success-url.com'
@@ -91,7 +90,7 @@ def test_valid_login_with_disallowed_external_redirect(self):
9190
{'auth-username': '[email protected]',
9291
'auth-password': 'secret',
9392
'login_view-current_step': 'auth'})
94-
self.assertRedirects(response, reverse('two_factor:setup'), fetch_redirect_response=False)
93+
self.assertRedirects(response, reverse('two_factor:profile'), fetch_redirect_response=False)
9594

9695
@mock.patch('two_factor.views.core.time')
9796
def test_valid_login_primary_key_stored(self, mock_time):
@@ -396,12 +395,12 @@ def test_login_different_user_on_existing_session(self, mock_logger):
396395
response = self._post({'auth-username': '[email protected]',
397396
'auth-password': 'secret',
398397
'login_view-current_step': 'auth'})
399-
self.assertRedirects(response, reverse('two_factor:setup'))
398+
self.assertRedirects(response, resolve_url(settings.LOGIN_REDIRECT_URL))
400399

401400
response = self._post({'auth-username': '[email protected]',
402401
'auth-password': 'secret',
403402
'login_view-current_step': 'auth'})
404-
self.assertRedirects(response, reverse('two_factor:setup'))
403+
self.assertRedirects(response, resolve_url(settings.LOGIN_REDIRECT_URL))
405404

406405
def test_missing_management_data(self):
407406
# missing management data
@@ -432,7 +431,7 @@ def test_login_different_user_with_otp_on_existing_session(self):
432431
response = self._post({'auth-username': '[email protected]',
433432
'auth-password': 'secret',
434433
'login_view-current_step': 'auth'})
435-
self.assertRedirects(response, reverse('two_factor:setup'))
434+
self.assertRedirects(response, resolve_url(settings.LOGIN_REDIRECT_URL))
436435

437436
response = self._post({'auth-username': '[email protected]',
438437
'auth-password': 'secret',

two_factor/views/core.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from django.forms import Form, ValidationError
1919
from django.http import Http404, HttpResponse, HttpResponseRedirect
2020
from django.shortcuts import redirect, resolve_url
21-
from django.urls import reverse
21+
from django.urls import reverse, resolve, Resolver404
2222
from django.utils.decorators import method_decorator
2323
from django.utils.functional import cached_property
2424
from django.utils.http import url_has_allowed_host_and_scheme
@@ -38,6 +38,7 @@
3838
from two_factor.plugins.phonenumber.utils import get_available_phone_methods
3939
from two_factor.plugins.registry import registry
4040
from two_factor.utils import totp_digits
41+
from two_factor.views.mixins import OTPRequiredMixin
4142

4243
from ..forms import (
4344
AuthenticationTokenForm, BackupTokenForm, DeviceValidationForm, MethodForm,
@@ -154,6 +155,10 @@ def done(self, form_list, **kwargs):
154155
device = getattr(self.get_user(), 'otp_device', None)
155156
response = redirect(redirect_to)
156157

158+
try:
159+
next_resolver_match = resolve(self.request.GET.get('next'))
160+
except Resolver404:
161+
next_resolver_match = None
157162
if device:
158163
signals.user_verified.send(sender=__name__, request=self.request,
159164
user=self.get_user(), device=device)
@@ -173,16 +178,17 @@ def done(self, form_list, **kwargs):
173178
httponly=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_HTTPONLY', True),
174179
samesite=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_SAMESITE', 'Lax'),
175180
)
176-
177181
return response
178182

179183
# If the user does not have a device.
180-
else:
184+
elif next_resolver_match and issubclass(next_resolver_match.func.view_class, OTPRequiredMixin):
181185
if self.request.GET.get('next'):
182186
self.request.session['next'] = self.get_success_url()
183187
return redirect('two_factor:setup')
184188

185-
# Copied from django.contrib.auth.views.LoginView (Branch: stable/1.11.x)
189+
return response
190+
191+
# Copied from django.conrib.auth.views.LoginView (Branch: stable/1.11.x)
186192
# https://github.com/django/django/blob/58df8aa40fe88f753ba79e091a52f236246260b3/django/contrib/auth/views.py#L63
187193
def get_success_url(self):
188194
url = self.get_redirect_url()

two_factor/views/mixins.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99

1010
class OTPRequiredMixin:
11+
""" Mark the class for further detection otp required from given class """
12+
otp_required = True
13+
1114
"""
1215
View mixin which verifies that the user logged in using OTP.
1316

0 commit comments

Comments
 (0)