11from __future__ import annotations
22
33import logging
4- from typing import Any , cast , override
4+ from typing import Any , override
55
66from django .contrib .auth import get_user_model
77from django .contrib .auth .models import (
1919from .exceptions import MissingInitialisation
2020from .jwt import verify_and_decode_token
2121from .models import OIDCClient , UserInformationClaimsSources
22- from .plugins import (
23- AbstractUserOIDCPluginProtocol ,
24- AnonymousUserOIDCPluginProtocol ,
25- )
22+ from .plugins import AbstractUserOIDCPlugin , AnonymousUserOIDCPlugin
2623from .registry import register as registry
2724from .typing import JSONObject
2825from .utils import extract_content_type
@@ -75,10 +72,12 @@ def __init__(self, *args, **kwargs) -> None:
7572
7673 # django-stubs returns AbstractBaseUser, but we depend on properties of
7774 # AbstractUser.
78- self .UserModel = cast (AbstractUser , get_user_model ())
75+ UserModel = get_user_model ()
76+ assert issubclass (UserModel , AbstractUser )
77+ self .UserModel = UserModel
7978
8079 @override
81- def get_settings (self , attr : str , * args : Any ) -> Any : # type : ignore
80+ def get_settings (self , attr : str , * args : Any ) -> Any : # pyright : ignore[reportIncompatibleMethodOverride]
8281 """
8382 Override the upstream library get_settings.
8483
@@ -106,7 +105,7 @@ def _check_candidate_backend(self) -> bool:
106105 # `OIDCAuthenticationCallbackView` for the `auth.authenticate(**kwargs)` call if this
107106 # needs updating.
108107 @override
109- def authenticate ( # type : ignore
108+ def authenticate ( # pyright : ignore[reportIncompatibleMethodOverride]
110109 self ,
111110 request : HttpRequest | None ,
112111 nonce : str | None = None ,
@@ -138,7 +137,7 @@ def authenticate( # type: ignore
138137 # Store the config class identifier on the user, so that we can store this in the user's
139138 # session after they have been successfully authenticated (by listening to the `user_logged_in` signal)
140139 if user :
141- user ._oidcdb_config_identifier = self .config .identifier # type : ignore
140+ user ._oidcdb_config_identifier = self .config .identifier # pyright : ignore[reportAttributeAccessIssue]
142141
143142 return user
144143
@@ -149,7 +148,7 @@ def verify_claims(self, claims: JSONObject) -> bool:
149148 assert self .config
150149
151150 plugin = registry [self .config .identifier ]
152- assert isinstance (plugin , AbstractUserOIDCPluginProtocol )
151+ assert isinstance (plugin , AbstractUserOIDCPlugin )
153152 return plugin .verify_claims (claims )
154153
155154 @override
@@ -214,11 +213,11 @@ def get_userinfo(
214213 @override
215214 def filter_users_by_claims (
216215 self , claims : JSONObject
217- ) -> models .Manager [AbstractUser ]: # type: ignore (parent function returns UserManager which is more specific than Manager)
216+ ) -> models .QuerySet [AbstractUser ]:
218217 assert self .config
219218 plugin = registry [self .config .identifier ]
220219
221- assert isinstance (plugin , AbstractUserOIDCPluginProtocol )
220+ assert isinstance (plugin , AbstractUserOIDCPlugin )
222221 return plugin .filter_users_by_claims (claims )
223222
224223 @override
@@ -227,30 +226,35 @@ def create_user(self, claims: JSONObject) -> AbstractUser:
227226 assert self .config
228227 plugin = registry [self .config .identifier ]
229228
230- assert isinstance (plugin , AbstractUserOIDCPluginProtocol )
229+ assert isinstance (plugin , AbstractUserOIDCPlugin )
231230 return plugin .create_user (claims )
232231
233232 @override
234233 def update_user (self , user : AbstractUser , claims : JSONObject ):
235234 assert self .config
236235 plugin = registry [self .config .identifier ]
237236
238- assert isinstance (plugin , AbstractUserOIDCPluginProtocol )
237+ assert isinstance (plugin , AbstractUserOIDCPlugin )
239238 return plugin .update_user (user , claims )
240239
241240 @override
242241 def get_or_create_user (
243242 self , access_token : str , id_token : str , payload : JSONObject
244- ) -> AnonymousUser | AbstractUser | None : # type: ignore (parent function returns only an AbstractUser | None)
243+ ) -> AnonymousUser | AbstractUser | None :
245244 """Get or create a user based on the tokens received."""
246245 assert self .config
247246
248247 plugin = registry [self .config .identifier ]
249248 assert isinstance (self .request , HttpRequest )
250249
251- if isinstance (plugin , AnonymousUserOIDCPluginProtocol ):
250+ # shortcut for "anonymous users" where the OIDC authentication *does* happen,
251+ # but no actual Django user instance is created.
252+ if isinstance (plugin , AnonymousUserOIDCPlugin ):
252253 return plugin .get_or_create_user (
253254 access_token , id_token , payload , self .request
254255 )
255256
256- return super ().get_or_create_user (access_token , id_token , payload )
257+ user = super ().get_or_create_user (access_token , id_token , payload )
258+ if user is not None :
259+ assert isinstance (user , self .UserModel )
260+ return user
0 commit comments