mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-06 21:21:15 -07:00
Update oauthlib-3.1.1
This commit is contained in:
parent
e58aa40099
commit
d76838a607
64 changed files with 4329 additions and 1421 deletions
|
@ -6,20 +6,20 @@ oauthlib.oauth2.rfc6749
|
|||
This module is an implementation of various logic needed
|
||||
for consuming OAuth 2.0 RFC6749.
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import time
|
||||
import warnings
|
||||
|
||||
from oauthlib.common import generate_token
|
||||
from oauthlib.oauth2.rfc6749 import tokens
|
||||
from oauthlib.oauth2.rfc6749.parameters import parse_token_response
|
||||
from oauthlib.oauth2.rfc6749.parameters import prepare_token_request
|
||||
from oauthlib.oauth2.rfc6749.parameters import prepare_token_revocation_request
|
||||
from oauthlib.oauth2.rfc6749.errors import TokenExpiredError
|
||||
from oauthlib.oauth2.rfc6749.errors import InsecureTransportError
|
||||
from oauthlib.oauth2.rfc6749.errors import (
|
||||
InsecureTransportError, TokenExpiredError,
|
||||
)
|
||||
from oauthlib.oauth2.rfc6749.parameters import (
|
||||
parse_token_response, prepare_token_request,
|
||||
prepare_token_revocation_request,
|
||||
)
|
||||
from oauthlib.oauth2.rfc6749.utils import is_secure_transport
|
||||
|
||||
|
||||
AUTH_HEADER = 'auth_header'
|
||||
URI_QUERY = 'query'
|
||||
BODY = 'body'
|
||||
|
@ -28,8 +28,8 @@ FORM_ENC_HEADERS = {
|
|||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
|
||||
class Client(object):
|
||||
|
||||
class Client:
|
||||
"""Base OAuth2 client responsible for access token management.
|
||||
|
||||
This class also acts as a generic interface providing methods common to all
|
||||
|
@ -47,6 +47,7 @@ class Client(object):
|
|||
Python, this is usually :py:class:`oauthlib.oauth2.WebApplicationClient`.
|
||||
|
||||
"""
|
||||
refresh_token_key = 'refresh_token'
|
||||
|
||||
def __init__(self, client_id,
|
||||
default_token_placement=AUTH_HEADER,
|
||||
|
@ -80,7 +81,7 @@ class Client(object):
|
|||
``token`` dict parameter.
|
||||
|
||||
:param refresh_token: A refresh token (string) used to refresh expired
|
||||
tokens. Can also be supplide inside the ``token`` dict parameter.
|
||||
tokens. Can also be supplied inside the ``token`` dict parameter.
|
||||
|
||||
:param mac_key: Encryption key used with MAC tokens.
|
||||
|
||||
|
@ -112,8 +113,10 @@ class Client(object):
|
|||
self.state_generator = state_generator
|
||||
self.state = state
|
||||
self.redirect_url = redirect_url
|
||||
self.code = None
|
||||
self.expires_in = None
|
||||
self._expires_at = None
|
||||
self._populate_attributes(self.token)
|
||||
self.populate_token_attributes(self.token)
|
||||
|
||||
@property
|
||||
def token_types(self):
|
||||
|
@ -141,6 +144,7 @@ class Client(object):
|
|||
|
||||
def parse_request_uri_response(self, *args, **kwargs):
|
||||
"""Abstract method used to parse redirection responses."""
|
||||
raise NotImplementedError("Must be implemented by inheriting classes.")
|
||||
|
||||
def add_token(self, uri, http_method='GET', body=None, headers=None,
|
||||
token_placement=None, **kwargs):
|
||||
|
@ -174,20 +178,20 @@ class Client(object):
|
|||
nonce="274312:dj83hs9s",
|
||||
mac="kDZvddkndxvhGRXZhvuDjEWhGeE="
|
||||
|
||||
.. _`I-D.ietf-oauth-v2-bearer`: http://tools.ietf.org/html/rfc6749#section-12.2
|
||||
.. _`I-D.ietf-oauth-v2-http-mac`: http://tools.ietf.org/html/rfc6749#section-12.2
|
||||
.. _`I-D.ietf-oauth-v2-bearer`: https://tools.ietf.org/html/rfc6749#section-12.2
|
||||
.. _`I-D.ietf-oauth-v2-http-mac`: https://tools.ietf.org/html/rfc6749#section-12.2
|
||||
"""
|
||||
if not is_secure_transport(uri):
|
||||
raise InsecureTransportError()
|
||||
|
||||
token_placement = token_placement or self.default_token_placement
|
||||
|
||||
case_insensitive_token_types = dict(
|
||||
(k.lower(), v) for k, v in self.token_types.items())
|
||||
case_insensitive_token_types = {
|
||||
k.lower(): v for k, v in self.token_types.items()}
|
||||
if not self.token_type.lower() in case_insensitive_token_types:
|
||||
raise ValueError("Unsupported token type: %s" % self.token_type)
|
||||
|
||||
if not self.access_token:
|
||||
if not (self.access_token or self.token.get('access_token')):
|
||||
raise ValueError("Missing access token.")
|
||||
|
||||
if self._expires_at and self._expires_at < time.time():
|
||||
|
@ -197,7 +201,7 @@ class Client(object):
|
|||
headers, token_placement, **kwargs)
|
||||
|
||||
def prepare_authorization_request(self, authorization_url, state=None,
|
||||
redirect_url=None, scope=None, **kwargs):
|
||||
redirect_url=None, scope=None, **kwargs):
|
||||
"""Prepare the authorization request.
|
||||
|
||||
This is the first step in many OAuth flows in which the user is
|
||||
|
@ -218,6 +222,11 @@ class Client(object):
|
|||
the provider. If provided then it must also be provided in the
|
||||
token request.
|
||||
|
||||
:param scope: List of scopes to request. Must be equal to
|
||||
or a subset of the scopes granted when obtaining the refresh
|
||||
token. If none is provided, the ones provided in the constructor are
|
||||
used.
|
||||
|
||||
:param kwargs: Additional parameters to included in the request.
|
||||
|
||||
:returns: The prepared request tuple with (url, headers, body).
|
||||
|
@ -227,14 +236,15 @@ class Client(object):
|
|||
|
||||
self.state = state or self.state_generator()
|
||||
self.redirect_url = redirect_url or self.redirect_url
|
||||
self.scope = scope or self.scope
|
||||
# do not assign scope to self automatically anymore
|
||||
scope = self.scope if scope is None else scope
|
||||
auth_url = self.prepare_request_uri(
|
||||
authorization_url, redirect_uri=self.redirect_url,
|
||||
scope=self.scope, state=self.state, **kwargs)
|
||||
authorization_url, redirect_uri=self.redirect_url,
|
||||
scope=scope, state=self.state, **kwargs)
|
||||
return auth_url, FORM_ENC_HEADERS, ''
|
||||
|
||||
def prepare_token_request(self, token_url, authorization_response=None,
|
||||
redirect_url=None, state=None, body='', **kwargs):
|
||||
redirect_url=None, state=None, body='', **kwargs):
|
||||
"""Prepare a token creation request.
|
||||
|
||||
Note that these requests usually require client authentication, either
|
||||
|
@ -251,7 +261,10 @@ class Client(object):
|
|||
:param redirect_url: The redirect_url supplied with the authorization
|
||||
request (if there was one).
|
||||
|
||||
:param body: Request body (URL encoded string).
|
||||
:param state:
|
||||
|
||||
:param body: Existing request body (URL encoded string) to embed parameters
|
||||
into. This may contain extra paramters. Default ''.
|
||||
|
||||
:param kwargs: Additional parameters to included in the request.
|
||||
|
||||
|
@ -263,15 +276,15 @@ class Client(object):
|
|||
state = state or self.state
|
||||
if authorization_response:
|
||||
self.parse_request_uri_response(
|
||||
authorization_response, state=state)
|
||||
authorization_response, state=state)
|
||||
self.redirect_url = redirect_url or self.redirect_url
|
||||
body = self.prepare_request_body(body=body,
|
||||
redirect_uri=self.redirect_url, **kwargs)
|
||||
redirect_uri=self.redirect_url, **kwargs)
|
||||
|
||||
return token_url, FORM_ENC_HEADERS, body
|
||||
|
||||
def prepare_refresh_token_request(self, token_url, refresh_token=None,
|
||||
body='', scope=None, **kwargs):
|
||||
body='', scope=None, **kwargs):
|
||||
"""Prepare an access token refresh request.
|
||||
|
||||
Expired access tokens can be replaced by new access tokens without
|
||||
|
@ -283,11 +296,13 @@ class Client(object):
|
|||
|
||||
:param refresh_token: Refresh token string.
|
||||
|
||||
:param body: Request body (URL encoded string).
|
||||
:param body: Existing request body (URL encoded string) to embed parameters
|
||||
into. This may contain extra paramters. Default ''.
|
||||
|
||||
:param scope: List of scopes to request. Must be equal to
|
||||
or a subset of the scopes granted when obtaining the refresh
|
||||
token.
|
||||
token. If none is provided, the ones provided in the constructor are
|
||||
used.
|
||||
|
||||
:param kwargs: Additional parameters to included in the request.
|
||||
|
||||
|
@ -296,13 +311,14 @@ class Client(object):
|
|||
if not is_secure_transport(token_url):
|
||||
raise InsecureTransportError()
|
||||
|
||||
self.scope = scope or self.scope
|
||||
# do not assign scope to self automatically anymore
|
||||
scope = self.scope if scope is None else scope
|
||||
body = self.prepare_refresh_body(body=body,
|
||||
refresh_token=refresh_token, scope=self.scope, **kwargs)
|
||||
refresh_token=refresh_token, scope=scope, **kwargs)
|
||||
return token_url, FORM_ENC_HEADERS, body
|
||||
|
||||
def prepare_token_revocation_request(self, revocation_url, token,
|
||||
token_type_hint="access_token", body='', callback=None, **kwargs):
|
||||
token_type_hint="access_token", body='', callback=None, **kwargs):
|
||||
"""Prepare a token revocation request.
|
||||
|
||||
:param revocation_url: Provider token revocation endpoint URL.
|
||||
|
@ -313,6 +329,8 @@ class Client(object):
|
|||
``"refresh_token"``. This is optional and if you wish to not pass it you
|
||||
must provide ``token_type_hint=None``.
|
||||
|
||||
:param body:
|
||||
|
||||
:param callback: A jsonp callback such as ``package.callback`` to be invoked
|
||||
upon receiving the response. Not that it should not include a () suffix.
|
||||
|
||||
|
@ -357,8 +375,8 @@ class Client(object):
|
|||
raise InsecureTransportError()
|
||||
|
||||
return prepare_token_revocation_request(revocation_url, token,
|
||||
token_type_hint=token_type_hint, body=body, callback=callback,
|
||||
**kwargs)
|
||||
token_type_hint=token_type_hint, body=body, callback=callback,
|
||||
**kwargs)
|
||||
|
||||
def parse_request_body_response(self, body, scope=None, **kwargs):
|
||||
"""Parse the JSON response body.
|
||||
|
@ -370,7 +388,8 @@ class Client(object):
|
|||
returns an error response as described in `Section 5.2`_.
|
||||
|
||||
:param body: The response body from the token request.
|
||||
:param scope: Scopes originally requested.
|
||||
:param scope: Scopes originally requested. If none is provided, the ones
|
||||
provided in the constructor are used.
|
||||
:return: Dictionary of token parameters.
|
||||
:raises: Warning if scope has changed. OAuth2Error if response is invalid.
|
||||
|
||||
|
@ -398,16 +417,17 @@ class Client(object):
|
|||
If omitted, the authorization server SHOULD provide the
|
||||
expiration time via other means or document the default value.
|
||||
|
||||
**scope**
|
||||
**scope**
|
||||
Providers may supply this in all responses but are required to only
|
||||
if it has changed since the authorization request.
|
||||
|
||||
.. _`Section 5.1`: http://tools.ietf.org/html/rfc6749#section-5.1
|
||||
.. _`Section 5.2`: http://tools.ietf.org/html/rfc6749#section-5.2
|
||||
.. _`Section 7.1`: http://tools.ietf.org/html/rfc6749#section-7.1
|
||||
.. _`Section 5.1`: https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
.. _`Section 5.2`: https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
.. _`Section 7.1`: https://tools.ietf.org/html/rfc6749#section-7.1
|
||||
"""
|
||||
scope = self.scope if scope is None else scope
|
||||
self.token = parse_token_response(body, scope=scope)
|
||||
self._populate_attributes(self.token)
|
||||
self.populate_token_attributes(self.token)
|
||||
return self.token
|
||||
|
||||
def prepare_refresh_body(self, body='', refresh_token=None, scope=None, **kwargs):
|
||||
|
@ -427,10 +447,12 @@ class Client(object):
|
|||
Section 3.3. The requested scope MUST NOT include any scope
|
||||
not originally granted by the resource owner, and if omitted is
|
||||
treated as equal to the scope originally granted by the
|
||||
resource owner.
|
||||
resource owner. Note that if none is provided, the ones provided
|
||||
in the constructor are used if any.
|
||||
"""
|
||||
refresh_token = refresh_token or self.refresh_token
|
||||
return prepare_token_request('refresh_token', body=body, scope=scope,
|
||||
scope = self.scope if scope is None else scope
|
||||
return prepare_token_request(self.refresh_token_key, body=body, scope=scope,
|
||||
refresh_token=refresh_token, **kwargs)
|
||||
|
||||
def _add_bearer_token(self, uri, http_method='GET', body=None,
|
||||
|
@ -455,13 +477,27 @@ class Client(object):
|
|||
|
||||
Warning: MAC token support is experimental as the spec is not yet stable.
|
||||
"""
|
||||
if token_placement != AUTH_HEADER:
|
||||
raise ValueError("Invalid token placement.")
|
||||
|
||||
headers = tokens.prepare_mac_header(self.access_token, uri,
|
||||
self.mac_key, http_method, headers=headers, body=body, ext=ext,
|
||||
hash_algorithm=self.mac_algorithm, **kwargs)
|
||||
return uri, headers, body
|
||||
|
||||
def _populate_attributes(self, response):
|
||||
"""Add commonly used values such as access_token to self."""
|
||||
warnings.warn("Please switch to the public method "
|
||||
"populate_token_attributes.", DeprecationWarning)
|
||||
return self.populate_token_attributes(response)
|
||||
|
||||
def populate_code_attributes(self, response):
|
||||
"""Add attributes from an auth code response to self."""
|
||||
|
||||
if 'code' in response:
|
||||
self.code = response.get('code')
|
||||
|
||||
def populate_token_attributes(self, response):
|
||||
"""Add attributes from a token exchange response to self."""
|
||||
|
||||
if 'access_token' in response:
|
||||
self.access_token = response.get('access_token')
|
||||
|
@ -479,12 +515,8 @@ class Client(object):
|
|||
if 'expires_at' in response:
|
||||
self._expires_at = int(response.get('expires_at'))
|
||||
|
||||
if 'code' in response:
|
||||
self.code = response.get('code')
|
||||
|
||||
if 'mac_key' in response:
|
||||
self.mac_key = response.get('mac_key')
|
||||
|
||||
if 'mac_algorithm' in response:
|
||||
self.mac_algorithm = response.get('mac_algorithm')
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue