pypomes-jwt 1.3.6__py3-none-any.whl → 1.3.8__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/__init__.py CHANGED
@@ -7,20 +7,15 @@ from .jwt_pomes import (
7
7
  jwt_issue_token, jwt_issue_tokens, jwt_refresh_tokens,
8
8
  jwt_get_claims, jwt_validate_token, jwt_revoke_token
9
9
  )
10
- from .jwt_providers import (
11
- provider_register, provider_get_token
12
- )
13
10
 
14
11
  __all__ = [
15
- # jwt_constants
12
+ # jwt_config
16
13
  "JwtConfig", "JwtDbConfig", "JwtAlgorithm",
17
14
  # jwt_pomes
18
15
  "jwt_needed", "jwt_verify_request",
19
16
  "jwt_assert_account", "jwt_set_account", "jwt_remove_account",
20
17
  "jwt_issue_token", "jwt_issue_tokens", "jwt_refresh_tokens",
21
- "jwt_get_claims", "jwt_validate_token", "jwt_revoke_token",
22
- # jwt_providers
23
- "provider_register", "provider_get_token"
18
+ "jwt_get_claims", "jwt_validate_token", "jwt_revoke_token"
24
19
  ]
25
20
 
26
21
  from importlib.metadata import version
pypomes_jwt/jwt_config.py CHANGED
@@ -66,14 +66,22 @@ del _encoding_key
66
66
  del _default_algorithm
67
67
 
68
68
 
69
+ # database access is not be necessary, if only handling externally provided JWT tokens
69
70
  class JwtDbConfig(StrEnum):
70
71
  """
71
72
  Parameters for JWT database connection.
72
73
  """
73
- ENGINE = env_get_str(key=f"{APP_PREFIX}_JWT_DB_ENGINE")
74
- TABLE = env_get_str(key=f"{APP_PREFIX}_JWT_DB_TABLE")
75
- COL_ACCOUNT = env_get_str(key=f"{APP_PREFIX}_JWT_DB_COL_ACCOUNT")
76
- COL_ALGORITHM = env_get_str(key=f"{APP_PREFIX}_JWT_DB_COL_ALGORITHM")
77
- COL_DECODER = env_get_str(key=f"{APP_PREFIX}_JWT_DB_COL_DECODER")
78
- COL_KID = env_get_str(key=f"{APP_PREFIX}_JWT_DB_COL_KID")
79
- COL_TOKEN = env_get_str(key=f"{APP_PREFIX}_JWT_DB_COL_TOKEN")
74
+ ENGINE = env_get_str(key=f"{APP_PREFIX}_JWT_DB_ENGINE",
75
+ def_value="")
76
+ TABLE = env_get_str(key=f"{APP_PREFIX}_JWT_DB_TABLE",
77
+ def_value="")
78
+ COL_ACCOUNT = env_get_str(key=f"{APP_PREFIX}_JWT_DB_COL_ACCOUNT",
79
+ def_value="")
80
+ COL_ALGORITHM = env_get_str(key=f"{APP_PREFIX}_JWT_DB_COL_ALGORITHM",
81
+ def_value="")
82
+ COL_DECODER = env_get_str(key=f"{APP_PREFIX}_JWT_DB_COL_DECODER",
83
+ def_value="")
84
+ COL_KID = env_get_str(key=f"{APP_PREFIX}_JWT_DB_COL_KID",
85
+ def_value="")
86
+ COL_TOKEN = env_get_str(key=f"{APP_PREFIX}_JWT_DB_COL_TOKEN",
87
+ def_value="")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pypomes_jwt
3
- Version: 1.3.6
3
+ Version: 1.3.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
@@ -10,8 +10,8 @@ Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.12
13
- Requires-Dist: cryptography>=46.0.2
13
+ Requires-Dist: cryptography>=46.0.3
14
14
  Requires-Dist: flask>=3.1.2
15
15
  Requires-Dist: pyjwt>=2.10.1
16
- Requires-Dist: pypomes-core>=2.7.6
17
- Requires-Dist: pypomes-db>=2.7.6
16
+ Requires-Dist: pypomes-core>=2.7.8
17
+ Requires-Dist: pypomes-db>=2.8.1
@@ -0,0 +1,8 @@
1
+ pypomes_jwt/__init__.py,sha256=esLvNt3Vr4WiZlx1lqKbLIXpDhdBFjqhqKUM6laSwg4,820
2
+ pypomes_jwt/jwt_config.py,sha256=ypr7BCRp1slJ503iyVmma-ljbaZAnbk_qpZKNRjD5CI,4026
3
+ pypomes_jwt/jwt_pomes.py,sha256=WWmZYVpG6wqlIjcJU3jNyBquCgfB-OcgCJBmm6imL4Q,23524
4
+ pypomes_jwt/jwt_registry.py,sha256=ypBEoL0I2F08sR2G2VO9wXxVeE252lNzjIAC3FGORhA,22631
5
+ pypomes_jwt-1.3.8.dist-info/METADATA,sha256=8qS7vQRszQmdG5YU2bWTzlFIy_XpoaEcruzNL40TDec,660
6
+ pypomes_jwt-1.3.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ pypomes_jwt-1.3.8.dist-info/licenses/LICENSE,sha256=NdakochSXm_H_-DSL_x2JlRCkYikj3snYYvTwgR5d_c,1086
8
+ pypomes_jwt-1.3.8.dist-info/RECORD,,
@@ -1,138 +0,0 @@
1
- import requests
2
- import sys
3
- from base64 import b64encode
4
- from datetime import datetime
5
- from logging import Logger
6
- from pypomes_core import TZ_LOCAL, exc_format
7
- from requests import Response
8
- from typing import Any
9
-
10
- # structure:
11
- # {
12
- # <provider-id>: {
13
- # "url": <strl>,
14
- # "user": <str>,
15
- # "pwd": <str>,
16
- # "basic-auth": <bool>,
17
- # "headers-data": <dict[str, str]>,
18
- # "body-data": <dict[str, str],
19
- # "token": <str>,
20
- # "expiration": <timestamp>
21
- # }
22
- # }
23
- _provider_registry: dict[str, dict[str, Any]] = {}
24
-
25
-
26
- def provider_register(provider_id: str,
27
- access_url: str,
28
- auth_user: str,
29
- auth_pwd: str,
30
- custom_auth: tuple[str, str] = None,
31
- headers_data: dict[str, str] = None,
32
- body_data: dict[str, str] = None) -> None:
33
- """
34
- Register an external authentication token provider.
35
-
36
- If specified, *custom_auth* provides key names for sending credentials (username and password, in this order)
37
- as key-value pairs in the body of the request. Otherwise, the external provider *provider_id* uses the standard
38
- HTTP Basic Authorization scheme, wherein the credentials are B64-encoded and send in the request headers.
39
-
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 *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
-
44
- :param provider_id: the provider's identification
45
- :param access_url: the url to request authentication tokens with
46
- :param auth_user: the basic authorization user
47
- :param auth_pwd: the basic authorization password
48
- :param custom_auth: optional key names for sending the credentials as key-value pairs in the body of the request
49
- :param headers_data: optional key-value pairs to be added to the request headers
50
- :param body_data: optional key-value pairs to be added to the request body
51
- """
52
- global _provider_registry # noqa: PLW0602
53
- _provider_registry[provider_id] = {
54
- "url": access_url,
55
- "user": auth_user,
56
- "pwd": auth_pwd,
57
- "custom-auth": custom_auth,
58
- "headers-data": headers_data,
59
- "body-data": body_data,
60
- "token": None,
61
- "expiration": datetime.now(tz=TZ_LOCAL).timestamp()
62
- }
63
-
64
-
65
- def provider_get_token(provider_id: str,
66
- errors: list[str] = None,
67
- logger: Logger = None) -> str | None:
68
- """
69
- Obtain an authentication token from the external provider *provider_id*.
70
-
71
- :param provider_id: the provider's identification
72
- :param errors: incidental error messages
73
- :param logger: optional logger
74
- """
75
- # initialize the return variable
76
- result: str | None = None
77
-
78
- global _provider_registry # noqa: PLW0602
79
- err_msg: str | None = None
80
- provider: dict[str, Any] = _provider_registry.get(provider_id)
81
- if provider:
82
- now: float = datetime.now(tz=TZ_LOCAL).timestamp()
83
- if now > provider.get("expiration"):
84
- user: str = provider.get("user")
85
- pwd: str = provider.get("pwd")
86
- headers_data: dict[str, str] = provider.get("headers-data") or {}
87
- body_data: dict[str, str] = provider.get("body-data") or {}
88
- custom_auth: tuple[str, str] = provider.get("custom-auth")
89
- if custom_auth:
90
- body_data[custom_auth[0]] = user
91
- body_data[custom_auth[1]] = pwd
92
- else:
93
- enc_bytes: bytes = b64encode(f"{user}:{pwd}".encode())
94
- headers_data["Authorization"] = f"Basic {enc_bytes.decode()}"
95
- url: str = provider.get("url")
96
- try:
97
- # typical return on a token request:
98
- # {
99
- # "token_type": "Bearer",
100
- # "access_token": <str>,
101
- # "expires_in": <number-of-seconds>,
102
- # optional data:
103
- # "refresh_token": <str>,
104
- # "refresh_expires_in": <number-of-seconds>
105
- # }
106
- response: Response = requests.post(url=url,
107
- data=body_data,
108
- headers=headers_data,
109
- timeout=None)
110
- if response.status_code < 200 or response.status_code >= 300:
111
- # request resulted in error, report the problem
112
- err_msg = (f"POST '{url}': failed, "
113
- f"status {response.status_code}, reason '{response.reason}'")
114
- else:
115
- reply: dict[str, Any] = response.json()
116
- provider["token"] = reply.get("access_token")
117
- provider["expiration"] = now + int(reply.get("expires_in"))
118
- if logger:
119
- logger.debug(msg=f"POST '{url}': status {response.status_code}")
120
- except Exception as e:
121
- # the operation raised an exception
122
- err_msg = exc_format(exc=e,
123
- exc_info=sys.exc_info())
124
- err_msg = f"POST '{url}': error, '{err_msg}'"
125
- else:
126
- err_msg: str = f"Provider '{provider_id}' not registered"
127
-
128
- if err_msg:
129
- if isinstance(errors, list):
130
- errors.append(err_msg)
131
- if logger:
132
- logger.error(msg=err_msg)
133
- else:
134
- result = provider.get("token")
135
-
136
- return result
137
-
138
-
@@ -1,9 +0,0 @@
1
- pypomes_jwt/__init__.py,sha256=vXAeaEnuUqpvGtV465TsW2Lf3ihijrMP2Hm4My79y88,968
2
- pypomes_jwt/jwt_config.py,sha256=GAFrvsCeBUIt2OzO-xLSM6qTe7iehvqrcHlu_CUnGAI,3638
3
- pypomes_jwt/jwt_pomes.py,sha256=WWmZYVpG6wqlIjcJU3jNyBquCgfB-OcgCJBmm6imL4Q,23524
4
- pypomes_jwt/jwt_providers.py,sha256=3o48fGZ9W0xwpdivECMb2E3GLdraU-Vh8zRyejbLgpc,5853
5
- pypomes_jwt/jwt_registry.py,sha256=ypBEoL0I2F08sR2G2VO9wXxVeE252lNzjIAC3FGORhA,22631
6
- pypomes_jwt-1.3.6.dist-info/METADATA,sha256=bWvYWUMYqc6AecDMkK0p3KxvXRMLZUTEglopfd8pk_A,660
7
- pypomes_jwt-1.3.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
8
- pypomes_jwt-1.3.6.dist-info/licenses/LICENSE,sha256=NdakochSXm_H_-DSL_x2JlRCkYikj3snYYvTwgR5d_c,1086
9
- pypomes_jwt-1.3.6.dist-info/RECORD,,