diff options
Diffstat (limited to '.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes')
10 files changed, 214 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/__init__.py b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/__init__.py new file mode 100644 index 00000000..8815ea0b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/__init__.py @@ -0,0 +1,9 @@ +# ruff: noqa: F401 +from .facebook import facebook_compliance_fix +from .fitbit import fitbit_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 diff --git a/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/douban.py b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/douban.py new file mode 100644 index 00000000..c8b99c72 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/douban.py @@ -0,0 +1,15 @@ +import json + + +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 = fixed_token.encode() + return r + + session._client_default_token_placement = "query" + session.register_compliance_hook("access_token_response", fix_token_type) + + return session diff --git a/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/ebay.py b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/ebay.py new file mode 100644 index 00000000..ef33f391 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/ebay.py @@ -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 diff --git a/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/facebook.py b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/facebook.py new file mode 100644 index 00000000..f44558a8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/facebook.py @@ -0,0 +1,27 @@ +from json import dumps +from urllib.parse import parse_qsl + + +def facebook_compliance_fix(session): + def _compliance_fix(r): + # if Facebook claims to be sending us json, let's trust them. + if "application/json" in r.headers.get("content-type", {}): + return r + + # Facebook returns a content-type of text/plain when sending their + # x-www-form-urlencoded responses, along with a 200. If not, let's + # assume we're getting JSON and bail on the fix. + if "text/plain" in r.headers.get("content-type", {}) and r.status_code == 200: + token = dict(parse_qsl(r.text, keep_blank_values=True)) + else: + return r + + expires = token.get("expires") + if expires is not None: + token["expires_in"] = expires + token["token_type"] = "Bearer" + r._content = dumps(token).encode() + return r + + session.register_compliance_hook("access_token_response", _compliance_fix) + return session diff --git a/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/fitbit.py b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/fitbit.py new file mode 100644 index 00000000..aacc68bf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/fitbit.py @@ -0,0 +1,23 @@ +""" +The Fitbit API breaks from the OAuth2 RFC standard by returning an "errors" +object list, rather than a single "error" string. This puts hooks in place so +that oauthlib can process an error in the results from access token and refresh +token responses. This is necessary to prevent getting the generic red herring +MissingTokenError. +""" + +from json import loads, dumps + + +def fitbit_compliance_fix(session): + def _missing_error(r): + token = loads(r.text) + if "errors" in token: + # Set the error to the first one we have + token["error"] = token["errors"][0]["errorType"] + r._content = dumps(token).encode() + return r + + session.register_compliance_hook("access_token_response", _missing_error) + session.register_compliance_hook("refresh_token_response", _missing_error) + return session diff --git a/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/instagram.py b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/instagram.py new file mode 100644 index 00000000..7d5a2ad4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/instagram.py @@ -0,0 +1,23 @@ +from urllib.parse import urlparse, parse_qs + +from oauthlib.common import add_params_to_uri + + +def instagram_compliance_fix(session): + def _non_compliant_param_name(url, headers, data): + # If the user has already specified the token in the URL + # then there's nothing to do. + # If the specified token is different from ``session.access_token``, + # we assume the user intends to override the access token. + url_query = dict(parse_qs(urlparse(url).query)) + token = url_query.get("access_token") + if token: + # Nothing to do, just return. + return url, headers, data + + token = [("access_token", session.access_token)] + url = add_params_to_uri(url, token) + return url, headers, data + + session.register_compliance_hook("protected_request", _non_compliant_param_name) + return session diff --git a/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/mailchimp.py b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/mailchimp.py new file mode 100644 index 00000000..0d602659 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/mailchimp.py @@ -0,0 +1,21 @@ +import json + + +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 = 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 = json.dumps(token).encode() + return r + + session.register_compliance_hook("access_token_response", _null_scope) + session.register_compliance_hook("access_token_response", _non_zero_expiration) + return session diff --git a/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/plentymarkets.py b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/plentymarkets.py new file mode 100644 index 00000000..859f0566 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/plentymarkets.py @@ -0,0 +1,27 @@ +from json import dumps, loads +import re + + +def plentymarkets_compliance_fix(session): + def _to_snake_case(n): + return re.sub("(.)([A-Z][a-z]+)", r"\1_\2", n).lower() + + def _compliance_fix(r): + # Plenty returns the Token in CamelCase instead of _ + if ( + "application/json" in r.headers.get("content-type", {}) + and r.status_code == 200 + ): + token = loads(r.text) + else: + return r + + fixed_token = {} + for k, v in token.items(): + fixed_token[_to_snake_case(k)] = v + + r._content = dumps(fixed_token).encode() + return r + + session.register_compliance_hook("access_token_response", _compliance_fix) + return session diff --git a/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/slack.py b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/slack.py new file mode 100644 index 00000000..9095a470 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/slack.py @@ -0,0 +1,34 @@ +from urllib.parse import urlparse, parse_qs + +from oauthlib.common import add_params_to_uri + + +def slack_compliance_fix(session): + def _non_compliant_param_name(url, headers, data): + # If the user has already specified the token, either in the URL + # or in a data dictionary, then there's nothing to do. + # If the specified token is different from ``session.access_token``, + # we assume the user intends to override the access token. + url_query = dict(parse_qs(urlparse(url).query)) + token = url_query.get("token") + if not token and isinstance(data, dict): + token = data.get("token") + + if token: + # Nothing to do, just return. + return url, headers, data + + if not data: + data = {"token": session.access_token} + elif isinstance(data, dict): + data["token"] = session.access_token + else: + # ``data`` is something other than a dict: maybe a stream, + # maybe a file object, maybe something else. We can't easily + # modify it, so we'll set the token by modifying the URL instead. + token = [("token", session.access_token)] + url = add_params_to_uri(url, token) + return url, headers, data + + session.register_compliance_hook("protected_request", _non_compliant_param_name) + return session diff --git a/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/weibo.py b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/weibo.py new file mode 100644 index 00000000..f1623fd6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/requests_oauthlib/compliance_fixes/weibo.py @@ -0,0 +1,13 @@ +from json import loads, dumps + + +def weibo_compliance_fix(session): + def _missing_token_type(r): + token = loads(r.text) + token["token_type"] = "Bearer" + r._content = dumps(token).encode() + return r + + session._client.default_token_placement = "query" + session.register_compliance_hook("access_token_response", _missing_token_type) + return session |