oidcauthlib 3.0.24__tar.gz → 3.0.26__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 (96) hide show
  1. {oidcauthlib-3.0.24/oidcauthlib.egg-info → oidcauthlib-3.0.26}/PKG-INFO +1 -1
  2. oidcauthlib-3.0.26/VERSION +1 -0
  3. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/userinfo/oidc_userinfo_manager.py +37 -5
  4. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26/oidcauthlib.egg-info}/PKG-INFO +1 -1
  5. oidcauthlib-3.0.24/VERSION +0 -1
  6. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/LICENSE +0 -0
  7. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/MANIFEST.in +0 -0
  8. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/README.md +0 -0
  9. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/__init__.py +0 -0
  10. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/__init__.py +0 -0
  11. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/auth_helper.py +0 -0
  12. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/auth_manager.py +0 -0
  13. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/cache/__init__.py +0 -0
  14. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/cache/oauth_cache.py +0 -0
  15. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/cache/oauth_memory_cache.py +0 -0
  16. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/cache/oauth_mongo_cache.py +0 -0
  17. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/config/__init__.py +0 -0
  18. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/config/auth_config.py +0 -0
  19. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/config/auth_config_reader.py +0 -0
  20. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/dcr/__init__.py +0 -0
  21. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/dcr/dcr_client.py +0 -0
  22. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/dcr/dcr_manager.py +0 -0
  23. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/dcr/dcr_registration.py +0 -0
  24. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/exceptions/__init__.py +0 -0
  25. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/exceptions/authorization_bearer_token_expired_exception.py +0 -0
  26. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/exceptions/authorization_bearer_token_invalid_exception.py +0 -0
  27. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/exceptions/authorization_bearer_token_missing_exception.py +0 -0
  28. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/exceptions/authorization_needed_exception.py +0 -0
  29. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/fastapi_auth_manager.py +0 -0
  30. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/middleware/__init__.py +0 -0
  31. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/middleware/request_scope_middleware.py +0 -0
  32. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/middleware/token_reader_middleware.py +0 -0
  33. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/models/__init__.py +0 -0
  34. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/models/auth.py +0 -0
  35. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/models/base_db_model.py +0 -0
  36. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/models/cache_item.py +0 -0
  37. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/models/client_key_set.py +0 -0
  38. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/models/token.py +0 -0
  39. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/repository/__init__.py +0 -0
  40. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/repository/base_repository.py +0 -0
  41. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/repository/memory/__init__.py +0 -0
  42. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/repository/memory/memory_repository.py +0 -0
  43. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/repository/mongo/__init__.py +0 -0
  44. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/repository/mongo/mongo_repository.py +0 -0
  45. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/repository/repository_factory.py +0 -0
  46. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/routers/__init__.py +0 -0
  47. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/routers/auth_router.py +0 -0
  48. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/token_reader.py +0 -0
  49. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/userinfo/__init__.py +0 -0
  50. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/well_known_configuration/__init__.py +0 -0
  51. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/well_known_configuration/auth_server_metadata.py +0 -0
  52. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/well_known_configuration/auth_server_metadata_discovery.py +0 -0
  53. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/well_known_configuration/well_known_configuration_cache.py +0 -0
  54. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/well_known_configuration/well_known_configuration_cache_result.py +0 -0
  55. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/auth/well_known_configuration/well_known_configuration_manager.py +0 -0
  56. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/cache_gate/__init__.py +0 -0
  57. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/cache_gate/advisory_lock.py +0 -0
  58. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/cache_gate/version_gate.py +0 -0
  59. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/container/__init__.py +0 -0
  60. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/container/oidc_authlib_container_factory.py +0 -0
  61. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/open_telemetry/__init__.py +0 -0
  62. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/open_telemetry/attribute_names.py +0 -0
  63. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/open_telemetry/configurator.py +0 -0
  64. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/open_telemetry/filtering_sampler.py +0 -0
  65. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/open_telemetry/filtering_span_exporter.py +0 -0
  66. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/open_telemetry/filtering_span_processor.py +0 -0
  67. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/open_telemetry/otel_setup.py +0 -0
  68. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/open_telemetry/span_names.py +0 -0
  69. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/py.typed +0 -0
  70. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/storage/__init__.py +0 -0
  71. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/storage/cache_to_collection_mapper.py +0 -0
  72. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/storage/memory_storage_factory.py +0 -0
  73. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/storage/mongo_gridfs_db.py +0 -0
  74. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/storage/mongo_gridfs_exception.py +0 -0
  75. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/storage/mongo_storage_factory.py +0 -0
  76. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/storage/storage_factory.py +0 -0
  77. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/storage/storage_factory_creator.py +0 -0
  78. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/__init__.py +0 -0
  79. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/cached.py +0 -0
  80. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/environment/__init__.py +0 -0
  81. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/environment/abstract_environment_variables.py +0 -0
  82. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/environment/oidc_environment_variables.py +0 -0
  83. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/logger/__init__.py +0 -0
  84. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/logger/log_levels.py +0 -0
  85. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/logger/logging_response.py +0 -0
  86. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/logger/logging_transport.py +0 -0
  87. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/mongo_url_utils.py +0 -0
  88. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib/utilities/url_validator.py +0 -0
  89. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib.egg-info/SOURCES.txt +0 -0
  90. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib.egg-info/dependency_links.txt +0 -0
  91. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib.egg-info/requires.txt +0 -0
  92. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/oidcauthlib.egg-info/top_level.txt +0 -0
  93. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/pyproject.toml +0 -0
  94. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/setup.cfg +0 -0
  95. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/tests/test_mongo_url_utils.py +0 -0
  96. {oidcauthlib-3.0.24 → oidcauthlib-3.0.26}/tests/test_simple.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oidcauthlib
3
- Version: 3.0.24
3
+ Version: 3.0.26
4
4
  Summary: oidcauthlib
5
5
  Author-email: Imran Qureshi <imran.qureshi@bwell.com>
6
6
  License: Apache-2.0
@@ -0,0 +1 @@
1
+ 3.0.26
@@ -23,6 +23,9 @@ logger.setLevel(SRC_LOG_LEVELS["AUTH"])
23
23
 
24
24
  _DEFAULT_PORTS = {"http": 80, "https": 443}
25
25
 
26
+ # Okta org-server access tokens carry the login in ``sub`` and the stable user id in this claim.
27
+ _OKTA_USER_ID_CLAIM = "uid"
28
+
26
29
 
27
30
  class OidcUserInfoCacheEntry(BaseModel):
28
31
  """Document stored for one cached scope list."""
@@ -179,14 +182,41 @@ class OidcUserInfoManager:
179
182
  """Short digest of ``cache_key``: the key embeds the user's ``sub``, which must not reach logs."""
180
183
  return hashlib.sha256(cache_key.encode()).hexdigest()[:12]
181
184
 
185
+ @staticmethod
186
+ def _user_id(*, access_token: Token) -> str | None:
187
+ """The token's stable user id claim, when it has a ``sub`` to alias and the claim is a non-empty string."""
188
+ user_id = (access_token.claims or {}).get(_OKTA_USER_ID_CLAIM)
189
+ if access_token.subject and isinstance(user_id, str) and user_id:
190
+ return user_id
191
+ return None
192
+
193
+ @staticmethod
194
+ def _token_subjects(*, access_token: Token) -> set[str]:
195
+ """Identifiers a userinfo ``sub`` may legitimately equal for this token; empty for a token without ``sub``.
196
+
197
+ Okta org-server access tokens carry the login in ``sub`` and the user id in ``uid``, while the userinfo
198
+ response's ``sub`` is that user id; so the token's ``uid`` counts as the same subject as its ``sub``.
199
+ The alias is not issuer-specific and relies on the caller having verified the token (the userinfo
200
+ request is made with that same token, so the response is always for the token's own user).
201
+ """
202
+ subject = access_token.subject
203
+ if not subject:
204
+ return set()
205
+ if not isinstance(subject, str):
206
+ # A malformed ``sub`` can never be shown to equal the response's; fail closed like any mismatch.
207
+ raise ValueError("User info response subject is missing or differs from the token's subject")
208
+ user_id = OidcUserInfoManager._user_id(access_token=access_token)
209
+ return {subject} | ({user_id} if user_id else set())
210
+
182
211
  async def get_user_info_async(self, *, access_token: Token) -> dict[str, Any]:
183
212
  """Fetch the userinfo response for ``access_token``.
184
213
 
185
214
  ``access_token`` must already have been verified by the caller; its claims are trusted.
186
215
 
187
- Per OIDC Core 5.3.2 the response must carry a ``sub`` equal to the token's ``sub``; a response without
188
- one, or with a different one, cannot be shown to describe the token's user and is rejected. A token
189
- that has no ``sub`` has nothing to compare, so its response is accepted (and never cached).
216
+ Per OIDC Core 5.3.2 the response must carry a ``sub`` equal to the token's ``sub`` (or its ``uid``, see
217
+ ``_token_subjects``); a response without one, or with a different one, cannot be shown to describe the
218
+ token's user and is rejected. A token that has no ``sub`` has nothing to compare (its ``uid`` is not
219
+ consulted), so its response is accepted (and never cached).
190
220
 
191
221
  Raises:
192
222
  ValueError: the token, auth config, discovery document or response is unusable, or the response's
@@ -222,7 +252,8 @@ class OidcUserInfoManager:
222
252
  user_info = response.json()
223
253
  if not isinstance(user_info, dict):
224
254
  raise ValueError("User info response is not a valid JSON object")
225
- if access_token.subject and user_info.get("sub") != access_token.subject:
255
+ token_subjects = self._token_subjects(access_token=access_token)
256
+ if token_subjects and user_info.get("sub") not in token_subjects:
226
257
  # Missing or different: ``sub`` is required in the response, and one that cannot be shown
227
258
  # to be the token's subject must not be turned into scopes. Neither subject is logged.
228
259
  raise ValueError("User info response subject is missing or differs from the token's subject")
@@ -243,7 +274,8 @@ class OidcUserInfoManager:
243
274
  cache_key = self.build_cache_key(
244
275
  issuer=access_token.issuer or (access_token.claims or {}).get("iss"),
245
276
  client_id=access_token.client_id,
246
- subject=access_token.subject,
277
+ # The stable user id when the token has one: a login can be reassigned to another user.
278
+ subject=self._user_id(access_token=access_token) or access_token.subject,
247
279
  )
248
280
 
249
281
  user_info_scopes: list[str] | None = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oidcauthlib
3
- Version: 3.0.24
3
+ Version: 3.0.26
4
4
  Summary: oidcauthlib
5
5
  Author-email: Imran Qureshi <imran.qureshi@bwell.com>
6
6
  License: Apache-2.0
@@ -1 +0,0 @@
1
- 3.0.24
File without changes
File without changes
File without changes
File without changes