mirror of
https://github.com/rembo10/headphones.git
synced 2026-05-13 15:19:29 +01:00
update requests_oauthlib
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
# ruff: noqa: F401
|
||||
import logging
|
||||
|
||||
from .oauth1_auth import OAuth1
|
||||
@@ -5,7 +6,7 @@ from .oauth1_session import OAuth1Session
|
||||
from .oauth2_auth import OAuth2
|
||||
from .oauth2_session import OAuth2Session, TokenUpdated
|
||||
|
||||
__version__ = "1.3.0"
|
||||
__version__ = "2.0.0"
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
# ruff: noqa: F401
|
||||
from .facebook import facebook_compliance_fix
|
||||
from .fitbit import fitbit_compliance_fix
|
||||
from .linkedin import linkedin_compliance_fix
|
||||
from .slack import slack_compliance_fix
|
||||
from .instagram import instagram_compliance_fix
|
||||
from .mailchimp import mailchimp_compliance_fix
|
||||
from .weibo import weibo_compliance_fix
|
||||
from .plentymarkets import plentymarkets_compliance_fix
|
||||
from .ebay import ebay_compliance_fix
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import json
|
||||
|
||||
from oauthlib.common import to_unicode
|
||||
|
||||
|
||||
def douban_compliance_fix(session):
|
||||
def fix_token_type(r):
|
||||
token = json.loads(r.text)
|
||||
token.setdefault("token_type", "Bearer")
|
||||
fixed_token = json.dumps(token)
|
||||
r._content = to_unicode(fixed_token).encode("utf-8")
|
||||
r._content = fixed_token.encode()
|
||||
return r
|
||||
|
||||
session._client_default_token_placement = "query"
|
||||
|
||||
22
lib/requests_oauthlib/compliance_fixes/ebay.py
Normal file
22
lib/requests_oauthlib/compliance_fixes/ebay.py
Normal file
@@ -0,0 +1,22 @@
|
||||
import json
|
||||
|
||||
|
||||
def ebay_compliance_fix(session):
|
||||
def _compliance_fix(response):
|
||||
token = json.loads(response.text)
|
||||
|
||||
# eBay responds with non-compliant token types.
|
||||
# https://developer.ebay.com/api-docs/static/oauth-client-credentials-grant.html
|
||||
# https://developer.ebay.com/api-docs/static/oauth-auth-code-grant-request.html
|
||||
# Modify these to be "Bearer".
|
||||
if token.get("token_type") in ["Application Access Token", "User Access Token"]:
|
||||
token["token_type"] = "Bearer"
|
||||
fixed_token = json.dumps(token)
|
||||
response._content = fixed_token.encode()
|
||||
|
||||
return response
|
||||
|
||||
session.register_compliance_hook("access_token_response", _compliance_fix)
|
||||
session.register_compliance_hook("refresh_token_response", _compliance_fix)
|
||||
|
||||
return session
|
||||
@@ -1,11 +1,5 @@
|
||||
from json import dumps
|
||||
|
||||
try:
|
||||
from urlparse import parse_qsl
|
||||
except ImportError:
|
||||
from urllib.parse import parse_qsl
|
||||
|
||||
from oauthlib.common import to_unicode
|
||||
from urllib.parse import parse_qsl
|
||||
|
||||
|
||||
def facebook_compliance_fix(session):
|
||||
@@ -26,7 +20,7 @@ def facebook_compliance_fix(session):
|
||||
if expires is not None:
|
||||
token["expires_in"] = expires
|
||||
token["token_type"] = "Bearer"
|
||||
r._content = to_unicode(dumps(token)).encode("UTF-8")
|
||||
r._content = dumps(token).encode()
|
||||
return r
|
||||
|
||||
session.register_compliance_hook("access_token_response", _compliance_fix)
|
||||
|
||||
@@ -8,8 +8,6 @@ MissingTokenError.
|
||||
|
||||
from json import loads, dumps
|
||||
|
||||
from oauthlib.common import to_unicode
|
||||
|
||||
|
||||
def fitbit_compliance_fix(session):
|
||||
def _missing_error(r):
|
||||
@@ -17,7 +15,7 @@ def fitbit_compliance_fix(session):
|
||||
if "errors" in token:
|
||||
# Set the error to the first one we have
|
||||
token["error"] = token["errors"][0]["errorType"]
|
||||
r._content = to_unicode(dumps(token)).encode("UTF-8")
|
||||
r._content = dumps(token).encode()
|
||||
return r
|
||||
|
||||
session.register_compliance_hook("access_token_response", _missing_error)
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
try:
|
||||
from urlparse import urlparse, parse_qs
|
||||
except ImportError:
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
|
||||
from oauthlib.common import add_params_to_uri
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
from json import loads, dumps
|
||||
|
||||
from oauthlib.common import add_params_to_uri, to_unicode
|
||||
|
||||
|
||||
def linkedin_compliance_fix(session):
|
||||
def _missing_token_type(r):
|
||||
token = loads(r.text)
|
||||
token["token_type"] = "Bearer"
|
||||
r._content = to_unicode(dumps(token)).encode("UTF-8")
|
||||
return r
|
||||
|
||||
def _non_compliant_param_name(url, headers, data):
|
||||
token = [("oauth2_access_token", session.access_token)]
|
||||
url = add_params_to_uri(url, token)
|
||||
return url, headers, data
|
||||
|
||||
session._client.default_token_placement = "query"
|
||||
session.register_compliance_hook("access_token_response", _missing_token_type)
|
||||
session.register_compliance_hook("protected_request", _non_compliant_param_name)
|
||||
return session
|
||||
@@ -1,21 +1,19 @@
|
||||
import json
|
||||
|
||||
from oauthlib.common import to_unicode
|
||||
|
||||
|
||||
def mailchimp_compliance_fix(session):
|
||||
def _null_scope(r):
|
||||
token = json.loads(r.text)
|
||||
if "scope" in token and token["scope"] is None:
|
||||
token.pop("scope")
|
||||
r._content = to_unicode(json.dumps(token)).encode("utf-8")
|
||||
r._content = json.dumps(token).encode()
|
||||
return r
|
||||
|
||||
def _non_zero_expiration(r):
|
||||
token = json.loads(r.text)
|
||||
if "expires_in" in token and token["expires_in"] == 0:
|
||||
token["expires_in"] = 3600
|
||||
r._content = to_unicode(json.dumps(token)).encode("utf-8")
|
||||
r._content = json.dumps(token).encode()
|
||||
return r
|
||||
|
||||
session.register_compliance_hook("access_token_response", _null_scope)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
from json import dumps, loads
|
||||
import re
|
||||
|
||||
from oauthlib.common import to_unicode
|
||||
|
||||
|
||||
def plentymarkets_compliance_fix(session):
|
||||
def _to_snake_case(n):
|
||||
@@ -22,7 +20,7 @@ def plentymarkets_compliance_fix(session):
|
||||
for k, v in token.items():
|
||||
fixed_token[_to_snake_case(k)] = v
|
||||
|
||||
r._content = to_unicode(dumps(fixed_token)).encode("UTF-8")
|
||||
r._content = dumps(fixed_token).encode()
|
||||
return r
|
||||
|
||||
session.register_compliance_hook("access_token_response", _compliance_fix)
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
try:
|
||||
from urlparse import urlparse, parse_qs
|
||||
except ImportError:
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
|
||||
from oauthlib.common import add_params_to_uri
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
from json import loads, dumps
|
||||
|
||||
from oauthlib.common import to_unicode
|
||||
|
||||
|
||||
def weibo_compliance_fix(session):
|
||||
def _missing_token_type(r):
|
||||
token = loads(r.text)
|
||||
token["token_type"] = "Bearer"
|
||||
r._content = to_unicode(dumps(token)).encode("UTF-8")
|
||||
r._content = dumps(token).encode()
|
||||
return r
|
||||
|
||||
session._client.default_token_placement = "query"
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from oauthlib.common import extract_params
|
||||
from oauthlib.oauth1 import Client, SIGNATURE_HMAC, SIGNATURE_TYPE_AUTH_HEADER
|
||||
from oauthlib.oauth1 import SIGNATURE_TYPE_BODY
|
||||
from requests.compat import is_py3
|
||||
from requests.utils import to_native_string
|
||||
from requests.auth import AuthBase
|
||||
|
||||
CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded"
|
||||
CONTENT_TYPE_MULTI_PART = "multipart/form-data"
|
||||
|
||||
if is_py3:
|
||||
unicode = str
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -83,7 +78,7 @@ class OAuth1(AuthBase):
|
||||
or self.client.signature_type == SIGNATURE_TYPE_BODY
|
||||
):
|
||||
content_type = CONTENT_TYPE_FORM_URLENCODED
|
||||
if not isinstance(content_type, unicode):
|
||||
if not isinstance(content_type, str):
|
||||
content_type = content_type.decode("utf-8")
|
||||
|
||||
is_form_encoded = CONTENT_TYPE_FORM_URLENCODED in content_type
|
||||
@@ -96,17 +91,17 @@ class OAuth1(AuthBase):
|
||||
if is_form_encoded:
|
||||
r.headers["Content-Type"] = CONTENT_TYPE_FORM_URLENCODED
|
||||
r.url, headers, r.body = self.client.sign(
|
||||
unicode(r.url), unicode(r.method), r.body or "", r.headers
|
||||
str(r.url), str(r.method), r.body or "", r.headers
|
||||
)
|
||||
elif self.force_include_body:
|
||||
# To allow custom clients to work on non form encoded bodies.
|
||||
r.url, headers, r.body = self.client.sign(
|
||||
unicode(r.url), unicode(r.method), r.body or "", r.headers
|
||||
str(r.url), str(r.method), r.body or "", r.headers
|
||||
)
|
||||
else:
|
||||
# Omit body data in the signing of non form-encoded requests
|
||||
r.url, headers, _ = self.client.sign(
|
||||
unicode(r.url), unicode(r.method), None, r.headers
|
||||
str(r.url), str(r.method), None, r.headers
|
||||
)
|
||||
|
||||
r.prepare_headers(headers)
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
try:
|
||||
from urlparse import urlparse
|
||||
except ImportError:
|
||||
from urllib.parse import urlparse
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import logging
|
||||
|
||||
@@ -85,7 +80,7 @@ class OAuth1Session(requests.Session):
|
||||
'https://api.twitter.com/oauth/authorize?oauth_token=sdf0o9823sjdfsdf&oauth_callback=https%3A%2F%2F127.0.0.1%2Fcallback'
|
||||
>>>
|
||||
>>> # Third step. Fetch the access token
|
||||
>>> redirect_response = raw_input('Paste the full redirect URL here.')
|
||||
>>> redirect_response = input('Paste the full redirect URL here.')
|
||||
>>> oauth_session.parse_authorization_response(redirect_response)
|
||||
{
|
||||
'oauth_token: 'kjerht2309u',
|
||||
@@ -258,7 +253,7 @@ class OAuth1Session(requests.Session):
|
||||
return add_params_to_uri(url, kwargs.items())
|
||||
|
||||
def fetch_request_token(self, url, realm=None, **request_kwargs):
|
||||
r"""Fetch a request token.
|
||||
"""Fetch a request token.
|
||||
|
||||
This is the first step in the OAuth 1 workflow. A request token is
|
||||
obtained by making a signed post request to url. The token is then
|
||||
@@ -267,8 +262,8 @@ class OAuth1Session(requests.Session):
|
||||
|
||||
:param url: The request token endpoint URL.
|
||||
:param realm: A list of realms to request access to.
|
||||
:param \*\*request_kwargs: Optional arguments passed to ''post''
|
||||
function in ''requests.Session''
|
||||
:param request_kwargs: Optional arguments passed to ''post''
|
||||
function in ''requests.Session''
|
||||
:returns: The response in dict format.
|
||||
|
||||
Note that a previously set callback_uri will be reset for your
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from __future__ import unicode_literals
|
||||
from oauthlib.oauth2 import WebApplicationClient, InsecureTransportError
|
||||
from oauthlib.oauth2 import is_secure_transport
|
||||
from requests.auth import AuthBase
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from oauthlib.common import generate_token, urldecode
|
||||
@@ -46,6 +44,7 @@ class OAuth2Session(requests.Session):
|
||||
token=None,
|
||||
state=None,
|
||||
token_updater=None,
|
||||
pkce=None,
|
||||
**kwargs
|
||||
):
|
||||
"""Construct a new OAuth 2 client session.
|
||||
@@ -72,18 +71,23 @@ class OAuth2Session(requests.Session):
|
||||
set a TokenUpdated warning will be raised when a token
|
||||
has been refreshed. This warning will carry the token
|
||||
in its token argument.
|
||||
:param pkce: Set "S256" or "plain" to enable PKCE. Default is disabled.
|
||||
:param kwargs: Arguments to pass to the Session constructor.
|
||||
"""
|
||||
super(OAuth2Session, self).__init__(**kwargs)
|
||||
self._client = client or WebApplicationClient(client_id, token=token)
|
||||
self.token = token or {}
|
||||
self.scope = scope
|
||||
self._scope = scope
|
||||
self.redirect_uri = redirect_uri
|
||||
self.state = state or generate_token
|
||||
self._state = state
|
||||
self.auto_refresh_url = auto_refresh_url
|
||||
self.auto_refresh_kwargs = auto_refresh_kwargs or {}
|
||||
self.token_updater = token_updater
|
||||
self._pkce = pkce
|
||||
|
||||
if self._pkce not in ["S256", "plain", None]:
|
||||
raise AttributeError("Wrong value for {}(.., pkce={})".format(self.__class__, self._pkce))
|
||||
|
||||
# Ensure that requests doesn't do any automatic auth. See #278.
|
||||
# The default behavior can be re-enabled by setting auth to None.
|
||||
@@ -95,8 +99,24 @@ class OAuth2Session(requests.Session):
|
||||
"access_token_response": set(),
|
||||
"refresh_token_response": set(),
|
||||
"protected_request": set(),
|
||||
"refresh_token_request": set(),
|
||||
"access_token_request": set(),
|
||||
}
|
||||
|
||||
@property
|
||||
def scope(self):
|
||||
"""By default the scope from the client is used, except if overridden"""
|
||||
if self._scope is not None:
|
||||
return self._scope
|
||||
elif self._client is not None:
|
||||
return self._client.scope
|
||||
else:
|
||||
return None
|
||||
|
||||
@scope.setter
|
||||
def scope(self, scope):
|
||||
self._scope = scope
|
||||
|
||||
def new_state(self):
|
||||
"""Generates a state string to be used in authorizations."""
|
||||
try:
|
||||
@@ -161,6 +181,13 @@ class OAuth2Session(requests.Session):
|
||||
:return: authorization_url, state
|
||||
"""
|
||||
state = state or self.new_state()
|
||||
if self._pkce:
|
||||
self._code_verifier = self._client.create_code_verifier(43)
|
||||
kwargs["code_challenge_method"] = self._pkce
|
||||
kwargs["code_challenge"] = self._client.create_code_challenge(
|
||||
code_verifier=self._code_verifier,
|
||||
code_challenge_method=self._pkce
|
||||
)
|
||||
return (
|
||||
self._client.prepare_request_uri(
|
||||
url,
|
||||
@@ -185,10 +212,11 @@ class OAuth2Session(requests.Session):
|
||||
force_querystring=False,
|
||||
timeout=None,
|
||||
headers=None,
|
||||
verify=True,
|
||||
verify=None,
|
||||
proxies=None,
|
||||
include_client_id=None,
|
||||
client_secret=None,
|
||||
cert=None,
|
||||
**kwargs
|
||||
):
|
||||
"""Generic method for fetching an access token from the token endpoint.
|
||||
@@ -229,6 +257,10 @@ class OAuth2Session(requests.Session):
|
||||
`auth` tuple. If the value is `None`, it will be
|
||||
omitted from the request, however if the value is
|
||||
an empty string, an empty string will be sent.
|
||||
:param cert: Client certificate to send for OAuth 2.0 Mutual-TLS Client
|
||||
Authentication (draft-ietf-oauth-mtls). Can either be the
|
||||
path of a file containing the private key and certificate or
|
||||
a tuple of two filenames for certificate and key.
|
||||
:param kwargs: Extra parameters to include in the token request.
|
||||
:return: A token dict
|
||||
"""
|
||||
@@ -247,6 +279,13 @@ class OAuth2Session(requests.Session):
|
||||
"Please supply either code or " "authorization_response parameters."
|
||||
)
|
||||
|
||||
if self._pkce:
|
||||
if self._code_verifier is None:
|
||||
raise ValueError(
|
||||
"Code verifier is not found, authorization URL must be generated before"
|
||||
)
|
||||
kwargs["code_verifier"] = self._code_verifier
|
||||
|
||||
# Earlier versions of this library build an HTTPBasicAuth header out of
|
||||
# `username` and `password`. The RFC states, however these attributes
|
||||
# must be in the request body and not the header.
|
||||
@@ -320,7 +359,7 @@ class OAuth2Session(requests.Session):
|
||||
|
||||
headers = headers or {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
}
|
||||
self.token = {}
|
||||
request_kwargs = {}
|
||||
@@ -333,6 +372,12 @@ class OAuth2Session(requests.Session):
|
||||
else:
|
||||
raise ValueError("The method kwarg must be POST or GET.")
|
||||
|
||||
for hook in self.compliance_hook["access_token_request"]:
|
||||
log.debug("Invoking access_token_request hook %s.", hook)
|
||||
token_url, headers, request_kwargs = hook(
|
||||
token_url, headers, request_kwargs
|
||||
)
|
||||
|
||||
r = self.request(
|
||||
method=method,
|
||||
url=token_url,
|
||||
@@ -341,6 +386,7 @@ class OAuth2Session(requests.Session):
|
||||
auth=auth,
|
||||
verify=verify,
|
||||
proxies=proxies,
|
||||
cert=cert,
|
||||
**request_kwargs
|
||||
)
|
||||
|
||||
@@ -382,7 +428,7 @@ class OAuth2Session(requests.Session):
|
||||
auth=None,
|
||||
timeout=None,
|
||||
headers=None,
|
||||
verify=True,
|
||||
verify=None,
|
||||
proxies=None,
|
||||
**kwargs
|
||||
):
|
||||
@@ -420,9 +466,13 @@ class OAuth2Session(requests.Session):
|
||||
if headers is None:
|
||||
headers = {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": ("application/x-www-form-urlencoded;charset=UTF-8"),
|
||||
"Content-Type": ("application/x-www-form-urlencoded"),
|
||||
}
|
||||
|
||||
for hook in self.compliance_hook["refresh_token_request"]:
|
||||
log.debug("Invoking refresh_token_request hook %s.", hook)
|
||||
token_url, headers, body = hook(token_url, headers, body)
|
||||
|
||||
r = self.post(
|
||||
token_url,
|
||||
data=dict(urldecode(body)),
|
||||
@@ -444,7 +494,7 @@ class OAuth2Session(requests.Session):
|
||||
r = hook(r)
|
||||
|
||||
self.token = self._client.parse_request_body_response(r.text, scope=self.scope)
|
||||
if not "refresh_token" in self.token:
|
||||
if "refresh_token" not in self.token:
|
||||
log.debug("No new refresh token given. Re-using old.")
|
||||
self.token["refresh_token"] = refresh_token
|
||||
return self.token
|
||||
@@ -458,6 +508,7 @@ class OAuth2Session(requests.Session):
|
||||
withhold_token=False,
|
||||
client_id=None,
|
||||
client_secret=None,
|
||||
files=None,
|
||||
**kwargs
|
||||
):
|
||||
"""Intercept all requests and add the OAuth 2 token if present."""
|
||||
@@ -513,7 +564,7 @@ class OAuth2Session(requests.Session):
|
||||
log.debug("Supplying headers %s and data %s", headers, data)
|
||||
log.debug("Passing through key word arguments %s.", kwargs)
|
||||
return super(OAuth2Session, self).request(
|
||||
method, url, headers=headers, data=data, **kwargs
|
||||
method, url, headers=headers, data=data, files=files, **kwargs
|
||||
)
|
||||
|
||||
def register_compliance_hook(self, hook_type, hook):
|
||||
@@ -523,6 +574,8 @@ class OAuth2Session(requests.Session):
|
||||
access_token_response invoked before token parsing.
|
||||
refresh_token_response invoked before refresh token parsing.
|
||||
protected_request invoked before making a request.
|
||||
access_token_request invoked before making a token fetch request.
|
||||
refresh_token_request invoked before making a refresh request.
|
||||
|
||||
If you find a new hook is needed please send a GitHub PR request
|
||||
or open an issue.
|
||||
|
||||
Reference in New Issue
Block a user