pypomes-jwt 1.1.9__py3-none-any.whl → 1.2.0__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.

@@ -1,7 +1,7 @@
1
1
  import jwt
2
2
  import string
3
3
  import sys
4
- from base64 import urlsafe_b64encode
4
+ from base64 import b64encode
5
5
  from datetime import datetime, timezone
6
6
  from logging import Logger
7
7
  from pypomes_core import str_random
@@ -184,8 +184,8 @@ class JwtRegistry:
184
184
  raise RuntimeError(err_msg)
185
185
 
186
186
  # obtain the account data in storage (may raise an exception)
187
- account_data: dict[str, Any] = self.__get_account_data(account_id=account_id,
188
- logger=logger)
187
+ account_data: dict[str, Any] = self.get_account_data(account_id=account_id,
188
+ logger=logger)
189
189
  # issue the token
190
190
  current_claims: dict[str, Any] = {}
191
191
  iss: str = account_data["claims"].get("iss")
@@ -240,8 +240,8 @@ class JwtRegistry:
240
240
  """
241
241
  # process the account data in storage
242
242
  with (self.access_lock):
243
- account_data: dict[str, Any] = self.__get_account_data(account_id=account_id,
244
- logger=logger)
243
+ account_data: dict[str, Any] = self.get_account_data(account_id=account_id,
244
+ logger=logger)
245
245
  current_claims: dict[str, Any] = account_data["claims"].copy()
246
246
  if account_claims:
247
247
  current_claims.update(account_claims)
@@ -271,10 +271,10 @@ class JwtRegistry:
271
271
  logger=logger)
272
272
  if curr_conn:
273
273
  # persist the candidate token (may raise an exception)
274
- token_id: int = _jwt_persist_token(account_id=account_id,
275
- jwt_token=refresh_token,
276
- db_conn=curr_conn,
277
- logger=logger)
274
+ token_id: int = JwtRegistry.jwt_persist_token(account_id=account_id,
275
+ jwt_token=refresh_token,
276
+ db_conn=curr_conn,
277
+ logger=logger)
278
278
  # issue the definitive refresh token
279
279
  refresh_token = jwt.encode(payload=current_claims,
280
280
  key=JwtConfig.ENCODING_KEY.value,
@@ -318,9 +318,9 @@ class JwtRegistry:
318
318
  "refresh-token": refresh_token
319
319
  }
320
320
 
321
- def __get_account_data(self,
322
- account_id: str,
323
- logger: Logger = PYPOMES_LOGGER) -> dict[str, Any]:
321
+ def get_account_data(self,
322
+ account_id: str,
323
+ logger: Logger = PYPOMES_LOGGER) -> dict[str, Any]:
324
324
  """
325
325
  Retrieve the JWT access data associated with *account_id*.
326
326
 
@@ -338,138 +338,138 @@ class JwtRegistry:
338
338
 
339
339
  return result
340
340
 
341
+ @staticmethod
342
+ def jwt_persist_token(account_id: str,
343
+ jwt_token: str,
344
+ db_conn: Any,
345
+ logger: Logger = PYPOMES_LOGGER) -> int:
346
+ """
347
+ Persist the given token, making sure that the account limit is complied with.
341
348
 
342
- def _jwt_persist_token(account_id: str,
343
- jwt_token: str,
344
- db_conn: Any,
345
- logger: Logger = PYPOMES_LOGGER) -> int:
346
- """
347
- Persist the given token, making sure that the account limit is complied with.
348
-
349
- The tokens in storage, associated with *account_id*, are examined for their expiration timestamp.
350
- If a token's expiration timestamp is in the past, it is removed from storage. If the maximum number
351
- of active tokens for *account_id* has been reached, the oldest active one is alse removed,
352
- to make room for the new *jwt_token*.
353
- The provided database connection *db_conn* indicates that this operation is part of a larger transaction.
354
-
355
- :param account_id: the account identification
356
- :param jwt_token: the JWT token to persist
357
- :param db_conn: the database connection to use
358
- :param logger: optional logger
359
- :return: the storage id of the inserted token
360
- :raises RuntimeError: error accessing the token database
361
- """
362
- from .jwt_pomes import jwt_get_claims
363
-
364
- # retrieve the account's tokens
365
- errors: list[str] = []
366
- # noinspection PyTypeChecker
367
- recs: list[tuple[int, str, str, str]] = \
368
- db_select(errors=errors,
369
- sel_stmt=f"SELECT {JwtDbConfig.COL_KID}, {JwtDbConfig.COL_TOKEN} "
370
- f"FROM {JwtDbConfig.TABLE}",
371
- where_data={JwtDbConfig.COL_ACCOUNT: account_id},
372
- engine=DbEngine(JwtDbConfig.ENGINE),
373
- connection=db_conn,
374
- committable=False,
375
- logger=logger)
376
- if errors:
377
- raise RuntimeError("; ".join(errors))
378
-
379
- if logger:
380
- logger.debug(msg=f"Read {len(recs)} token from storage for account '{account_id}'")
381
- # remove the expired tokens
382
- just_now: int = int(datetime.now(tz=timezone.utc).timestamp())
383
- oldest_ts: int = sys.maxsize
384
- oldest_id: int | None = None
385
- existing_ids: list[int] = []
386
- expired: list[int] = []
387
- for rec in recs:
388
- token: str = rec[1]
389
- token_id: int = rec[0]
390
- token_payload: dict[str, Any] = (jwt_get_claims(errors=errors,
391
- token=token,
392
- logger=logger) or {}).get("payload")
349
+ The tokens in storage, associated with *account_id*, are examined for their expiration timestamp.
350
+ If a token's expiration timestamp is in the past, it is removed from storage. If the maximum number
351
+ of active tokens for *account_id* has been reached, the oldest active one is alse removed,
352
+ to make room for the new *jwt_token*.
353
+ The provided database connection *db_conn* indicates that this operation is part of a larger transaction.
354
+
355
+ :param account_id: the account identification
356
+ :param jwt_token: the JWT token to persist
357
+ :param db_conn: the database connection to use
358
+ :param logger: optional logger
359
+ :return: the storage id of the inserted token
360
+ :raises RuntimeError: error accessing the token database
361
+ """
362
+ from .jwt_pomes import jwt_get_claims
363
+
364
+ # retrieve the account's tokens
365
+ errors: list[str] = []
366
+ # noinspection PyTypeChecker
367
+ recs: list[tuple[int, str, str, str]] = \
368
+ db_select(errors=errors,
369
+ sel_stmt=f"SELECT {JwtDbConfig.COL_KID}, {JwtDbConfig.COL_TOKEN} "
370
+ f"FROM {JwtDbConfig.TABLE}",
371
+ where_data={JwtDbConfig.COL_ACCOUNT: account_id},
372
+ engine=DbEngine(JwtDbConfig.ENGINE),
373
+ connection=db_conn,
374
+ committable=False,
375
+ logger=logger)
393
376
  if errors:
394
377
  raise RuntimeError("; ".join(errors))
395
378
 
396
- # find expired tokens
397
- exp: int = token_payload.get("exp", sys.maxsize)
398
- if exp < just_now:
399
- expired.append(token_id)
400
-
401
- # find oldest token
402
- iat: int = token_payload.get("iat", sys.maxsize)
403
- if iat < oldest_ts:
404
- oldest_ts = iat
405
- oldest_id = token_id
406
-
407
- # save token id
408
- existing_ids.append(token_id)
409
-
410
- # remove expired tokens from persistence
411
- if expired:
412
- db_delete(errors=errors,
413
- delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
414
- where_data={JwtDbConfig.COL_KID: expired},
379
+ if logger:
380
+ logger.debug(msg=f"Read {len(recs)} token from storage for account '{account_id}'")
381
+ # remove the expired tokens
382
+ just_now: int = int(datetime.now(tz=timezone.utc).timestamp())
383
+ oldest_ts: int = sys.maxsize
384
+ oldest_id: int | None = None
385
+ existing_ids: list[int] = []
386
+ expired: list[int] = []
387
+ for rec in recs:
388
+ token: str = rec[1]
389
+ token_id: int = rec[0]
390
+ token_payload: dict[str, Any] = (jwt_get_claims(errors=errors,
391
+ token=token,
392
+ logger=logger) or {}).get("payload")
393
+ if errors:
394
+ raise RuntimeError("; ".join(errors))
395
+
396
+ # find expired tokens
397
+ exp: int = token_payload.get("exp", sys.maxsize)
398
+ if exp < just_now:
399
+ expired.append(token_id)
400
+
401
+ # find oldest token
402
+ iat: int = token_payload.get("iat", sys.maxsize)
403
+ if iat < oldest_ts:
404
+ oldest_ts = iat
405
+ oldest_id = token_id
406
+
407
+ # save token id
408
+ existing_ids.append(token_id)
409
+
410
+ # remove expired tokens from persistence
411
+ if expired:
412
+ db_delete(errors=errors,
413
+ delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
414
+ where_data={JwtDbConfig.COL_KID: expired},
415
+ engine=DbEngine(JwtDbConfig.ENGINE),
416
+ connection=db_conn,
417
+ committable=False,
418
+ logger=logger)
419
+ if errors:
420
+ raise RuntimeError("; ".join(errors))
421
+ if logger:
422
+ logger.debug(msg=f"{len(expired)} tokens of account "
423
+ f"'{account_id}' removed from storage")
424
+
425
+ if 0 < JwtConfig.ACCOUNT_LIMIT.value <= len(recs) - len(expired):
426
+ # delete the oldest token to make way for the new one
427
+ db_delete(errors=errors,
428
+ delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
429
+ where_data={JwtDbConfig.COL_KID: oldest_id},
430
+ engine=DbEngine(JwtDbConfig.ENGINE),
431
+ connection=db_conn,
432
+ committable=False,
433
+ logger=logger)
434
+ if errors:
435
+ raise RuntimeError("; ".join(errors))
436
+ if logger:
437
+ logger.debug(msg="Oldest active token of account "
438
+ f"'{account_id}' removed from storage")
439
+ # persist token
440
+ db_insert(errors=errors,
441
+ insert_stmt=f"INSERT INTO {JwtDbConfig.TABLE}",
442
+ insert_data={
443
+ JwtDbConfig.COL_ACCOUNT: account_id,
444
+ JwtDbConfig.COL_TOKEN: jwt_token,
445
+ JwtDbConfig.COL_ALGORITHM: JwtConfig.DEFAULT_ALGORITHM.value,
446
+ JwtDbConfig.COL_DECODER: b64encode(s=JwtConfig.DECODING_KEY.value).decode()
447
+ },
415
448
  engine=DbEngine(JwtDbConfig.ENGINE),
416
449
  connection=db_conn,
417
450
  committable=False,
418
451
  logger=logger)
419
452
  if errors:
420
453
  raise RuntimeError("; ".join(errors))
421
- if logger:
422
- logger.debug(msg=f"{len(expired)} tokens of account "
423
- f"'{account_id}' removed from storage")
424
-
425
- if 0 < JwtConfig.ACCOUNT_LIMIT.value <= len(recs) - len(expired):
426
- # delete the oldest token to make way for the new one
427
- db_delete(errors=errors,
428
- delete_stmt=f"DELETE FROM {JwtDbConfig.TABLE}",
429
- where_data={JwtDbConfig.COL_KID: oldest_id},
430
- engine=DbEngine(JwtDbConfig.ENGINE),
431
- connection=db_conn,
432
- committable=False,
433
- logger=logger)
454
+
455
+ # obtain and return the token's storage id
456
+ # HAZARD: JWT_DB_COL_TOKEN's column type might prevent it for being used in a WHERE clause
457
+ where_clause: str | None = None
458
+ if existing_ids:
459
+ where_clause = f"{JwtDbConfig.COL_KID} NOT IN {existing_ids}"
460
+ where_clause = where_clause.replace("[", "(", 1).replace("]", ")", 1)
461
+ reply: list[tuple[int]] = db_select(errors=errors,
462
+ sel_stmt=f"SELECT {JwtDbConfig.COL_KID} "
463
+ f"FROM {JwtDbConfig.TABLE}",
464
+ where_clause=where_clause,
465
+ where_data={JwtDbConfig.COL_ACCOUNT: account_id},
466
+ min_count=1,
467
+ max_count=1,
468
+ engine=DbEngine(JwtDbConfig.ENGINE),
469
+ connection=db_conn,
470
+ committable=False,
471
+ logger=logger)
434
472
  if errors:
435
473
  raise RuntimeError("; ".join(errors))
436
- if logger:
437
- logger.debug(msg="Oldest active token of account "
438
- f"'{account_id}' removed from storage")
439
- # persist token
440
- db_insert(errors=errors,
441
- insert_stmt=f"INSERT INTO {JwtDbConfig.TABLE}",
442
- insert_data={
443
- JwtDbConfig.COL_ACCOUNT: account_id,
444
- JwtDbConfig.COL_TOKEN: jwt_token,
445
- JwtDbConfig.COL_ALGORITHM: JwtConfig.DEFAULT_ALGORITHM.value,
446
- JwtDbConfig.COL_DECODER: urlsafe_b64encode(s=JwtConfig.DECODING_KEY.value).decode()
447
- },
448
- engine=DbEngine(JwtDbConfig.ENGINE),
449
- connection=db_conn,
450
- committable=False,
451
- logger=logger)
452
- if errors:
453
- raise RuntimeError("; ".join(errors))
454
-
455
- # obtain and return the token's storage id
456
- # HAZARD: JWT_DB_COL_TOKEN's column type might prevent it for being used in a WHERE clause
457
- where_clause: str | None = None
458
- if existing_ids:
459
- where_clause = f"{JwtDbConfig.COL_KID} NOT IN {existing_ids}"
460
- where_clause = where_clause.replace("[", "(", 1).replace("]", ")", 1)
461
- reply: list[tuple[int]] = db_select(errors=errors,
462
- sel_stmt=f"SELECT {JwtDbConfig.COL_KID} "
463
- f"FROM {JwtDbConfig.TABLE}",
464
- where_clause=where_clause,
465
- where_data={JwtDbConfig.COL_ACCOUNT: account_id},
466
- min_count=1,
467
- max_count=1,
468
- engine=DbEngine(JwtDbConfig.ENGINE),
469
- connection=db_conn,
470
- committable=False,
471
- logger=logger)
472
- if errors:
473
- raise RuntimeError("; ".join(errors))
474
-
475
- return reply[0][0]
474
+
475
+ return reply[0][0]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pypomes_jwt
3
- Version: 1.1.9
3
+ Version: 1.2.0
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=NZzjWKnhjxNuoE32V6soKo9sG5ypmt25V0mBAh3rAIs,793
2
+ pypomes_jwt/jwt_config.py,sha256=mtihd58_O00FuFXcNBKsabftG6UHu3Cj24i6cZXoskc,3096
3
+ pypomes_jwt/jwt_pomes.py,sha256=ptfxnBBtVVan0mBpHtmNto3yBBIDGp29JGeOGN8kD-8,24011
4
+ pypomes_jwt/jwt_registry.py,sha256=os-lK7FAzBHfu43VS2Xkz8n_wVpM9Hp4qUtjVxd-xj8,22656
5
+ pypomes_jwt-1.2.0.dist-info/METADATA,sha256=vDbuVcGkI-1rdP8XTqsaZ9mcs3NS3THqnMtD6wD8rFM,670
6
+ pypomes_jwt-1.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ pypomes_jwt-1.2.0.dist-info/licenses/LICENSE,sha256=NdakochSXm_H_-DSL_x2JlRCkYikj3snYYvTwgR5d_c,1086
8
+ pypomes_jwt-1.2.0.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=ptfxnBBtVVan0mBpHtmNto3yBBIDGp29JGeOGN8kD-8,24011
4
- pypomes_jwt/jwt_registry.py,sha256=LZMjAquURa-oEMAyn8RbRBlOQlwg_lmcoB9NASkv39E,22137
5
- pypomes_jwt-1.1.9.dist-info/METADATA,sha256=8udfNQmkAQabyf2fivZp_IJYYuJHd6HZt93btgIsmz0,670
6
- pypomes_jwt-1.1.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
- pypomes_jwt-1.1.9.dist-info/licenses/LICENSE,sha256=NdakochSXm_H_-DSL_x2JlRCkYikj3snYYvTwgR5d_c,1086
8
- pypomes_jwt-1.1.9.dist-info/RECORD,,