1"""
2These are the default methods implementations that are used in this extension.
3All of these can be updated on an app by app basis using the JWTManager
4loader decorators. For further information, check out the following links:
5
6http://flask-jwt-extended.readthedocs.io/en/latest/changing_default_behavior.html
7http://flask-jwt-extended.readthedocs.io/en/latest/tokens_from_complex_object.html
8"""
9from http import HTTPStatus
10from typing import Any
11
12from flask import jsonify
13from flask.typing import ResponseReturnValue
14
15from flask_jwt_extended.config import config
16
17
18def default_additional_claims_callback(userdata: Any) -> dict:
19 """
20 By default, we add no additional claims to the access tokens.
21
22 :param userdata: data passed in as the ```identity``` argument to the
23 ```create_access_token``` and ```create_refresh_token```
24 functions
25 """
26 return {}
27
28
29def default_blocklist_callback(jwt_headers: dict, jwt_data: dict) -> bool:
30 return False
31
32
33def default_jwt_headers_callback(default_headers) -> dict:
34 """
35 By default header typically consists of two parts: the type of the token,
36 which is JWT, and the signing algorithm being used, such as HMAC SHA256
37 or RSA. But we don't set the default header here we set it as empty which
38 further by default set while encoding the token
39 :return: default we set None here
40 """
41 return {}
42
43
44def default_user_identity_callback(userdata: Any) -> str:
45 """
46 By default, we use the passed in object directly as the jwt identity.
47 See this for additional info:
48
49 :param userdata: data passed in as the ```identity``` argument to the
50 ```create_access_token``` and ```create_refresh_token```
51 functions
52 """
53 return userdata
54
55
56def default_expired_token_callback(
57 _expired_jwt_header: dict, _expired_jwt_data: dict
58) -> ResponseReturnValue:
59 """
60 By default, if an expired token attempts to access a protected endpoint,
61 we return a generic error message with a 401 status
62 """
63 return jsonify({config.error_msg_key: "Token has expired"}), HTTPStatus.UNAUTHORIZED
64
65
66def default_invalid_token_callback(error_string: str) -> ResponseReturnValue:
67 """
68 By default, if an invalid token attempts to access a protected endpoint, we
69 return the error string for why it is not valid with a 422 status code
70
71 :param error_string: String indicating why the token is invalid
72 """
73 return (
74 jsonify({config.error_msg_key: error_string}),
75 HTTPStatus.UNPROCESSABLE_ENTITY,
76 )
77
78
79def default_unauthorized_callback(error_string: str) -> ResponseReturnValue:
80 """
81 By default, if a protected endpoint is accessed without a JWT, we return
82 the error string indicating why this is unauthorized, with a 401 status code
83
84 :param error_string: String indicating why this request is unauthorized
85 """
86 return jsonify({config.error_msg_key: error_string}), HTTPStatus.UNAUTHORIZED
87
88
89def default_needs_fresh_token_callback(
90 jwt_header: dict, jwt_data: dict
91) -> ResponseReturnValue:
92 """
93 By default, if a non-fresh jwt is used to access a ```fresh_jwt_required```
94 endpoint, we return a general error message with a 401 status code
95 """
96 return (
97 jsonify({config.error_msg_key: "Fresh token required"}),
98 HTTPStatus.UNAUTHORIZED,
99 )
100
101
102def default_revoked_token_callback(
103 jwt_header: dict, jwt_data: dict
104) -> ResponseReturnValue:
105 """
106 By default, if a revoked token is used to access a protected endpoint, we
107 return a general error message with a 401 status code
108 """
109 return (
110 jsonify({config.error_msg_key: "Token has been revoked"}),
111 HTTPStatus.UNAUTHORIZED,
112 )
113
114
115def default_user_lookup_error_callback(
116 _jwt_header: dict, jwt_data: dict
117) -> ResponseReturnValue:
118 """
119 By default, if a user_lookup callback is defined and the callback
120 function returns None, we return a general error message with a 401
121 status code
122 """
123 identity = jwt_data[config.identity_claim_key]
124 result = {config.error_msg_key: f"Error loading the user {identity}"}
125 return jsonify(result), HTTPStatus.UNAUTHORIZED
126
127
128def default_token_verification_callback(_jwt_header: dict, _jwt_data: dict) -> bool:
129 """
130 By default, we do not do any verification of the user claims.
131 """
132 return True
133
134
135def default_token_verification_failed_callback(
136 _jwt_header: dict, _jwt_data: dict
137) -> ResponseReturnValue:
138 """
139 By default, if the user claims verification failed, we return a generic
140 error message with a 400 status code
141 """
142 return (
143 jsonify({config.error_msg_key: "User claims verification failed"}),
144 HTTPStatus.BAD_REQUEST,
145 )
146
147
148def default_decode_key_callback(jwt_header: dict, jwt_data: dict) -> str:
149 """
150 By default, the decode key specified via the JWT_SECRET_KEY or
151 JWT_PUBLIC_KEY settings will be used to decode all tokens
152 """
153 return config.decode_key
154
155
156def default_encode_key_callback(identity: Any) -> str:
157 """
158 By default, the encode key specified via the JWT_SECRET_KEY or
159 JWT_PRIVATE_KEY settings will be used to encode all tokens
160 """
161 return config.encode_key