Authlib 1.8.0__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 (227) hide show
  1. {authlib-1.8.0 → authlib-1.9.0}/Authlib.egg-info/PKG-INFO +1 -1
  2. {authlib-1.8.0 → authlib-1.9.0}/Authlib.egg-info/SOURCES.txt +3 -0
  3. {authlib-1.8.0 → authlib-1.9.0}/PKG-INFO +1 -1
  4. {authlib-1.8.0 → authlib-1.9.0}/authlib/consts.py +1 -1
  5. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/base_client/async_openid.py +3 -3
  6. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/base_client/sync_openid.py +5 -5
  7. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/httpx_client/_compat.py +1 -3
  8. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/httpx_client/oauth2_client.py +1 -1
  9. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/requests_client/assertion_session.py +1 -3
  10. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/client_mixin.py +1 -3
  11. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/drafts/_jwe_enc_cryptodome.py +2 -3
  12. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/drafts/_jwe_enc_cryptography.py +2 -3
  13. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7515/__init__.py +1 -1
  14. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7515/jws.py +9 -8
  15. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7516/__init__.py +1 -1
  16. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7517/__init__.py +1 -1
  17. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7518/jwe_encs.py +1 -3
  18. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7518/jws_algs.py +1 -3
  19. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7518/oct_key.py +8 -3
  20. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7519/__init__.py +1 -1
  21. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7519/claims.py +1 -1
  22. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/__init__.py +1 -1
  23. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/client_auth.py +10 -5
  24. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/parameters.py +6 -18
  25. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/signature.py +9 -25
  26. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/base.py +1 -1
  27. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/client.py +25 -10
  28. authlib-1.9.0/authlib/oauth2/drafts/__init__.py +11 -0
  29. authlib-1.9.0/authlib/oauth2/drafts/id_jag.py +314 -0
  30. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/__init__.py +1 -1
  31. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/authenticate_client.py +2 -5
  32. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/errors.py +8 -10
  33. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/__init__.py +1 -3
  34. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/authorization_code.py +4 -12
  35. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/base.py +1 -3
  36. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/client_credentials.py +1 -1
  37. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/implicit.py +2 -6
  38. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/refresh_token.py +2 -6
  39. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/models.py +2 -6
  40. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/parameters.py +6 -13
  41. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/resource_protector.py +1 -3
  42. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6750/__init__.py +1 -1
  43. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6750/errors.py +4 -4
  44. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7009/__init__.py +1 -1
  45. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7009/parameters.py +1 -1
  46. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7009/revocation.py +1 -3
  47. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7521/client.py +4 -10
  48. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7523/__init__.py +1 -1
  49. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7523/client.py +1 -3
  50. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7523/jwt_bearer.py +9 -16
  51. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7523/validator.py +6 -2
  52. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7591/__init__.py +1 -1
  53. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7591/errors.py +4 -4
  54. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7592/__init__.py +1 -1
  55. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7636/__init__.py +1 -1
  56. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7662/__init__.py +1 -1
  57. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7662/introspection.py +2 -6
  58. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc8414/__init__.py +1 -1
  59. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc8414/models.py +1 -4
  60. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc8414/well_known.py +1 -3
  61. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc8628/__init__.py +1 -1
  62. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc8693/__init__.py +1 -1
  63. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9068/revocation.py +1 -3
  64. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9068/token_validator.py +1 -3
  65. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9101/authorization_server.py +76 -18
  66. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/__init__.py +2 -0
  67. authlib-1.9.0/authlib/oidc/core/authorization_request.py +39 -0
  68. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/grants/hybrid.py +3 -3
  69. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/grants/implicit.py +2 -2
  70. {authlib-1.8.0 → authlib-1.9.0}/pyproject.toml +1 -0
  71. {authlib-1.8.0 → authlib-1.9.0}/Authlib.egg-info/dependency_links.txt +0 -0
  72. {authlib-1.8.0 → authlib-1.9.0}/Authlib.egg-info/requires.txt +0 -0
  73. {authlib-1.8.0 → authlib-1.9.0}/Authlib.egg-info/top_level.txt +0 -0
  74. {authlib-1.8.0 → authlib-1.9.0}/LICENSE +0 -0
  75. {authlib-1.8.0 → authlib-1.9.0}/MANIFEST.in +0 -0
  76. {authlib-1.8.0 → authlib-1.9.0}/README.md +0 -0
  77. {authlib-1.8.0 → authlib-1.9.0}/authlib/__init__.py +0 -0
  78. {authlib-1.8.0 → authlib-1.9.0}/authlib/_joserfc_helpers.py +0 -0
  79. {authlib-1.8.0 → authlib-1.9.0}/authlib/common/__init__.py +0 -0
  80. {authlib-1.8.0 → authlib-1.9.0}/authlib/common/encoding.py +0 -0
  81. {authlib-1.8.0 → authlib-1.9.0}/authlib/common/errors.py +0 -0
  82. {authlib-1.8.0 → authlib-1.9.0}/authlib/common/language.py +0 -0
  83. {authlib-1.8.0 → authlib-1.9.0}/authlib/common/security.py +0 -0
  84. {authlib-1.8.0 → authlib-1.9.0}/authlib/common/urls.py +0 -0
  85. {authlib-1.8.0 → authlib-1.9.0}/authlib/deprecate.py +0 -0
  86. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/__init__.py +0 -0
  87. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/base_client/__init__.py +0 -0
  88. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/base_client/async_app.py +0 -0
  89. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/base_client/errors.py +0 -0
  90. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/base_client/framework_integration.py +0 -0
  91. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/base_client/registry.py +0 -0
  92. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/base_client/sync_app.py +0 -0
  93. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_client/__init__.py +0 -0
  94. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_client/apps.py +0 -0
  95. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_client/integration.py +0 -0
  96. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_oauth1/__init__.py +0 -0
  97. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_oauth1/authorization_server.py +0 -0
  98. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_oauth1/nonce.py +0 -0
  99. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_oauth1/resource_protector.py +0 -0
  100. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_oauth2/__init__.py +0 -0
  101. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_oauth2/authorization_server.py +0 -0
  102. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_oauth2/endpoints.py +0 -0
  103. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_oauth2/requests.py +0 -0
  104. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_oauth2/resource_protector.py +0 -0
  105. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/django_oauth2/signals.py +0 -0
  106. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_client/__init__.py +0 -0
  107. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_client/apps.py +0 -0
  108. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_client/integration.py +0 -0
  109. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_oauth1/__init__.py +0 -0
  110. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_oauth1/authorization_server.py +0 -0
  111. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_oauth1/cache.py +0 -0
  112. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_oauth1/resource_protector.py +0 -0
  113. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_oauth2/__init__.py +0 -0
  114. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_oauth2/authorization_server.py +0 -0
  115. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_oauth2/errors.py +0 -0
  116. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_oauth2/requests.py +0 -0
  117. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_oauth2/resource_protector.py +0 -0
  118. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/flask_oauth2/signals.py +0 -0
  119. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/httpx_client/__init__.py +0 -0
  120. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/httpx_client/assertion_client.py +0 -0
  121. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/httpx_client/oauth1_client.py +0 -0
  122. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/httpx_client/utils.py +0 -0
  123. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/requests_client/__init__.py +0 -0
  124. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/requests_client/oauth1_session.py +0 -0
  125. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/requests_client/oauth2_session.py +0 -0
  126. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/requests_client/utils.py +0 -0
  127. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/__init__.py +0 -0
  128. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/functions.py +0 -0
  129. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/sqla_oauth2/tokens_mixins.py +0 -0
  130. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/starlette_client/__init__.py +0 -0
  131. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/starlette_client/apps.py +0 -0
  132. {authlib-1.8.0 → authlib-1.9.0}/authlib/integrations/starlette_client/integration.py +0 -0
  133. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/__init__.py +0 -0
  134. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/drafts/__init__.py +0 -0
  135. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/drafts/_jwe_algorithms.py +0 -0
  136. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/errors.py +0 -0
  137. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/jwk.py +0 -0
  138. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7515/models.py +0 -0
  139. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7516/jwe.py +0 -0
  140. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7516/models.py +0 -0
  141. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7517/_cryptography_key.py +0 -0
  142. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7517/asymmetric_key.py +0 -0
  143. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7517/base_key.py +0 -0
  144. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7517/jwk.py +0 -0
  145. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7517/key_set.py +0 -0
  146. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7518/__init__.py +0 -0
  147. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7518/ec_key.py +0 -0
  148. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7518/jwe_algs.py +0 -0
  149. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7518/jwe_zips.py +0 -0
  150. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7518/rsa_key.py +0 -0
  151. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7518/util.py +0 -0
  152. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc7519/jwt.py +0 -0
  153. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc8037/__init__.py +0 -0
  154. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc8037/jws_eddsa.py +0 -0
  155. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/rfc8037/okp_key.py +0 -0
  156. {authlib-1.8.0 → authlib-1.9.0}/authlib/jose/util.py +0 -0
  157. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/__init__.py +0 -0
  158. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/client.py +0 -0
  159. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/errors.py +0 -0
  160. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/authorization_server.py +0 -0
  161. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/base_server.py +0 -0
  162. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/errors.py +0 -0
  163. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/models.py +0 -0
  164. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/resource_protector.py +0 -0
  165. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/rsa.py +0 -0
  166. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/util.py +0 -0
  167. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth1/rfc5849/wrapper.py +0 -0
  168. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/__init__.py +0 -0
  169. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/auth.py +0 -0
  170. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/claims.py +0 -0
  171. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/authorization_server.py +0 -0
  172. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/endpoint.py +0 -0
  173. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/grants/resource_owner_password_credentials.py +0 -0
  174. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/hooks.py +0 -0
  175. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/requests.py +0 -0
  176. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/token_endpoint.py +0 -0
  177. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/util.py +0 -0
  178. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6749/wrappers.py +0 -0
  179. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6750/parameters.py +0 -0
  180. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6750/token.py +0 -0
  181. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc6750/validator.py +0 -0
  182. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7521/__init__.py +0 -0
  183. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7523/assertion.py +0 -0
  184. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7523/auth.py +2 -2
  185. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7523/token.py +0 -0
  186. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7591/claims.py +0 -0
  187. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7591/endpoint.py +0 -0
  188. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7592/endpoint.py +0 -0
  189. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7636/challenge.py +0 -0
  190. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7662/models.py +0 -0
  191. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc7662/token_validator.py +0 -0
  192. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc8628/device_code.py +0 -0
  193. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc8628/endpoint.py +0 -0
  194. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc8628/errors.py +0 -0
  195. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc8628/models.py +0 -0
  196. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9068/__init__.py +0 -0
  197. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9068/claims.py +0 -0
  198. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9068/introspection.py +0 -0
  199. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9068/token.py +0 -0
  200. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9101/__init__.py +0 -0
  201. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9101/discovery.py +0 -0
  202. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9101/errors.py +0 -0
  203. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9101/registration.py +0 -0
  204. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9207/__init__.py +0 -0
  205. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9207/discovery.py +0 -0
  206. {authlib-1.8.0 → authlib-1.9.0}/authlib/oauth2/rfc9207/parameter.py +0 -0
  207. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/__init__.py +0 -0
  208. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/claims.py +0 -0
  209. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/errors.py +0 -0
  210. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/grants/__init__.py +0 -0
  211. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/grants/_legacy.py +0 -0
  212. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/grants/code.py +0 -0
  213. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/grants/util.py +0 -0
  214. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/models.py +0 -0
  215. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/userinfo.py +0 -0
  216. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/core/util.py +0 -0
  217. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/discovery/__init__.py +0 -0
  218. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/discovery/models.py +0 -0
  219. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/discovery/well_known.py +0 -0
  220. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/registration/__init__.py +0 -0
  221. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/registration/claims.py +0 -0
  222. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/rpinitiated/__init__.py +0 -0
  223. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/rpinitiated/discovery.py +0 -0
  224. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/rpinitiated/end_session.py +0 -0
  225. {authlib-1.8.0 → authlib-1.9.0}/authlib/oidc/rpinitiated/registration.py +0 -0
  226. {authlib-1.8.0 → authlib-1.9.0}/setup.cfg +0 -0
  227. {authlib-1.8.0 → 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.8.0
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
@@ -126,6 +126,8 @@ authlib/oauth2/auth.py
126
126
  authlib/oauth2/base.py
127
127
  authlib/oauth2/claims.py
128
128
  authlib/oauth2/client.py
129
+ authlib/oauth2/drafts/__init__.py
130
+ authlib/oauth2/drafts/id_jag.py
129
131
  authlib/oauth2/rfc6749/__init__.py
130
132
  authlib/oauth2/rfc6749/authenticate_client.py
131
133
  authlib/oauth2/rfc6749/authorization_server.py
@@ -200,6 +202,7 @@ authlib/oauth2/rfc9207/discovery.py
200
202
  authlib/oauth2/rfc9207/parameter.py
201
203
  authlib/oidc/__init__.py
202
204
  authlib/oidc/core/__init__.py
205
+ authlib/oidc/core/authorization_request.py
203
206
  authlib/oidc/core/claims.py
204
207
  authlib/oidc/core/errors.py
205
208
  authlib/oidc/core/models.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Authlib
3
- Version: 1.8.0
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
@@ -1,5 +1,5 @@
1
1
  name = "Authlib"
2
- version = "1.8.0"
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})"
@@ -43,6 +43,9 @@ class AsyncOpenIDMixin:
43
43
  self, token, nonce, claims_options=None, claims_cls=None, leeway=120
44
44
  ):
45
45
  """Return an instance of UserInfo from token's ``id_token``."""
46
+ if "id_token" not in token:
47
+ return None
48
+
46
49
  claims_params = dict(
47
50
  nonce=nonce,
48
51
  client_id=self.client_id,
@@ -80,9 +83,6 @@ class AsyncOpenIDMixin:
80
83
  )
81
84
 
82
85
  claims = claims_cls(token.claims, token.header, claims_options, claims_params)
83
- # https://github.com/authlib/authlib/issues/259
84
- if claims.get("nonce_supported") is False:
85
- claims.params["nonce"] = None
86
86
  claims.validate(leeway=leeway)
87
87
  return UserInfo(claims)
88
88
 
@@ -40,7 +40,11 @@ class OpenIDMixin:
40
40
  def parse_id_token(
41
41
  self, token, nonce, claims_options=None, claims_cls=None, leeway=120
42
42
  ):
43
- """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
+ """
44
48
  if "id_token" not in token:
45
49
  return None
46
50
 
@@ -78,10 +82,6 @@ class OpenIDMixin:
78
82
  )
79
83
 
80
84
  claims = claims_cls(token.claims, token.header, claims_options, claims_params)
81
- # https://github.com/authlib/authlib/issues/259
82
- if claims.get("nonce_supported") is False:
83
- claims.params["nonce"] = None
84
-
85
85
  claims.validate(leeway=leeway)
86
86
  return UserInfo(claims)
87
87
 
@@ -11,8 +11,6 @@ try:
11
11
  except ImportError:
12
12
  import httpx as httpx2
13
13
 
14
- deprecate(
15
- "The httpx module is deprecated; please use httpx2 instead."
16
- )
14
+ deprecate("The httpx module is deprecated; please use httpx2 instead.")
17
15
 
18
16
  __all__ = ["httpx2"]
@@ -5,7 +5,7 @@ import typing
5
5
  from contextlib import asynccontextmanager
6
6
 
7
7
  from ._compat import httpx2
8
- from anyio import Lock # Import after httpx so import errors refer to httpx
8
+ from anyio import Lock # Import after httpx so import errors refer to httpx
9
9
 
10
10
  from authlib.common.urls import url_decode
11
11
  from authlib.oauth2.auth import ClientAuth
@@ -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
@@ -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
@@ -1,9 +1,7 @@
1
1
  """authlib.jose.rfc7518.
2
2
  ~~~~~~~~~~~~~~~~~~~~
3
3
 
4
- "alg" (Algorithm) Header Parameter Values for JWS per `Section 3`_.
5
-
6
- .. _`Section 3`: https://tools.ietf.org/html/rfc7518#section-3
4
+ "alg" (Algorithm) Header Parameter Values for JWS per :rfc:`7518#section-3`.
7
5
  """
8
6
 
9
7
  import hashlib
@@ -41,6 +41,7 @@ class OctKey(Key):
41
41
  self.check_key_op(operation)
42
42
  if not self.raw_key:
43
43
  self.load_raw_key()
44
+ self._check_key(self.raw_key)
44
45
  return self.raw_key
45
46
 
46
47
  def load_raw_key(self):
@@ -62,6 +63,12 @@ class OctKey(Key):
62
63
  def validate_raw_key(cls, key):
63
64
  return isinstance(key, bytes)
64
65
 
66
+ @staticmethod
67
+ def _check_key(raw_key):
68
+ # PEM parsers accept leading text, including comments and whitespace.
69
+ if any(marker in raw_key for marker in POSSIBLE_UNSAFE_KEYS):
70
+ raise ValueError("This key may not be safe to import")
71
+
65
72
  @classmethod
66
73
  def import_key(cls, raw, options=None):
67
74
  """Import a key from bytes, string, or dict data."""
@@ -77,9 +84,7 @@ class OctKey(Key):
77
84
  else:
78
85
  raw_key = to_bytes(raw)
79
86
 
80
- # security check
81
- if raw_key.startswith(POSSIBLE_UNSAFE_KEYS):
82
- raise ValueError("This key may not be safe to import")
87
+ cls._check_key(raw_key)
83
88
 
84
89
  key = cls(raw_key=raw_key, options=options)
85
90
  return key
@@ -4,7 +4,7 @@
4
4
  This module represents a direct implementation of
5
5
  JSON Web Token (JWT).
6
6
 
7
- https://tools.ietf.org/html/rfc7519
7
+ :rfc:`7519`
8
8
  """
9
9
 
10
10
  from .claims import BaseClaims
@@ -224,4 +224,4 @@ class JWTClaims(BaseClaims):
224
224
 
225
225
 
226
226
  def _validate_numeric_time(s):
227
- return isinstance(s, (int, float))
227
+ return isinstance(s, (int, float)) and not isinstance(s, bool)
@@ -3,7 +3,7 @@
3
3
 
4
4
  This module represents a direct implementation of The OAuth 1.0 Protocol.
5
5
 
6
- https://tools.ietf.org/html/rfc5849
6
+ :rfc:`5849`
7
7
  """
8
8
 
9
9
  from .authorization_server import AuthorizationServer
@@ -78,12 +78,10 @@ class ClientAuth:
78
78
  def get_oauth_signature(self, method, uri, headers, body):
79
79
  """Get an OAuth signature to be used in signing a request.
80
80
 
81
- To satisfy `section 3.4.1.2`_ item 2, if the request argument's
81
+ To satisfy :rfc:`5849#section-3.4.1.2` item 2, if the request argument's
82
82
  headers dict attribute contains a Host item, its value will
83
83
  replace any netloc part of the request argument's uri attribute
84
84
  value.
85
-
86
- .. _`section 3.4.1.2`: https://tools.ietf.org/html/rfc5849#section-3.4.1.2
87
85
  """
88
86
  sign = self.SIGNATURE_METHODS.get(self.signature_method)
89
87
  if not sign:
@@ -150,9 +148,16 @@ class ClientAuth:
150
148
  oauth_body_hash = base64.b64encode(hashlib.sha1(body).digest())
151
149
  oauth_params.append(("oauth_body_hash", oauth_body_hash.decode("utf-8")))
152
150
 
153
- uri, headers, body = self._render(uri, headers, body, oauth_params)
151
+ # The signature is calculated over a rendered request that
152
+ # includes the OAuth parameters. The final request is rendered
153
+ # from the original values so the parameters are not duplicated.
154
+ rendered_uri, rendered_headers, rendered_body = self._render(
155
+ uri, headers, body, oauth_params
156
+ )
154
157
 
155
- sig = self.get_oauth_signature(method, uri, headers, body)
158
+ sig = self.get_oauth_signature(
159
+ method, rendered_uri, rendered_headers, rendered_body
160
+ )
156
161
  oauth_params.append(("oauth_signature", sig))
157
162
 
158
163
  uri, headers, body = self._render(uri, headers, body, oauth_params)
@@ -1,9 +1,7 @@
1
1
  """authlib.spec.rfc5849.parameters.
2
2
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
3
 
4
- This module contains methods related to `section 3.5`_ of the OAuth 1.0a spec.
5
-
6
- .. _`section 3.5`: https://tools.ietf.org/html/rfc5849#section-3.5
4
+ This module contains methods related to :rfc:`5849#section-3.5`.
7
5
  """
8
6
 
9
7
  from authlib.common.urls import extract_params
@@ -15,10 +13,10 @@ from .util import escape
15
13
 
16
14
  def prepare_headers(oauth_params, headers=None, realm=None):
17
15
  """**Prepare the Authorization header.**
18
- Per `section 3.5.1`_ of the spec.
16
+ Per :rfc:`5849#section-3.5.1`.
19
17
 
20
18
  Protocol parameters can be transmitted using the HTTP "Authorization"
21
- header field as defined by `RFC2617`_ with the auth-scheme name set to
19
+ header field as defined by :rfc:`2617` with the auth-scheme name set to
22
20
  "OAuth" (case insensitive).
23
21
 
24
22
  For example::
@@ -31,9 +29,6 @@ def prepare_headers(oauth_params, headers=None, realm=None):
31
29
  oauth_callback="http%3A%2F%2Fprinter.example.com%2Fready",
32
30
  oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D",
33
31
  oauth_version="1.0"
34
-
35
- .. _`section 3.5.1`: https://tools.ietf.org/html/rfc5849#section-3.5.1
36
- .. _`RFC2617`: https://tools.ietf.org/html/rfc2617
37
32
  """
38
33
  headers = headers or {}
39
34
 
@@ -64,10 +59,7 @@ def _append_params(oauth_params, params):
64
59
 
65
60
  Both params and oauth_params is must be lists of 2-tuples.
66
61
 
67
- Per `section 3.5.2`_ and `3.5.3`_ of the spec.
68
-
69
- .. _`section 3.5.2`: https://tools.ietf.org/html/rfc5849#section-3.5.2
70
- .. _`3.5.3`: https://tools.ietf.org/html/rfc5849#section-3.5.3
62
+ Per :rfc:`5849#section-3.5.2` and :rfc:`5849#section-3.5.3`.
71
63
 
72
64
  """
73
65
  merged = list(params)
@@ -83,9 +75,7 @@ def _append_params(oauth_params, params):
83
75
  def prepare_form_encoded_body(oauth_params, body):
84
76
  """Prepare the Form-Encoded Body.
85
77
 
86
- Per `section 3.5.2`_ of the spec.
87
-
88
- .. _`section 3.5.2`: https://tools.ietf.org/html/rfc5849#section-3.5.2
78
+ Per :rfc:`5849#section-3.5.2`.
89
79
 
90
80
  """
91
81
  # append OAuth params to the existing body
@@ -95,9 +85,7 @@ def prepare_form_encoded_body(oauth_params, body):
95
85
  def prepare_request_uri_query(oauth_params, uri):
96
86
  """Prepare the Request URI Query.
97
87
 
98
- Per `section 3.5.3`_ of the spec.
99
-
100
- .. _`section 3.5.3`: https://tools.ietf.org/html/rfc5849#section-3.5.3
88
+ Per :rfc:`5849#section-3.5.3`.
101
89
 
102
90
  """
103
91
  # append OAuth params to the existing set of query components
@@ -1,9 +1,7 @@
1
1
  """authlib.oauth1.rfc5849.signature.
2
2
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
3
 
4
- This module represents a direct implementation of `section 3.4`_ of the spec.
5
-
6
- .. _`section 3.4`: https://tools.ietf.org/html/rfc5849#section-3.4
4
+ This module represents a direct implementation of :rfc:`5849#section-3.4`.
7
5
  """
8
6
 
9
7
  import binascii
@@ -27,7 +25,7 @@ SIGNATURE_TYPE_BODY = "BODY"
27
25
 
28
26
 
29
27
  def construct_base_string(method, uri, params, host=None):
30
- """Generate signature base string from request, per `Section 3.4.1`_.
28
+ """Generate signature base string from request, per :rfc:`5849#section-3.4.1`.
31
29
 
32
30
  For example, the HTTP request::
33
31
 
@@ -52,8 +50,6 @@ def construct_base_string(method, uri, params, host=None):
52
50
  key%3D9djdj82h48djs9d2%26oauth_nonce%3D7d8f3e4a%26oauth_signature_m
53
51
  ethod%3DHMAC-SHA1%26oauth_timestamp%3D137131201%26oauth_token%3Dkkk
54
52
  9d7dh3k39sjv7
55
-
56
- .. _`Section 3.4.1`: https://tools.ietf.org/html/rfc5849#section-3.4.1
57
53
  """
58
54
  # Create base string URI per Section 3.4.1.2
59
55
  base_string_uri = normalize_base_string_uri(uri, host)
@@ -84,7 +80,7 @@ def construct_base_string(method, uri, params, host=None):
84
80
 
85
81
 
86
82
  def normalize_base_string_uri(uri, host=None):
87
- """Normalize Base String URI per `Section 3.4.1.2`_.
83
+ """Normalize Base String URI per :rfc:`5849#section-3.4.1.2`.
88
84
 
89
85
  For example, the HTTP request::
90
86
 
@@ -100,8 +96,6 @@ def normalize_base_string_uri(uri, host=None):
100
96
 
101
97
  is represented by the base string URI: "https://www.example.net:8080/".
102
98
 
103
- .. _`Section 3.4.1.2`: https://tools.ietf.org/html/rfc5849#section-3.4.1.2
104
-
105
99
  The host argument overrides the netloc part of the uri argument.
106
100
  """
107
101
  uri = to_unicode(uri)
@@ -155,7 +149,7 @@ def normalize_base_string_uri(uri, host=None):
155
149
 
156
150
 
157
151
  def normalize_parameters(params):
158
- """Normalize parameters per `Section 3.4.1.3.2`_.
152
+ """Normalize parameters per :rfc:`5849#section-3.4.1.3.2`.
159
153
 
160
154
  For example, the list of parameters from the previous section would
161
155
  be normalized as follows:
@@ -220,8 +214,6 @@ def normalize_parameters(params):
220
214
  a2=r%20b&a3=2%20q&a3=a&b5=%3D%253D&c%40=&c2=&oauth_consumer_key=9dj
221
215
  dj82h48djs9d2&oauth_nonce=7d8f3e4a&oauth_signature_method=HMAC-SHA1
222
216
  &oauth_timestamp=137131201&oauth_token=kkk9d7dh3k39sjv7
223
-
224
- .. _`Section 3.4.1.3.2`: https://tools.ietf.org/html/rfc5849#section-3.4.1.3.2
225
217
  """
226
218
  # 1. First, the name and value of each parameter are encoded
227
219
  # (`Section 3.6`_).
@@ -252,15 +244,12 @@ def generate_signature_base_string(request):
252
244
 
253
245
 
254
246
  def hmac_sha1_signature(base_string, client_secret, token_secret):
255
- """Generate signature via HMAC-SHA1 method, per `Section 3.4.2`_.
247
+ """Generate signature via HMAC-SHA1 method, per :rfc:`5849#section-3.4.2`.
256
248
 
257
249
  The "HMAC-SHA1" signature method uses the HMAC-SHA1 signature
258
- algorithm as defined in `RFC2104`_::
250
+ algorithm as defined in :rfc:`2104`::
259
251
 
260
252
  digest = HMAC - SHA1(key, text)
261
-
262
- .. _`RFC2104`: https://tools.ietf.org/html/rfc2104
263
- .. _`Section 3.4.2`: https://tools.ietf.org/html/rfc5849#section-3.4.2
264
253
  """
265
254
  # The HMAC-SHA1 function variables are used in following way:
266
255
 
@@ -297,17 +286,14 @@ def hmac_sha1_signature(base_string, client_secret, token_secret):
297
286
 
298
287
 
299
288
  def rsa_sha1_signature(base_string, rsa_private_key):
300
- """Generate signature via RSA-SHA1 method, per `Section 3.4.3`_.
289
+ """Generate signature via RSA-SHA1 method, per :rfc:`5849#section-3.4.3`.
301
290
 
302
291
  The "RSA-SHA1" signature method uses the RSASSA-PKCS1-v1_5 signature
303
- algorithm as defined in `RFC3447, Section 8.2`_ (also known as
292
+ algorithm as defined in :rfc:`3447#section-8.2` (also known as
304
293
  PKCS#1), using SHA-1 as the hash function for EMSA-PKCS1-v1_5. To
305
294
  use this method, the client MUST have established client credentials
306
295
  with the server that included its RSA public key (in a manner that is
307
296
  beyond the scope of this specification).
308
-
309
- .. _`Section 3.4.3`: https://tools.ietf.org/html/rfc5849#section-3.4.3
310
- .. _`RFC3447, Section 8.2`: https://tools.ietf.org/html/rfc3447#section-8.2
311
297
  """
312
298
  from .rsa import sign_sha1
313
299
 
@@ -318,15 +304,13 @@ def rsa_sha1_signature(base_string, rsa_private_key):
318
304
 
319
305
 
320
306
  def plaintext_signature(client_secret, token_secret):
321
- """Generate signature via PLAINTEXT method, per `Section 3.4.4`_.
307
+ """Generate signature via PLAINTEXT method, per :rfc:`5849#section-3.4.4`.
322
308
 
323
309
  The "PLAINTEXT" method does not employ a signature algorithm. It
324
310
  MUST be used with a transport-layer mechanism such as TLS or SSL (or
325
311
  sent over a secure channel with equivalent protections). It does not
326
312
  utilize the signature base string or the "oauth_timestamp" and
327
313
  "oauth_nonce" parameters.
328
-
329
- .. _`Section 3.4.4`: https://tools.ietf.org/html/rfc5849#section-3.4.4
330
314
  """
331
315
  # The "oauth_signature" protocol parameter is set to the concatenated
332
316
  # value of:
@@ -5,7 +5,7 @@ from authlib.common.urls import add_params_to_uri
5
5
  def invalid_error_characters(text: str) -> list[str]:
6
6
  """Check whether the string only contains characters from the restricted ASCII set defined in RFC6749 for errors.
7
7
 
8
- https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
8
+ :rfc:`6749#section-4.1.2.1`
9
9
  """
10
10
  valid_ranges = [
11
11
  (0x20, 0x21),
@@ -17,6 +17,28 @@ DEFAULT_HEADERS = {
17
17
  }
18
18
 
19
19
 
20
+ def _load_token_response(resp):
21
+ """Return the JSON object of a token endpoint response.
22
+
23
+ Raise the HTTP error of the response when its body is not a JSON object,
24
+ such as a rate-limit page from a gateway.
25
+ """
26
+ if resp.status_code >= 500:
27
+ resp.raise_for_status()
28
+
29
+ try:
30
+ token = resp.json()
31
+ except ValueError:
32
+ token = None
33
+
34
+ if not isinstance(token, dict):
35
+ resp.raise_for_status()
36
+ raise ValueError(
37
+ f"Token endpoint response is not a JSON object (HTTP {resp.status_code})."
38
+ )
39
+ return token
40
+
41
+
20
42
  class OAuth2Client:
21
43
  """Construct a new OAuth 2 protocol client.
22
44
 
@@ -325,7 +347,7 @@ class OAuth2Client:
325
347
  headers=None,
326
348
  **kwargs,
327
349
  ):
328
- """Revoke token method defined via `RFC7009`_.
350
+ """Revoke token method defined via :rfc:`7009`.
329
351
 
330
352
  :param url: Revoke Token endpoint, must be HTTPS.
331
353
  :param token: The token to be revoked.
@@ -336,8 +358,6 @@ class OAuth2Client:
336
358
  :param auth: An auth tuple or method as accepted by requests.
337
359
  :param headers: Dict to default request headers with.
338
360
  :return: Revocation Response
339
-
340
- .. _`RFC7009`: https://tools.ietf.org/html/rfc7009
341
361
  """
342
362
  if auth is None:
343
363
  auth = self.client_auth(self.revocation_endpoint_auth_method)
@@ -362,7 +382,7 @@ class OAuth2Client:
362
382
  headers=None,
363
383
  **kwargs,
364
384
  ):
365
- """Implementation of OAuth 2.0 Token Introspection defined via `RFC7662`_.
385
+ """Implementation of OAuth 2.0 Token Introspection defined via :rfc:`7662`.
366
386
 
367
387
  :param url: Introspection Endpoint, must be HTTPS.
368
388
  :param token: The token to be introspected.
@@ -373,8 +393,6 @@ class OAuth2Client:
373
393
  :param auth: An auth tuple or method as accepted by requests.
374
394
  :param headers: Dict to default request headers with.
375
395
  :return: Introspection Response
376
-
377
- .. _`RFC7662`: https://tools.ietf.org/html/rfc7662
378
396
  """
379
397
  if auth is None:
380
398
  auth = self.client_auth(self.token_endpoint_auth_method)
@@ -412,10 +430,7 @@ class OAuth2Client:
412
430
  self.compliance_hook[hook_type].add(hook)
413
431
 
414
432
  def parse_response_token(self, resp):
415
- if resp.status_code >= 500:
416
- resp.raise_for_status()
417
-
418
- token = resp.json()
433
+ token = _load_token_response(resp)
419
434
  if "error" in token:
420
435
  raise self.oauth_error_class(
421
436
  error=token["error"], description=token.get("error_description")
@@ -0,0 +1,11 @@
1
+ """authlib.oauth2.drafts.
2
+ ~~~~~~~~~~~~~~~~~~~~~~~~
3
+
4
+ Implementations of OAuth 2.0 specifications that are still in IETF draft
5
+ status. APIs in this package may change to track spec revisions until
6
+ the corresponding RFC is published.
7
+ """
8
+
9
+ from .id_jag import IDJAGGrant
10
+
11
+ __all__ = ["IDJAGGrant"]