oidcauthlib 3.0.7__tar.gz → 3.0.9__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.
Files changed (86) hide show
  1. {oidcauthlib-3.0.7/oidcauthlib.egg-info → oidcauthlib-3.0.9}/PKG-INFO +3 -2
  2. oidcauthlib-3.0.9/VERSION +1 -0
  3. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/auth_manager.py +6 -1
  4. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/cache/oauth_memory_cache.py +1 -2
  5. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/fastapi_auth_manager.py +16 -7
  6. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/well_known_configuration/well_known_configuration_cache.py +1 -0
  7. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/environment/oidc_environment_variables.py +20 -0
  8. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9/oidcauthlib.egg-info}/PKG-INFO +3 -2
  9. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/pyproject.toml +2 -1
  10. oidcauthlib-3.0.7/VERSION +0 -1
  11. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/LICENSE +0 -0
  12. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/MANIFEST.in +0 -0
  13. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/README.md +0 -0
  14. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/__init__.py +0 -0
  15. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/__init__.py +0 -0
  16. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/auth_helper.py +0 -0
  17. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/cache/__init__.py +0 -0
  18. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/cache/oauth_cache.py +0 -0
  19. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/cache/oauth_mongo_cache.py +0 -0
  20. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/config/__init__.py +0 -0
  21. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/config/auth_config.py +0 -0
  22. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/config/auth_config_reader.py +0 -0
  23. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/dcr/__init__.py +0 -0
  24. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/dcr/dcr_client.py +0 -0
  25. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/dcr/dcr_manager.py +0 -0
  26. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/dcr/dcr_registration.py +0 -0
  27. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/exceptions/__init__.py +0 -0
  28. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/exceptions/authorization_bearer_token_expired_exception.py +0 -0
  29. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/exceptions/authorization_bearer_token_invalid_exception.py +0 -0
  30. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/exceptions/authorization_bearer_token_missing_exception.py +0 -0
  31. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/exceptions/authorization_needed_exception.py +0 -0
  32. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/middleware/__init__.py +0 -0
  33. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/middleware/request_scope_middleware.py +0 -0
  34. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/middleware/token_reader_middleware.py +0 -0
  35. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/models/__init__.py +0 -0
  36. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/models/auth.py +0 -0
  37. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/models/base_db_model.py +0 -0
  38. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/models/cache_item.py +0 -0
  39. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/models/client_key_set.py +0 -0
  40. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/models/token.py +0 -0
  41. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/repository/__init__.py +0 -0
  42. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/repository/base_repository.py +0 -0
  43. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/repository/memory/__init__.py +0 -0
  44. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/repository/memory/memory_repository.py +0 -0
  45. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/repository/mongo/__init__.py +0 -0
  46. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/repository/mongo/mongo_repository.py +0 -0
  47. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/repository/repository_factory.py +0 -0
  48. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/routers/__init__.py +0 -0
  49. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/routers/auth_router.py +0 -0
  50. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/token_reader.py +0 -0
  51. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/well_known_configuration/__init__.py +0 -0
  52. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/well_known_configuration/auth_server_metadata.py +0 -0
  53. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/well_known_configuration/auth_server_metadata_discovery.py +0 -0
  54. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/well_known_configuration/well_known_configuration_cache_result.py +0 -0
  55. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/auth/well_known_configuration/well_known_configuration_manager.py +0 -0
  56. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/container/__init__.py +0 -0
  57. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/container/oidc_authlib_container_factory.py +0 -0
  58. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/open_telemetry/__init__.py +0 -0
  59. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/open_telemetry/attribute_names.py +0 -0
  60. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/open_telemetry/span_names.py +0 -0
  61. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/py.typed +0 -0
  62. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/storage/__init__.py +0 -0
  63. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/storage/cache_to_collection_mapper.py +0 -0
  64. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/storage/memory_storage_factory.py +0 -0
  65. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/storage/mongo_gridfs_db.py +0 -0
  66. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/storage/mongo_gridfs_exception.py +0 -0
  67. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/storage/mongo_storage_factory.py +0 -0
  68. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/storage/storage_factory.py +0 -0
  69. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/storage/storage_factory_creator.py +0 -0
  70. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/__init__.py +0 -0
  71. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/cached.py +0 -0
  72. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/environment/__init__.py +0 -0
  73. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/environment/abstract_environment_variables.py +0 -0
  74. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/logger/__init__.py +0 -0
  75. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/logger/log_levels.py +0 -0
  76. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/logger/logging_response.py +0 -0
  77. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/logger/logging_transport.py +0 -0
  78. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/mongo_url_utils.py +0 -0
  79. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib/utilities/url_validator.py +0 -0
  80. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib.egg-info/SOURCES.txt +0 -0
  81. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib.egg-info/dependency_links.txt +0 -0
  82. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib.egg-info/requires.txt +0 -0
  83. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/oidcauthlib.egg-info/top_level.txt +0 -0
  84. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/setup.cfg +0 -0
  85. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/tests/test_mongo_url_utils.py +0 -0
  86. {oidcauthlib-3.0.7 → oidcauthlib-3.0.9}/tests/test_simple.py +0 -0
@@ -1,13 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oidcauthlib
3
- Version: 3.0.7
3
+ Version: 3.0.9
4
4
  Summary: oidcauthlib
5
5
  Author-email: Imran Qureshi <imran.qureshi@bwell.com>
6
- License-Expression: Apache-2.0
6
+ License: Apache-2.0
7
7
  Project-URL: Homepage, https://github.com/icanbwell/oidc-auth-lib
8
8
  Classifier: Development Status :: 4 - Beta
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Operating System :: OS Independent
11
+ Classifier: License :: OSI Approved :: Apache Software License
11
12
  Requires-Python: >=3.12
12
13
  Description-Content-Type: text/markdown
13
14
  License-File: LICENSE
@@ -0,0 +1 @@
1
+ 3.0.9
@@ -38,6 +38,7 @@ from oidcauthlib.utilities.url_validator import validate_url
38
38
 
39
39
  logger = logging.getLogger(__name__)
40
40
  logger.setLevel(SRC_LOG_LEVELS["AUTH"])
41
+ OAUTH_STATE_CACHE_TTL_SECONDS: int = int(os.getenv("OAUTH_STATE_CACHE_TTL_SECONDS", "300"))
41
42
 
42
43
 
43
44
  class AuthManager:
@@ -273,7 +274,11 @@ class AuthManager:
273
274
  if "nonce" in rv:
274
275
  state_data["nonce"] = rv["nonce"]
275
276
  cache_key = f"_state_{auth_provider}_{state}"
276
- await self.cache.set(cache_key, json.dumps({"data": state_data}))
277
+ await self.cache.set(
278
+ cache_key,
279
+ json.dumps({"data": state_data}),
280
+ expires=OAUTH_STATE_CACHE_TTL_SECONDS,
281
+ )
277
282
  logger.debug(f"Saved OAuth state to cache key={cache_key} data={state_data}")
278
283
  return cast(str, rv["url"])
279
284
 
@@ -14,11 +14,10 @@ class OAuthMemoryCache(OAuthCache):
14
14
  def id(self) -> uuid.UUID:
15
15
  return self.id_
16
16
 
17
- _cache: dict[str, str] = {}
18
-
19
17
  def __init__(self) -> None:
20
18
  """Initialize the AuthCache."""
21
19
  self.id_ = uuid.uuid4()
20
+ self._cache: dict[str, str] = {}
22
21
 
23
22
  @override
24
23
  async def delete(self, key: str) -> None:
@@ -143,15 +143,20 @@ class FastAPIAuthManager(AuthManager):
143
143
  # Retrieve state data saved by create_authorization_url
144
144
  cache_key = f"_state_{auth_provider}_{state}"
145
145
  cached_value = await self.cache.get(cache_key)
146
- if cached_value:
147
- state_data = json.loads(cached_value).get("data", {})
148
- await self.cache.delete(cache_key)
149
- else:
150
- logger.warning(
151
- "No cached state data found for key=%s — token exchange may fail (missing code_verifier/redirect_uri)",
146
+ if not cached_value:
147
+ from authlib.integrations.base_client import OAuthError
148
+
149
+ logger.error(
150
+ "No cached state data found for key=%s — aborting token exchange "
151
+ "(missing code_verifier/redirect_uri makes this a security risk)",
152
152
  cache_key,
153
153
  )
154
- state_data = {}
154
+ raise OAuthError(
155
+ error="invalid_state",
156
+ description="OAuth state validation failed: no cached state data found. "
157
+ "The state may have expired or was already consumed.",
158
+ )
159
+ state_data = json.loads(cached_value).get("data", {})
155
160
 
156
161
  # Build params for fetch_access_token
157
162
  params: Dict[str, Any] = {"code": code, "state": state}
@@ -163,6 +168,10 @@ class FastAPIAuthManager(AuthManager):
163
168
 
164
169
  token = await client.fetch_access_token(**params) # type: ignore[no-untyped-call]
165
170
 
171
+ # Delete the cache entry only after a successful token exchange so the
172
+ # user can retry the callback if the exchange fails transiently.
173
+ await self.cache.delete(cache_key)
174
+
166
175
  # Parse id_token if present (OpenID Connect).
167
176
  # parse_id_token requires jwks_uri in server_metadata to verify the
168
177
  # signature. When the provider was registered with explicit endpoints
@@ -247,6 +247,7 @@ class WellKnownConfigurationCache:
247
247
  await self.well_known_store.put(
248
248
  key=well_known_uri,
249
249
  value=well_known_configuration_cache_result.model_dump(),
250
+ ttl=self.environment_variables.well_known_cache_ttl_seconds,
250
251
  )
251
252
  logger.info(f"Cached OIDC discovery document for {well_known_uri}")
252
253
  return well_known_configuration_cache_result
@@ -196,6 +196,26 @@ class OidcEnvironmentVariables(AbstractEnvironmentVariables):
196
196
  except ValueError:
197
197
  raise ValueError("MAX_MONGO_INLINE_SIZE_KB must be a positive integer representing bytes")
198
198
 
199
+ @property
200
+ def well_known_cache_ttl_seconds(self) -> int:
201
+ """TTL in seconds for well-known configuration entries in the persistent store.
202
+
203
+ Controls how long OIDC discovery documents (including JWKS keys) are
204
+ cached in MongoDB before expiring. This ensures key rotations by
205
+ identity providers are picked up within a bounded window.
206
+
207
+ Set via WELL_KNOWN_CACHE_TTL_SECONDS environment variable.
208
+ Defaults to 3600 seconds (1 hour).
209
+
210
+ Returns:
211
+ TTL in seconds
212
+ """
213
+ try:
214
+ ttl = int(os.environ.get("WELL_KNOWN_CACHE_TTL_SECONDS", "3600"))
215
+ return ttl
216
+ except ValueError:
217
+ raise ValueError("WELL_KNOWN_CACHE_TTL_SECONDS must be a positive integer representing seconds")
218
+
199
219
  @property
200
220
  def well_known_config_http_timeout_seconds(self) -> int:
201
221
  """HTTP timeout in seconds for fetching well-known configurations.
@@ -1,13 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oidcauthlib
3
- Version: 3.0.7
3
+ Version: 3.0.9
4
4
  Summary: oidcauthlib
5
5
  Author-email: Imran Qureshi <imran.qureshi@bwell.com>
6
- License-Expression: Apache-2.0
6
+ License: Apache-2.0
7
7
  Project-URL: Homepage, https://github.com/icanbwell/oidc-auth-lib
8
8
  Classifier: Development Status :: 4 - Beta
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Operating System :: OS Independent
11
+ Classifier: License :: OSI Approved :: Apache Software License
11
12
  Requires-Python: >=3.12
12
13
  Description-Content-Type: text/markdown
13
14
  License-File: LICENSE
@@ -7,7 +7,7 @@ name = "oidcauthlib"
7
7
  dynamic = ["version"]
8
8
  description = "oidcauthlib"
9
9
  readme = "README.md"
10
- license = "Apache-2.0"
10
+ license = { text = "Apache-2.0" }
11
11
  requires-python = ">=3.12"
12
12
  authors = [
13
13
  { name = "Imran Qureshi", email = "imran.qureshi@bwell.com" },
@@ -16,6 +16,7 @@ classifiers = [
16
16
  "Development Status :: 4 - Beta",
17
17
  "Programming Language :: Python :: 3",
18
18
  "Operating System :: OS Independent",
19
+ "License :: OSI Approved :: Apache Software License",
19
20
  ]
20
21
  dependencies = [
21
22
  "httpx>=0.27.2",
oidcauthlib-3.0.7/VERSION DELETED
@@ -1 +0,0 @@
1
- 3.0.7
File without changes
File without changes
File without changes
File without changes