pypomes-jwt 1.2.6__tar.gz → 1.2.8__tar.gz
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-1.2.6 → pypomes_jwt-1.2.8}/PKG-INFO +4 -4
- {pypomes_jwt-1.2.6 → pypomes_jwt-1.2.8}/pyproject.toml +4 -4
- {pypomes_jwt-1.2.6 → pypomes_jwt-1.2.8}/src/pypomes_jwt/jwt_pomes.py +36 -36
- {pypomes_jwt-1.2.6 → pypomes_jwt-1.2.8}/src/pypomes_jwt/jwt_providers.py +7 -4
- {pypomes_jwt-1.2.6 → pypomes_jwt-1.2.8}/src/pypomes_jwt/jwt_registry.py +25 -30
- {pypomes_jwt-1.2.6 → pypomes_jwt-1.2.8}/.gitignore +0 -0
- {pypomes_jwt-1.2.6 → pypomes_jwt-1.2.8}/LICENSE +0 -0
- {pypomes_jwt-1.2.6 → pypomes_jwt-1.2.8}/README.md +0 -0
- {pypomes_jwt-1.2.6 → pypomes_jwt-1.2.8}/src/pypomes_jwt/__init__.py +0 -0
- {pypomes_jwt-1.2.6 → pypomes_jwt-1.2.8}/src/pypomes_jwt/jwt_config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pypomes_jwt
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.8
|
|
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
|
|
@@ -11,7 +11,7 @@ Classifier: Operating System :: OS Independent
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Requires-Python: >=3.12
|
|
13
13
|
Requires-Dist: cryptography>=45.0.6
|
|
14
|
-
Requires-Dist: flask>=3.1.
|
|
14
|
+
Requires-Dist: flask>=3.1.2
|
|
15
15
|
Requires-Dist: pyjwt>=2.10.1
|
|
16
|
-
Requires-Dist: pypomes-core>=2.
|
|
17
|
-
Requires-Dist: pypomes-db>=2.
|
|
16
|
+
Requires-Dist: pypomes-core>=2.7.0
|
|
17
|
+
Requires-Dist: pypomes-db>=2.5.8
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "pypomes_jwt"
|
|
9
|
-
version = "1.2.
|
|
9
|
+
version = "1.2.8"
|
|
10
10
|
authors = [
|
|
11
11
|
{ name="GT Nunes", email="wisecoder01@gmail.com" }
|
|
12
12
|
]
|
|
@@ -20,10 +20,10 @@ classifiers = [
|
|
|
20
20
|
]
|
|
21
21
|
dependencies = [
|
|
22
22
|
"cryptography>=45.0.6",
|
|
23
|
-
"Flask>=3.1.
|
|
23
|
+
"Flask>=3.1.2",
|
|
24
24
|
"PyJWT>=2.10.1",
|
|
25
|
-
"pypomes_core>=2.
|
|
26
|
-
"pypomes_db>=2.
|
|
25
|
+
"pypomes_core>=2.7.0",
|
|
26
|
+
"pypomes_db>=2.5.8"
|
|
27
27
|
]
|
|
28
28
|
|
|
29
29
|
[project.urls]
|
|
@@ -6,7 +6,7 @@ from logging import Logger
|
|
|
6
6
|
from pypomes_core import exc_format
|
|
7
7
|
from pypomes_db import (
|
|
8
8
|
DbEngine, db_connect, db_commit,
|
|
9
|
-
db_rollback, db_select, db_delete
|
|
9
|
+
db_rollback, db_close, db_select, db_delete
|
|
10
10
|
)
|
|
11
11
|
from typing import Any
|
|
12
12
|
|
|
@@ -54,8 +54,7 @@ def jwt_verify_request(request: Request) -> Response:
|
|
|
54
54
|
if auth_header and auth_header.startswith("Bearer "):
|
|
55
55
|
# yes, extract and validate the JWT access token
|
|
56
56
|
token: str = auth_header.split(" ")[1]
|
|
57
|
-
claims: dict[str, Any] = jwt_validate_token(
|
|
58
|
-
token=token,
|
|
57
|
+
claims: dict[str, Any] = jwt_validate_token(token=token,
|
|
59
58
|
nature="A")
|
|
60
59
|
if claims:
|
|
61
60
|
login: str = request.values.get("login")
|
|
@@ -129,10 +128,10 @@ def jwt_remove_account(account_id: str,
|
|
|
129
128
|
logger=logger)
|
|
130
129
|
|
|
131
130
|
|
|
132
|
-
def jwt_validate_token(
|
|
133
|
-
token: str,
|
|
131
|
+
def jwt_validate_token(token: str,
|
|
134
132
|
nature: str = None,
|
|
135
133
|
account_id: str = None,
|
|
134
|
+
errors: list[str] = None,
|
|
136
135
|
logger: Logger = None) -> dict[str, Any] | None:
|
|
137
136
|
"""
|
|
138
137
|
Verify if *token* is a valid JWT token.
|
|
@@ -147,10 +146,10 @@ def jwt_validate_token(errors: list[str] | None,
|
|
|
147
146
|
On success, return the token's claims (*header* and *payload*), as documented in *jwt_get_claims()*
|
|
148
147
|
On failure, *errors* will contain the reason(s) for rejecting *token*.
|
|
149
148
|
|
|
150
|
-
:param errors: incidental error messages
|
|
151
149
|
:param token: the token to be validated
|
|
152
150
|
:param nature: prefix identifying the nature of locally issued tokens
|
|
153
151
|
:param account_id: optionally, validate the token's account owner
|
|
152
|
+
:param errors: incidental error messages
|
|
154
153
|
:param logger: optional logger
|
|
155
154
|
:return: The token's claims (*header* and *payload*) if it is valid, *None* otherwise
|
|
156
155
|
"""
|
|
@@ -188,12 +187,12 @@ def jwt_validate_token(errors: list[str] | None,
|
|
|
188
187
|
where_data: dict[str, Any] = {JwtDbConfig.COL_KID: int(token_kid[1:])}
|
|
189
188
|
if account_id:
|
|
190
189
|
where_data[JwtDbConfig.COL_ACCOUNT] = account_id
|
|
191
|
-
recs: list[tuple[str]] = db_select(
|
|
192
|
-
sel_stmt=f"SELECT {JwtDbConfig.COL_ALGORITHM}, "
|
|
190
|
+
recs: list[tuple[str]] = db_select(sel_stmt=f"SELECT {JwtDbConfig.COL_ALGORITHM}, "
|
|
193
191
|
f"{JwtDbConfig.COL_DECODER} "
|
|
194
192
|
f"FROM {JwtDbConfig.TABLE}",
|
|
195
193
|
where_data=where_data,
|
|
196
194
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
195
|
+
errors=op_errors,
|
|
197
196
|
logger=logger)
|
|
198
197
|
if recs:
|
|
199
198
|
token_alg = recs[0][0]
|
|
@@ -255,18 +254,18 @@ def jwt_validate_token(errors: list[str] | None,
|
|
|
255
254
|
return result
|
|
256
255
|
|
|
257
256
|
|
|
258
|
-
def jwt_revoke_token(
|
|
259
|
-
account_id: str,
|
|
257
|
+
def jwt_revoke_token(account_id: str,
|
|
260
258
|
token: str,
|
|
259
|
+
errors: list[str] = None,
|
|
261
260
|
logger: Logger = None) -> bool:
|
|
262
261
|
"""
|
|
263
262
|
Revoke the *refresh_token* associated with *account_id*.
|
|
264
263
|
|
|
265
264
|
Revoke operations require access to a database table defined by *JWT_DB_TABLE*.
|
|
266
265
|
|
|
267
|
-
:param errors: incidental error messages
|
|
268
266
|
:param account_id: the account identification
|
|
269
267
|
:param token: the token to be revoked
|
|
268
|
+
:param errors: incidental error messages
|
|
270
269
|
:param logger: optional logger
|
|
271
270
|
:return: *True* if operation could be performed, *False* otherwise
|
|
272
271
|
"""
|
|
@@ -277,22 +276,22 @@ def jwt_revoke_token(errors: list[str] | None,
|
|
|
277
276
|
logger.debug(msg=f"Revoking token of account '{account_id}'")
|
|
278
277
|
|
|
279
278
|
op_errors: list[str] = []
|
|
280
|
-
token_claims: dict[str, Any] = jwt_validate_token(
|
|
281
|
-
token=token,
|
|
279
|
+
token_claims: dict[str, Any] = jwt_validate_token(token=token,
|
|
282
280
|
account_id=account_id,
|
|
281
|
+
errors=op_errors,
|
|
283
282
|
logger=logger)
|
|
284
283
|
if not op_errors:
|
|
285
284
|
token_kid: str = token_claims["header"].get("kid")
|
|
286
285
|
if token_kid[0:1] not in ["A", "R"]:
|
|
287
286
|
op_errors.append("Invalid token")
|
|
288
287
|
else:
|
|
289
|
-
db_delete(
|
|
290
|
-
delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
|
|
288
|
+
db_delete(delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
|
|
291
289
|
where_data={
|
|
292
290
|
JwtDbConfig.COL_KID: int(token_kid[1:]),
|
|
293
291
|
JwtDbConfig.COL_ACCOUNT: account_id
|
|
294
292
|
},
|
|
295
293
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
294
|
+
errors=op_errors,
|
|
296
295
|
logger=logger)
|
|
297
296
|
if op_errors:
|
|
298
297
|
if logger:
|
|
@@ -305,12 +304,12 @@ def jwt_revoke_token(errors: list[str] | None,
|
|
|
305
304
|
return result
|
|
306
305
|
|
|
307
306
|
|
|
308
|
-
def jwt_issue_token(
|
|
309
|
-
account_id: str,
|
|
307
|
+
def jwt_issue_token(account_id: str,
|
|
310
308
|
nature: str,
|
|
311
309
|
duration: int,
|
|
312
310
|
lead_interval: int = None,
|
|
313
311
|
claims: dict[str, Any] = None,
|
|
312
|
+
errors: list[str] = None,
|
|
314
313
|
logger: Logger = None) -> str:
|
|
315
314
|
"""
|
|
316
315
|
Issue or refresh, and return, a JWT token associated with *account_id*, of the specified *nature*.
|
|
@@ -320,12 +319,12 @@ def jwt_issue_token(errors: list[str] | None,
|
|
|
320
319
|
The parameter *duration* specifies the token's validity interval (at least 60 seconds).
|
|
321
320
|
These claims are ignored, if specified in *claims*: *iat*, *iss*, *exp*, *jti*, *nbf*, and *sub*.
|
|
322
321
|
|
|
323
|
-
:param errors: incidental error messages
|
|
324
322
|
:param account_id: the account identification
|
|
325
323
|
:param nature: the token's nature, must be a single letter in the range *[B-Z]*, less *R*
|
|
326
324
|
:param duration: the number of seconds for the token to remain valid (at least 60 seconds)
|
|
327
325
|
:param claims: optional token's claims
|
|
328
326
|
:param lead_interval: optional interval for the token to become active (in seconds)
|
|
327
|
+
:param errors: incidental error messages
|
|
329
328
|
:param logger: optional logger
|
|
330
329
|
:return: the JWT token data, or *None* if error
|
|
331
330
|
"""
|
|
@@ -359,9 +358,9 @@ def jwt_issue_token(errors: list[str] | None,
|
|
|
359
358
|
return result
|
|
360
359
|
|
|
361
360
|
|
|
362
|
-
def jwt_issue_tokens(
|
|
363
|
-
account_id: str,
|
|
361
|
+
def jwt_issue_tokens(account_id: str,
|
|
364
362
|
account_claims: dict[str, Any] = None,
|
|
363
|
+
errors: list[str] = None,
|
|
365
364
|
logger: Logger = None) -> dict[str, Any]:
|
|
366
365
|
"""
|
|
367
366
|
Issue the JWT token pair associated with *account_id*, for access and refresh operations.
|
|
@@ -377,9 +376,9 @@ def jwt_issue_tokens(errors: list[str] | None,
|
|
|
377
376
|
"refresh-token": <jwt-token>
|
|
378
377
|
}
|
|
379
378
|
|
|
380
|
-
:param errors: incidental error messages
|
|
381
379
|
:param account_id: the account identification
|
|
382
380
|
:param account_claims: if provided, may supercede currently registered account-related claims
|
|
381
|
+
:param errors: incidental error messages
|
|
383
382
|
:param logger: optional logger
|
|
384
383
|
:return: the JWT token data, or *None* if error
|
|
385
384
|
"""
|
|
@@ -413,9 +412,9 @@ def jwt_issue_tokens(errors: list[str] | None,
|
|
|
413
412
|
return result
|
|
414
413
|
|
|
415
414
|
|
|
416
|
-
def jwt_refresh_tokens(
|
|
417
|
-
account_id: str,
|
|
415
|
+
def jwt_refresh_tokens(account_id: str,
|
|
418
416
|
refresh_token: str,
|
|
417
|
+
errors: list[str] = None,
|
|
419
418
|
logger: Logger = None) -> dict[str, Any]:
|
|
420
419
|
"""
|
|
421
420
|
Refresh the JWT token pair associated with *account_id*, for access and refresh operations.
|
|
@@ -446,24 +445,23 @@ def jwt_refresh_tokens(errors: list[str] | None,
|
|
|
446
445
|
# assert the refresh token
|
|
447
446
|
if refresh_token:
|
|
448
447
|
# is the refresh token valid ?
|
|
449
|
-
token_claims: dict[str, Any] = jwt_validate_token(
|
|
450
|
-
token=refresh_token,
|
|
448
|
+
token_claims: dict[str, Any] = jwt_validate_token(token=refresh_token,
|
|
451
449
|
nature="R",
|
|
452
450
|
account_id=account_id,
|
|
451
|
+
errors=op_errors,
|
|
453
452
|
logger=logger)
|
|
454
453
|
if token_claims:
|
|
455
454
|
# yes, proceed
|
|
456
455
|
token_kid: str = token_claims["header"].get("kid")
|
|
457
456
|
|
|
458
457
|
# start the database transaction
|
|
459
|
-
db_conn: Any = db_connect(
|
|
460
|
-
autocommit=False,
|
|
458
|
+
db_conn: Any = db_connect(autocommit=False,
|
|
461
459
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
460
|
+
errors=op_errors,
|
|
462
461
|
logger=logger)
|
|
463
462
|
if db_conn:
|
|
464
463
|
# delete current refresh token
|
|
465
|
-
db_delete(
|
|
466
|
-
delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
|
|
464
|
+
db_delete(delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
|
|
467
465
|
where_data={
|
|
468
466
|
JwtDbConfig.COL_KID: int(token_kid[1:]),
|
|
469
467
|
JwtDbConfig.COL_ACCOUNT: account_id
|
|
@@ -471,6 +469,7 @@ def jwt_refresh_tokens(errors: list[str] | None,
|
|
|
471
469
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
472
470
|
connection=db_conn,
|
|
473
471
|
committable=False,
|
|
472
|
+
errors=op_errors,
|
|
474
473
|
logger=logger)
|
|
475
474
|
|
|
476
475
|
# issue the token pair
|
|
@@ -492,13 +491,14 @@ def jwt_refresh_tokens(errors: list[str] | None,
|
|
|
492
491
|
|
|
493
492
|
# wrap-up the transaction
|
|
494
493
|
if op_errors:
|
|
495
|
-
db_rollback(
|
|
496
|
-
connection=db_conn,
|
|
494
|
+
db_rollback(connection=db_conn,
|
|
497
495
|
logger=logger)
|
|
498
496
|
else:
|
|
499
|
-
db_commit(
|
|
500
|
-
|
|
497
|
+
db_commit(connection=db_conn,
|
|
498
|
+
errors=op_errors,
|
|
501
499
|
logger=logger)
|
|
500
|
+
db_close(connection=db_conn,
|
|
501
|
+
logger=logger)
|
|
502
502
|
else:
|
|
503
503
|
# refresh token not found
|
|
504
504
|
op_errors.append("Refresh token was not provided")
|
|
@@ -512,8 +512,8 @@ def jwt_refresh_tokens(errors: list[str] | None,
|
|
|
512
512
|
return result
|
|
513
513
|
|
|
514
514
|
|
|
515
|
-
def jwt_get_claims(
|
|
516
|
-
|
|
515
|
+
def jwt_get_claims(token: str,
|
|
516
|
+
errors: list[str] = None,
|
|
517
517
|
logger: Logger = None) -> dict[str, Any] | None:
|
|
518
518
|
"""
|
|
519
519
|
Retrieve the claims set of a JWT *token*.
|
|
@@ -548,8 +548,8 @@ def jwt_get_claims(errors: list[str] | None,
|
|
|
548
548
|
}
|
|
549
549
|
}
|
|
550
550
|
|
|
551
|
-
:param errors: incidental error messages
|
|
552
551
|
:param token: the token to be inspected for claims
|
|
552
|
+
:param errors: incidental error messages
|
|
553
553
|
:param logger: optional logger
|
|
554
554
|
:return: the token's claimset, or *None* if error
|
|
555
555
|
"""
|
|
@@ -38,8 +38,8 @@ def provider_register(provider_id: str,
|
|
|
38
38
|
HTTP Basic Authorization scheme, wherein the credentials are B64-encoded and send in the request headers.
|
|
39
39
|
|
|
40
40
|
Optional constant key-value pairs (such as ['Content-Type', 'application/x-www-form-urlencoded']), to be
|
|
41
|
-
added to the request headers, may be specified in *
|
|
42
|
-
(such as ['
|
|
41
|
+
added to the request headers, may be specified in *headers_data*. Likewise, optional constant key-value pairs
|
|
42
|
+
(such as ['grant_type', 'client_credentials']), to be added to the request body, may be specified in *body_data*.
|
|
43
43
|
|
|
44
44
|
:param provider_id: the provider's identification
|
|
45
45
|
:param access_url: the url to request authentication tokens with
|
|
@@ -96,9 +96,12 @@ def provider_get_token(errors: list[str] | None,
|
|
|
96
96
|
try:
|
|
97
97
|
# typical return on a token request:
|
|
98
98
|
# {
|
|
99
|
-
# "expires_in": <number-of-seconds>,
|
|
100
99
|
# "token_type": "bearer",
|
|
101
|
-
# "access_token": <
|
|
100
|
+
# "access_token": <str>,
|
|
101
|
+
# "expires_in": <number-of-seconds>,
|
|
102
|
+
# optional data:
|
|
103
|
+
# "refresh_token": <str>,
|
|
104
|
+
# "refresh_expires_in": <nomber-of-seconds>
|
|
102
105
|
# }
|
|
103
106
|
response: Response = requests.post(url=url,
|
|
104
107
|
data=body_data,
|
|
@@ -133,8 +133,7 @@ class JwtRegistry:
|
|
|
133
133
|
account_data = self.access_registry.pop(account_id, None)
|
|
134
134
|
|
|
135
135
|
# remove from database
|
|
136
|
-
db_delete(
|
|
137
|
-
delete_stmt=f"DELETE FROM {JwtDbConfig}",
|
|
136
|
+
db_delete(delete_stmt=f"DELETE FROM {JwtDbConfig}",
|
|
138
137
|
where_data={JwtDbConfig.COL_ACCOUNT: account_id},
|
|
139
138
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
140
139
|
logger=logger)
|
|
@@ -264,9 +263,9 @@ class JwtRegistry:
|
|
|
264
263
|
headers={"kid": "R0"})
|
|
265
264
|
|
|
266
265
|
# make sure to have a database connection
|
|
267
|
-
curr_conn: Any = db_conn or db_connect(
|
|
268
|
-
autocommit=False,
|
|
266
|
+
curr_conn: Any = db_conn or db_connect(autocommit=False,
|
|
269
267
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
268
|
+
errors=errors,
|
|
270
269
|
logger=logger)
|
|
271
270
|
if curr_conn:
|
|
272
271
|
# persist the candidate token (may raise an exception)
|
|
@@ -280,24 +279,22 @@ class JwtRegistry:
|
|
|
280
279
|
algorithm=JwtConfig.DEFAULT_ALGORITHM.value,
|
|
281
280
|
headers={"kid": f"R{token_id}"})
|
|
282
281
|
# persist it
|
|
283
|
-
db_update(
|
|
284
|
-
update_stmt=f"UPDATE {JwtDbConfig.TABLE}",
|
|
282
|
+
db_update(update_stmt=f"UPDATE {JwtDbConfig.TABLE}",
|
|
285
283
|
update_data={JwtDbConfig.COL_TOKEN: refresh_token},
|
|
286
284
|
where_data={JwtDbConfig.COL_KID: token_id},
|
|
287
285
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
288
286
|
connection=curr_conn,
|
|
289
|
-
|
|
287
|
+
errors=errors,
|
|
290
288
|
logger=logger)
|
|
291
289
|
|
|
292
290
|
# wrap-up the transaction
|
|
293
291
|
if not db_conn:
|
|
294
292
|
if errors:
|
|
295
|
-
db_rollback(
|
|
296
|
-
connection=curr_conn,
|
|
293
|
+
db_rollback(connection=curr_conn,
|
|
297
294
|
logger=logger)
|
|
298
295
|
else:
|
|
299
|
-
db_commit(
|
|
300
|
-
|
|
296
|
+
db_commit(connection=curr_conn,
|
|
297
|
+
errors=errors,
|
|
301
298
|
logger=logger)
|
|
302
299
|
if errors:
|
|
303
300
|
raise RuntimeError("; ".join(errors))
|
|
@@ -340,7 +337,7 @@ class JwtRegistry:
|
|
|
340
337
|
@staticmethod
|
|
341
338
|
def jwt_persist_token(account_id: str,
|
|
342
339
|
jwt_token: str,
|
|
343
|
-
db_conn: Any,
|
|
340
|
+
db_conn: Any = None,
|
|
344
341
|
logger: Logger = None) -> int:
|
|
345
342
|
"""
|
|
346
343
|
Persist the given token, making sure that the account limit is complied with.
|
|
@@ -349,7 +346,9 @@ class JwtRegistry:
|
|
|
349
346
|
If a token's expiration timestamp is in the past, it is removed from storage. If the maximum number
|
|
350
347
|
of active tokens for *account_id* has been reached, the oldest active one is alse removed,
|
|
351
348
|
to make room for the new *jwt_token*.
|
|
352
|
-
|
|
349
|
+
|
|
350
|
+
If provided, *db_conn* indicates that this operation is part of a larger database transaction.
|
|
351
|
+
Otherwise, the database transaction's scope is limited to this operation.
|
|
353
352
|
|
|
354
353
|
:param account_id: the account identification
|
|
355
354
|
:param jwt_token: the JWT token to persist
|
|
@@ -364,19 +363,18 @@ class JwtRegistry:
|
|
|
364
363
|
errors: list[str] = []
|
|
365
364
|
# noinspection PyTypeChecker
|
|
366
365
|
recs: list[tuple[int, str, str, str]] = \
|
|
367
|
-
db_select(
|
|
368
|
-
sel_stmt=f"SELECT {JwtDbConfig.COL_KID}, {JwtDbConfig.COL_TOKEN} "
|
|
366
|
+
db_select(sel_stmt=f"SELECT {JwtDbConfig.COL_KID}, {JwtDbConfig.COL_TOKEN} "
|
|
369
367
|
f"FROM {JwtDbConfig.TABLE}",
|
|
370
368
|
where_data={JwtDbConfig.COL_ACCOUNT: account_id},
|
|
371
369
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
372
370
|
connection=db_conn,
|
|
373
|
-
|
|
371
|
+
errors=errors,
|
|
374
372
|
logger=logger)
|
|
375
373
|
if errors:
|
|
376
374
|
raise RuntimeError("; ".join(errors))
|
|
377
375
|
|
|
378
376
|
if logger:
|
|
379
|
-
logger.debug(msg=f"
|
|
377
|
+
logger.debug(msg=f"Retrieved {len(recs)} tokens from storage for account '{account_id}'")
|
|
380
378
|
# remove the expired tokens
|
|
381
379
|
just_now: int = int(datetime.now(tz=UTC).timestamp())
|
|
382
380
|
oldest_ts: int = sys.maxsize
|
|
@@ -385,8 +383,8 @@ class JwtRegistry:
|
|
|
385
383
|
for rec in recs:
|
|
386
384
|
token: str = rec[1]
|
|
387
385
|
token_id: int = rec[0]
|
|
388
|
-
token_payload: dict[str, Any] = (jwt_get_claims(
|
|
389
|
-
|
|
386
|
+
token_payload: dict[str, Any] = (jwt_get_claims(token=token,
|
|
387
|
+
errors=errors,
|
|
390
388
|
logger=logger) or {}).get("payload")
|
|
391
389
|
if errors:
|
|
392
390
|
raise RuntimeError("; ".join(errors))
|
|
@@ -404,12 +402,11 @@ class JwtRegistry:
|
|
|
404
402
|
|
|
405
403
|
# remove expired tokens from persistence
|
|
406
404
|
if expired:
|
|
407
|
-
db_delete(
|
|
408
|
-
delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
|
|
405
|
+
db_delete(delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
|
|
409
406
|
where_data={JwtDbConfig.COL_KID: expired},
|
|
410
407
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
411
408
|
connection=db_conn,
|
|
412
|
-
|
|
409
|
+
errors=errors,
|
|
413
410
|
logger=logger)
|
|
414
411
|
if errors:
|
|
415
412
|
raise RuntimeError("; ".join(errors))
|
|
@@ -419,12 +416,11 @@ class JwtRegistry:
|
|
|
419
416
|
|
|
420
417
|
if 0 < JwtConfig.ACCOUNT_LIMIT.value <= len(recs) - len(expired):
|
|
421
418
|
# delete the oldest token to make way for the new one
|
|
422
|
-
db_delete(
|
|
423
|
-
delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
|
|
419
|
+
db_delete(delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
|
|
424
420
|
where_data={JwtDbConfig.COL_KID: oldest_id},
|
|
425
421
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
426
422
|
connection=db_conn,
|
|
427
|
-
|
|
423
|
+
errors=errors,
|
|
428
424
|
logger=logger)
|
|
429
425
|
if errors:
|
|
430
426
|
raise RuntimeError("; ".join(errors))
|
|
@@ -432,8 +428,7 @@ class JwtRegistry:
|
|
|
432
428
|
logger.debug(msg="Oldest active token of account "
|
|
433
429
|
f"'{account_id}' removed from storage")
|
|
434
430
|
# persist token
|
|
435
|
-
col_kid: int = db_insert(
|
|
436
|
-
insert_stmt=f"INSERT INTO {JwtDbConfig.TABLE}",
|
|
431
|
+
col_kid: int = db_insert(insert_stmt=f"INSERT INTO {JwtDbConfig.TABLE}",
|
|
437
432
|
insert_data={
|
|
438
433
|
JwtDbConfig.COL_ACCOUNT: account_id,
|
|
439
434
|
JwtDbConfig.COL_TOKEN: jwt_token,
|
|
@@ -443,14 +438,13 @@ class JwtRegistry:
|
|
|
443
438
|
return_cols={JwtDbConfig.COL_KID: int},
|
|
444
439
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
445
440
|
connection=db_conn,
|
|
446
|
-
|
|
441
|
+
errors=errors,
|
|
447
442
|
logger=logger)
|
|
448
443
|
if errors:
|
|
449
444
|
raise RuntimeError("; ".join(errors))
|
|
450
445
|
|
|
451
446
|
# obtain and return the token's storage id
|
|
452
|
-
reply: list[tuple[int]] = db_select(
|
|
453
|
-
sel_stmt=f"SELECT {JwtDbConfig.COL_KID} "
|
|
447
|
+
reply: list[tuple[int]] = db_select(sel_stmt=f"SELECT {JwtDbConfig.COL_KID} "
|
|
454
448
|
f"FROM {JwtDbConfig.TABLE}",
|
|
455
449
|
where_data={JwtDbConfig.COL_KID: col_kid},
|
|
456
450
|
min_count=1,
|
|
@@ -458,6 +452,7 @@ class JwtRegistry:
|
|
|
458
452
|
engine=DbEngine(JwtDbConfig.ENGINE),
|
|
459
453
|
connection=db_conn,
|
|
460
454
|
committable=False,
|
|
455
|
+
errors=errors,
|
|
461
456
|
logger=logger)
|
|
462
457
|
if errors:
|
|
463
458
|
raise RuntimeError("; ".join(errors))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|