oauthlib 3.3.0__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.3.0 → oauthlib-3.3.1}/CHANGELOG.rst +6 -0
- {oauthlib-3.3.0/oauthlib.egg-info → oauthlib-3.3.1}/PKG-INFO +1 -1
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/__init__.py +1 -1
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/parameters.py +5 -3
- {oauthlib-3.3.0 → oauthlib-3.3.1/oauthlib.egg-info}/PKG-INFO +1 -1
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib.egg-info/SOURCES.txt +0 -3
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib.egg-info/top_level.txt +0 -1
- {oauthlib-3.3.0 → oauthlib-3.3.1}/setup.py +1 -1
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_web_application.py +21 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/test_parameters.py +5 -0
- oauthlib-3.3.0/examples/device_code_flow.py +0 -260
- oauthlib-3.3.0/examples/skeleton_oauth2_web_application_server.py +0 -114
- oauthlib-3.3.0/tests/openid/connect/core/grant_types/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/LICENSE +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/MANIFEST.in +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/README.rst +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/common.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/access_token.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/authorization.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/base.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/pre_configured.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/request_token.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/resource.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/endpoints/signature_only.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/errors.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/parameters.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/request_validator.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/signature.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth1/rfc5849/utils.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/backend_application.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/base.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/legacy_application.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/mobile_application.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/service_application.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/clients/web_application.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/authorization.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/base.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/introspect.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/metadata.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/resource.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/revocation.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/endpoints/token.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/errors.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/base.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/implicit.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/request_validator.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/tokens.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc6749/utils.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/clients/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/clients/device.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/endpoints/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/endpoints/device_authorization.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/endpoints/pre_configured.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/errors.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/grant_types/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/grant_types/device_code.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/oauth2/rfc8628/request_validator.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/__init__.py +0 -0
- {oauthlib-3.3.0/examples → oauthlib-3.3.1/oauthlib/openid/connect}/__init__.py +0 -0
- {oauthlib-3.3.0/oauthlib/openid/connect → oauthlib-3.3.1/oauthlib/openid/connect/core}/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/endpoints/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/endpoints/pre_configured.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/endpoints/userinfo.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/exceptions.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/authorization_code.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/base.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/dispatchers.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/hybrid.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/implicit.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/refresh_token.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/request_validator.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/tokens.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/signals.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/uri_validate.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib.egg-info/dependency_links.txt +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib.egg-info/requires.txt +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/setup.cfg +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/__init__.py +0 -0
- {oauthlib-3.3.0/oauthlib/openid/connect/core → oauthlib-3.3.1/tests/oauth1}/__init__.py +0 -0
- {oauthlib-3.3.0/tests/oauth1 → oauthlib-3.3.1/tests/oauth1/rfc5849}/__init__.py +0 -0
- {oauthlib-3.3.0/tests/oauth1/rfc5849 → oauthlib-3.3.1/tests/oauth1/rfc5849/endpoints}/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_access_token.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_authorization.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_base.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_request_token.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_resource.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/endpoints/test_signature_only.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/test_client.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/test_parameters.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/test_request_validator.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/test_signatures.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth1/rfc5849/test_utils.py +0 -0
- {oauthlib-3.3.0/tests/oauth1/rfc5849/endpoints → oauthlib-3.3.1/tests/oauth2}/__init__.py +0 -0
- {oauthlib-3.3.0/tests/oauth2 → oauthlib-3.3.1/tests/oauth2/rfc6749}/__init__.py +0 -0
- {oauthlib-3.3.0/tests/oauth2/rfc6749 → oauthlib-3.3.1/tests/oauth2/rfc6749/clients}/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_backend_application.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_base.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_legacy_application.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_mobile_application.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/clients/test_service_application.py +0 -0
- {oauthlib-3.3.0/tests/oauth2/rfc6749/clients → oauthlib-3.3.1/tests/oauth2/rfc6749/endpoints}/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_base_endpoint.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_client_authentication.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_credentials_preservation.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_error_responses.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_extra_credentials.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_introspect_endpoint.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_metadata.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_resource_owner_association.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_revocation_endpoint.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_scope_handling.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_utils.py +0 -0
- {oauthlib-3.3.0/tests/oauth2/rfc6749/endpoints → oauthlib-3.3.1/tests/oauth2/rfc6749/grant_types}/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_authorization_code.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_client_credentials.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_implicit.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_refresh_token.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_resource_owner_password.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/test_request_validator.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/test_server.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/test_tokens.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/test_utils.py +0 -0
- {oauthlib-3.3.0/tests/oauth2/rfc6749/grant_types → oauthlib-3.3.1/tests/oauth2/rfc8628}/__init__.py +0 -0
- {oauthlib-3.3.0/tests/oauth2/rfc8628 → oauthlib-3.3.1/tests/oauth2/rfc8628/clients}/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc8628/clients/test_device.py +0 -0
- {oauthlib-3.3.0/tests/oauth2/rfc8628/clients → oauthlib-3.3.1/tests/oauth2/rfc8628/endpoints}/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc8628/endpoints/test_device_application_server.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc8628/endpoints/test_error_responses.py +0 -0
- {oauthlib-3.3.0/tests/oauth2/rfc8628/endpoints → oauthlib-3.3.1/tests/oauth2/rfc8628/grant_types}/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc8628/grant_types/test_device_code.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc8628/test_server.py +0 -0
- {oauthlib-3.3.0/tests/oauth2/rfc8628/grant_types → oauthlib-3.3.1/tests/openid}/__init__.py +0 -0
- {oauthlib-3.3.0/tests/openid → oauthlib-3.3.1/tests/openid/connect}/__init__.py +0 -0
- {oauthlib-3.3.0/tests/openid/connect → oauthlib-3.3.1/tests/openid/connect/core}/__init__.py +0 -0
- {oauthlib-3.3.0/tests/openid/connect/core → oauthlib-3.3.1/tests/openid/connect/core/endpoints}/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/endpoints/test_claims_handling.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/endpoints/test_openid_connect_params_handling.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/endpoints/test_refresh_token.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/endpoints/test_userinfo_endpoint.py +0 -0
- {oauthlib-3.3.0/tests/openid/connect/core/endpoints → oauthlib-3.3.1/tests/openid/connect/core/grant_types}/__init__.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_authorization_code.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_base.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_dispatchers.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_hybrid.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_implicit.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_refresh_token.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/test_request_validator.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/test_server.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/test_tokens.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/test_common.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/test_uri_validate.py +0 -0
- {oauthlib-3.3.0 → oauthlib-3.3.1}/tests/unittest/__init__.py +0 -0
|
@@ -476,7 +476,7 @@ def parse_expires(params):
|
|
|
476
476
|
"""Parse `expires_in`, `expires_at` fields from params
|
|
477
477
|
|
|
478
478
|
Parse following these rules:
|
|
479
|
-
- `expires_in` must be either
|
|
479
|
+
- `expires_in` must be either integer, float or None. If a float, it is converted into an integer.
|
|
480
480
|
- `expires_at` is not in specification so it does its best to:
|
|
481
481
|
- convert into a int, else
|
|
482
482
|
- convert into a float, else
|
|
@@ -495,14 +495,16 @@ def parse_expires(params):
|
|
|
495
495
|
if 'expires_in' in params:
|
|
496
496
|
if isinstance(params.get('expires_in'), int):
|
|
497
497
|
expires_in = params.get('expires_in')
|
|
498
|
+
elif isinstance(params.get('expires_in'), float):
|
|
499
|
+
expires_in = int(params.get('expires_in'))
|
|
498
500
|
elif isinstance(params.get('expires_in'), str):
|
|
499
501
|
try:
|
|
500
502
|
# Attempt to convert to int
|
|
501
503
|
expires_in = int(params.get('expires_in'))
|
|
502
504
|
except ValueError:
|
|
503
|
-
raise ValueError("
|
|
505
|
+
raise ValueError("expires_in must be an int")
|
|
504
506
|
elif params.get('expires_in') is not None:
|
|
505
|
-
raise ValueError("
|
|
507
|
+
raise ValueError("expires_in must be an int")
|
|
506
508
|
|
|
507
509
|
if 'expires_at' in params:
|
|
508
510
|
if isinstance(params.get('expires_at'), (float, int)):
|
|
@@ -33,7 +33,7 @@ setup(
|
|
|
33
33
|
url='https://github.com/oauthlib/oauthlib',
|
|
34
34
|
platforms='any',
|
|
35
35
|
license='BSD-3-Clause',
|
|
36
|
-
packages=find_packages(exclude=('docs', 'tests', 'tests.*')),
|
|
36
|
+
packages=find_packages(exclude=('docs', 'examples', 'tests', 'tests.*')),
|
|
37
37
|
python_requires='>=3.8',
|
|
38
38
|
extras_require={
|
|
39
39
|
'rsa': rsa_require,
|
|
@@ -262,3 +262,24 @@ class WebApplicationClientTest(TestCase):
|
|
|
262
262
|
with self.assertWarns(DeprecationWarning), self.assertRaises(ValueError):
|
|
263
263
|
client.prepare_request_body(client_id='different_client_id')
|
|
264
264
|
# testing the exact exception message in Python2&Python3 is a pain
|
|
265
|
+
|
|
266
|
+
def test_expires_in_as_str(self):
|
|
267
|
+
"""
|
|
268
|
+
see regression issue #906
|
|
269
|
+
"""
|
|
270
|
+
|
|
271
|
+
client = WebApplicationClient(
|
|
272
|
+
client_id="dummy",
|
|
273
|
+
token={"access_token": "xyz", "expires_in": "3600"}
|
|
274
|
+
)
|
|
275
|
+
self.assertIsNotNone(client)
|
|
276
|
+
client = WebApplicationClient(
|
|
277
|
+
client_id="dummy",
|
|
278
|
+
token={"access_token": "xyz", "expires_in": 3600}
|
|
279
|
+
)
|
|
280
|
+
self.assertIsNotNone(client)
|
|
281
|
+
client = WebApplicationClient(
|
|
282
|
+
client_id="dummy",
|
|
283
|
+
token={"access_token": "xyz", "expires_in": 3600.12}
|
|
284
|
+
)
|
|
285
|
+
self.assertIsNotNone(client)
|
|
@@ -312,6 +312,11 @@ class ParameterTests(TestCase):
|
|
|
312
312
|
('expires_in and expires_at float', (3600, 200.42), (3600, 200.42, 200.42)),
|
|
313
313
|
('expires_in and expires_at str-int', (3600, "200"), (3600, 200, 200)),
|
|
314
314
|
('expires_in and expires_at str-float', (3600, "200.42"), (3600, 200.42, 200.42)),
|
|
315
|
+
('expires_in float only', (3600.12, None), (3600, 4600, 4600)),
|
|
316
|
+
('expires_in float and expires_at', (3600.12, 200), (3600, 200, 200)),
|
|
317
|
+
('expires_in float and expires_at float', (3600.12, 200.42), (3600, 200.42, 200.42)),
|
|
318
|
+
('expires_in float and expires_at str-int', (3600.12, "200"), (3600, 200, 200)),
|
|
319
|
+
('expires_in float and expires_at str-float', (3600.12, "200.42"), (3600, 200.42, 200.42)),
|
|
315
320
|
('expires_in str only', ("3600", None), (3600, 4600, 4600)),
|
|
316
321
|
('expires_in str and expires_at', ("3600", 200), (3600, 200, 200)),
|
|
317
322
|
('expires_in str and expires_at float', ("3600", 200.42), (3600, 200.42, 200.42)),
|
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
import enum
|
|
2
|
-
import json
|
|
3
|
-
import datetime
|
|
4
|
-
from datetime import timedelta
|
|
5
|
-
|
|
6
|
-
from oauthlib.oauth2 import RequestValidator, Server, DeviceApplicationServer
|
|
7
|
-
from oauthlib.oauth2.rfc8628 import errors as device_flow_errors
|
|
8
|
-
from oauthlib.oauth2.rfc8628.errors import AccessDenied, AuthorizationPendingError, ExpiredTokenError, SlowDownError
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"""
|
|
12
|
-
A pseudocode implementation of the device flow code under an Oauth2 provider.
|
|
13
|
-
|
|
14
|
-
This example is not concerned with openid in any way.
|
|
15
|
-
|
|
16
|
-
This example is also not a 1:1 pseudocode implementation. Please refer to the rfc
|
|
17
|
-
for the full details.
|
|
18
|
-
https://datatracker.ietf.org/doc/html/rfc8628
|
|
19
|
-
|
|
20
|
-
This module is just acting as a way to demonstrate the main pieces
|
|
21
|
-
needed in oauthlib to implement the flow
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
We also assume you already have the /token & /login endpoint in your provider.
|
|
25
|
-
|
|
26
|
-
Your provider will also need the following endpoints(which will be discussed
|
|
27
|
-
in the example below):
|
|
28
|
-
- /device_authorization (part of rfc)
|
|
29
|
-
- /device (part of rfc)
|
|
30
|
-
- /approve-deny (up to your implementation, this is an example)
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"""
|
|
35
|
-
Device flow pseudocode implementation step by step:
|
|
36
|
-
0. Providing some way to represent the device flow session
|
|
37
|
-
|
|
38
|
-
Some python object to represent the current state of the device during
|
|
39
|
-
the device flow. This, for example, could be an object that persists
|
|
40
|
-
and represents the device in a database
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class Device:
|
|
45
|
-
class DeviceFlowStatus(enum.Enum):
|
|
46
|
-
AUTHORIZED = "Authorized"
|
|
47
|
-
AUTHORIZATION_PENDING = "Authorization_pending"
|
|
48
|
-
EXPIRED = "Expired"
|
|
49
|
-
DENIED = "Denied"
|
|
50
|
-
|
|
51
|
-
# https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
|
|
52
|
-
# https://datatracker.ietf.org/doc/html/rfc8628#section-3.4
|
|
53
|
-
id = ... # if Device is representing a database object, this will be the id of that row
|
|
54
|
-
device_code = ...
|
|
55
|
-
user_code = ...
|
|
56
|
-
scope = ...
|
|
57
|
-
interval = ... # in seconds, default is 5
|
|
58
|
-
expires = ... # seconds
|
|
59
|
-
status = ... # DeviceFlowStatus with AUTHORIZATION_PENDING as the default
|
|
60
|
-
|
|
61
|
-
client_id = ...
|
|
62
|
-
last_checked = ... # datetime
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"""
|
|
66
|
-
1. User goes on their device(client) and the client sends a request to /device_authorization
|
|
67
|
-
against the provider:
|
|
68
|
-
https://datatracker.ietf.org/doc/html/rfc8628#section-3.1
|
|
69
|
-
https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
POST /device_authorization HTTP/1.1
|
|
73
|
-
Host: server.example.com
|
|
74
|
-
Content-Type: application/x-www-form-urlencoded
|
|
75
|
-
|
|
76
|
-
client_id=1406020730&scope=example_scope
|
|
77
|
-
|
|
78
|
-
Response:
|
|
79
|
-
HTTP/1.1 200 OK
|
|
80
|
-
Content-Type: application/json
|
|
81
|
-
Cache-Control: no-store
|
|
82
|
-
|
|
83
|
-
{
|
|
84
|
-
"device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
|
|
85
|
-
"user_code": "WDJB-MJHT",
|
|
86
|
-
"verification_uri": "https://example.com/device",
|
|
87
|
-
"verification_uri_complete":
|
|
88
|
-
"https://example.com/device?user_code=WDJB-MJHT",
|
|
89
|
-
"expires_in": 1800,
|
|
90
|
-
"interval": 5
|
|
91
|
-
}
|
|
92
|
-
"""
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
class DeviceAuthorizationEndpoint:
|
|
96
|
-
@staticmethod
|
|
97
|
-
def create_device_authorization_response(request):
|
|
98
|
-
server = DeviceApplicationServer(interval=5, verification_uri="https://example.com/device")
|
|
99
|
-
return server.create_device_authorization_response(request)
|
|
100
|
-
|
|
101
|
-
def post(self, request):
|
|
102
|
-
headers, data, status = self.create_device_authorization_response(request)
|
|
103
|
-
device_response = ...
|
|
104
|
-
|
|
105
|
-
# Create an instance of examples.device_flow.Device` using `request` and `data`that encapsulates
|
|
106
|
-
# https://datatracker.ietf.org/doc/html/rfc8628#section-3.1 &
|
|
107
|
-
# https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
|
|
108
|
-
|
|
109
|
-
return device_response
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
"""
|
|
113
|
-
2. Client presents the information to the user
|
|
114
|
-
(There's a section on non visual capable devices as well
|
|
115
|
-
https://datatracker.ietf.org/doc/html/rfc8628#section-5.7)
|
|
116
|
-
+-------------------------------------------------+
|
|
117
|
-
| |
|
|
118
|
-
| Scan the QR code or, using +------------+ |
|
|
119
|
-
| a browser on another device, |[_].. . [_]| |
|
|
120
|
-
| visit: | . .. . .| |
|
|
121
|
-
| https://example.com/device | . . . ....| |
|
|
122
|
-
| |. . . . | |
|
|
123
|
-
| And enter the code: |[_]. ... . | |
|
|
124
|
-
| WDJB-MJHT +------------+ |
|
|
125
|
-
| |
|
|
126
|
-
+-------------------------------------------------+
|
|
127
|
-
"""
|
|
128
|
-
# The implementation for step 2 is up to the owner of device.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
""""
|
|
132
|
-
3 (The browser flow). User goes to https://example.com/device where they're presented with a
|
|
133
|
-
form to fill in the user code.
|
|
134
|
-
|
|
135
|
-
Implement that endpoint on your provider and follow the logic in the rfc.
|
|
136
|
-
|
|
137
|
-
Making use of the errors in `oauthlib.oauth2.rfc8628.errors`
|
|
138
|
-
|
|
139
|
-
raise AccessDenied/AuthorizationPendingError/ExpiredTokenError where appropriate making use of
|
|
140
|
-
`examples.device_flow.Device` to get and update current state of the device during the session
|
|
141
|
-
|
|
142
|
-
If the user isn't logged in(after inputting the user-code), they should be redirected to the provider's /login
|
|
143
|
-
endpoint and redirected back to an /approve-deny endpoint(The name and implementation of /approve-deny is up
|
|
144
|
-
to the owner of the provider, this is just an example).
|
|
145
|
-
They should then see an "approve" or "deny" button to authorize the device.
|
|
146
|
-
|
|
147
|
-
Again, using `examples.device_flow.Device` to update the status appropriately during the session.
|
|
148
|
-
"""
|
|
149
|
-
# /device and /approve-deny is up to the owner of the provider to implement. Again, make sure to
|
|
150
|
-
# keep referring to the rfc when implementing.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
"""
|
|
154
|
-
4 (The polling flow)
|
|
155
|
-
https://datatracker.ietf.org/doc/html/rfc8628#section-3.4
|
|
156
|
-
https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
Right after step 2, the device polls the /token endpoint every "interval" amount of seconds
|
|
160
|
-
to check if user has approved or denied the request.
|
|
161
|
-
|
|
162
|
-
When grant type is `urn:ietf:params:oauth:grant-type:device_code`,
|
|
163
|
-
`oauthlib.oauth2.rfc8628.grant_types.device_code.DeviceCodeGrant` will be the handler
|
|
164
|
-
that handles token generation.
|
|
165
|
-
"""
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
# This is purely for illustrative purposes
|
|
169
|
-
# to demonstrate rate limiting on the token endpoint for the device flow.
|
|
170
|
-
# It is up to as the provider to decide how you want
|
|
171
|
-
# to rate limit the device during polling.
|
|
172
|
-
def rate_limit(func, rate="1/5s"):
|
|
173
|
-
def wrapper():
|
|
174
|
-
# some logic to ensure client device is rate limited by a minimum
|
|
175
|
-
# of 1 request every 5 seconds during device polling
|
|
176
|
-
# https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
|
|
177
|
-
|
|
178
|
-
# use device_code to retrieve device
|
|
179
|
-
device = Device
|
|
180
|
-
|
|
181
|
-
# get the time in seconds since the device polled the /token endpoint
|
|
182
|
-
now = datetime.datetime.now(tz=datetime.UTC)
|
|
183
|
-
diff = now - timedelta(device.last_checked)
|
|
184
|
-
total_seconds_since_last_device_poll = diff.total_seconds()
|
|
185
|
-
|
|
186
|
-
device.last_checked = now
|
|
187
|
-
|
|
188
|
-
# for illustrative purposes. 1/5s means 1 request every 5 seconds.
|
|
189
|
-
# so if `total_seconds_since_last_device_poll` is 4 seconds, this will
|
|
190
|
-
# raise an error
|
|
191
|
-
if total_seconds_since_last_device_poll < rate:
|
|
192
|
-
raise device_flow_errors.SlowDownError()
|
|
193
|
-
|
|
194
|
-
result = func()
|
|
195
|
-
return result
|
|
196
|
-
|
|
197
|
-
return wrapper
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
class ExampleRequestValidator(RequestValidator):
|
|
201
|
-
# All the other methods that need to be implemented...
|
|
202
|
-
# see examples.skeleton_oauth2_web_application_server.SkeletonValidator
|
|
203
|
-
# for a more complete example.
|
|
204
|
-
|
|
205
|
-
# Here our main concern is this method:
|
|
206
|
-
def create_token_response(self): ...
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
class ServerSetupForTokenEndpoint:
|
|
210
|
-
def __init__(self):
|
|
211
|
-
validator = ExampleRequestValidator
|
|
212
|
-
self.server = Server(validator)
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
# You should already have the /token endpoint implemented in your provider.
|
|
216
|
-
class TokenEndpoint(ServerSetupForTokenEndpoint):
|
|
217
|
-
def default_flow_token_response(self, request):
|
|
218
|
-
url, headers, body, status = self.server.create_token_response(request)
|
|
219
|
-
access_token = json.loads(body).get("access_token")
|
|
220
|
-
|
|
221
|
-
# return access_token in a http response
|
|
222
|
-
return access_token
|
|
223
|
-
|
|
224
|
-
@rate_limit # this will raise the SlowDownError
|
|
225
|
-
def device_flow_token_response(self, request, device_code):
|
|
226
|
-
"""
|
|
227
|
-
Following the rfc, this will route the device request accordingly and raise
|
|
228
|
-
required errors.
|
|
229
|
-
|
|
230
|
-
Remember that unlike other auth flows, the device if polling this endpoint once
|
|
231
|
-
every "interval" amount of seconds.
|
|
232
|
-
"""
|
|
233
|
-
# using device_code arg to retrieve the correct device object instance
|
|
234
|
-
device = Device
|
|
235
|
-
|
|
236
|
-
if device.status == device.DeviceFlowStatus.AUTHORIZATION_PENDING:
|
|
237
|
-
raise AuthorizationPendingError()
|
|
238
|
-
|
|
239
|
-
# If user clicked "deny" in the /approve-deny page endpoint.
|
|
240
|
-
# the device gets set to 'authorized' in /approve-deny and /device checks
|
|
241
|
-
# if someone tries to input a code for a user code that's already been authorized
|
|
242
|
-
if device.status == device.DeviceFlowStatus.DENIED:
|
|
243
|
-
raise AccessDenied()
|
|
244
|
-
|
|
245
|
-
url, headers, body, status = self.server.create_token_response(request)
|
|
246
|
-
|
|
247
|
-
access_token = json.loads(body).get("access_token")
|
|
248
|
-
|
|
249
|
-
device.status = device.EXPIRED
|
|
250
|
-
|
|
251
|
-
# return access_token in a http response
|
|
252
|
-
return access_token
|
|
253
|
-
|
|
254
|
-
# Example of how token endpoint could handle the token creation depending on
|
|
255
|
-
# the grant type during a POST to /token.
|
|
256
|
-
def post(self, request):
|
|
257
|
-
params = request.POST
|
|
258
|
-
if params.get("grant_type") == "urn:ietf:params:oauth:grant-type:device_code":
|
|
259
|
-
return self.device_flow_token_response(request, params["device_code"])
|
|
260
|
-
return self.default_flow_token_response(request)
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# Skeleton for an OAuth 2 Web Application Server which is an OAuth
|
|
2
|
-
# provider configured for Authorization Code, Refresh Token grants and
|
|
3
|
-
# for dispensing Bearer Tokens.
|
|
4
|
-
|
|
5
|
-
# This example is meant to act as a supplement to the documentation,
|
|
6
|
-
# see https://oauthlib.readthedocs.io/en/latest/.
|
|
7
|
-
|
|
8
|
-
from oauthlib.oauth2 import RequestValidator, WebApplicationServer
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class SkeletonValidator(RequestValidator):
|
|
12
|
-
|
|
13
|
-
# Ordered roughly in order of appearance in the authorization grant flow
|
|
14
|
-
|
|
15
|
-
# Pre- and post-authorization.
|
|
16
|
-
|
|
17
|
-
def validate_client_id(self, client_id, request, *args, **kwargs):
|
|
18
|
-
# Simple validity check, does client exist? Not banned?
|
|
19
|
-
pass
|
|
20
|
-
|
|
21
|
-
def validate_redirect_uri(self, client_id, redirect_uri, request, *args, **kwargs):
|
|
22
|
-
# Is the client allowed to use the supplied redirect_uri? i.e. has
|
|
23
|
-
# the client previously registered this EXACT redirect uri.
|
|
24
|
-
pass
|
|
25
|
-
|
|
26
|
-
def get_default_redirect_uri(self, client_id, request, *args, **kwargs):
|
|
27
|
-
# The redirect used if none has been supplied.
|
|
28
|
-
# Prefer your clients to pre register a redirect uri rather than
|
|
29
|
-
# supplying one on each authorization request.
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
def validate_scopes(self, client_id, scopes, client, request, *args, **kwargs):
|
|
33
|
-
# Is the client allowed to access the requested scopes?
|
|
34
|
-
pass
|
|
35
|
-
|
|
36
|
-
def get_default_scopes(self, client_id, request, *args, **kwargs):
|
|
37
|
-
# Scopes a client will authorize for if none are supplied in the
|
|
38
|
-
# authorization request.
|
|
39
|
-
pass
|
|
40
|
-
|
|
41
|
-
def validate_response_type(self, client_id, response_type, client, request, *args, **kwargs):
|
|
42
|
-
# Clients should only be allowed to use one type of response type, the
|
|
43
|
-
# one associated with their one allowed grant type.
|
|
44
|
-
# In this case it must be "code".
|
|
45
|
-
pass
|
|
46
|
-
|
|
47
|
-
# Post-authorization
|
|
48
|
-
|
|
49
|
-
def save_authorization_code(self, client_id, code, request, *args, **kwargs):
|
|
50
|
-
# Remember to associate it with request.scopes, request.redirect_uri
|
|
51
|
-
# request.client and request.user (the last is passed in
|
|
52
|
-
# post_authorization credentials, i.e. { 'user': request.user}.
|
|
53
|
-
pass
|
|
54
|
-
|
|
55
|
-
# Token request
|
|
56
|
-
|
|
57
|
-
def client_authentication_required(self, request, *args, **kwargs):
|
|
58
|
-
# Check if the client provided authentication information that needs to
|
|
59
|
-
# be validated, e.g. HTTP Basic auth
|
|
60
|
-
pass
|
|
61
|
-
|
|
62
|
-
def authenticate_client(self, request, *args, **kwargs):
|
|
63
|
-
# Whichever authentication method suits you, HTTP Basic might work
|
|
64
|
-
pass
|
|
65
|
-
|
|
66
|
-
def authenticate_client_id(self, client_id, request, *args, **kwargs):
|
|
67
|
-
# The client_id must match an existing public (non-confidential) client
|
|
68
|
-
pass
|
|
69
|
-
|
|
70
|
-
def validate_code(self, client_id, code, client, request, *args, **kwargs):
|
|
71
|
-
# Validate the code belongs to the client. Add associated scopes
|
|
72
|
-
# and user to request.scopes and request.user.
|
|
73
|
-
pass
|
|
74
|
-
|
|
75
|
-
def confirm_redirect_uri(self, client_id, code, redirect_uri, client, request, *args, **kwargs):
|
|
76
|
-
# You did save the redirect uri with the authorization code right?
|
|
77
|
-
pass
|
|
78
|
-
|
|
79
|
-
def validate_grant_type(self, client_id, grant_type, client, request, *args, **kwargs):
|
|
80
|
-
# Clients should only be allowed to use one type of grant.
|
|
81
|
-
# In this case, it must be "authorization_code" or "refresh_token"
|
|
82
|
-
pass
|
|
83
|
-
|
|
84
|
-
def save_bearer_token(self, token, request, *args, **kwargs):
|
|
85
|
-
# Remember to associate it with request.scopes, request.user and
|
|
86
|
-
# request.client. The two former will be set when you validate
|
|
87
|
-
# the authorization code. Don't forget to save both the
|
|
88
|
-
# access_token and the refresh_token and set expiration for the
|
|
89
|
-
# access_token to now + expires_in seconds.
|
|
90
|
-
pass
|
|
91
|
-
|
|
92
|
-
def invalidate_authorization_code(self, client_id, code, request, *args, **kwargs):
|
|
93
|
-
# Authorization codes are use once, invalidate it when a Bearer token
|
|
94
|
-
# has been acquired.
|
|
95
|
-
pass
|
|
96
|
-
|
|
97
|
-
# Protected resource request
|
|
98
|
-
|
|
99
|
-
def validate_bearer_token(self, token, scopes, request):
|
|
100
|
-
# Remember to check expiration and scope membership
|
|
101
|
-
pass
|
|
102
|
-
|
|
103
|
-
# Token refresh request
|
|
104
|
-
|
|
105
|
-
def get_original_scopes(self, refresh_token, request, *args, **kwargs):
|
|
106
|
-
# Obtain the token associated with the given refresh_token and
|
|
107
|
-
# return its scopes, these will be passed on to the refreshed
|
|
108
|
-
# access token if the client did not specify a scope during the
|
|
109
|
-
# request.
|
|
110
|
-
pass
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
validator = SkeletonValidator()
|
|
114
|
-
server = WebApplicationServer(validator)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0/oauthlib/openid/connect → oauthlib-3.3.1/oauthlib/openid/connect/core}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/oauthlib/openid/connect/core/grant_types/authorization_code.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0/tests/oauth1/rfc5849 → oauthlib-3.3.1/tests/oauth1/rfc5849/endpoints}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0/tests/oauth2/rfc6749 → oauthlib-3.3.1/tests/oauth2/rfc6749/clients}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_client_authentication.py
RENAMED
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_credentials_preservation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_introspect_endpoint.py
RENAMED
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_resource_owner_association.py
RENAMED
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/endpoints/test_revocation_endpoint.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_authorization_code.py
RENAMED
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_client_credentials.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc6749/grant_types/test_resource_owner_password.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0/tests/oauth2/rfc6749/grant_types → oauthlib-3.3.1/tests/oauth2/rfc8628}/__init__.py
RENAMED
|
File without changes
|
{oauthlib-3.3.0/tests/oauth2/rfc8628 → oauthlib-3.3.1/tests/oauth2/rfc8628/clients}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/oauth2/rfc8628/endpoints/test_device_application_server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0/tests/openid/connect → oauthlib-3.3.1/tests/openid/connect/core}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/endpoints/test_claims_handling.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/endpoints/test_userinfo_endpoint.py
RENAMED
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_authorization_code.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oauthlib-3.3.0 → oauthlib-3.3.1}/tests/openid/connect/core/grant_types/test_refresh_token.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|