pypomes-jwt 1.1.5__py3-none-any.whl → 1.1.7__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 CHANGED
@@ -38,6 +38,8 @@ def jwt_verify_request(request: Request) -> Response:
38
38
  """
39
39
  Verify whether the HTTP *request* has the proper authorization, as per the JWT standard.
40
40
 
41
+ This implementation assumes that HTTP requests are handled with the *Flask* framework.
42
+
41
43
  :param request: the *request* to be verified
42
44
  :return: *None* if the *request* is valid, otherwise a *Response* reporting the error
43
45
  """
@@ -47,15 +49,19 @@ def jwt_verify_request(request: Request) -> Response:
47
49
  # retrieve the authorization from the request header
48
50
  auth_header: str = request.headers.get("Authorization")
49
51
 
50
- # was a 'Bearer' authorization obtained ?
52
+ # validate the authorization token
51
53
  bad_token: bool = True
52
54
  if auth_header and auth_header.startswith("Bearer "):
53
55
  # yes, extract and validate the JWT access token
54
56
  token: str = auth_header.split(" ")[1]
55
- if jwt_validate_token(errors=None,
56
- nature="A",
57
- token=token):
58
- bad_token = False
57
+ claims: dict[str, Any] = jwt_validate_token(errors=None,
58
+ token=token,
59
+ nature="A")
60
+ if claims:
61
+ login: str = request.values.get("login")
62
+ subject: str = claims["payload"].get("sub")
63
+ if not login or not subject or login == subject:
64
+ bad_token = False
59
65
 
60
66
  # deny the authorization
61
67
  if bad_token:
@@ -78,7 +84,7 @@ def jwt_set_account(account_id: str,
78
84
  claims: dict[str, Any],
79
85
  access_max_age: int = JwtConfig.ACCESS_MAX_AGE.value,
80
86
  refresh_max_age: int = JwtConfig.REFRESH_MAX_AGE.value,
81
- grace_interval: int = None,
87
+ lead_interval: int = None,
82
88
  logger: Logger = None) -> None:
83
89
  """
84
90
  Establish the data needed to obtain JWT tokens for *account_id*.
@@ -92,7 +98,7 @@ def jwt_set_account(account_id: str,
92
98
  :param claims: the JWT claimset, as key-value pairs
93
99
  :param access_max_age: access token duration, in seconds
94
100
  :param refresh_max_age: refresh token duration, in seconds
95
- :param grace_interval: optional time to wait for token to be valid, in seconds
101
+ :param lead_interval: optional time to wait for token to be valid, in seconds
96
102
  :param logger: optional logger
97
103
  """
98
104
  if logger:
@@ -103,7 +109,7 @@ def jwt_set_account(account_id: str,
103
109
  claims=claims,
104
110
  access_max_age=access_max_age,
105
111
  refresh_max_age=max(refresh_max_age, access_max_age + 300),
106
- grace_interval=grace_interval,
112
+ lead_interval=lead_interval,
107
113
  logger=logger)
108
114
 
109
115
 
@@ -302,7 +308,7 @@ def jwt_issue_token(errors: list[str] | None,
302
308
  account_id: str,
303
309
  nature: str,
304
310
  duration: int,
305
- grace_interval: int = None,
311
+ lead_interval: int = None,
306
312
  claims: dict[str, Any] = None,
307
313
  logger: Logger = None) -> str:
308
314
  """
@@ -318,7 +324,7 @@ def jwt_issue_token(errors: list[str] | None,
318
324
  :param nature: the token's nature, must be a single letter in the range *[B-Z]*, less *R*
319
325
  :param duration: the number of seconds for the token to remain valid (at least 60 seconds)
320
326
  :param claims: optional token's claims
321
- :param grace_interval: optional interval for the token to become active (in seconds)
327
+ :param lead_interval: optional interval for the token to become active (in seconds)
322
328
  :param logger: optional logger
323
329
  :return: the JWT token data, or *None* if error
324
330
  """
@@ -334,7 +340,7 @@ def jwt_issue_token(errors: list[str] | None,
334
340
  nature=nature,
335
341
  duration=duration,
336
342
  claims=claims,
337
- grace_interval=grace_interval,
343
+ lead_interval=lead_interval,
338
344
  logger=logger)
339
345
  if logger:
340
346
  logger.debug(msg=f"Token is '{result}'")
@@ -26,7 +26,7 @@ class JwtRegistry:
26
26
  <account-id>: {
27
27
  "access-max-age": <int>, # defaults to JWT_ACCESS_MAX_AGE (in seconds)
28
28
  "refresh-max-age": <int>, # defaults to JWT_REFRESH_MAX_AGE (in seconds)
29
- "grace-interval": <int>, # time to wait for token to be valid, in seconds
29
+ "lead-interval": <int>, # time to wait for token to be valid, in seconds
30
30
  "claims": {
31
31
  "iss": <string>, # token'ss issuer
32
32
  "birthdate": <string>, # subject's birth date
@@ -35,9 +35,6 @@ class JwtRegistry:
35
35
  "name": <string>, # subject's name
36
36
  "roles": <List[str]>, # subject roles
37
37
  "nonce": <string>, # used to associate a Client session with a token
38
- # output, only
39
- "valid-from": <string>, # token's start (<YYYY-MM-DDThh:mm:ss+00:00>)
40
- "valid-until": <string>, # token's finish (<YYYY-MM-DDThh:mm:ss+00:00>)
41
38
  ...
42
39
  }
43
40
  },
@@ -63,8 +60,6 @@ class JwtRegistry:
63
60
 
64
61
  Account-related claims are optional claims, and convey information about the registered account they belong to.
65
62
  Alhough they can be freely specified, these are some of the most commonly used claims:
66
- "valid-from": <string> token's start (<YYYY-MM-DDThh:mm:ss+00:00>)
67
- "valid-until": <string> token's finish (<YYYY-MM-DDThh:mm:ss+00.00>)
68
63
  "birthdate": <string> subject's birth date
69
64
  "email": <string> subject's email
70
65
  "gender": <string> subject's gender
@@ -92,7 +87,7 @@ class JwtRegistry:
92
87
  claims: dict[str, Any],
93
88
  access_max_age: int,
94
89
  refresh_max_age: int,
95
- grace_interval: int | None,
90
+ lead_interval: int | None,
96
91
  logger: Logger = None) -> None:
97
92
  """
98
93
  Add to storage the parameters needed to produce and validate JWT tokens for *account_id*.
@@ -105,7 +100,7 @@ class JwtRegistry:
105
100
  :param claims: the JWT claimset, as key-value pairs
106
101
  :param access_max_age: access token duration, in seconds (at least 60 seconds)
107
102
  :param refresh_max_age: refresh token duration, in seconds (greater than *access_max_age*)
108
- :param grace_interval: time to wait for token to be valid, in seconds
103
+ :param lead_interval: time to wait for token to be valid, in seconds
109
104
  :param logger: optional logger
110
105
  """
111
106
  # build and store the access data for the account
@@ -114,7 +109,7 @@ class JwtRegistry:
114
109
  self.access_registry[account_id] = {
115
110
  "access-max-age": access_max_age,
116
111
  "refresh-max-age": refresh_max_age,
117
- "grace-interval": grace_interval,
112
+ "lead-interval": lead_interval,
118
113
  "claims": claims or {}
119
114
  }
120
115
  if logger:
@@ -155,7 +150,7 @@ class JwtRegistry:
155
150
  account_id: str,
156
151
  nature: str,
157
152
  duration: int,
158
- grace_interval: int = None,
153
+ lead_interval: int = None,
159
154
  claims: dict[str, Any] = None,
160
155
  logger: Logger = None) -> str:
161
156
  """
@@ -170,7 +165,7 @@ class JwtRegistry:
170
165
  :param nature: the token's nature, must be a single letter in the range *[B-Z]*, less *R*
171
166
  :param duration: the number of seconds for the token to remain valid (at least 60 seconds)
172
167
  :param claims: optional token's claims
173
- :param grace_interval: optional interval for the token to become active (in seconds)
168
+ :param lead_interval: optional interval for the token to become active (in seconds)
174
169
  :param logger: optional logger
175
170
  :return: the JWT token
176
171
  :raises RuntimeError: invalid parameter
@@ -203,8 +198,8 @@ class JwtRegistry:
203
198
  current_claims["sub"] = account_id
204
199
  just_now: int = int(datetime.now(tz=timezone.utc).timestamp())
205
200
  current_claims["iat"] = just_now
206
- if grace_interval:
207
- current_claims["nbf"] = just_now + grace_interval
201
+ if lead_interval:
202
+ current_claims["nbf"] = just_now + lead_interval
208
203
  current_claims["exp"] = just_now + duration
209
204
 
210
205
  # may raise an exception
@@ -256,9 +251,9 @@ class JwtRegistry:
256
251
 
257
252
  just_now: int = int(datetime.now(tz=timezone.utc).timestamp())
258
253
  current_claims["iat"] = just_now
259
- grace_interval = account_data.get("grace-interval")
260
- if grace_interval:
261
- current_claims["nbf"] = just_now + grace_interval
254
+ lead_interval = account_data.get("lead-interval")
255
+ if lead_interval:
256
+ current_claims["nbf"] = just_now + lead_interval
262
257
 
263
258
  # issue a candidate refresh token first, and persist it
264
259
  current_claims["exp"] = just_now + account_data.get("refresh-max-age")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pypomes_jwt
3
- Version: 1.1.5
3
+ Version: 1.1.7
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
@@ -12,5 +12,5 @@ Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.12
13
13
  Requires-Dist: cryptography>=44.0.2
14
14
  Requires-Dist: pyjwt>=2.10.1
15
- Requires-Dist: pypomes-core>=2.0.4
15
+ Requires-Dist: pypomes-core>=2.0.5
16
16
  Requires-Dist: pypomes-db>=2.1.1
@@ -0,0 +1,8 @@
1
+ pypomes_jwt/__init__.py,sha256=NZzjWKnhjxNuoE32V6soKo9sG5ypmt25V0mBAh3rAIs,793
2
+ pypomes_jwt/jwt_config.py,sha256=mtihd58_O00FuFXcNBKsabftG6UHu3Cj24i6cZXoskc,3096
3
+ pypomes_jwt/jwt_pomes.py,sha256=wplcnbC1RGgfJ1VlFpRVtSXTSRfthEjqGec7S1CWHis,23858
4
+ pypomes_jwt/jwt_registry.py,sha256=Zfhv5bn53UcSPuPSHns4AVMv7izrzd75HPp5eId2dck,21993
5
+ pypomes_jwt-1.1.7.dist-info/METADATA,sha256=I9h4WUglqMoy7a_1uwwnG9FPi4DosV9NVZ_O1afJD7Q,632
6
+ pypomes_jwt-1.1.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ pypomes_jwt-1.1.7.dist-info/licenses/LICENSE,sha256=NdakochSXm_H_-DSL_x2JlRCkYikj3snYYvTwgR5d_c,1086
8
+ pypomes_jwt-1.1.7.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- pypomes_jwt/__init__.py,sha256=NZzjWKnhjxNuoE32V6soKo9sG5ypmt25V0mBAh3rAIs,793
2
- pypomes_jwt/jwt_config.py,sha256=mtihd58_O00FuFXcNBKsabftG6UHu3Cj24i6cZXoskc,3096
3
- pypomes_jwt/jwt_pomes.py,sha256=5B5xYA6Z3zJvYwYTZoqD1sH1mraSwdYQVKEvVx2fCSY,23517
4
- pypomes_jwt/jwt_registry.py,sha256=gMnximiWagh7OkoXEM6msvdXdrXIqosolbyajTIbhTs,22372
5
- pypomes_jwt-1.1.5.dist-info/METADATA,sha256=tzzNQQ4bebsCN_N7qgDkuoI0D82IMKCnNsubQn_Vw_k,632
6
- pypomes_jwt-1.1.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
- pypomes_jwt-1.1.5.dist-info/licenses/LICENSE,sha256=NdakochSXm_H_-DSL_x2JlRCkYikj3snYYvTwgR5d_c,1086
8
- pypomes_jwt-1.1.5.dist-info/RECORD,,