1212)
1313
1414if TYPE_CHECKING :
15+ from collections .abc import Callable
16+
1517 from .backends .base import BaseAuth
16- from .storage import UserProtocol
18+ from .storage import BaseStorage , UserProtocol
1719 from .strategy import HttpResponseProtocol
1820
1921
@@ -22,7 +24,9 @@ def do_auth(backend: BaseAuth, redirect_name: str = "next") -> HttpResponseProto
2224 data = backend .strategy .request_data (merge = False )
2325
2426 # Save extra data into session.
25- for field_name in backend .setting ("FIELDS_STORED_IN_SESSION" , []):
27+ for field_name in cast (
28+ "list[str]" , backend .setting ("FIELDS_STORED_IN_SESSION" , [])
29+ ):
2630 if field_name in data :
2731 backend .strategy .session_set (field_name , data [field_name ])
2832 else :
@@ -33,7 +37,7 @@ def do_auth(backend: BaseAuth, redirect_name: str = "next") -> HttpResponseProto
3337 redirect_uri = data [redirect_name ]
3438 if backend .setting ("SANITIZE_REDIRECTS" , True ):
3539 allowed_hosts = [
36- * backend .setting ("ALLOWED_REDIRECT_HOSTS" , []),
40+ * cast ( "list[str]" , backend .setting ("ALLOWED_REDIRECT_HOSTS" , []) ),
3741 backend .strategy .request_host (),
3842 ]
3943 redirect_uri = sanitize_redirect (allowed_hosts , redirect_uri )
@@ -43,9 +47,9 @@ def do_auth(backend: BaseAuth, redirect_name: str = "next") -> HttpResponseProto
4347 return backend .start ()
4448
4549
46- def do_complete (
50+ def do_complete ( # noqa: C901,PLR0912
4751 backend : BaseAuth ,
48- login ,
52+ login : Callable ,
4953 user : UserProtocol | None = None ,
5054 redirect_name : str = "next" ,
5155 * args ,
@@ -54,15 +58,19 @@ def do_complete(
5458 data = backend .strategy .request_data ()
5559
5660 is_authenticated = user_is_authenticated (user )
57- user = user if is_authenticated else None
61+ authenticated_user : UserProtocol | HttpResponseProtocol | None = (
62+ user if is_authenticated else None
63+ )
5864
5965 partial = partial_pipeline_data (backend , user , * args , ** kwargs )
6066 if partial :
61- user = backend .continue_pipeline (partial )
67+ authenticated_user = backend .continue_pipeline (partial )
6268 # clean partial data after usage
6369 backend .strategy .clean_partial_pipeline (partial .token )
6470 else :
65- user = backend .complete (* args , user = user , redirect_name = redirect_name , ** kwargs )
71+ authenticated_user = backend .complete (
72+ * args , user = authenticated_user , redirect_name = redirect_name , ** kwargs
73+ )
6674
6775 # pop redirect value before the session is trashed on login(), but after
6876 # the pipeline so that the pipeline can change the redirect if needed
@@ -72,12 +80,15 @@ def do_complete(
7280
7381 # check if the output value is something else than a user and just
7482 # return it to the client
75- user_model = backend .strategy .storage .user .user_model ()
76- if user and not isinstance (user , user_model ):
77- return cast ("HttpResponseProtocol" , user )
83+ user_model = cast ("type[BaseStorage]" , backend .strategy .storage ).user .user_model ()
84+ if authenticated_user and not isinstance (authenticated_user , user_model ):
85+ return cast ("HttpResponseProtocol" , authenticated_user )
86+
87+ authenticated_user = cast ("UserProtocol | None" , authenticated_user )
88+ url : str | None
7889
7990 if is_authenticated :
80- if not user :
91+ if not authenticated_user :
8192 url = setting_url (backend , redirect_value , "LOGIN_REDIRECT_URL" )
8293 else :
8394 url = setting_url (
@@ -86,17 +97,17 @@ def do_complete(
8697 "NEW_ASSOCIATION_REDIRECT_URL" ,
8798 "LOGIN_REDIRECT_URL" ,
8899 )
89- elif user :
100+ elif authenticated_user :
90101 # check if inactive users are allowed to login
91102 bypass_inactivation = backend .strategy .setting (
92103 "ALLOW_INACTIVE_USERS_LOGIN" , False
93104 )
94- if bypass_inactivation or user_is_active (user ):
105+ if bypass_inactivation or user_is_active (authenticated_user ):
95106 # catch is_new/social_user in case login() resets the instance
96107 # These attributes are set in BaseAuth.pipeline()
97- is_new = getattr (user , "is_new" , False )
98- social_user = user .social_user # type: ignore[union-attr]
99- login (backend , user , social_user )
108+ is_new = getattr (authenticated_user , "is_new" , False )
109+ social_user = authenticated_user .social_user # type: ignore[union-attr]
110+ login (backend , authenticated_user , social_user )
100111 # store last login backend name in session
101112 backend .strategy .session_set (
102113 "social_auth_last_login_backend" , social_user .provider
@@ -114,28 +125,31 @@ def do_complete(
114125 else :
115126 if backend .setting ("INACTIVE_USER_LOGIN" , False ):
116127 # This attribute is set in BaseAuth.pipeline()
117- social_user = user .social_user # type: ignore[union-attr]
118- login (backend , user , social_user )
128+ social_user = authenticated_user .social_user # type: ignore[union-attr]
129+ login (backend , authenticated_user , social_user )
119130 url = setting_url (
120131 backend , "INACTIVE_USER_URL" , "LOGIN_ERROR_URL" , "LOGIN_URL"
121132 )
122133 else :
123134 url = setting_url (backend , "LOGIN_ERROR_URL" , "LOGIN_URL" )
124135
125- assert url , "By this point URL has to have been set"
136+ if not url :
137+ raise ValueError ("By this point URL has to have been set" )
126138
127139 if redirect_value and redirect_value != url :
128140 redirect_value = quote (redirect_value )
129141 url += ("&" if "?" in url else "?" ) + f"{ redirect_name } ={ redirect_value } "
130142
131143 if backend .setting ("SANITIZE_REDIRECTS" , True ):
132144 allowed_hosts = [
133- * backend .setting ("ALLOWED_REDIRECT_HOSTS" , []),
145+ * cast ( "list[str]" , backend .setting ("ALLOWED_REDIRECT_HOSTS" , []) ),
134146 backend .strategy .request_host (),
135147 ]
136148 url = sanitize_redirect (allowed_hosts , url ) or backend .setting (
137149 "LOGIN_REDIRECT_URL"
138150 )
151+ if url is None :
152+ raise ValueError ("Disallowed URL" )
139153 return backend .strategy .redirect (url )
140154
141155
@@ -160,20 +174,22 @@ def do_disconnect(
160174 )
161175
162176 if isinstance (response , dict ):
163- url = backend .strategy .absolute_uri (
177+ url : str | None = backend .strategy .absolute_uri (
164178 backend .strategy .request_data ().get (redirect_name , "" )
165179 or backend .setting ("DISCONNECT_REDIRECT_URL" )
166180 or backend .setting ("LOGIN_REDIRECT_URL" )
167181 )
168182 if backend .setting ("SANITIZE_REDIRECTS" , True ):
169183 allowed_hosts = [
170- * backend .setting ("ALLOWED_REDIRECT_HOSTS" , []),
184+ * cast ( "list[str]" , backend .setting ("ALLOWED_REDIRECT_HOSTS" , []) ),
171185 backend .strategy .request_host (),
172186 ]
173187 url = (
174188 sanitize_redirect (allowed_hosts , url )
175189 or backend .setting ("DISCONNECT_REDIRECT_URL" )
176190 or backend .setting ("LOGIN_REDIRECT_URL" )
177191 )
192+ if not url :
193+ raise ValueError ("Disallowed URL" )
178194 response = backend .strategy .redirect (url )
179195 return response
0 commit comments