File tree Expand file tree Collapse file tree 3 files changed +42
-12
lines changed Expand file tree Collapse file tree 3 files changed +42
-12
lines changed Original file line number Diff line number Diff line change 1
1
from __future__ import annotations
2
2
3
- from urllib .parse import urlencode
4
-
5
3
from allauth .account .adapter import DefaultAccountAdapter
6
4
from allauth .exceptions import ImmediateHttpResponse
7
5
from allauth .socialaccount .models import SocialLogin
11
9
from django .http import HttpResponseRedirect
12
10
from django .urls import reverse
13
11
12
+ from allauth_2fa .utils import get_next_query_string
14
13
from allauth_2fa .utils import user_has_valid_totp_device
15
14
16
15
@@ -45,16 +44,9 @@ def get_2fa_authenticate_url(self, request: HttpRequest) -> str:
45
44
redirect_url = reverse ("two-factor-authenticate" )
46
45
47
46
# Add "next" parameter to the URL if possible.
48
- # If the view function smells like a class-based view, we can interrogate it.
49
- if getattr (request .resolver_match .func , "view_class" , None ):
50
- view = request .resolver_match .func .view_class ()
51
- view .request = request
52
- success_url = view .get_success_url ()
53
- query_params = request .GET .copy ()
54
- if success_url :
55
- query_params [view .redirect_field_name ] = success_url
56
- if query_params :
57
- redirect_url += f"?{ urlencode (query_params )} "
47
+ query_string = get_next_query_string (request )
48
+ if query_string :
49
+ redirect_url += query_string
58
50
59
51
return redirect_url
60
52
Original file line number Diff line number Diff line change 6
6
from urllib .parse import urlencode
7
7
8
8
import qrcode
9
+ from django .http import HttpRequest
9
10
from django_otp .models import Device
10
11
from qrcode .image .svg import SvgPathImage
11
12
@@ -35,3 +36,29 @@ def user_has_valid_totp_device(user) -> bool:
35
36
if not user .is_authenticated :
36
37
return False
37
38
return user .totpdevice_set .filter (confirmed = True ).exists ()
39
+
40
+
41
+ def get_next_query_string (request : HttpRequest ) -> str | None :
42
+ """
43
+ Get the query string (including the prefix `?`) to
44
+ redirect to after a successful POST.
45
+
46
+ If a query string can't be determined, returns None.
47
+ """
48
+ # If the view function smells like a class-based view,
49
+ # we can interrogate it.
50
+ try :
51
+ view = request .resolver_match .func .view_class ()
52
+ redirect_field_name = view .redirect_field_name
53
+ except AttributeError :
54
+ # Interrogation failed :(
55
+ return None
56
+
57
+ view .request = request
58
+ query_params = request .GET .copy ()
59
+ success_url = view .get_success_url ()
60
+ if success_url :
61
+ query_params [redirect_field_name ] = success_url
62
+ if query_params :
63
+ return f"?{ urlencode (query_params )} "
64
+ return None
Original file line number Diff line number Diff line change 5
5
6
6
import pytest
7
7
from allauth .account .signals import user_logged_in
8
+ from allauth .account .views import PasswordResetFromKeyView
8
9
from django .conf import settings
9
10
from django .contrib .auth import get_user_model
10
11
from django .contrib .auth .models import AbstractUser
20
21
from pytest_django .asserts import assertRedirects
21
22
22
23
from allauth_2fa import views
24
+ from allauth_2fa .adapter import OTPAdapter
23
25
from allauth_2fa .middleware import BaseRequire2FAMiddleware
24
26
25
27
from . import forms as forms_overrides
@@ -393,3 +395,12 @@ def test_forms_override(
393
395
settings_key : f"{ custom_form_cls .__module__ } .{ custom_form_cls .__qualname__ } " ,
394
396
}
395
397
assert view .get_form_class () is custom_form_cls
398
+
399
+
400
+ @pytest .mark .parametrize ("view_cls" , [PasswordResetFromKeyView ])
401
+ def test_view_missing_attribute (request , view_cls ) -> None :
402
+ # Ensure we're testing a view that's missing the attribute.
403
+ assert hasattr (view_cls (), "get_redirect_field_name" ) is False
404
+
405
+ # Ensure the function doesn't fail when the attribute is missing.
406
+ assert OTPAdapter ().get_2fa_authenticate_url (request ) is not None
You can’t perform that action at this time.
0 commit comments