oauthlib 3.2.2__tar.gz → 3.3.1__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.
- {oauthlib-3.2.2 → oauthlib-3.3.1}/CHANGELOG.rst +30 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/LICENSE +5 -5
- {oauthlib-3.2.2/oauthlib.egg-info → oauthlib-3.3.1}/PKG-INFO +37 -18
- {oauthlib-3.2.2 → oauthlib-3.3.1}/README.rst +10 -6
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/__init__.py +13 -13
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/common.py +6 -5
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/__init__.py +3 -2
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/base.py +3 -8
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/signature.py +4 -4
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/utils.py +3 -2
- oauthlib-3.3.1/oauthlib/oauth2/__init__.py +70 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/base.py +14 -21
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/mobile_application.py +1 -1
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/service_application.py +2 -2
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/web_application.py +3 -3
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/base.py +2 -2
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/introspect.py +1 -1
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/metadata.py +2 -2
- oauthlib-3.3.1/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py +287 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/resource.py +1 -1
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/errors.py +3 -4
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py +3 -4
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/base.py +2 -5
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py +4 -5
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/implicit.py +1 -4
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py +3 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py +5 -6
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/parameters.py +85 -28
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/request_validator.py +2 -2
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/tokens.py +3 -9
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/__init__.py +6 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/clients/device.py +3 -3
- oauthlib-3.3.1/oauthlib/oauth2/rfc8628/endpoints/__init__.py +10 -0
- oauthlib-3.3.1/oauthlib/oauth2/rfc8628/endpoints/device_authorization.py +232 -0
- oauthlib-3.3.1/oauthlib/oauth2/rfc8628/endpoints/pre_configured.py +36 -0
- oauthlib-3.3.1/oauthlib/oauth2/rfc8628/errors.py +55 -0
- oauthlib-3.3.1/oauthlib/oauth2/rfc8628/grant_types/__init__.py +1 -0
- oauthlib-3.3.1/oauthlib/oauth2/rfc8628/grant_types/device_code.py +111 -0
- oauthlib-3.3.1/oauthlib/oauth2/rfc8628/request_validator.py +25 -0
- oauthlib-3.3.1/oauthlib/openid/connect/core/endpoints/pre_configured.py +139 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/exceptions.py +5 -4
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/base.py +5 -1
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/dispatchers.py +3 -3
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/hybrid.py +5 -6
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/request_validator.py +1 -1
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/tokens.py +1 -4
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/signals.py +3 -2
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/uri_validate.py +1 -2
- {oauthlib-3.2.2 → oauthlib-3.3.1/oauthlib.egg-info}/PKG-INFO +37 -18
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib.egg-info/SOURCES.txt +14 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/setup.cfg +1 -1
- {oauthlib-3.2.2 → oauthlib-3.3.1}/setup.py +12 -13
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_base.py +1 -1
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/test_signatures.py +37 -30
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/test_utils.py +2 -2
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_base.py +48 -25
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_service_application.py +1 -1
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_web_application.py +25 -9
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_metadata.py +5 -4
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_refresh_token.py +17 -1
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/test_parameters.py +27 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/test_tokens.py +1 -1
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/test_utils.py +1 -1
- oauthlib-3.3.1/tests/oauth2/rfc8628/endpoints/test_device_application_server.py +26 -0
- oauthlib-3.3.1/tests/oauth2/rfc8628/endpoints/test_error_responses.py +95 -0
- oauthlib-3.3.1/tests/oauth2/rfc8628/grant_types/test_device_code.py +172 -0
- oauthlib-3.3.1/tests/oauth2/rfc8628/test_server.py +113 -0
- oauthlib-3.3.1/tests/openid/connect/core/endpoints/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/endpoints/test_openid_connect_params_handling.py +3 -1
- oauthlib-3.3.1/tests/openid/connect/core/endpoints/test_refresh_token.py +32 -0
- oauthlib-3.3.1/tests/openid/connect/core/grant_types/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/test_uri_validate.py +2 -1
- oauthlib-3.2.2/oauthlib/oauth2/__init__.py +0 -36
- oauthlib-3.2.2/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py +0 -216
- oauthlib-3.2.2/oauthlib/openid/connect/core/endpoints/pre_configured.py +0 -97
- {oauthlib-3.2.2 → oauthlib-3.3.1}/MANIFEST.in +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/access_token.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/authorization.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/pre_configured.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/request_token.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/resource.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/signature_only.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/errors.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/parameters.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/request_validator.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/backend_application.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/legacy_application.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/authorization.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/revocation.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/token.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/utils.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/clients/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/endpoints/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/endpoints/userinfo.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/authorization_code.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/implicit.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/refresh_token.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib.egg-info/dependency_links.txt +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib.egg-info/requires.txt +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/oauthlib.egg-info/top_level.txt +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_access_token.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_authorization.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_request_token.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_resource.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_signature_only.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/test_client.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/test_parameters.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth1/rfc5849/test_request_validator.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_backend_application.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_legacy_application.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_mobile_application.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_base_endpoint.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_client_authentication.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_credentials_preservation.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_error_responses.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_extra_credentials.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_introspect_endpoint.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_resource_owner_association.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_revocation_endpoint.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_scope_handling.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_utils.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_authorization_code.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_client_credentials.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_implicit.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_resource_owner_password.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/test_request_validator.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc6749/test_server.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc8628/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc8628/clients/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/oauth2/rfc8628/clients/test_device.py +0 -0
- {oauthlib-3.2.2/tests/openid → oauthlib-3.3.1/tests/oauth2/rfc8628/endpoints}/__init__.py +0 -0
- {oauthlib-3.2.2/tests/openid/connect → oauthlib-3.3.1/tests/oauth2/rfc8628/grant_types}/__init__.py +0 -0
- {oauthlib-3.2.2/tests/openid/connect/core → oauthlib-3.3.1/tests/openid}/__init__.py +0 -0
- {oauthlib-3.2.2/tests/openid/connect/core/endpoints → oauthlib-3.3.1/tests/openid/connect}/__init__.py +0 -0
- {oauthlib-3.2.2/tests/openid/connect/core/grant_types → oauthlib-3.3.1/tests/openid/connect/core}/__init__.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/endpoints/test_claims_handling.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/endpoints/test_userinfo_endpoint.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_authorization_code.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_base.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_dispatchers.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_hybrid.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_implicit.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_refresh_token.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/test_request_validator.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/test_server.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/openid/connect/core/test_tokens.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/test_common.py +0 -0
- {oauthlib-3.2.2 → oauthlib-3.3.1}/tests/unittest/__init__.py +0 -0
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
3.3.1 (2025-06-19):
|
|
5
|
+
------------------
|
|
6
|
+
OAuth2.0 Client:
|
|
7
|
+
* #906: fix regression of expires_in parsing when float in string.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
3.3.0 (2025-06-17):
|
|
11
|
+
------------------
|
|
12
|
+
OAuth2.0 Provider:
|
|
13
|
+
* OIDC: #879 Changed in how ui_locales is parsed
|
|
14
|
+
* RFC8628: Added OAuth2.0 Device Authorization Grant support
|
|
15
|
+
* PKCE: #876, #893 Fixed `create_code_verifier` length
|
|
16
|
+
* OIDC: Pre-configured OIDC server to use Refresh Token by default
|
|
17
|
+
|
|
18
|
+
OAuth2.0 Common:
|
|
19
|
+
* OAuth2Error: Allow 0 to be a valid state
|
|
20
|
+
|
|
21
|
+
OAuth2.0 Client:
|
|
22
|
+
* #745: expires_at is forced to be an int
|
|
23
|
+
* #899: expires_at clarification
|
|
24
|
+
|
|
25
|
+
General:
|
|
26
|
+
* Removed Python 3.5, 3.6, 3.7 support
|
|
27
|
+
* #859, #883: Added Python 3.12, 3.13 Support
|
|
28
|
+
* Added dependency-review GitHub Action
|
|
29
|
+
* Updated various references of license (SPDX identifier..)
|
|
30
|
+
* Added GitHub Action for lint, replaced bandy with ruff, removed isort...
|
|
31
|
+
* Migrated to GitHub Actions from Travis
|
|
32
|
+
* Added Security Policy
|
|
33
|
+
|
|
4
34
|
3.2.2 (2022-10-17)
|
|
5
35
|
------------------
|
|
6
36
|
OAuth2.0 Provider:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (c)
|
|
1
|
+
Copyright (c) The OAuthlib Community
|
|
2
2
|
All rights reserved.
|
|
3
3
|
|
|
4
4
|
Redistribution and use in source and binary forms, with or without
|
|
@@ -11,14 +11,14 @@ modification, are permitted provided that the following conditions are met:
|
|
|
11
11
|
notice, this list of conditions and the following disclaimer in the
|
|
12
12
|
documentation and/or other materials provided with the distribution.
|
|
13
13
|
|
|
14
|
-
3. Neither the name of
|
|
15
|
-
be used to endorse or promote products derived from this
|
|
16
|
-
specific prior written permission.
|
|
14
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
15
|
+
contributors may be used to endorse or promote products derived from this
|
|
16
|
+
software without specific prior written permission.
|
|
17
17
|
|
|
18
18
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
19
19
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
20
20
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
21
|
-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
22
22
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
23
23
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
24
24
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
@@ -1,50 +1,65 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: oauthlib
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.1
|
|
4
4
|
Summary: A generic, spec-compliant, thorough implementation of the OAuth request-signing logic
|
|
5
5
|
Home-page: https://github.com/oauthlib/oauthlib
|
|
6
6
|
Author: The OAuthlib Community
|
|
7
|
-
|
|
8
|
-
Maintainer:
|
|
9
|
-
|
|
10
|
-
License: BSD
|
|
7
|
+
Maintainer: Jonathan Huot
|
|
8
|
+
Maintainer-email: jonathan.huot@gmail.com
|
|
9
|
+
License: BSD-3-Clause
|
|
11
10
|
Platform: any
|
|
12
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
13
12
|
Classifier: Environment :: Web Environment
|
|
14
13
|
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: License :: OSI Approved
|
|
16
|
-
Classifier: License :: OSI Approved :: BSD License
|
|
17
14
|
Classifier: Operating System :: MacOS
|
|
18
15
|
Classifier: Operating System :: POSIX
|
|
19
16
|
Classifier: Operating System :: POSIX :: Linux
|
|
20
17
|
Classifier: Programming Language :: Python
|
|
21
18
|
Classifier: Programming Language :: Python :: 3
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
24
19
|
Classifier: Programming Language :: Python :: 3.8
|
|
25
20
|
Classifier: Programming Language :: Python :: 3.9
|
|
26
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
27
25
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
28
26
|
Classifier: Programming Language :: Python :: Implementation
|
|
29
27
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
30
28
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
31
29
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
32
|
-
Requires-Python: >=3.
|
|
30
|
+
Requires-Python: >=3.8
|
|
33
31
|
Description-Content-Type: text/x-rst
|
|
32
|
+
License-File: LICENSE
|
|
34
33
|
Provides-Extra: rsa
|
|
34
|
+
Requires-Dist: cryptography>=3.0.0; extra == "rsa"
|
|
35
35
|
Provides-Extra: signedtoken
|
|
36
|
+
Requires-Dist: cryptography>=3.0.0; extra == "signedtoken"
|
|
37
|
+
Requires-Dist: pyjwt<3,>=2.0.0; extra == "signedtoken"
|
|
36
38
|
Provides-Extra: signals
|
|
37
|
-
|
|
39
|
+
Requires-Dist: blinker>=1.4.0; extra == "signals"
|
|
40
|
+
Dynamic: author
|
|
41
|
+
Dynamic: classifier
|
|
42
|
+
Dynamic: description
|
|
43
|
+
Dynamic: description-content-type
|
|
44
|
+
Dynamic: home-page
|
|
45
|
+
Dynamic: license
|
|
46
|
+
Dynamic: license-file
|
|
47
|
+
Dynamic: maintainer
|
|
48
|
+
Dynamic: maintainer-email
|
|
49
|
+
Dynamic: platform
|
|
50
|
+
Dynamic: provides-extra
|
|
51
|
+
Dynamic: requires-python
|
|
52
|
+
Dynamic: summary
|
|
38
53
|
|
|
39
54
|
OAuthLib - Python Framework for OAuth1 & OAuth2
|
|
40
55
|
===============================================
|
|
41
56
|
|
|
42
57
|
*A generic, spec-compliant, thorough implementation of the OAuth request-signing
|
|
43
|
-
logic for Python 3.
|
|
58
|
+
logic for Python 3.8+*
|
|
44
59
|
|
|
45
|
-
.. image:: https://
|
|
46
|
-
:target: https://
|
|
47
|
-
:alt:
|
|
60
|
+
.. image:: https://github.com/oauthlib/oauthlib/actions/workflows/python-build.yml/badge.svg
|
|
61
|
+
:target: https://github.com/oauthlib/oauthlib/actions
|
|
62
|
+
:alt: GitHub Actions
|
|
48
63
|
.. image:: https://coveralls.io/repos/oauthlib/oauthlib/badge.svg?branch=master
|
|
49
64
|
:target: https://coveralls.io/r/oauthlib/oauthlib
|
|
50
65
|
:alt: Coveralls
|
|
@@ -113,7 +128,9 @@ Which web frameworks are supported?
|
|
|
113
128
|
|
|
114
129
|
The following packages provide OAuth support using OAuthLib.
|
|
115
130
|
|
|
116
|
-
- For Django there is
|
|
131
|
+
- For Django there is:
|
|
132
|
+
- `django-oauth-toolkit`_, which includes `Django REST framework`_ support.
|
|
133
|
+
- `django-allauth`_, which includes `Django REST framework`_ as well as `Django Ninja`_ support.
|
|
117
134
|
- For Flask there is `flask-oauthlib`_ and `Flask-Dance`_.
|
|
118
135
|
- For Pyramid there is `pyramid-oauthlib`_.
|
|
119
136
|
- For Bottle there is `bottle-oauthlib`_.
|
|
@@ -127,6 +144,8 @@ please open a Pull Request, updating the documentation.
|
|
|
127
144
|
.. _`Flask-Dance`: https://github.com/singingwolfboy/flask-dance
|
|
128
145
|
.. _`pyramid-oauthlib`: https://github.com/tilgovi/pyramid-oauthlib
|
|
129
146
|
.. _`bottle-oauthlib`: https://github.com/thomsonreuters/bottle-oauthlib
|
|
147
|
+
.. _`django-allauth`: https://allauth.org/
|
|
148
|
+
.. _`Django Ninja`: https://django-ninja.dev/
|
|
130
149
|
|
|
131
150
|
Using OAuthLib? Please get in touch!
|
|
132
151
|
------------------------------------
|
|
@@ -148,7 +167,7 @@ have the pleasure to run into each other, please send a docs pull request =)
|
|
|
148
167
|
License
|
|
149
168
|
-------
|
|
150
169
|
|
|
151
|
-
OAuthLib is yours to use and abuse according to the terms of the BSD license.
|
|
170
|
+
OAuthLib is yours to use and abuse according to the terms of the BSD-3-Clause license.
|
|
152
171
|
Check the LICENSE file for full details.
|
|
153
172
|
|
|
154
173
|
Credits
|
|
@@ -2,11 +2,11 @@ OAuthLib - Python Framework for OAuth1 & OAuth2
|
|
|
2
2
|
===============================================
|
|
3
3
|
|
|
4
4
|
*A generic, spec-compliant, thorough implementation of the OAuth request-signing
|
|
5
|
-
logic for Python 3.
|
|
5
|
+
logic for Python 3.8+*
|
|
6
6
|
|
|
7
|
-
.. image:: https://
|
|
8
|
-
:target: https://
|
|
9
|
-
:alt:
|
|
7
|
+
.. image:: https://github.com/oauthlib/oauthlib/actions/workflows/python-build.yml/badge.svg
|
|
8
|
+
:target: https://github.com/oauthlib/oauthlib/actions
|
|
9
|
+
:alt: GitHub Actions
|
|
10
10
|
.. image:: https://coveralls.io/repos/oauthlib/oauthlib/badge.svg?branch=master
|
|
11
11
|
:target: https://coveralls.io/r/oauthlib/oauthlib
|
|
12
12
|
:alt: Coveralls
|
|
@@ -75,7 +75,9 @@ Which web frameworks are supported?
|
|
|
75
75
|
|
|
76
76
|
The following packages provide OAuth support using OAuthLib.
|
|
77
77
|
|
|
78
|
-
- For Django there is
|
|
78
|
+
- For Django there is:
|
|
79
|
+
- `django-oauth-toolkit`_, which includes `Django REST framework`_ support.
|
|
80
|
+
- `django-allauth`_, which includes `Django REST framework`_ as well as `Django Ninja`_ support.
|
|
79
81
|
- For Flask there is `flask-oauthlib`_ and `Flask-Dance`_.
|
|
80
82
|
- For Pyramid there is `pyramid-oauthlib`_.
|
|
81
83
|
- For Bottle there is `bottle-oauthlib`_.
|
|
@@ -89,6 +91,8 @@ please open a Pull Request, updating the documentation.
|
|
|
89
91
|
.. _`Flask-Dance`: https://github.com/singingwolfboy/flask-dance
|
|
90
92
|
.. _`pyramid-oauthlib`: https://github.com/tilgovi/pyramid-oauthlib
|
|
91
93
|
.. _`bottle-oauthlib`: https://github.com/thomsonreuters/bottle-oauthlib
|
|
94
|
+
.. _`django-allauth`: https://allauth.org/
|
|
95
|
+
.. _`Django Ninja`: https://django-ninja.dev/
|
|
92
96
|
|
|
93
97
|
Using OAuthLib? Please get in touch!
|
|
94
98
|
------------------------------------
|
|
@@ -110,7 +114,7 @@ have the pleasure to run into each other, please send a docs pull request =)
|
|
|
110
114
|
License
|
|
111
115
|
-------
|
|
112
116
|
|
|
113
|
-
OAuthLib is yours to use and abuse according to the terms of the BSD license.
|
|
117
|
+
OAuthLib is yours to use and abuse according to the terms of the BSD-3-Clause license.
|
|
114
118
|
Check the LICENSE file for full details.
|
|
115
119
|
|
|
116
120
|
Credits
|
|
@@ -5,30 +5,30 @@
|
|
|
5
5
|
A generic, spec-compliant, thorough implementation of the OAuth
|
|
6
6
|
request-signing logic.
|
|
7
7
|
|
|
8
|
-
:copyright: (c)
|
|
9
|
-
:license: BSD, see LICENSE for details.
|
|
8
|
+
:copyright: (c) The OAuthlib Community
|
|
9
|
+
:license: BSD-3-Clause, see LICENSE for details.
|
|
10
10
|
"""
|
|
11
11
|
import logging
|
|
12
12
|
from logging import NullHandler
|
|
13
13
|
|
|
14
14
|
__author__ = 'The OAuthlib Community'
|
|
15
|
-
__version__ = '3.
|
|
15
|
+
__version__ = '3.3.1'
|
|
16
16
|
|
|
17
17
|
logging.getLogger('oauthlib').addHandler(NullHandler())
|
|
18
18
|
|
|
19
19
|
_DEBUG = False
|
|
20
20
|
|
|
21
21
|
def set_debug(debug_val):
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
"""Set value of debug flag
|
|
23
|
+
|
|
24
24
|
:param debug_val: Value to set. Must be a bool value.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
"""
|
|
26
|
+
global _DEBUG # noqa: PLW0603
|
|
27
|
+
_DEBUG = debug_val
|
|
28
28
|
|
|
29
29
|
def get_debug():
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
"""Get debug mode value.
|
|
31
|
+
|
|
32
|
+
:return: `True` if debug mode is on, `False` otherwise
|
|
33
|
+
"""
|
|
34
|
+
return _DEBUG
|
|
@@ -34,7 +34,7 @@ INVALID_HEX_PATTERN = re.compile(r'%[^0-9A-Fa-f]|%[0-9A-Fa-f][^0-9A-Fa-f]')
|
|
|
34
34
|
|
|
35
35
|
always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
36
36
|
'abcdefghijklmnopqrstuvwxyz'
|
|
37
|
-
'
|
|
37
|
+
'0123456789_.-')
|
|
38
38
|
|
|
39
39
|
log = logging.getLogger('oauthlib')
|
|
40
40
|
|
|
@@ -198,7 +198,7 @@ def generate_token(length=30, chars=UNICODE_ASCII_CHARACTER_SET):
|
|
|
198
198
|
|
|
199
199
|
|
|
200
200
|
def generate_signed_token(private_pem, request):
|
|
201
|
-
import jwt
|
|
201
|
+
import jwt # noqa: PLC0415
|
|
202
202
|
|
|
203
203
|
now = datetime.datetime.utcnow()
|
|
204
204
|
|
|
@@ -216,7 +216,7 @@ def generate_signed_token(private_pem, request):
|
|
|
216
216
|
|
|
217
217
|
|
|
218
218
|
def verify_signed_token(public_pem, token):
|
|
219
|
-
import jwt
|
|
219
|
+
import jwt # noqa: PLC0415
|
|
220
220
|
|
|
221
221
|
return jwt.decode(token, public_pem, algorithms=['RS256'])
|
|
222
222
|
|
|
@@ -316,7 +316,7 @@ class CaseInsensitiveDict(dict):
|
|
|
316
316
|
return super().__getitem__(key)
|
|
317
317
|
|
|
318
318
|
def get(self, k, default=None):
|
|
319
|
-
return self[k] if k in self else default
|
|
319
|
+
return self[k] if k in self else default # noqa: SIM401
|
|
320
320
|
|
|
321
321
|
def __setitem__(self, k, v):
|
|
322
322
|
super().__setitem__(k, v)
|
|
@@ -346,7 +346,8 @@ class Request:
|
|
|
346
346
|
def __init__(self, uri, http_method='GET', body=None, headers=None,
|
|
347
347
|
encoding='utf-8'):
|
|
348
348
|
# Convert to unicode using encoding if given, else assume unicode
|
|
349
|
-
encode
|
|
349
|
+
def encode(x):
|
|
350
|
+
return to_unicode(x, encoding) if encoding else x
|
|
350
351
|
|
|
351
352
|
self.uri = encode(uri)
|
|
352
353
|
self.http_method = encode(http_method)
|
|
@@ -121,7 +121,8 @@ class Client:
|
|
|
121
121
|
:param timestamp: Use this timestamp instead of using current. (Mainly for testing)
|
|
122
122
|
"""
|
|
123
123
|
# Convert to unicode using encoding if given, else assume unicode
|
|
124
|
-
encode
|
|
124
|
+
def encode(x):
|
|
125
|
+
return to_unicode(x, encoding) if encoding else x
|
|
125
126
|
|
|
126
127
|
self.client_key = encode(client_key)
|
|
127
128
|
self.client_secret = encode(client_secret)
|
|
@@ -219,7 +220,7 @@ class Client:
|
|
|
219
220
|
content_type = request.headers.get('Content-Type', None)
|
|
220
221
|
content_type_eligible = content_type and content_type.find('application/x-www-form-urlencoded') < 0
|
|
221
222
|
if request.body is not None and content_type_eligible:
|
|
222
|
-
params.append(('oauth_body_hash', base64.b64encode(hashlib.sha1(request.body.encode('utf-8')).digest()).decode('utf-8')))
|
|
223
|
+
params.append(('oauth_body_hash', base64.b64encode(hashlib.sha1(request.body.encode('utf-8')).digest()).decode('utf-8'))) # noqa: S324
|
|
223
224
|
|
|
224
225
|
return params
|
|
225
226
|
|
|
@@ -69,12 +69,10 @@ class BaseEndpoint:
|
|
|
69
69
|
def _create_request(self, uri, http_method, body, headers):
|
|
70
70
|
# Only include body data from x-www-form-urlencoded requests
|
|
71
71
|
headers = CaseInsensitiveDict(headers or {})
|
|
72
|
-
if
|
|
73
|
-
CONTENT_TYPE_FORM_URLENCODED in headers["Content-Type"]):
|
|
72
|
+
if "Content-Type" in headers and CONTENT_TYPE_FORM_URLENCODED in headers["Content-Type"]: # noqa: SIM108
|
|
74
73
|
request = Request(uri, http_method, body, headers)
|
|
75
74
|
else:
|
|
76
75
|
request = Request(uri, http_method, '', headers)
|
|
77
|
-
|
|
78
76
|
signature_type, params, oauth_params = (
|
|
79
77
|
self._get_signature_type_and_params(request))
|
|
80
78
|
|
|
@@ -129,8 +127,7 @@ class BaseEndpoint:
|
|
|
129
127
|
# Considerations section (`Section 4`_) before deciding on which
|
|
130
128
|
# method to support.
|
|
131
129
|
# .. _`Section 4`: https://tools.ietf.org/html/rfc5849#section-4
|
|
132
|
-
if (
|
|
133
|
-
self.request_validator.allowed_signature_methods):
|
|
130
|
+
if (request.signature_method not in self.request_validator.allowed_signature_methods):
|
|
134
131
|
raise errors.InvalidSignatureMethodError(
|
|
135
132
|
description="Invalid signature, {} not in {!r}.".format(
|
|
136
133
|
request.signature_method,
|
|
@@ -180,9 +177,7 @@ class BaseEndpoint:
|
|
|
180
177
|
|
|
181
178
|
def _check_signature(self, request, is_token_request=False):
|
|
182
179
|
# ---- RSA Signature verification ----
|
|
183
|
-
if request.signature_method
|
|
184
|
-
request.signature_method == SIGNATURE_RSA_SHA256 or \
|
|
185
|
-
request.signature_method == SIGNATURE_RSA_SHA512:
|
|
180
|
+
if request.signature_method in {SIGNATURE_RSA_SHA1, SIGNATURE_RSA_SHA256, SIGNATURE_RSA_SHA512}:
|
|
186
181
|
# RSA-based signature method
|
|
187
182
|
|
|
188
183
|
# The server verifies the signature per `[RFC3447] section 8.2.2`_
|
|
@@ -45,6 +45,7 @@ import warnings
|
|
|
45
45
|
from oauthlib.common import extract_params, safe_string_equals, urldecode
|
|
46
46
|
|
|
47
47
|
from . import utils
|
|
48
|
+
import contextlib
|
|
48
49
|
|
|
49
50
|
log = logging.getLogger(__name__)
|
|
50
51
|
|
|
@@ -188,10 +189,9 @@ def base_string_uri(uri: str, host: str = None) -> str:
|
|
|
188
189
|
raise ValueError('missing host')
|
|
189
190
|
|
|
190
191
|
# NOTE: Try guessing if we're dealing with IP or hostname
|
|
191
|
-
|
|
192
|
+
with contextlib.suppress(ValueError):
|
|
192
193
|
hostname = ipaddress.ip_address(hostname)
|
|
193
|
-
|
|
194
|
-
pass
|
|
194
|
+
|
|
195
195
|
|
|
196
196
|
if isinstance(hostname, ipaddress.IPv6Address):
|
|
197
197
|
hostname = f"[{hostname}]"
|
|
@@ -568,7 +568,7 @@ def _get_jwt_rsa_algorithm(hash_algorithm_name: str):
|
|
|
568
568
|
# Not in cache: instantiate a new RSAAlgorithm
|
|
569
569
|
|
|
570
570
|
# PyJWT has some nice pycrypto/cryptography abstractions
|
|
571
|
-
import jwt.algorithms as jwt_algorithms
|
|
571
|
+
import jwt.algorithms as jwt_algorithms # noqa: PLC0415
|
|
572
572
|
m = {
|
|
573
573
|
'SHA-1': jwt_algorithms.hashes.SHA1,
|
|
574
574
|
'SHA-256': jwt_algorithms.hashes.SHA256,
|
|
@@ -30,7 +30,8 @@ def filter_params(target):
|
|
|
30
30
|
|
|
31
31
|
def filter_oauth_params(params):
|
|
32
32
|
"""Removes all non oauth parameters from a dict or a list of params."""
|
|
33
|
-
is_oauth
|
|
33
|
+
def is_oauth(kv):
|
|
34
|
+
return kv[0].startswith('oauth_')
|
|
34
35
|
if isinstance(params, dict):
|
|
35
36
|
return list(filter(is_oauth, list(params.items())))
|
|
36
37
|
else:
|
|
@@ -59,7 +60,7 @@ def unescape(u):
|
|
|
59
60
|
return unquote(u)
|
|
60
61
|
|
|
61
62
|
|
|
62
|
-
def parse_keqv_list(l):
|
|
63
|
+
def parse_keqv_list(l): # noqa: E741
|
|
63
64
|
"""A unicode-safe version of urllib2.parse_keqv_list"""
|
|
64
65
|
# With Python 2.6, parse_http_list handles unicode fine
|
|
65
66
|
return urllib2.parse_keqv_list(l)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
oauthlib.oauth2
|
|
3
|
+
~~~~~~~~~~~~~~
|
|
4
|
+
|
|
5
|
+
This module is a wrapper for the most recent implementation of OAuth 2.0 Client
|
|
6
|
+
and Server classes.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .rfc6749.clients import (
|
|
10
|
+
BackendApplicationClient,
|
|
11
|
+
Client,
|
|
12
|
+
LegacyApplicationClient,
|
|
13
|
+
MobileApplicationClient,
|
|
14
|
+
ServiceApplicationClient,
|
|
15
|
+
WebApplicationClient,
|
|
16
|
+
)
|
|
17
|
+
from .rfc6749.endpoints import (
|
|
18
|
+
AuthorizationEndpoint,
|
|
19
|
+
BackendApplicationServer,
|
|
20
|
+
IntrospectEndpoint,
|
|
21
|
+
LegacyApplicationServer,
|
|
22
|
+
MetadataEndpoint,
|
|
23
|
+
MobileApplicationServer,
|
|
24
|
+
ResourceEndpoint,
|
|
25
|
+
RevocationEndpoint,
|
|
26
|
+
Server,
|
|
27
|
+
TokenEndpoint,
|
|
28
|
+
WebApplicationServer,
|
|
29
|
+
)
|
|
30
|
+
from .rfc6749.errors import (
|
|
31
|
+
AccessDeniedError,
|
|
32
|
+
FatalClientError,
|
|
33
|
+
InsecureTransportError,
|
|
34
|
+
InvalidClientError,
|
|
35
|
+
InvalidClientIdError,
|
|
36
|
+
InvalidGrantError,
|
|
37
|
+
InvalidRedirectURIError,
|
|
38
|
+
InvalidRequestError,
|
|
39
|
+
InvalidRequestFatalError,
|
|
40
|
+
InvalidScopeError,
|
|
41
|
+
MismatchingRedirectURIError,
|
|
42
|
+
MismatchingStateError,
|
|
43
|
+
MissingClientIdError,
|
|
44
|
+
MissingCodeError,
|
|
45
|
+
MissingRedirectURIError,
|
|
46
|
+
MissingResponseTypeError,
|
|
47
|
+
MissingTokenError,
|
|
48
|
+
MissingTokenTypeError,
|
|
49
|
+
OAuth2Error,
|
|
50
|
+
ServerError,
|
|
51
|
+
TemporarilyUnavailableError,
|
|
52
|
+
TokenExpiredError,
|
|
53
|
+
UnauthorizedClientError,
|
|
54
|
+
UnsupportedGrantTypeError,
|
|
55
|
+
UnsupportedResponseTypeError,
|
|
56
|
+
UnsupportedTokenTypeError,
|
|
57
|
+
)
|
|
58
|
+
from .rfc6749.grant_types import (
|
|
59
|
+
AuthorizationCodeGrant,
|
|
60
|
+
ClientCredentialsGrant,
|
|
61
|
+
ImplicitGrant,
|
|
62
|
+
RefreshTokenGrant,
|
|
63
|
+
ResourceOwnerPasswordCredentialsGrant,
|
|
64
|
+
)
|
|
65
|
+
from .rfc6749.request_validator import RequestValidator
|
|
66
|
+
from .rfc6749.tokens import BearerToken, OAuth2Token
|
|
67
|
+
from .rfc6749.utils import is_secure_transport
|
|
68
|
+
from .rfc8628.clients import DeviceClient
|
|
69
|
+
from oauthlib.oauth2.rfc8628.endpoints import DeviceAuthorizationEndpoint, DeviceApplicationServer
|
|
70
|
+
from oauthlib.oauth2.rfc8628.grant_types import DeviceCodeGrant
|
|
@@ -8,17 +8,16 @@ for consuming OAuth 2.0 RFC6749.
|
|
|
8
8
|
"""
|
|
9
9
|
import base64
|
|
10
10
|
import hashlib
|
|
11
|
-
import re
|
|
12
|
-
import secrets
|
|
13
11
|
import time
|
|
14
12
|
import warnings
|
|
15
13
|
|
|
16
|
-
from oauthlib.common import generate_token
|
|
14
|
+
from oauthlib.common import UNICODE_ASCII_CHARACTER_SET, generate_token
|
|
17
15
|
from oauthlib.oauth2.rfc6749 import tokens
|
|
18
16
|
from oauthlib.oauth2.rfc6749.errors import (
|
|
19
17
|
InsecureTransportError, TokenExpiredError,
|
|
20
18
|
)
|
|
21
19
|
from oauthlib.oauth2.rfc6749.parameters import (
|
|
20
|
+
parse_expires,
|
|
22
21
|
parse_token_response, prepare_token_request,
|
|
23
22
|
prepare_token_revocation_request,
|
|
24
23
|
)
|
|
@@ -207,7 +206,7 @@ class Client:
|
|
|
207
206
|
|
|
208
207
|
case_insensitive_token_types = {
|
|
209
208
|
k.lower(): v for k, v in self.token_types.items()}
|
|
210
|
-
if
|
|
209
|
+
if self.token_type.lower() not in case_insensitive_token_types:
|
|
211
210
|
raise ValueError("Unsupported token type: %s" % self.token_type)
|
|
212
211
|
|
|
213
212
|
if not (self.access_token or self.token.get('access_token')):
|
|
@@ -466,7 +465,7 @@ class Client:
|
|
|
466
465
|
return uri, headers, body
|
|
467
466
|
|
|
468
467
|
def create_code_verifier(self, length):
|
|
469
|
-
"""Create PKCE **code_verifier** used in computing **code_challenge**.
|
|
468
|
+
"""Create PKCE **code_verifier** used in computing **code_challenge**.
|
|
470
469
|
See `RFC7636 Section 4.1`_
|
|
471
470
|
|
|
472
471
|
:param length: REQUIRED. The length of the code_verifier.
|
|
@@ -491,11 +490,7 @@ class Client:
|
|
|
491
490
|
if not length <= 128:
|
|
492
491
|
raise ValueError("Length must be less than or equal to 128")
|
|
493
492
|
|
|
494
|
-
|
|
495
|
-
code_verifier = secrets.token_urlsafe(length)
|
|
496
|
-
|
|
497
|
-
if not re.search(allowed_characters, code_verifier):
|
|
498
|
-
raise ValueError("code_verifier contains invalid characters")
|
|
493
|
+
code_verifier = generate_token(length, UNICODE_ASCII_CHARACTER_SET + "-._~")
|
|
499
494
|
|
|
500
495
|
self.code_verifier = code_verifier
|
|
501
496
|
|
|
@@ -530,10 +525,10 @@ class Client:
|
|
|
530
525
|
"""
|
|
531
526
|
code_challenge = None
|
|
532
527
|
|
|
533
|
-
if code_verifier
|
|
528
|
+
if code_verifier is None:
|
|
534
529
|
raise ValueError("Invalid code_verifier")
|
|
535
530
|
|
|
536
|
-
if code_challenge_method
|
|
531
|
+
if code_challenge_method is None:
|
|
537
532
|
code_challenge_method = "plain"
|
|
538
533
|
self.code_challenge_method = code_challenge_method
|
|
539
534
|
code_challenge = code_verifier
|
|
@@ -587,15 +582,13 @@ class Client:
|
|
|
587
582
|
if 'token_type' in response:
|
|
588
583
|
self.token_type = response.get('token_type')
|
|
589
584
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
self.
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
except:
|
|
598
|
-
self._expires_at = None
|
|
585
|
+
vin, vat, v_at = parse_expires(response)
|
|
586
|
+
if vin:
|
|
587
|
+
self.expires_in = vin
|
|
588
|
+
if vat:
|
|
589
|
+
self.expires_at = vat
|
|
590
|
+
if v_at:
|
|
591
|
+
self._expires_at = v_at
|
|
599
592
|
|
|
600
593
|
if 'mac_key' in response:
|
|
601
594
|
self.mac_key = response.get('mac_key')
|
|
@@ -43,7 +43,7 @@ class MobileApplicationClient(Client):
|
|
|
43
43
|
redirection URI, it may be exposed to the resource owner and other
|
|
44
44
|
applications residing on the same device.
|
|
45
45
|
"""
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
response_type = 'token'
|
|
48
48
|
|
|
49
49
|
def prepare_request_uri(self, uri, redirect_uri=None, scope=None,
|
|
@@ -91,7 +91,7 @@ class ServiceApplicationClient(Client):
|
|
|
91
91
|
``https://provider.com/oauth2/token``.
|
|
92
92
|
|
|
93
93
|
:param expires_at: A unix expiration timestamp for the JWT. Defaults
|
|
94
|
-
to an hour from now, i.e. ``time.time() + 3600``.
|
|
94
|
+
to an hour from now, i.e. ``round(time.time()) + 3600``.
|
|
95
95
|
|
|
96
96
|
:param issued_at: A unix timestamp of when the JWT was created.
|
|
97
97
|
Defaults to now, i.e. ``time.time()``.
|
|
@@ -149,7 +149,7 @@ class ServiceApplicationClient(Client):
|
|
|
149
149
|
|
|
150
150
|
.. _`Section 3.2.1`: https://tools.ietf.org/html/rfc6749#section-3.2.1
|
|
151
151
|
"""
|
|
152
|
-
import jwt
|
|
152
|
+
import jwt # noqa: PLC0415
|
|
153
153
|
|
|
154
154
|
key = private_key or self.private_key
|
|
155
155
|
if not key:
|
|
@@ -33,7 +33,7 @@ class WebApplicationClient(Client):
|
|
|
33
33
|
browser) and capable of receiving incoming requests (via redirection)
|
|
34
34
|
from the authorization server.
|
|
35
35
|
"""
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
grant_type = 'authorization_code'
|
|
38
38
|
|
|
39
39
|
def __init__(self, client_id, code=None, **kwargs):
|
|
@@ -62,8 +62,8 @@ class WebApplicationClient(Client):
|
|
|
62
62
|
to the client. The parameter SHOULD be used for preventing
|
|
63
63
|
cross-site request forgery as described in `Section 10.12`_.
|
|
64
64
|
|
|
65
|
-
:param code_challenge: OPTIONAL. PKCE parameter. REQUIRED if PKCE is enforced.
|
|
66
|
-
A challenge derived from the code_verifier that is sent in the
|
|
65
|
+
:param code_challenge: OPTIONAL. PKCE parameter. REQUIRED if PKCE is enforced.
|
|
66
|
+
A challenge derived from the code_verifier that is sent in the
|
|
67
67
|
authorization request, to be verified against later.
|
|
68
68
|
|
|
69
69
|
:param code_challenge_method: OPTIONAL. PKCE parameter. A method that was used to derive code challenge.
|
|
@@ -32,7 +32,7 @@ class BaseEndpoint:
|
|
|
32
32
|
if valid_request_methods is not None:
|
|
33
33
|
valid_request_methods = [x.upper() for x in valid_request_methods]
|
|
34
34
|
self._valid_request_methods = valid_request_methods
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
|
|
37
37
|
@property
|
|
38
38
|
def available(self):
|
|
@@ -40,7 +40,7 @@ class BaseEndpoint:
|
|
|
40
40
|
|
|
41
41
|
@available.setter
|
|
42
42
|
def available(self, available):
|
|
43
|
-
self._available = available
|
|
43
|
+
self._available = available
|
|
44
44
|
|
|
45
45
|
@property
|
|
46
46
|
def catch_errors(self):
|
|
@@ -74,7 +74,7 @@ class IntrospectEndpoint(BaseEndpoint):
|
|
|
74
74
|
request
|
|
75
75
|
)
|
|
76
76
|
if claims is None:
|
|
77
|
-
return resp_headers, json.dumps(
|
|
77
|
+
return resp_headers, json.dumps({'active': False}), 200
|
|
78
78
|
if "active" in claims:
|
|
79
79
|
claims.pop("active")
|
|
80
80
|
return resp_headers, json.dumps(dict(active=True, **claims)), 200
|
|
@@ -38,9 +38,9 @@ class MetadataEndpoint(BaseEndpoint):
|
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
40
|
def __init__(self, endpoints, claims={}, raise_errors=True):
|
|
41
|
-
assert isinstance(claims, dict)
|
|
41
|
+
assert isinstance(claims, dict) # noqa: S101
|
|
42
42
|
for endpoint in endpoints:
|
|
43
|
-
assert isinstance(endpoint, BaseEndpoint)
|
|
43
|
+
assert isinstance(endpoint, BaseEndpoint) # noqa: S101
|
|
44
44
|
|
|
45
45
|
BaseEndpoint.__init__(self)
|
|
46
46
|
self.raise_errors = raise_errors
|