pypomes-jwt 0.8.3__tar.gz → 0.8.5__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-0.8.3 → pypomes_jwt-0.8.5}/PKG-INFO +2 -2
- {pypomes_jwt-0.8.3 → pypomes_jwt-0.8.5}/pyproject.toml +2 -2
- {pypomes_jwt-0.8.3 → pypomes_jwt-0.8.5}/src/pypomes_jwt/jwt_data.py +19 -10
- {pypomes_jwt-0.8.3 → pypomes_jwt-0.8.5}/src/pypomes_jwt/jwt_pomes.py +7 -5
- {pypomes_jwt-0.8.3 → pypomes_jwt-0.8.5}/.gitignore +0 -0
- {pypomes_jwt-0.8.3 → pypomes_jwt-0.8.5}/LICENSE +0 -0
- {pypomes_jwt-0.8.3 → pypomes_jwt-0.8.5}/README.md +0 -0
- {pypomes_jwt-0.8.3 → pypomes_jwt-0.8.5}/src/__init__.py +0 -0
- {pypomes_jwt-0.8.3 → pypomes_jwt-0.8.5}/src/pypomes_jwt/__init__.py +0 -0
- {pypomes_jwt-0.8.3 → pypomes_jwt-0.8.5}/src/pypomes_jwt/jwt_constants.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pypomes_jwt
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.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
|
|
@@ -13,4 +13,4 @@ Requires-Python: >=3.12
|
|
|
13
13
|
Requires-Dist: cryptography>=44.0.2
|
|
14
14
|
Requires-Dist: pyjwt>=2.10.1
|
|
15
15
|
Requires-Dist: pypomes-core>=1.8.3
|
|
16
|
-
Requires-Dist: pypomes-db>=1.9.
|
|
16
|
+
Requires-Dist: pypomes-db>=1.9.6
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "pypomes_jwt"
|
|
9
|
-
version = "0.8.
|
|
9
|
+
version = "0.8.5"
|
|
10
10
|
authors = [
|
|
11
11
|
{ name="GT Nunes", email="wisecoder01@gmail.com" }
|
|
12
12
|
]
|
|
@@ -22,7 +22,7 @@ dependencies = [
|
|
|
22
22
|
"PyJWT>=2.10.1",
|
|
23
23
|
"cryptography>=44.0.2",
|
|
24
24
|
"pypomes_core>=1.8.3",
|
|
25
|
-
"pypomes_db>=1.9.
|
|
25
|
+
"pypomes_db>=1.9.6"
|
|
26
26
|
]
|
|
27
27
|
|
|
28
28
|
[project.urls]
|
|
@@ -35,12 +35,14 @@ class JwtData:
|
|
|
35
35
|
"token-audience": <string> # the audience the token is intended for
|
|
36
36
|
"token_nonce": <string> # value used to associate a client session with a token
|
|
37
37
|
"claims": {
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
38
|
+
"valid-from": <string> # token's start (<YYYY-MM-DD hh:mm:ss>)
|
|
39
|
+
"valid-until": <string> # token's finish (<YYYY-MM-DD hh:mm:ss>)
|
|
40
|
+
"birthdate": <string>, # subject's birth date
|
|
41
|
+
"email": <string>, # subject's email
|
|
42
|
+
"gender": <string>, # subject's gender
|
|
43
|
+
"name": <string>, # subject's name
|
|
44
|
+
"roles": <List[str]>, # subject roles
|
|
45
|
+
"nonce": <string>, # value used to associate a Client session with a token
|
|
44
46
|
...
|
|
45
47
|
}
|
|
46
48
|
},
|
|
@@ -66,6 +68,8 @@ class JwtData:
|
|
|
66
68
|
|
|
67
69
|
Account-related claims are optional claims, and convey information about the registered account they belong to.
|
|
68
70
|
Alhough they can be freely specified, these are some of the most commonly used claims:
|
|
71
|
+
"valid-from": <string> # token's start (<YYYY-MM-DD hh:mm:ss>)
|
|
72
|
+
"valid-until": <string> # token's finish (<YYYY-MM-DD hh:mm:ss>)
|
|
69
73
|
"birthdate": <string> # subject's birth date
|
|
70
74
|
"email": <string> # subject's email
|
|
71
75
|
"gender": <string> # subject's gender
|
|
@@ -238,6 +242,8 @@ class JwtData:
|
|
|
238
242
|
|
|
239
243
|
# issue a candidate refresh token first, and persist it
|
|
240
244
|
current_claims["exp"] = just_now + account_data.get("refresh-max-age")
|
|
245
|
+
current_claims["valid-from"] = datetime.fromtimestamp(timestamp=current_claims["iat"])
|
|
246
|
+
current_claims["valid-until"] = datetime.fromtimestamp(timestamp=current_claims["exp"])
|
|
241
247
|
# may raise an exception
|
|
242
248
|
refresh_token: str = jwt.encode(payload=current_claims,
|
|
243
249
|
key=JWT_ENCODING_KEY,
|
|
@@ -400,15 +406,18 @@ def _jwt_persist_token(errors: list[str],
|
|
|
400
406
|
if errors:
|
|
401
407
|
raise RuntimeError("; ".join(errors))
|
|
402
408
|
|
|
403
|
-
|
|
409
|
+
# find expired tokens
|
|
410
|
+
exp: int = token_claims["payload"].get("exp", sys.maxsize)
|
|
404
411
|
if exp < datetime.now(tz=timezone.utc).timestamp():
|
|
405
412
|
expired.append(token_kid)
|
|
406
|
-
|
|
413
|
+
|
|
414
|
+
# find oldest token
|
|
415
|
+
iat: int = token_claims["payload"].get("iat", sys.maxsize)
|
|
416
|
+
if iat < oldest:
|
|
407
417
|
oldest = exp
|
|
408
418
|
surplus = token_kid
|
|
409
419
|
|
|
410
420
|
# remove expired tokens from persistence
|
|
411
|
-
# ruff: noqa: SIM102
|
|
412
421
|
if expired:
|
|
413
422
|
db_delete(errors=errors,
|
|
414
423
|
delete_stmt=f"DELETE FROM {JWT_DB_TABLE}",
|
|
@@ -422,7 +431,7 @@ def _jwt_persist_token(errors: list[str],
|
|
|
422
431
|
f"'{account_id}' removed from storage")
|
|
423
432
|
|
|
424
433
|
if 0 < JWT_ACCOUNT_LIMIT <= len(recs) - len(expired):
|
|
425
|
-
# delete the oldest
|
|
434
|
+
# delete the oldest token to make way for the new one
|
|
426
435
|
db_delete(errors=errors,
|
|
427
436
|
delete_stmt=f"DELETE FROM {JWT_DB_TABLE}",
|
|
428
437
|
where_data={JWT_DB_COL_KID: surplus},
|
|
@@ -57,7 +57,7 @@ def jwt_verify_request(request: Request,
|
|
|
57
57
|
# yes, extract and validate the JWT access token
|
|
58
58
|
token: str = auth_header.split(" ")[1]
|
|
59
59
|
if logger:
|
|
60
|
-
logger.debug(msg=
|
|
60
|
+
logger.debug(msg="Token was found")
|
|
61
61
|
errors: list[str] = []
|
|
62
62
|
jwt_validate_token(errors=errors,
|
|
63
63
|
nature="A",
|
|
@@ -174,7 +174,7 @@ def jwt_validate_token(errors: list[str] | None,
|
|
|
174
174
|
# initialize the return variable
|
|
175
175
|
result: dict[str, Any] | None = None
|
|
176
176
|
if logger:
|
|
177
|
-
logger.debug(msg=
|
|
177
|
+
logger.debug(msg="Validate JWT token")
|
|
178
178
|
|
|
179
179
|
# extract needed data from token header
|
|
180
180
|
token_header: dict[str, Any] = jwt.get_unverified_header(jwt=token)
|
|
@@ -245,7 +245,7 @@ def jwt_validate_token(errors: list[str] | None,
|
|
|
245
245
|
if isinstance(errors, list):
|
|
246
246
|
errors.extend(op_errors)
|
|
247
247
|
elif logger:
|
|
248
|
-
logger.debug(msg=
|
|
248
|
+
logger.debug(msg="Token is valid")
|
|
249
249
|
|
|
250
250
|
return result
|
|
251
251
|
|
|
@@ -379,9 +379,11 @@ def jwt_get_claims(errors: list[str] | None,
|
|
|
379
379
|
"header": {
|
|
380
380
|
"alg": "RS256",
|
|
381
381
|
"typ": "JWT",
|
|
382
|
-
"kid": "
|
|
382
|
+
"kid": "1234"
|
|
383
383
|
},
|
|
384
384
|
"payload": {
|
|
385
|
+
"valid-from": <YYYY-MM-DD hh:mm:ss>
|
|
386
|
+
"valid-until": <YYYY-MM-DD hh:mm:ss>
|
|
385
387
|
"birthdate": "1980-01-01",
|
|
386
388
|
"email": "jdoe@mail.com",
|
|
387
389
|
"exp": 1516640454,
|
|
@@ -409,7 +411,7 @@ def jwt_get_claims(errors: list[str] | None,
|
|
|
409
411
|
result: dict[str, Any] | None = None
|
|
410
412
|
|
|
411
413
|
if logger:
|
|
412
|
-
logger.debug(msg=
|
|
414
|
+
logger.debug(msg="Retrieve claims for token")
|
|
413
415
|
|
|
414
416
|
try:
|
|
415
417
|
# retrieve the token's claims
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|