pypomes-jwt 0.9.3__py3-none-any.whl → 0.9.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pypomes-jwt might be problematic. Click here for more details.
- pypomes_jwt/jwt_pomes.py +28 -38
- pypomes_jwt/jwt_registry.py +8 -16
- {pypomes_jwt-0.9.3.dist-info → pypomes_jwt-0.9.5.dist-info}/METADATA +1 -1
- pypomes_jwt-0.9.5.dist-info/RECORD +8 -0
- pypomes_jwt-0.9.3.dist-info/RECORD +0 -8
- {pypomes_jwt-0.9.3.dist-info → pypomes_jwt-0.9.5.dist-info}/WHEEL +0 -0
- {pypomes_jwt-0.9.3.dist-info → pypomes_jwt-0.9.5.dist-info}/licenses/LICENSE +0 -0
pypomes_jwt/jwt_pomes.py
CHANGED
|
@@ -61,7 +61,7 @@ def jwt_verify_request(request: Request,
|
|
|
61
61
|
logger.debug(msg="Bearer token was retrieved")
|
|
62
62
|
errors: list[str] = []
|
|
63
63
|
jwt_validate_token(errors=errors,
|
|
64
|
-
|
|
64
|
+
nature="A",
|
|
65
65
|
token=token)
|
|
66
66
|
if errors:
|
|
67
67
|
err_msg = "; ".join(errors)
|
|
@@ -94,10 +94,8 @@ def jwt_set_account(account_id: str,
|
|
|
94
94
|
access_max_age: int = JWT_ACCESS_MAX_AGE,
|
|
95
95
|
refresh_max_age: int = JWT_REFRESH_MAX_AGE,
|
|
96
96
|
grace_interval: int = None,
|
|
97
|
-
token_audience: str = None,
|
|
98
|
-
token_nonce: str = None,
|
|
99
97
|
request_timeout: int = None,
|
|
100
|
-
remote_provider: bool =
|
|
98
|
+
remote_provider: bool = None,
|
|
101
99
|
logger: Logger = None) -> None:
|
|
102
100
|
"""
|
|
103
101
|
Set the data needed to obtain JWT tokens for *account_id*.
|
|
@@ -108,8 +106,6 @@ def jwt_set_account(account_id: str,
|
|
|
108
106
|
:param access_max_age: access token duration, in seconds
|
|
109
107
|
:param refresh_max_age: refresh token duration, in seconds
|
|
110
108
|
:param grace_interval: optional time to wait for token to be valid, in seconds
|
|
111
|
-
:param token_audience: optional audience the token is intended for
|
|
112
|
-
:param token_nonce: optional value used to associate a client session with a token
|
|
113
109
|
:param request_timeout: timeout for the requests to the reference URL
|
|
114
110
|
:param remote_provider: whether the JWT provider is a remote server
|
|
115
111
|
:param logger: optional logger
|
|
@@ -132,8 +128,6 @@ def jwt_set_account(account_id: str,
|
|
|
132
128
|
access_max_age=access_max_age,
|
|
133
129
|
refresh_max_age=refresh_max_age,
|
|
134
130
|
grace_interval=grace_interval,
|
|
135
|
-
token_audience=token_audience,
|
|
136
|
-
token_nonce=token_nonce,
|
|
137
131
|
request_timeout=request_timeout,
|
|
138
132
|
remote_provider=remote_provider,
|
|
139
133
|
logger=logger)
|
|
@@ -157,7 +151,7 @@ def jwt_remove_account(account_id: str,
|
|
|
157
151
|
|
|
158
152
|
def jwt_validate_token(errors: list[str] | None,
|
|
159
153
|
token: str,
|
|
160
|
-
|
|
154
|
+
nature: str = None,
|
|
161
155
|
account_id: str = None,
|
|
162
156
|
logger: Logger = None) -> dict[str, Any] | None:
|
|
163
157
|
"""
|
|
@@ -170,7 +164,7 @@ def jwt_validate_token(errors: list[str] | None,
|
|
|
170
164
|
|
|
171
165
|
:param errors: incidental error messages
|
|
172
166
|
:param token: the token to be validated
|
|
173
|
-
:param
|
|
167
|
+
:param nature: prefix identifying the nature of locally issued tokens
|
|
174
168
|
:param account_id: optionally, validate the token's account owner
|
|
175
169
|
:param logger: optional logger
|
|
176
170
|
:return: The token's claims (header and payload) if if is valid, *None* otherwise
|
|
@@ -188,9 +182,10 @@ def jwt_validate_token(errors: list[str] | None,
|
|
|
188
182
|
op_errors: list[str] = []
|
|
189
183
|
|
|
190
184
|
# retrieve token data from database
|
|
191
|
-
if
|
|
185
|
+
if nature and not (token_kid and token_kid[0:1] == nature):
|
|
192
186
|
op_errors.append("Invalid token")
|
|
193
|
-
elif token_kid and len(token_kid) > 1 and
|
|
187
|
+
elif token_kid and len(token_kid) > 1 and \
|
|
188
|
+
token_kid[0:1] in ["A", "R"] and token[1:].isdigit():
|
|
194
189
|
# token was likely issued locally
|
|
195
190
|
where_data: dict[str, Any] = {JWT_DB_COL_KID: int(token_kid[1:])}
|
|
196
191
|
if account_id:
|
|
@@ -276,18 +271,20 @@ def jwt_revoke_token(errors: list[str] | None,
|
|
|
276
271
|
op_errors: list[str] = []
|
|
277
272
|
token_claims: dict[str, Any] = jwt_validate_token(errors=op_errors,
|
|
278
273
|
token=refresh_token,
|
|
279
|
-
natures=["A", "R"],
|
|
280
274
|
account_id=account_id,
|
|
281
275
|
logger=logger)
|
|
282
276
|
if not op_errors:
|
|
283
277
|
token_kid: str = token_claims["header"].get("kid")
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
278
|
+
if token_kid[0:1] not in ["A", "R"]:
|
|
279
|
+
op_errors.append("Invalid token")
|
|
280
|
+
else:
|
|
281
|
+
db_delete(errors=op_errors,
|
|
282
|
+
delete_stmt=f"DELETE FROM {JWT_DB_TABLE}",
|
|
283
|
+
where_data={
|
|
284
|
+
JWT_DB_COL_KID: int(token_kid[1:]),
|
|
285
|
+
JWT_DB_COL_ACCOUNT: account_id
|
|
286
|
+
},
|
|
287
|
+
logger=logger)
|
|
291
288
|
if op_errors:
|
|
292
289
|
if logger:
|
|
293
290
|
logger.error(msg="; ".join(op_errors))
|
|
@@ -357,12 +354,10 @@ def jwt_issue_tokens(errors: list[str] | None,
|
|
|
357
354
|
account_claims: dict[str, Any] = None,
|
|
358
355
|
logger: Logger = None) -> dict[str, Any]:
|
|
359
356
|
"""
|
|
360
|
-
Issue the JWT
|
|
357
|
+
Issue the JWT token pair associated with *account_id*, for access and refresh operations.
|
|
361
358
|
|
|
362
|
-
|
|
363
|
-
claims
|
|
364
|
-
if provided in *account_claims*: *iat*, *iss*, *exp*, *jti*, *nbf*, and *sub*.
|
|
365
|
-
Other claims specified therein may supercede registered account-related claims.
|
|
359
|
+
These claims are ignored, if provided in *account_claims*: *iat*, *iss*, *exp*, *jti*, *nbf*, and *sub*.
|
|
360
|
+
Other claims specified therein may supercede currently registered account-related claims.
|
|
366
361
|
|
|
367
362
|
Structure of the return data:
|
|
368
363
|
{
|
|
@@ -374,7 +369,7 @@ def jwt_issue_tokens(errors: list[str] | None,
|
|
|
374
369
|
|
|
375
370
|
:param errors: incidental error messages
|
|
376
371
|
:param account_id: the account identification
|
|
377
|
-
:param account_claims: if provided, may supercede registered claims
|
|
372
|
+
:param account_claims: if provided, may supercede currently registered account-related claims
|
|
378
373
|
:param logger: optional logger
|
|
379
374
|
:return: the JWT token data, or *None* if error
|
|
380
375
|
"""
|
|
@@ -382,7 +377,7 @@ def jwt_issue_tokens(errors: list[str] | None,
|
|
|
382
377
|
result: dict[str, Any] | None = None
|
|
383
378
|
|
|
384
379
|
if logger:
|
|
385
|
-
logger.debug(msg=f"Issuing a
|
|
380
|
+
logger.debug(msg=f"Issuing a JWT token pair for '{account_id}'")
|
|
386
381
|
op_errors: list[str] = []
|
|
387
382
|
|
|
388
383
|
try:
|
|
@@ -406,10 +401,10 @@ def jwt_issue_tokens(errors: list[str] | None,
|
|
|
406
401
|
|
|
407
402
|
def jwt_refresh_tokens(errors: list[str] | None,
|
|
408
403
|
account_id: str,
|
|
409
|
-
refresh_token: str
|
|
404
|
+
refresh_token: str,
|
|
410
405
|
logger: Logger = None) -> dict[str, Any]:
|
|
411
406
|
"""
|
|
412
|
-
|
|
407
|
+
Refresh the JWT token pair associated with *account_id*, for access and refresh operations.
|
|
413
408
|
|
|
414
409
|
The claims in *refresh-token* are used on issuing the new tokens.
|
|
415
410
|
|
|
@@ -431,14 +426,14 @@ def jwt_refresh_tokens(errors: list[str] | None,
|
|
|
431
426
|
result: dict[str, Any] | None = None
|
|
432
427
|
|
|
433
428
|
if logger:
|
|
434
|
-
logger.debug(msg=f"Refreshing a
|
|
429
|
+
logger.debug(msg=f"Refreshing a JWT token pair for '{account_id}'")
|
|
435
430
|
op_errors: list[str] = []
|
|
436
431
|
|
|
437
432
|
# verify whether this refresh token is legitimate
|
|
438
433
|
if refresh_token:
|
|
439
434
|
account_claims: dict[str, Any] = (jwt_validate_token(errors=op_errors,
|
|
440
435
|
token=refresh_token,
|
|
441
|
-
|
|
436
|
+
nature="R",
|
|
442
437
|
account_id=account_id,
|
|
443
438
|
logger=logger) or {}).get("payload")
|
|
444
439
|
# revoke current refresh token
|
|
@@ -446,16 +441,11 @@ def jwt_refresh_tokens(errors: list[str] | None,
|
|
|
446
441
|
account_id=account_id,
|
|
447
442
|
refresh_token=refresh_token,
|
|
448
443
|
logger=logger):
|
|
449
|
-
account_claims.pop("exp", None)
|
|
450
|
-
account_claims.pop("iat", None)
|
|
451
|
-
account_claims.pop("iss", None)
|
|
452
|
-
account_claims.pop("jti", None)
|
|
453
|
-
account_claims.pop("nbt", None)
|
|
454
|
-
account_claims.pop("sub", None)
|
|
455
444
|
# issue tokens
|
|
456
445
|
result = jwt_issue_tokens(errors=errors,
|
|
457
446
|
account_id=account_id,
|
|
458
|
-
account_claims=account_claims
|
|
447
|
+
account_claims=account_claims,
|
|
448
|
+
logger=logger)
|
|
459
449
|
else:
|
|
460
450
|
op_errors.append("Refresh token was not provided")
|
|
461
451
|
|
pypomes_jwt/jwt_registry.py
CHANGED
|
@@ -33,9 +33,7 @@ class JwtRegistry:
|
|
|
33
33
|
"access-max-age": <int>, # in seconds - defaults to JWT_ACCESS_MAX_AGE
|
|
34
34
|
"refresh-max-age": <int>, # in seconds - defaults to JWT_REFRESH_MAX_AGE
|
|
35
35
|
"grace-interval": <int> # time to wait for token to be valid, in seconds
|
|
36
|
-
#
|
|
37
|
-
"token-audience": <string> # the audience the token is intended for
|
|
38
|
-
"token_nonce": <string> # value used to associate a client session with a token
|
|
36
|
+
"request-timeout": <int> # timeout for the requests to the reference URL (in seconds)
|
|
39
37
|
"claims": {
|
|
40
38
|
"valid-from": <string> # token's start (<YYYY-MM-DDThh:mm:ss+00:00>)
|
|
41
39
|
"valid-until": <string> # token's finish (<YYYY-MM-DDThh:mm:ss+00:00>)
|
|
@@ -45,7 +43,7 @@ class JwtRegistry:
|
|
|
45
43
|
"gender": <string>, # subject's gender
|
|
46
44
|
"name": <string>, # subject's name
|
|
47
45
|
"roles": <List[str]>, # subject roles
|
|
48
|
-
"nonce": <string>, #
|
|
46
|
+
"nonce": <string>, # used to associate a Client session with a token
|
|
49
47
|
...
|
|
50
48
|
}
|
|
51
49
|
},
|
|
@@ -78,7 +76,7 @@ class JwtRegistry:
|
|
|
78
76
|
"gender": <string> # subject's gender
|
|
79
77
|
"name": <string> # subject's name
|
|
80
78
|
"roles": <List[str]> # subject roles
|
|
81
|
-
"nonce": <string> #
|
|
79
|
+
"nonce": <string> # used to associate a client session with a token
|
|
82
80
|
|
|
83
81
|
The token header has these items:
|
|
84
82
|
"alg": <string> # the algorithm used to sign the token (one of *HS256*, *HS51*', *RSA256*, *RSA512*)
|
|
@@ -101,11 +99,9 @@ class JwtRegistry:
|
|
|
101
99
|
claims: dict[str, Any],
|
|
102
100
|
access_max_age: int,
|
|
103
101
|
refresh_max_age: int,
|
|
104
|
-
grace_interval: int,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
request_timeout: int,
|
|
108
|
-
remote_provider: bool,
|
|
102
|
+
grace_interval: int | None,
|
|
103
|
+
request_timeout: int | None,
|
|
104
|
+
remote_provider: bool | None,
|
|
109
105
|
logger: Logger = None) -> None:
|
|
110
106
|
"""
|
|
111
107
|
Add to storage the parameters needed to produce and validate JWT tokens for *account_id*.
|
|
@@ -121,9 +117,7 @@ class JwtRegistry:
|
|
|
121
117
|
:param access_max_age: access token duration, in seconds
|
|
122
118
|
:param refresh_max_age: refresh token duration, in seconds
|
|
123
119
|
:param grace_interval: time to wait for token to be valid, in seconds
|
|
124
|
-
:param
|
|
125
|
-
:param token_nonce: optional value used to associate a client session with a token
|
|
126
|
-
:param request_timeout: timeout for the requests to the reference URL
|
|
120
|
+
:param request_timeout: timeout for the requests to the reference URL (in seconds)
|
|
127
121
|
:param remote_provider: whether the JWT provider is a remote server
|
|
128
122
|
:param logger: optional logger
|
|
129
123
|
"""
|
|
@@ -135,8 +129,6 @@ class JwtRegistry:
|
|
|
135
129
|
"access-max-age": access_max_age,
|
|
136
130
|
"refresh-max-age": refresh_max_age,
|
|
137
131
|
"grace-interval": grace_interval,
|
|
138
|
-
"token-audience": token_audience,
|
|
139
|
-
"token-nonce": token_nonce,
|
|
140
132
|
"request-timeout": request_timeout,
|
|
141
133
|
"remote-provider": remote_provider,
|
|
142
134
|
"claims": claims or {}
|
|
@@ -246,7 +238,7 @@ class JwtRegistry:
|
|
|
246
238
|
account_claims: dict[str, Any] = None,
|
|
247
239
|
logger: Logger = None) -> dict[str, Any]:
|
|
248
240
|
"""
|
|
249
|
-
Issue and return
|
|
241
|
+
Issue and return a JWT token pair associated with *account_id*.
|
|
250
242
|
|
|
251
243
|
These claims are ignored, if specified in *account_claims*: *iat*, *iss*, *exp*, *jti*, *nbf*, and *sub*.
|
|
252
244
|
Other claims specified therein may supercede registered account-related claims.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pypomes_jwt
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.5
|
|
4
4
|
Summary: A collection of Python pomes, penyeach (JWT module)
|
|
5
5
|
Project-URL: Homepage, https://github.com/TheWiseCoder/PyPomes-JWT
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/TheWiseCoder/PyPomes-JWT/issues
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
pypomes_jwt/__init__.py,sha256=t6TzpvttDuLMaKSGuBicOf9cZU4Y0N9mtby3ThS4lt8,1398
|
|
2
|
+
pypomes_jwt/jwt_constants.py,sha256=IQV39AiZKGuU8XxZBgJ-KJZQZ_mmnxyOnRZeuxlqDRk,4045
|
|
3
|
+
pypomes_jwt/jwt_pomes.py,sha256=ZQ-x9nJqRqSfLXcoN0crh4a-BhT1MNOMvZkFTsaQsuE,21069
|
|
4
|
+
pypomes_jwt/jwt_registry.py,sha256=27Z0wbDCNcy_Klm50dGhJ1ZVYznj0SNdMjzHVT_Uzzo,25588
|
|
5
|
+
pypomes_jwt-0.9.5.dist-info/METADATA,sha256=IZT48rR9ftHECxA8Xy0HhhkHLX1rUQk-rDsdtMgb8TI,632
|
|
6
|
+
pypomes_jwt-0.9.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
7
|
+
pypomes_jwt-0.9.5.dist-info/licenses/LICENSE,sha256=NdakochSXm_H_-DSL_x2JlRCkYikj3snYYvTwgR5d_c,1086
|
|
8
|
+
pypomes_jwt-0.9.5.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
pypomes_jwt/__init__.py,sha256=t6TzpvttDuLMaKSGuBicOf9cZU4Y0N9mtby3ThS4lt8,1398
|
|
2
|
-
pypomes_jwt/jwt_constants.py,sha256=IQV39AiZKGuU8XxZBgJ-KJZQZ_mmnxyOnRZeuxlqDRk,4045
|
|
3
|
-
pypomes_jwt/jwt_pomes.py,sha256=UnEkOUN0vovlenyb8ROvpM96Qf0Mx-JRle-EooyTy7k,21734
|
|
4
|
-
pypomes_jwt/jwt_registry.py,sha256=TANRyMGxoO7sR2EwO_bgVzIMjM3OHAr7olvnSmMtwCQ,26020
|
|
5
|
-
pypomes_jwt-0.9.3.dist-info/METADATA,sha256=DrB3ku89ZNBM3FBpnnnmDv-Rvi4F70sIXj0M5zJnQOM,632
|
|
6
|
-
pypomes_jwt-0.9.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
7
|
-
pypomes_jwt-0.9.3.dist-info/licenses/LICENSE,sha256=NdakochSXm_H_-DSL_x2JlRCkYikj3snYYvTwgR5d_c,1086
|
|
8
|
-
pypomes_jwt-0.9.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|