6
6
from flask_jwt_extended .config import config
7
7
from flask_jwt_extended .exceptions import (
8
8
JWTDecodeError , NoAuthorizationError , InvalidHeaderError , WrongTokenError ,
9
- RevokedTokenError , FreshTokenRequired , CSRFError
9
+ RevokedTokenError , FreshTokenRequired , CSRFError , UserLoadError
10
10
)
11
11
from flask_jwt_extended .default_callbacks import (
12
12
default_expired_token_callback , default_user_claims_callback ,
13
13
default_user_identity_callback , default_invalid_token_callback ,
14
- default_unauthorized_callback ,
15
- default_needs_fresh_token_callback ,
16
- default_revoked_token_callback
14
+ default_unauthorized_callback , default_needs_fresh_token_callback ,
15
+ default_revoked_token_callback , default_user_loader_error_callback
17
16
)
18
17
from flask_jwt_extended .tokens import (
19
- encode_refresh_token , decode_jwt ,
20
- encode_access_token
18
+ encode_refresh_token , decode_jwt , encode_access_token
21
19
)
20
+ from flask_jwt_extended .utils import get_jwt_identity
22
21
23
22
24
23
class JWTManager (object ):
@@ -39,6 +38,8 @@ def __init__(self, app=None):
39
38
self ._unauthorized_callback = default_unauthorized_callback
40
39
self ._needs_fresh_token_callback = default_needs_fresh_token_callback
41
40
self ._revoked_token_callback = default_revoked_token_callback
41
+ self ._user_loader_callback = None
42
+ self ._user_loader_error_callback = default_user_loader_error_callback
42
43
43
44
# Register this extension with the flask app now (if it is provided)
44
45
if app is not None :
@@ -101,6 +102,14 @@ def handle_revoked_token_error(e):
101
102
def handle_fresh_token_required (e ):
102
103
return self ._needs_fresh_token_callback ()
103
104
105
+ @app .errorhandler (UserLoadError )
106
+ def handler_user_load_error (e ):
107
+ # The identity is already saved before this exception was raised,
108
+ # otherwise a different exception would be raised, which is why we
109
+ # can safely call get_jwt_identity() here
110
+ identity = get_jwt_identity ()
111
+ return self ._user_loader_error_callback (identity )
112
+
104
113
@staticmethod
105
114
def _set_default_configuration_options (app ):
106
115
"""
@@ -244,6 +253,50 @@ def revoked_token_loader(self, callback):
244
253
self ._revoked_token_callback = callback
245
254
return callback
246
255
256
+ def user_loader_callback_loader (self , callback ):
257
+ """
258
+ Sets the callback method to be called to load a user on a protected
259
+ endpoint.
260
+
261
+ By default this is not is not used.
262
+
263
+ If a callback method is passed in here, it must take one argument,
264
+ which is the identity of the user to load. It must return the user
265
+ object, or None in the case of an error (which will cause the TODO
266
+ error handler to be hit)
267
+ """
268
+ self ._user_loader_callback = callback
269
+ return callback
270
+
271
+ def user_loader_error_loader (self , callback ):
272
+ """
273
+ Sets the callback method to be called if a user fails or is refused
274
+ to load when calling the _user_loader_callback function (indicated by
275
+ that function returning None)
276
+
277
+ The default implementation will return json:
278
+ '{"msg": "Error loading the user <identity>"}' with a 400 status code.
279
+
280
+ Callback must be a function that takes one argument, the identity of the
281
+ user who failed to load.
282
+ """
283
+ self ._user_loader_error_callback = callback
284
+ return callback
285
+
286
+ def has_user_loader (self ):
287
+ """
288
+ Returns True if a user_loader_callback has been defined in this
289
+ application, False otherwise
290
+ """
291
+ return self ._user_loader_callback is not None
292
+
293
+ def user_loader (self , identity ):
294
+ """
295
+ Calls the _user_loader_callback function (if it is defined) and returns
296
+ the resulting user from this callback.
297
+ """
298
+ return self ._user_loader_callback (identity )
299
+
247
300
def create_refresh_token (self , identity , expires_delta = None ):
248
301
"""
249
302
Creates a new refresh token
@@ -315,3 +368,4 @@ def create_access_token(self, identity, fresh=False, expires_delta=None):
315
368
config .algorithm , csrf = config .csrf_protect )
316
369
store_token (decoded_token , revoked = False )
317
370
return access_token
371
+
0 commit comments