Authlib 1.7.2__tar.gz → 1.9.0__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 (229) hide show
  1. {authlib-1.7.2 → authlib-1.9.0}/Authlib.egg-info/PKG-INFO +3 -3
  2. {authlib-1.7.2 → authlib-1.9.0}/Authlib.egg-info/SOURCES.txt +4 -0
  3. authlib-1.9.0/Authlib.egg-info/requires.txt +2 -0
  4. {authlib-1.7.2 → authlib-1.9.0}/PKG-INFO +3 -3
  5. authlib-1.9.0/authlib/common/security.py +48 -0
  6. {authlib-1.7.2 → authlib-1.9.0}/authlib/common/urls.py +11 -2
  7. {authlib-1.7.2 → authlib-1.9.0}/authlib/consts.py +1 -1
  8. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/async_openid.py +6 -5
  9. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/sync_openid.py +8 -7
  10. authlib-1.9.0/authlib/integrations/httpx_client/_compat.py +16 -0
  11. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/httpx_client/assertion_client.py +12 -13
  12. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/httpx_client/oauth1_client.py +10 -15
  13. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/httpx_client/oauth2_client.py +15 -16
  14. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/httpx_client/utils.py +7 -2
  15. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/requests_client/assertion_session.py +3 -3
  16. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/client_mixin.py +1 -3
  17. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/drafts/_jwe_enc_cryptodome.py +2 -3
  18. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/drafts/_jwe_enc_cryptography.py +2 -3
  19. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7515/__init__.py +1 -1
  20. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7515/jws.py +9 -8
  21. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7516/__init__.py +1 -1
  22. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/__init__.py +1 -1
  23. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/jwe_encs.py +1 -3
  24. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/jws_algs.py +1 -3
  25. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/oct_key.py +8 -3
  26. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7519/__init__.py +1 -1
  27. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7519/claims.py +1 -1
  28. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/__init__.py +1 -1
  29. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/client_auth.py +10 -5
  30. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/errors.py +1 -1
  31. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/parameters.py +6 -18
  32. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/signature.py +9 -25
  33. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/base.py +1 -1
  34. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/client.py +25 -10
  35. authlib-1.9.0/authlib/oauth2/drafts/__init__.py +11 -0
  36. authlib-1.9.0/authlib/oauth2/drafts/id_jag.py +314 -0
  37. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/__init__.py +1 -1
  38. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/authenticate_client.py +2 -5
  39. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/errors.py +8 -10
  40. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/__init__.py +1 -3
  41. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/authorization_code.py +4 -12
  42. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/base.py +1 -3
  43. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/client_credentials.py +1 -1
  44. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/implicit.py +2 -6
  45. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/refresh_token.py +2 -6
  46. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/models.py +2 -6
  47. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/parameters.py +6 -13
  48. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/resource_protector.py +1 -3
  49. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6750/__init__.py +1 -1
  50. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6750/errors.py +4 -4
  51. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7009/__init__.py +1 -1
  52. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7009/parameters.py +1 -1
  53. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7009/revocation.py +1 -3
  54. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7521/client.py +8 -10
  55. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/__init__.py +1 -1
  56. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/assertion.py +6 -0
  57. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/client.py +19 -4
  58. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/jwt_bearer.py +35 -19
  59. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/token.py +1 -1
  60. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/validator.py +7 -2
  61. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7591/__init__.py +1 -1
  62. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7591/errors.py +4 -4
  63. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7592/__init__.py +1 -1
  64. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7636/__init__.py +1 -1
  65. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7662/__init__.py +1 -1
  66. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7662/introspection.py +2 -6
  67. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8414/__init__.py +1 -1
  68. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8414/models.py +1 -4
  69. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8414/well_known.py +1 -3
  70. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8628/__init__.py +1 -1
  71. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8628/endpoint.py +1 -1
  72. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8693/__init__.py +1 -1
  73. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/revocation.py +1 -3
  74. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/token.py +1 -1
  75. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/token_validator.py +2 -5
  76. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9101/authorization_server.py +76 -18
  77. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/__init__.py +2 -0
  78. authlib-1.9.0/authlib/oidc/core/authorization_request.py +39 -0
  79. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/_legacy.py +12 -8
  80. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/code.py +6 -4
  81. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/hybrid.py +3 -3
  82. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/implicit.py +2 -2
  83. {authlib-1.7.2 → authlib-1.9.0}/pyproject.toml +22 -22
  84. authlib-1.7.2/Authlib.egg-info/requires.txt +0 -2
  85. authlib-1.7.2/authlib/common/security.py +0 -21
  86. {authlib-1.7.2 → authlib-1.9.0}/Authlib.egg-info/dependency_links.txt +0 -0
  87. {authlib-1.7.2 → authlib-1.9.0}/Authlib.egg-info/top_level.txt +0 -0
  88. {authlib-1.7.2 → authlib-1.9.0}/LICENSE +0 -0
  89. {authlib-1.7.2 → authlib-1.9.0}/MANIFEST.in +0 -0
  90. {authlib-1.7.2 → authlib-1.9.0}/README.md +0 -0
  91. {authlib-1.7.2 → authlib-1.9.0}/authlib/__init__.py +0 -0
  92. {authlib-1.7.2 → authlib-1.9.0}/authlib/_joserfc_helpers.py +0 -0
  93. {authlib-1.7.2 → authlib-1.9.0}/authlib/common/__init__.py +0 -0
  94. {authlib-1.7.2 → authlib-1.9.0}/authlib/common/encoding.py +0 -0
  95. {authlib-1.7.2 → authlib-1.9.0}/authlib/common/errors.py +0 -0
  96. {authlib-1.7.2 → authlib-1.9.0}/authlib/common/language.py +0 -0
  97. {authlib-1.7.2 → authlib-1.9.0}/authlib/deprecate.py +0 -0
  98. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/__init__.py +0 -0
  99. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/__init__.py +0 -0
  100. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/async_app.py +0 -0
  101. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/errors.py +0 -0
  102. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/framework_integration.py +0 -0
  103. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/registry.py +0 -0
  104. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/base_client/sync_app.py +0 -0
  105. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_client/__init__.py +0 -0
  106. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_client/apps.py +0 -0
  107. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_client/integration.py +0 -0
  108. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth1/__init__.py +0 -0
  109. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth1/authorization_server.py +0 -0
  110. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth1/nonce.py +0 -0
  111. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth1/resource_protector.py +0 -0
  112. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/__init__.py +0 -0
  113. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/authorization_server.py +0 -0
  114. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/endpoints.py +0 -0
  115. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/requests.py +0 -0
  116. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/resource_protector.py +0 -0
  117. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/django_oauth2/signals.py +0 -0
  118. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_client/__init__.py +0 -0
  119. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_client/apps.py +0 -0
  120. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_client/integration.py +0 -0
  121. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth1/__init__.py +0 -0
  122. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth1/authorization_server.py +0 -0
  123. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth1/cache.py +0 -0
  124. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth1/resource_protector.py +0 -0
  125. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/__init__.py +0 -0
  126. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/authorization_server.py +0 -0
  127. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/errors.py +0 -0
  128. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/requests.py +0 -0
  129. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/resource_protector.py +0 -0
  130. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/flask_oauth2/signals.py +0 -0
  131. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/httpx_client/__init__.py +0 -0
  132. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/requests_client/__init__.py +0 -0
  133. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/requests_client/oauth1_session.py +0 -0
  134. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/requests_client/oauth2_session.py +0 -0
  135. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/requests_client/utils.py +0 -0
  136. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/__init__.py +0 -0
  137. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/functions.py +0 -0
  138. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/tokens_mixins.py +0 -0
  139. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/starlette_client/__init__.py +0 -0
  140. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/starlette_client/apps.py +0 -0
  141. {authlib-1.7.2 → authlib-1.9.0}/authlib/integrations/starlette_client/integration.py +0 -0
  142. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/__init__.py +0 -0
  143. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/drafts/__init__.py +0 -0
  144. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/drafts/_jwe_algorithms.py +0 -0
  145. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/errors.py +0 -0
  146. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/jwk.py +0 -0
  147. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7515/models.py +0 -0
  148. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7516/jwe.py +0 -0
  149. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7516/models.py +0 -0
  150. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/_cryptography_key.py +0 -0
  151. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/asymmetric_key.py +0 -0
  152. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/base_key.py +0 -0
  153. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/jwk.py +0 -0
  154. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7517/key_set.py +0 -0
  155. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/__init__.py +0 -0
  156. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/ec_key.py +0 -0
  157. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/jwe_algs.py +0 -0
  158. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/jwe_zips.py +0 -0
  159. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/rsa_key.py +0 -0
  160. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7518/util.py +0 -0
  161. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc7519/jwt.py +0 -0
  162. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc8037/__init__.py +0 -0
  163. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc8037/jws_eddsa.py +0 -0
  164. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/rfc8037/okp_key.py +0 -0
  165. {authlib-1.7.2 → authlib-1.9.0}/authlib/jose/util.py +0 -0
  166. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/__init__.py +0 -0
  167. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/client.py +0 -0
  168. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/errors.py +0 -0
  169. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/authorization_server.py +0 -0
  170. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/base_server.py +0 -0
  171. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/models.py +0 -0
  172. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/resource_protector.py +0 -0
  173. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/rsa.py +0 -0
  174. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/util.py +0 -0
  175. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth1/rfc5849/wrapper.py +0 -0
  176. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/__init__.py +0 -0
  177. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/auth.py +0 -0
  178. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/claims.py +0 -0
  179. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/authorization_server.py +0 -0
  180. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/endpoint.py +0 -0
  181. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/resource_owner_password_credentials.py +0 -0
  182. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/hooks.py +0 -0
  183. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/requests.py +0 -0
  184. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/token_endpoint.py +0 -0
  185. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/util.py +0 -0
  186. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6749/wrappers.py +0 -0
  187. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6750/parameters.py +0 -0
  188. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6750/token.py +0 -0
  189. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc6750/validator.py +0 -0
  190. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7521/__init__.py +0 -0
  191. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7523/auth.py +2 -2
  192. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7591/claims.py +0 -0
  193. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7591/endpoint.py +0 -0
  194. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7592/endpoint.py +0 -0
  195. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7636/challenge.py +0 -0
  196. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7662/models.py +0 -0
  197. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc7662/token_validator.py +0 -0
  198. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8628/device_code.py +0 -0
  199. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8628/errors.py +0 -0
  200. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc8628/models.py +0 -0
  201. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/__init__.py +0 -0
  202. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/claims.py +0 -0
  203. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9068/introspection.py +0 -0
  204. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9101/__init__.py +0 -0
  205. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9101/discovery.py +0 -0
  206. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9101/errors.py +0 -0
  207. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9101/registration.py +0 -0
  208. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9207/__init__.py +0 -0
  209. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9207/discovery.py +0 -0
  210. {authlib-1.7.2 → authlib-1.9.0}/authlib/oauth2/rfc9207/parameter.py +0 -0
  211. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/__init__.py +0 -0
  212. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/claims.py +0 -0
  213. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/errors.py +0 -0
  214. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/__init__.py +0 -0
  215. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/grants/util.py +0 -0
  216. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/models.py +0 -0
  217. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/userinfo.py +0 -0
  218. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/core/util.py +0 -0
  219. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/discovery/__init__.py +0 -0
  220. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/discovery/models.py +0 -0
  221. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/discovery/well_known.py +0 -0
  222. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/registration/__init__.py +0 -0
  223. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/registration/claims.py +0 -0
  224. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/rpinitiated/__init__.py +0 -0
  225. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/rpinitiated/discovery.py +0 -0
  226. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/rpinitiated/end_session.py +0 -0
  227. {authlib-1.7.2 → authlib-1.9.0}/authlib/oidc/rpinitiated/registration.py +0 -0
  228. {authlib-1.7.2 → authlib-1.9.0}/setup.cfg +0 -0
  229. {authlib-1.7.2 → authlib-1.9.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Authlib
3
- Version: 1.7.2
3
+ Version: 1.9.0
4
4
  Summary: The ultimate Python library in building OAuth and OpenID Connect servers and clients.
5
5
  Author-email: Hsiaoming Yang <me@lepture.com>
6
6
  License: BSD-3-Clause
@@ -32,8 +32,8 @@ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
32
32
  Requires-Python: >=3.10
33
33
  Description-Content-Type: text/markdown
34
34
  License-File: LICENSE
35
- Requires-Dist: cryptography
36
- Requires-Dist: joserfc>=1.6.0
35
+ Requires-Dist: cryptography>=45.0.1
36
+ Requires-Dist: joserfc>=1.6.1
37
37
  Dynamic: license-file
38
38
 
39
39
  <div align="center">
@@ -54,6 +54,7 @@ authlib/integrations/flask_oauth2/requests.py
54
54
  authlib/integrations/flask_oauth2/resource_protector.py
55
55
  authlib/integrations/flask_oauth2/signals.py
56
56
  authlib/integrations/httpx_client/__init__.py
57
+ authlib/integrations/httpx_client/_compat.py
57
58
  authlib/integrations/httpx_client/assertion_client.py
58
59
  authlib/integrations/httpx_client/oauth1_client.py
59
60
  authlib/integrations/httpx_client/oauth2_client.py
@@ -125,6 +126,8 @@ authlib/oauth2/auth.py
125
126
  authlib/oauth2/base.py
126
127
  authlib/oauth2/claims.py
127
128
  authlib/oauth2/client.py
129
+ authlib/oauth2/drafts/__init__.py
130
+ authlib/oauth2/drafts/id_jag.py
128
131
  authlib/oauth2/rfc6749/__init__.py
129
132
  authlib/oauth2/rfc6749/authenticate_client.py
130
133
  authlib/oauth2/rfc6749/authorization_server.py
@@ -199,6 +202,7 @@ authlib/oauth2/rfc9207/discovery.py
199
202
  authlib/oauth2/rfc9207/parameter.py
200
203
  authlib/oidc/__init__.py
201
204
  authlib/oidc/core/__init__.py
205
+ authlib/oidc/core/authorization_request.py
202
206
  authlib/oidc/core/claims.py
203
207
  authlib/oidc/core/errors.py
204
208
  authlib/oidc/core/models.py
@@ -0,0 +1,2 @@
1
+ cryptography>=45.0.1
2
+ joserfc>=1.6.1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Authlib
3
- Version: 1.7.2
3
+ Version: 1.9.0
4
4
  Summary: The ultimate Python library in building OAuth and OpenID Connect servers and clients.
5
5
  Author-email: Hsiaoming Yang <me@lepture.com>
6
6
  License: BSD-3-Clause
@@ -32,8 +32,8 @@ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
32
32
  Requires-Python: >=3.10
33
33
  Description-Content-Type: text/markdown
34
34
  License-File: LICENSE
35
- Requires-Dist: cryptography
36
- Requires-Dist: joserfc>=1.6.0
35
+ Requires-Dist: cryptography>=45.0.1
36
+ Requires-Dist: joserfc>=1.6.1
37
37
  Dynamic: license-file
38
38
 
39
39
  <div align="center">
@@ -0,0 +1,48 @@
1
+ import ipaddress
2
+ import os
3
+ import random
4
+ import string
5
+ from urllib.parse import urlsplit
6
+
7
+ UNICODE_ASCII_CHARACTER_SET = string.ascii_letters + string.digits
8
+
9
+
10
+ def generate_token(length=30, chars=UNICODE_ASCII_CHARACTER_SET):
11
+ rand = random.SystemRandom()
12
+ return "".join(rand.choice(chars) for _ in range(length))
13
+
14
+
15
+ def is_secure_transport(uri):
16
+ """Check if the uri is over ssl."""
17
+ if os.getenv("AUTHLIB_INSECURE_TRANSPORT"):
18
+ return True
19
+
20
+ try:
21
+ parts = urlsplit(uri)
22
+ except ValueError:
23
+ return False
24
+
25
+ if not parts.hostname:
26
+ return False
27
+
28
+ if parts.scheme == "https":
29
+ return True
30
+
31
+ if parts.scheme != "http":
32
+ return False
33
+
34
+ # rfc8252 §7.3: native apps may use http for loopback redirection URIs.
35
+ if parts.hostname == "localhost":
36
+ return True
37
+
38
+ try:
39
+ address = ipaddress.ip_address(parts.hostname)
40
+ except ValueError:
41
+ return False
42
+
43
+ # IPv6Address.is_loopback only accounts for the mapped IPv4 address since
44
+ # CPython 3.10.16, 3.11.11 and 3.12.4.
45
+ if isinstance(address, ipaddress.IPv6Address) and address.ipv4_mapped:
46
+ address = address.ipv4_mapped
47
+
48
+ return address.is_loopback
@@ -140,7 +140,16 @@ def extract_params(raw):
140
140
 
141
141
 
142
142
  def is_valid_url(url: str, fragments_allowed=True):
143
- parsed = urlparse.urlparse(url)
144
- return (
143
+ try:
144
+ parsed = urlparse.urlparse(url)
145
+ except ValueError:
146
+ return False
147
+
148
+ # The userinfo component can disguise the actual host,
149
+ # as in "https://provider.test@attacker.test/".
150
+ if "@" in parsed.netloc:
151
+ return False
152
+
153
+ return bool(
145
154
  parsed.scheme and parsed.hostname and (fragments_allowed or not parsed.fragment)
146
155
  )
@@ -1,5 +1,5 @@
1
1
  name = "Authlib"
2
- version = "1.7.2"
2
+ version = "1.9.0"
3
3
  author = "Hsiaoming Yang <me@lepture.com>"
4
4
  homepage = "https://authlib.org"
5
5
  default_user_agent = f"{name}/{version} (+{homepage})"
@@ -1,6 +1,7 @@
1
1
  from joserfc import jwt
2
2
  from joserfc.errors import InvalidKeyIdError
3
3
  from joserfc.jwk import KeySet
4
+ from joserfc.jws import JWSRegistry
4
5
 
5
6
  from authlib.common.security import generate_token
6
7
  from authlib.common.urls import add_params_to_uri
@@ -42,6 +43,9 @@ class AsyncOpenIDMixin:
42
43
  self, token, nonce, claims_options=None, claims_cls=None, leeway=120
43
44
  ):
44
45
  """Return an instance of UserInfo from token's ``id_token``."""
46
+ if "id_token" not in token:
47
+ return None
48
+
45
49
  claims_params = dict(
46
50
  nonce=nonce,
47
51
  client_id=self.client_id,
@@ -67,7 +71,7 @@ class AsyncOpenIDMixin:
67
71
  token = jwt.decode(
68
72
  token["id_token"],
69
73
  key=key_set,
70
- algorithms=alg_values,
74
+ registry=JWSRegistry(algorithms=alg_values, strict_check_header=False),
71
75
  )
72
76
  except InvalidKeyIdError:
73
77
  jwks = await self.fetch_jwk_set(force=True)
@@ -75,13 +79,10 @@ class AsyncOpenIDMixin:
75
79
  token = jwt.decode(
76
80
  token["id_token"],
77
81
  key=key_set,
78
- algorithms=alg_values,
82
+ registry=JWSRegistry(algorithms=alg_values, strict_check_header=False),
79
83
  )
80
84
 
81
85
  claims = claims_cls(token.claims, token.header, claims_options, claims_params)
82
- # https://github.com/authlib/authlib/issues/259
83
- if claims.get("nonce_supported") is False:
84
- claims.params["nonce"] = None
85
86
  claims.validate(leeway=leeway)
86
87
  return UserInfo(claims)
87
88
 
@@ -1,6 +1,7 @@
1
1
  from joserfc import jwt
2
2
  from joserfc.errors import InvalidKeyIdError
3
3
  from joserfc.jwk import KeySet
4
+ from joserfc.jws import JWSRegistry
4
5
 
5
6
  from authlib.common.security import generate_token
6
7
  from authlib.common.urls import add_params_to_uri
@@ -39,7 +40,11 @@ class OpenIDMixin:
39
40
  def parse_id_token(
40
41
  self, token, nonce, claims_options=None, claims_cls=None, leeway=120
41
42
  ):
42
- """Return an instance of UserInfo from token's ``id_token``."""
43
+ """Return UserInfo after validating the token's ``id_token``.
44
+
45
+ The expected ``nonce`` is controlled by the application. Token claims
46
+ such as ``nonce_supported`` cannot disable its validation.
47
+ """
43
48
  if "id_token" not in token:
44
49
  return None
45
50
 
@@ -66,21 +71,17 @@ class OpenIDMixin:
66
71
  token = jwt.decode(
67
72
  token["id_token"],
68
73
  key=key_set,
69
- algorithms=alg_values,
74
+ registry=JWSRegistry(algorithms=alg_values, strict_check_header=False),
70
75
  )
71
76
  except InvalidKeyIdError:
72
77
  key_set = KeySet.import_key_set(self.fetch_jwk_set(force=True))
73
78
  token = jwt.decode(
74
79
  token["id_token"],
75
80
  key=key_set,
76
- algorithms=alg_values,
81
+ registry=JWSRegistry(algorithms=alg_values, strict_check_header=False),
77
82
  )
78
83
 
79
84
  claims = claims_cls(token.claims, token.header, claims_options, claims_params)
80
- # https://github.com/authlib/authlib/issues/259
81
- if claims.get("nonce_supported") is False:
82
- claims.params["nonce"] = None
83
-
84
85
  claims.validate(leeway=leeway)
85
86
  return UserInfo(claims)
86
87
 
@@ -0,0 +1,16 @@
1
+ """Compatibility shim for httpx2 with legacy httpx fallback.
2
+
3
+ Falls back to httpx when httpx2 is unavailable. The fallback is deprecated
4
+ and will be removed in a future release.
5
+ """
6
+
7
+ from authlib.deprecate import deprecate
8
+
9
+ try:
10
+ import httpx2
11
+ except ImportError:
12
+ import httpx as httpx2
13
+
14
+ deprecate("The httpx module is deprecated; please use httpx2 instead.")
15
+
16
+ __all__ = ["httpx2"]
@@ -1,18 +1,18 @@
1
- import httpx
2
- from httpx import USE_CLIENT_DEFAULT
3
- from httpx import Response
4
-
5
1
  from authlib.oauth2.rfc7521 import AssertionClient as _AssertionClient
6
2
  from authlib.oauth2.rfc7523 import JWTBearerGrant
7
3
 
8
4
  from ..base_client import OAuthError
5
+ from ._compat import httpx2
9
6
  from .oauth2_client import OAuth2Auth
10
7
  from .utils import extract_client_kwargs
11
8
 
9
+ USE_CLIENT_DEFAULT = httpx2.USE_CLIENT_DEFAULT
10
+ Response = httpx2.Response
11
+
12
12
  __all__ = ["AsyncAssertionClient"]
13
13
 
14
14
 
15
- class AsyncAssertionClient(_AssertionClient, httpx.AsyncClient):
15
+ class AsyncAssertionClient(_AssertionClient, httpx2.AsyncClient):
16
16
  token_auth_class = OAuth2Auth
17
17
  oauth_error_class = OAuthError
18
18
  JWT_BEARER_GRANT_TYPE = JWTBearerGrant.GRANT_TYPE
@@ -31,10 +31,11 @@ class AsyncAssertionClient(_AssertionClient, httpx.AsyncClient):
31
31
  claims=None,
32
32
  token_placement="header",
33
33
  scope=None,
34
+ client_id=None,
34
35
  **kwargs,
35
36
  ):
36
37
  client_kwargs = extract_client_kwargs(kwargs)
37
- httpx.AsyncClient.__init__(self, **client_kwargs)
38
+ httpx2.AsyncClient.__init__(self, **client_kwargs)
38
39
 
39
40
  _AssertionClient.__init__(
40
41
  self,
@@ -47,6 +48,7 @@ class AsyncAssertionClient(_AssertionClient, httpx.AsyncClient):
47
48
  claims=claims,
48
49
  token_placement=token_placement,
49
50
  scope=scope,
51
+ client_id=client_id,
50
52
  **kwargs,
51
53
  )
52
54
 
@@ -69,7 +71,7 @@ class AsyncAssertionClient(_AssertionClient, httpx.AsyncClient):
69
71
  return self.parse_response_token(resp)
70
72
 
71
73
 
72
- class AssertionClient(_AssertionClient, httpx.Client):
74
+ class AssertionClient(_AssertionClient, httpx2.Client):
73
75
  token_auth_class = OAuth2Auth
74
76
  oauth_error_class = OAuthError
75
77
  JWT_BEARER_GRANT_TYPE = JWTBearerGrant.GRANT_TYPE
@@ -88,15 +90,11 @@ class AssertionClient(_AssertionClient, httpx.Client):
88
90
  claims=None,
89
91
  token_placement="header",
90
92
  scope=None,
93
+ client_id=None,
91
94
  **kwargs,
92
95
  ):
93
96
  client_kwargs = extract_client_kwargs(kwargs)
94
- # app keyword was dropped!
95
- app_value = client_kwargs.pop("app", None)
96
- if app_value is not None:
97
- client_kwargs["transport"] = httpx.WSGITransport(app=app_value)
98
-
99
- httpx.Client.__init__(self, **client_kwargs)
97
+ httpx2.Client.__init__(self, **client_kwargs)
100
98
 
101
99
  _AssertionClient.__init__(
102
100
  self,
@@ -109,6 +107,7 @@ class AssertionClient(_AssertionClient, httpx.Client):
109
107
  claims=claims,
110
108
  token_placement=token_placement,
111
109
  scope=scope,
110
+ client_id=client_id,
112
111
  **kwargs,
113
112
  )
114
113
 
@@ -1,10 +1,5 @@
1
1
  import typing
2
2
 
3
- import httpx
4
- from httpx import Auth
5
- from httpx import Request
6
- from httpx import Response
7
-
8
3
  from authlib.common.encoding import to_unicode
9
4
  from authlib.oauth1 import SIGNATURE_HMAC_SHA1
10
5
  from authlib.oauth1 import SIGNATURE_TYPE_HEADER
@@ -12,12 +7,17 @@ from authlib.oauth1 import ClientAuth
12
7
  from authlib.oauth1.client import OAuth1Client as _OAuth1Client
13
8
 
14
9
  from ..base_client import OAuthError
10
+ from ._compat import httpx2
15
11
  from .utils import build_request
16
12
  from .utils import extract_client_kwargs
17
13
 
14
+ Auth = httpx2.Auth
15
+ Request = httpx2.Request
16
+ Response = httpx2.Response
17
+
18
18
 
19
19
  class OAuth1Auth(Auth, ClientAuth):
20
- """Signs the httpx request using OAuth 1 (RFC5849)."""
20
+ """Signs the httpx2 request using OAuth 1 (RFC5849)."""
21
21
 
22
22
  requires_request_body = True
23
23
 
@@ -31,7 +31,7 @@ class OAuth1Auth(Auth, ClientAuth):
31
31
  )
32
32
 
33
33
 
34
- class AsyncOAuth1Client(_OAuth1Client, httpx.AsyncClient):
34
+ class AsyncOAuth1Client(_OAuth1Client, httpx2.AsyncClient):
35
35
  auth_class = OAuth1Auth
36
36
 
37
37
  def __init__(
@@ -49,7 +49,7 @@ class AsyncOAuth1Client(_OAuth1Client, httpx.AsyncClient):
49
49
  **kwargs,
50
50
  ):
51
51
  _client_kwargs = extract_client_kwargs(kwargs)
52
- httpx.AsyncClient.__init__(self, **_client_kwargs)
52
+ httpx2.AsyncClient.__init__(self, **_client_kwargs)
53
53
 
54
54
  _OAuth1Client.__init__(
55
55
  self,
@@ -99,7 +99,7 @@ class AsyncOAuth1Client(_OAuth1Client, httpx.AsyncClient):
99
99
  raise OAuthError(error_type, error_description)
100
100
 
101
101
 
102
- class OAuth1Client(_OAuth1Client, httpx.Client):
102
+ class OAuth1Client(_OAuth1Client, httpx2.Client):
103
103
  auth_class = OAuth1Auth
104
104
 
105
105
  def __init__(
@@ -117,12 +117,7 @@ class OAuth1Client(_OAuth1Client, httpx.Client):
117
117
  **kwargs,
118
118
  ):
119
119
  _client_kwargs = extract_client_kwargs(kwargs)
120
- # app keyword was dropped!
121
- app_value = _client_kwargs.pop("app", None)
122
- if app_value is not None:
123
- _client_kwargs["transport"] = httpx.WSGITransport(app=app_value)
124
-
125
- httpx.Client.__init__(self, **_client_kwargs)
120
+ httpx2.Client.__init__(self, **_client_kwargs)
126
121
 
127
122
  _OAuth1Client.__init__(
128
123
  self,
@@ -1,12 +1,11 @@
1
+ # ruff: noqa: I001
2
+ # The import order below is intentional: httpx compatibility must be loaded
3
+ # before anyio so import errors refer to httpx.
1
4
  import typing
2
5
  from contextlib import asynccontextmanager
3
6
 
4
- import httpx
7
+ from ._compat import httpx2
5
8
  from anyio import Lock # Import after httpx so import errors refer to httpx
6
- from httpx import USE_CLIENT_DEFAULT
7
- from httpx import Auth
8
- from httpx import Request
9
- from httpx import Response
10
9
 
11
10
  from authlib.common.urls import url_decode
12
11
  from authlib.oauth2.auth import ClientAuth
@@ -20,6 +19,11 @@ from ..base_client import UnsupportedTokenTypeError
20
19
  from .utils import HTTPX_CLIENT_KWARGS
21
20
  from .utils import build_request
22
21
 
22
+ USE_CLIENT_DEFAULT = httpx2.USE_CLIENT_DEFAULT
23
+ Auth = httpx2.Auth
24
+ Request = httpx2.Request
25
+ Response = httpx2.Response
26
+
23
27
  __all__ = [
24
28
  "OAuth2Auth",
25
29
  "OAuth2ClientAuth",
@@ -60,7 +64,7 @@ class OAuth2ClientAuth(Auth, ClientAuth):
60
64
  )
61
65
 
62
66
 
63
- class AsyncOAuth2Client(_OAuth2Client, httpx.AsyncClient):
67
+ class AsyncOAuth2Client(_OAuth2Client, httpx2.AsyncClient):
64
68
  SESSION_REQUEST_PARAMS = HTTPX_CLIENT_KWARGS
65
69
 
66
70
  client_auth_class = OAuth2ClientAuth
@@ -81,9 +85,9 @@ class AsyncOAuth2Client(_OAuth2Client, httpx.AsyncClient):
81
85
  leeway=60,
82
86
  **kwargs,
83
87
  ):
84
- # extract httpx.Client kwargs
88
+ # extract httpx2.Client kwargs
85
89
  client_kwargs = self._extract_session_request_params(kwargs)
86
- httpx.AsyncClient.__init__(self, **client_kwargs)
90
+ httpx2.AsyncClient.__init__(self, **client_kwargs)
87
91
 
88
92
  # We use a Lock to synchronize coroutines to prevent
89
93
  # multiple concurrent attempts to refresh the same token
@@ -208,7 +212,7 @@ class AsyncOAuth2Client(_OAuth2Client, httpx.AsyncClient):
208
212
  )
209
213
 
210
214
 
211
- class OAuth2Client(_OAuth2Client, httpx.Client):
215
+ class OAuth2Client(_OAuth2Client, httpx2.Client):
212
216
  SESSION_REQUEST_PARAMS = HTTPX_CLIENT_KWARGS
213
217
 
214
218
  client_auth_class = OAuth2ClientAuth
@@ -228,14 +232,9 @@ class OAuth2Client(_OAuth2Client, httpx.Client):
228
232
  update_token=None,
229
233
  **kwargs,
230
234
  ):
231
- # extract httpx.Client kwargs
235
+ # extract httpx2.Client kwargs
232
236
  client_kwargs = self._extract_session_request_params(kwargs)
233
- # app keyword was dropped!
234
- app_value = client_kwargs.pop("app", None)
235
- if app_value is not None:
236
- client_kwargs["transport"] = httpx.WSGITransport(app=app_value)
237
-
238
- httpx.Client.__init__(self, **client_kwargs)
237
+ httpx2.Client.__init__(self, **client_kwargs)
239
238
 
240
239
  _OAuth2Client.__init__(
241
240
  self,
@@ -1,4 +1,6 @@
1
- from httpx import Request
1
+ from ._compat import httpx2
2
+
3
+ Request = httpx2.Request
2
4
 
3
5
  HTTPX_CLIENT_KWARGS = [
4
6
  "headers",
@@ -32,7 +34,10 @@ def extract_client_kwargs(kwargs):
32
34
  def build_request(url, headers, body, initial_request: Request) -> Request:
33
35
  """Make sure that all the data from initial request is passed to the updated object."""
34
36
  updated_request = Request(
35
- method=initial_request.method, url=url, headers=headers, content=body
37
+ method=initial_request.method,
38
+ url=url,
39
+ headers=headers,
40
+ content=body,
36
41
  )
37
42
 
38
43
  if hasattr(initial_request, "extensions"):
@@ -17,9 +17,7 @@ class AssertionAuth(OAuth2Auth):
17
17
 
18
18
  class AssertionSession(AssertionClient, Session):
19
19
  """Constructs a new Assertion Framework for OAuth 2.0 Authorization Grants
20
- per RFC7521_.
21
-
22
- .. _RFC7521: https://tools.ietf.org/html/rfc7521
20
+ per :rfc:`7521`.
23
21
  """
24
22
 
25
23
  token_auth_class = AssertionAuth
@@ -39,6 +37,7 @@ class AssertionSession(AssertionClient, Session):
39
37
  claims=None,
40
38
  token_placement="header",
41
39
  scope=None,
40
+ client_id=None,
42
41
  default_timeout=None,
43
42
  leeway=60,
44
43
  **kwargs,
@@ -57,6 +56,7 @@ class AssertionSession(AssertionClient, Session):
57
56
  claims=claims,
58
57
  token_placement=token_placement,
59
58
  scope=scope,
59
+ client_id=client_id,
60
60
  leeway=leeway,
61
61
  **kwargs,
62
62
  )
@@ -22,9 +22,7 @@ class OAuth2ClientMixin(ClientMixin):
22
22
  @property
23
23
  def client_info(self):
24
24
  """Implementation for Client Info in OAuth 2.0 Dynamic Client
25
- Registration Protocol via `Section 3.2.1`_.
26
-
27
- .. _`Section 3.2.1`: https://tools.ietf.org/html/rfc7591#section-3.2.1
25
+ Registration Protocol via :rfc:`7591#section-3.2.1`.
28
26
  """
29
27
  return dict(
30
28
  client_id=self.client_id,
@@ -1,9 +1,8 @@
1
1
  """authlib.jose.draft.
2
2
  ~~~~~~~~~~~~~~~~~~~~
3
3
 
4
- Content Encryption per `Section 4`_.
5
-
6
- .. _`Section 4`: https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02#section-4
4
+ Content Encryption per
5
+ :draft:`draft-amringer-jose-chacha-02 Section 4 <draft-amringer-jose-chacha-02#section-4>`.
7
6
  """
8
7
 
9
8
  from Cryptodome.Cipher import ChaCha20_Poly1305 as Cryptodome_ChaCha20_Poly1305
@@ -1,9 +1,8 @@
1
1
  """authlib.jose.draft.
2
2
  ~~~~~~~~~~~~~~~~~~~~
3
3
 
4
- Content Encryption per `Section 4`_.
5
-
6
- .. _`Section 4`: https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02#section-4
4
+ Content Encryption per
5
+ :draft:`draft-amringer-jose-chacha-02 Section 4 <draft-amringer-jose-chacha-02#section-4>`.
7
6
  """
8
7
 
9
8
  from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
@@ -4,7 +4,7 @@
4
4
  This module represents a direct implementation of
5
5
  JSON Web Signature (JWS).
6
6
 
7
- https://tools.ietf.org/html/rfc7515
7
+ :rfc:`7515`
8
8
  """
9
9
 
10
10
  from .jws import JsonWebSignature
@@ -52,7 +52,7 @@ class JsonWebSignature:
52
52
  def serialize_compact(self, protected, payload, key):
53
53
  """Generate a JWS Compact Serialization. The JWS Compact Serialization
54
54
  represents digitally signed or MACed content as a compact, URL-safe
55
- string, per `Section 7.1`_.
55
+ string, per :rfc:`7515#section-7.1`.
56
56
 
57
57
  .. code-block:: text
58
58
 
@@ -81,15 +81,13 @@ class JsonWebSignature:
81
81
  def deserialize_compact(self, s, key, decode=None):
82
82
  """Exact JWS Compact Serialization, and validate with the given key.
83
83
  If key is not provided, the returned dict will contain the signature,
84
- and signing input values. Via `Section 7.1`_.
84
+ and signing input values. Via :rfc:`7515#section-7.1`.
85
85
 
86
86
  :param s: text of JWS Compact Serialization
87
87
  :param key: key used to verify the signature
88
88
  :param decode: a function to decode payload data
89
89
  :return: JWSObject
90
90
  :raise: BadSignatureError
91
-
92
- .. _`Section 7.1`: https://tools.ietf.org/html/rfc7515#section-7.1
93
91
  """
94
92
  if len(s) > self.MAX_CONTENT_LENGTH:
95
93
  raise ValueError("Serialization is too long.")
@@ -119,7 +117,7 @@ class JsonWebSignature:
119
117
  def serialize_json(self, header_obj, payload, key):
120
118
  """Generate a JWS JSON Serialization. The JWS JSON Serialization
121
119
  represents digitally signed or MACed content as a JSON object,
122
- per `Section 7.2`_.
120
+ per :rfc:`7515#section-7.2`.
123
121
 
124
122
  :param header_obj: A dict/list of header
125
123
  :param payload: A string/dict of payload
@@ -170,15 +168,13 @@ class JsonWebSignature:
170
168
  def deserialize_json(self, obj, key, decode=None):
171
169
  """Exact JWS JSON Serialization, and validate with the given key.
172
170
  If key is not provided, it will return a dict without signature
173
- verification. Header will still be validated. Via `Section 7.2`_.
171
+ verification. Header will still be validated. Via :rfc:`7515#section-7.2`.
174
172
 
175
173
  :param obj: text of JWS JSON Serialization
176
174
  :param key: key used to verify the signature
177
175
  :param decode: a function to decode payload data
178
176
  :return: JWSObject
179
177
  :raise: BadSignatureError
180
-
181
- .. _`Section 7.2`: https://tools.ietf.org/html/rfc7515#section-7.2
182
178
  """
183
179
  obj = ensure_dict(obj, "JWS")
184
180
 
@@ -204,6 +200,11 @@ class JsonWebSignature:
204
200
 
205
201
  headers = []
206
202
  is_valid = True
203
+
204
+ # invalidates cases like obj["signatures"] = None or obj["signatures"] = []
205
+ if not obj["signatures"]:
206
+ is_valid = False
207
+
207
208
  for header_obj in obj["signatures"]:
208
209
  jws_header, valid = self._validate_json_jws(
209
210
  payload_segment, payload, header_obj, key
@@ -4,7 +4,7 @@
4
4
  This module represents a direct implementation of
5
5
  JSON Web Encryption (JWE).
6
6
 
7
- https://tools.ietf.org/html/rfc7516
7
+ :rfc:`7516`
8
8
  """
9
9
 
10
10
  from .jwe import JsonWebEncryption
@@ -4,7 +4,7 @@
4
4
  This module represents a direct implementation of
5
5
  JSON Web Key (JWK).
6
6
 
7
- https://tools.ietf.org/html/rfc7517
7
+ :rfc:`7517`
8
8
  """
9
9
 
10
10
  from ._cryptography_key import load_pem_key
@@ -2,9 +2,7 @@
2
2
  ~~~~~~~~~~~~~~~~~~~~
3
3
 
4
4
  Cryptographic Algorithms for Cryptographic Algorithms for Content
5
- Encryption per `Section 5`_.
6
-
7
- .. _`Section 5`: https://tools.ietf.org/html/rfc7518#section-5
5
+ Encryption per :rfc:`7518#section-5`.
8
6
  """
9
7
 
10
8
  import hashlib