summaryrefslogtreecommitdiff
path: root/oauthlib/oauth2/rfc6749/__init__.py
diff options
context:
space:
mode:
authorIb Lundgren <ib.lundgren@gmail.com>2013-05-30 12:13:12 +0100
committerIb Lundgren <ib.lundgren@gmail.com>2013-05-30 12:13:12 +0100
commit07b2c2bca9b7c0deb24a801841b373198b8a99bf (patch)
tree3dda951d7bdb7c8327d352b3a956c301accbf420 /oauthlib/oauth2/rfc6749/__init__.py
parentcd6da5ab2522e283d2fd7f89c74d77cab83b5eb8 (diff)
downloadoauthlib-07b2c2bca9b7c0deb24a801841b373198b8a99bf.tar.gz
Split OAuth2 large modules into smaller ones. #168.
Diffstat (limited to 'oauthlib/oauth2/rfc6749/__init__.py')
-rw-r--r--oauthlib/oauth2/rfc6749/__init__.py1301
1 files changed, 1 insertions, 1300 deletions
diff --git a/oauthlib/oauth2/rfc6749/__init__.py b/oauthlib/oauth2/rfc6749/__init__.py
index f8ee488..c82c06a 100644
--- a/oauthlib/oauth2/rfc6749/__init__.py
+++ b/oauthlib/oauth2/rfc6749/__init__.py
@@ -8,962 +8,11 @@ oauthlib.oauth2.rfc6749
This module is an implementation of various logic needed
for consuming and providing OAuth 2.0 RFC6749.
"""
-import datetime
import functools
-import logging
-from oauthlib.common import Request
-from . import tokens, grant_types
-from .errors import TokenExpiredError, InsecureTransportError
+from oauthlib.common import log
from .errors import TemporarilyUnavailableError, ServerError
from .errors import FatalClientError, OAuth2Error
-from .parameters import prepare_grant_uri, prepare_token_request
-from .parameters import parse_authorization_code_response
-from .parameters import parse_implicit_response, parse_token_response
-
-
-AUTH_HEADER = 'auth_header'
-URI_QUERY = 'query'
-BODY = 'body'
-
-log = logging.getLogger('oauthlib')
-
-# Add a NullHandler to prevent warnings for users who don't wish
-# to configure logging.
-try:
- log.addHandler(logging.NullHandler())
-# NullHandler gracefully backported to 2.6
-except AttributeError:
- class NullHandler(logging.Handler):
- def emit(self, record):
- pass
- log.addHandler(NullHandler())
-
-
-class Client(object):
- """Base OAuth2 client responsible for access tokens.
-
- While this class can be used to simply append tokens onto requests
- it is often more useful to use a client targeted at a specific workflow.
- """
-
- def __init__(self, client_id,
- default_token_placement=AUTH_HEADER,
- token_type='Bearer',
- access_token=None,
- refresh_token=None,
- mac_key=None,
- mac_algorithm=None,
- token=None,
- **kwargs):
- """Initialize a client with commonly used attributes."""
-
- self.client_id = client_id
- self.default_token_placement = default_token_placement
- self.token_type = token_type
- self.access_token = access_token
- self.refresh_token = refresh_token
- self.mac_key = mac_key
- self.mac_algorithm = mac_algorithm
- self.token = token or {}
- self._expires_at = None
- self._populate_attributes(self.token)
-
- @property
- def token_types(self):
- """Supported token types and their respective methods
-
- Additional tokens can be supported by extending this dictionary.
-
- The Bearer token spec is stable and safe to use.
-
- The MAC token spec is not yet stable and support for MAC tokens
- is experimental and currently matching version 00 of the spec.
- """
- return {
- 'Bearer': self._add_bearer_token,
- 'MAC': self._add_mac_token
- }
-
- def add_token(self, uri, http_method='GET', body=None, headers=None,
- token_placement=None, **kwargs):
- """Add token to the request uri, body or authorization header.
-
- The access token type provides the client with the information
- required to successfully utilize the access token to make a protected
- resource request (along with type-specific attributes). The client
- MUST NOT use an access token if it does not understand the token
- type.
-
- For example, the "bearer" token type defined in
- [`I-D.ietf-oauth-v2-bearer`_] is utilized by simply including the access
- token string in the request:
-
- .. code-block:: http
-
- GET /resource/1 HTTP/1.1
- Host: example.com
- Authorization: Bearer mF_9.B5f-4.1JqM
-
- while the "mac" token type defined in [`I-D.ietf-oauth-v2-http-mac`_] is
- utilized by issuing a MAC key together with the access token which is
- used to sign certain components of the HTTP requests:
-
- .. code-block:: http
-
- GET /resource/1 HTTP/1.1
- Host: example.com
- Authorization: MAC id="h480djs93hd8",
- 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
- """
- if not uri.lower().startswith('https://'):
- 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())
- 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:
- raise ValueError("Missing access token.")
-
- if self._expires_at and self._expires_at < datetime.datetime.now():
- raise TokenExpiredError()
-
- return case_insensitive_token_types[self.token_type.lower()](uri, http_method, body,
- headers, token_placement, **kwargs)
-
- def prepare_refresh_body(self, body='', refresh_token=None, scope=None, **kwargs):
- """Prepare an access token request, using a refresh token.
-
- If the authorization server issued a refresh token to the client, the
- client makes a refresh request to the token endpoint by adding the
- following parameters using the "application/x-www-form-urlencoded"
- format in the HTTP request entity-body:
-
- grant_type
- REQUIRED. Value MUST be set to "refresh_token".
- refresh_token
- REQUIRED. The refresh token issued to the client.
- scope
- OPTIONAL. The scope of the access request as described by
- 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.
- """
- refresh_token = refresh_token or self.refresh_token
- return prepare_token_request('refresh_token', body=body, scope=scope,
- refresh_token=refresh_token, **kwargs)
-
- def _add_bearer_token(self, uri, http_method='GET', body=None,
- headers=None, token_placement=None):
- """Add a bearer token to the request uri, body or authorization header."""
- if token_placement == AUTH_HEADER:
- headers = tokens.prepare_bearer_headers(self.access_token, headers)
-
- elif token_placement == URI_QUERY:
- uri = tokens.prepare_bearer_uri(self.access_token, uri)
-
- elif token_placement == BODY:
- body = tokens.prepare_bearer_body(self.access_token, body)
-
- else:
- raise ValueError("Invalid token placement.")
- return uri, headers, body
-
- def _add_mac_token(self, uri, http_method='GET', body=None,
- headers=None, token_placement=AUTH_HEADER, ext=None, **kwargs):
- """Add a MAC token to the request authorization header.
-
- Warning: MAC token support is experimental as the spec is not yet stable.
- """
- 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."""
-
- if 'access_token' in response:
- self.access_token = response.get('access_token')
-
- if 'refresh_token' in response:
- self.refresh_token = response.get('refresh_token')
-
- if 'token_type' in response:
- self.token_type = response.get('token_type')
-
- if 'expires_in' in response:
- self.expires_in = response.get('expires_in')
- self._expires_at = datetime.datetime.now() + datetime.timedelta(
- seconds=int(self.expires_in))
-
- 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')
-
- def prepare_request_uri(self, *args, **kwargs):
- """Abstract method used to create request URIs."""
- raise NotImplementedError("Must be implemented by inheriting classes.")
-
- def prepare_request_body(self, *args, **kwargs):
- """Abstract method used to create request bodies."""
- raise NotImplementedError("Must be implemented by inheriting classes.")
-
- def parse_request_uri_response(self, *args, **kwargs):
- """Abstract method used to parse redirection responses."""
-
- def parse_request_body_response(self, *args, **kwargs):
- """Abstract method used to parse JSON responses."""
-
-
-class WebApplicationClient(Client):
- """A client utilizing the authorization code grant workflow.
-
- A web application is a confidential client running on a web
- server. Resource owners access the client via an HTML user
- interface rendered in a user-agent on the device used by the
- resource owner. The client credentials as well as any access
- token issued to the client are stored on the web server and are
- not exposed to or accessible by the resource owner.
-
- The authorization code grant type is used to obtain both access
- tokens and refresh tokens and is optimized for confidential clients.
- As a redirection-based flow, the client must be capable of
- interacting with the resource owner's user-agent (typically a web
- browser) and capable of receiving incoming requests (via redirection)
- from the authorization server.
- """
-
- def __init__(self, client_id, code=None, **kwargs):
- super(WebApplicationClient, self).__init__(client_id, **kwargs)
- self.code = code
-
- def prepare_request_uri(self, uri, redirect_uri=None, scope=None,
- state=None, **kwargs):
- """Prepare the authorization code request URI
-
- The client constructs the request URI by adding the following
- parameters to the query component of the authorization endpoint URI
- using the "application/x-www-form-urlencoded" format, per `Appendix B`_:
-
- :param redirect_uri: OPTIONAL. The redirect URI must be an absolute URI
- and it should have been registerd with the OAuth
- provider prior to use. As described in `Section 3.1.2`_.
-
- :param scope: OPTIONAL. The scope of the access request as described by
- Section 3.3`_. These may be any string but are commonly
- URIs or various categories such as ``videos`` or ``documents``.
-
- :param state: RECOMMENDED. An opaque value used by the client to maintain
- state between the request and callback. The authorization
- server includes this value when redirecting the user-agent back
- to the client. The parameter SHOULD be used for preventing
- cross-site request forgery as described in `Section 10.12`_.
-
- :param kwargs: Extra arguments to include in the request URI.
-
- In addition to supplied parameters, OAuthLib will append the ``client_id``
- that was provided in the constructor as well as the mandatory ``response_type``
- argument, set to ``code``::
-
- >>> from oauthlib.oauth2 import WebApplicationClient
- >>> client = WebApplicationClient('your_id')
- >>> client.prepare_request_uri('https://example.com')
- 'https://example.com?client_id=your_id&response_type=code'
- >>> client.prepare_request_uri('https://example.com', redirect_uri='https://a.b/callback')
- 'https://example.com?client_id=your_id&response_type=code&redirect_uri=https%3A%2F%2Fa.b%2Fcallback'
- >>> client.prepare_request_uri('https://example.com', scope=['profile', 'pictures'])
- 'https://example.com?client_id=your_id&response_type=code&scope=profile+pictures'
- >>> client.prepare_request_uri('https://example.com', foo='bar')
- 'https://example.com?client_id=your_id&response_type=code&foo=bar'
-
- .. _`Appendix B`: http://tools.ietf.org/html/rfc6749#appendix-B
- .. _`Section 2.2`: http://tools.ietf.org/html/rfc6749#section-2.2
- .. _`Section 3.1.2`: http://tools.ietf.org/html/rfc6749#section-3.1.2
- .. _`Section 3.3`: http://tools.ietf.org/html/rfc6749#section-3.3
- .. _`Section 10.12`: http://tools.ietf.org/html/rfc6749#section-10.12
- """
- return prepare_grant_uri(uri, self.client_id, 'code',
- redirect_uri=redirect_uri, scope=scope, state=state, **kwargs)
-
- def prepare_request_body(self, client_id=None, code=None, body='',
- redirect_uri=None, **kwargs):
- """Prepare the access token request body.
-
- The client makes a request to the token endpoint by adding the
- following parameters using the "application/x-www-form-urlencoded"
- format in the HTTP request entity-body:
-
- :param client_id: REQUIRED, if the client is not authenticating with the
- authorization server as described in `Section 3.2.1`_.
-
- :param code: REQUIRED. The authorization code received from the
- authorization server.
-
- :param redirect_uri: REQUIRED, if the "redirect_uri" parameter was included in the
- authorization request as described in `Section 4.1.1`_, and their
- values MUST be identical.
-
- :param kwargs: Extra parameters to include in the token request.
-
- In addition OAuthLib will add the ``grant_type`` parameter set to
- ``authorization_code``.
-
- If the client type is confidential or the client was issued client
- credentials (or assigned other authentication requirements), the
- client MUST authenticate with the authorization server as described
- in `Section 3.2.1`_::
-
- >>> from oauthlib.oauth2 import WebApplicationClient
- >>> client = WebApplicationClient('your_id')
- >>> client.prepare_request_body(code='sh35ksdf09sf')
- 'grant_type=authorization_code&code=sh35ksdf09sf'
- >>> client.prepare_request_body(code='sh35ksdf09sf', foo='bar')
- 'grant_type=authorization_code&code=sh35ksdf09sf&foo=bar'
-
- .. _`Section 4.1.1`: http://tools.ietf.org/html/rfc6749#section-4.1.1
- .. _`Section 3.2.1`: http://tools.ietf.org/html/rfc6749#section-3.2.1
- """
- code = code or self.code
- return prepare_token_request('authorization_code', code=code, body=body,
- client_id=self.client_id, redirect_uri=redirect_uri, **kwargs)
-
- def parse_request_uri_response(self, uri, state=None):
- """Parse the URI query for code and state.
-
- If the resource owner grants the access request, the authorization
- server issues an authorization code and delivers it to the client by
- adding the following parameters to the query component of the
- redirection URI using the "application/x-www-form-urlencoded" format:
-
- :param uri: The callback URI that resulted from the user being redirected
- back from the provider to you, the client.
- :param state: The state provided in the authorization request.
-
- **code**
- The authorization code generated by the authorization server.
- The authorization code MUST expire shortly after it is issued
- to mitigate the risk of leaks. A maximum authorization code
- lifetime of 10 minutes is RECOMMENDED. The client MUST NOT
- use the authorization code more than once. If an authorization
- code is used more than once, the authorization server MUST deny
- the request and SHOULD revoke (when possible) all tokens
- previously issued based on that authorization code.
- The authorization code is bound to the client identifier and
- redirection URI.
-
- **state**
- If the "state" parameter was present in the authorization request.
-
- This method is mainly intended to enforce strict state checking with
- the added benefit of easily extracting parameters from the URI::
-
- >>> from oauthlib.oauth2 import WebApplicationClient
- >>> client = WebApplicationClient('your_id')
- >>> uri = 'https://example.com/callback?code=sdfkjh345&state=sfetw45'
- >>> client.parse_request_uri_response(uri, state='sfetw45')
- {'state': 'sfetw45', 'code': 'sdfkjh345'}
- >>> client.parse_request_uri_response(uri, state='other')
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "oauthlib/oauth2/rfc6749/__init__.py", line 357, in parse_request_uri_response
- back from the provider to you, the client.
- File "oauthlib/oauth2/rfc6749/parameters.py", line 153, in parse_authorization_code_response
- raise MismatchingStateError()
- oauthlib.oauth2.rfc6749.errors.MismatchingStateError
- """
- response = parse_authorization_code_response(uri, state=state)
- self._populate_attributes(response)
- return response
-
- def parse_request_body_response(self, body, scope=None):
- """Parse the JSON response body.
-
- If the access token request is valid and authorized, the
- authorization server issues an access token and optional refresh
- token as described in `Section 5.1`_. If the request client
- authentication failed or is invalid, the authorization server returns
- an error response as described in `Section 5.2`_.
-
- :param body: The response body from the token request.
- :param scope: Scopes originally requested.
- :return: Dictionary of token parameters.
- :raises: Warning if scope has changed. OAuth2Error if response is invalid.
-
- These response are json encoded and could easily be parsed without
- the assistance of OAuthLib. However, there are a few subtle issues
- to be aware of regarding the response which are helpfully addressed
- through the raising of various errors.
-
- A successful response should always contain
-
- **access_token**
- The access token issued by the authorization server. Often
- a random string.
-
- **token_type**
- The type of the token issued as described in `Section 7.1`_.
- Commonly ``Bearer``.
-
- While it is not mandated it is recommended that the provider include
-
- **expires_in**
- The lifetime in seconds of the access token. For
- example, the value "3600" denotes that the access token will
- expire in one hour from the time the response was generated.
- If omitted, the authorization server SHOULD provide the
- expiration time via other means or document the default value.
-
- **scope**
- Providers may supply this in all responses but are required to only
- if it has changed since the authorization request.
-
- A normal response might look like::
-
- >>> json.loads(response_body)
- {
- 'access_token': 'sdfkjh345',
- 'token_type': 'Bearer',
- 'expires_in': '3600',
- 'refresh_token': 'x345dgasd',
- 'scope': 'hello world',
- }
- >>> from oauthlib.oauth2 import WebApplicationClient
- >>> client = WebApplicationClient('your_id')
- >>> client.parse_request_body_response(response_body)
- {
- 'access_token': 'sdfkjh345',
- 'token_type': 'Bearer',
- 'expires_in': '3600',
- 'refresh_token': 'x345dgasd',
- 'scope': ['hello', 'world'], # note the list
- }
-
- If there was a scope change you will be notified with a warning::
-
- >>> client.parse_request_body_response(response_body, scope=['images'])
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "oauthlib/oauth2/rfc6749/__init__.py", line 421, in parse_request_body_response
- .. _`Section 5.2`: http://tools.ietf.org/html/rfc6749#section-5.2
- File "oauthlib/oauth2/rfc6749/parameters.py", line 263, in parse_token_response
- validate_token_parameters(params, scope)
- File "oauthlib/oauth2/rfc6749/parameters.py", line 285, in validate_token_parameters
- raise Warning("Scope has changed to %s." % new_scope)
- Warning: Scope has changed to [u'hello', u'world'].
-
- If there was an error on the providers side you will be notified with
- an error. For example, if there was no ``token_type`` provided::
-
- >>> client.parse_request_body_response(response_body)
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "oauthlib/oauth2/rfc6749/__init__.py", line 421, in parse_request_body_response
- File "oauthlib/oauth2/rfc6749/__init__.py", line 421, in parse_request_body_response
- File "oauthlib/oauth2/rfc6749/parameters.py", line 263, in parse_token_response
- validate_token_parameters(params, scope)
- File "oauthlib/oauth2/rfc6749/parameters.py", line 276, in validate_token_parameters
- raise MissingTokenTypeError()
- oauthlib.oauth2.rfc6749.errors.MissingTokenTypeError
-
- .. _`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
- """
- self.token = parse_token_response(body, scope=scope)
- self._populate_attributes(self.token)
- return self.token
-
-
-class MobileApplicationClient(Client):
- """A public client utilizing the implicit code grant workflow.
-
- A user-agent-based application is a public client in which the
- client code is downloaded from a web server and executes within a
- user-agent (e.g. web browser) on the device used by the resource
- owner. Protocol data and credentials are easily accessible (and
- often visible) to the resource owner. Since such applications
- reside within the user-agent, they can make seamless use of the
- user-agent capabilities when requesting authorization.
-
- The implicit grant type is used to obtain access tokens (it does not
- support the issuance of refresh tokens) and is optimized for public
- clients known to operate a particular redirection URI. These clients
- are typically implemented in a browser using a scripting language
- such as JavaScript.
-
- As a redirection-based flow, the client must be capable of
- interacting with the resource owner's user-agent (typically a web
- browser) and capable of receiving incoming requests (via redirection)
- from the authorization server.
-
- Unlike the authorization code grant type in which the client makes
- separate requests for authorization and access token, the client
- receives the access token as the result of the authorization request.
-
- The implicit grant type does not include client authentication, and
- relies on the presence of the resource owner and the registration of
- the redirection URI. Because the access token is encoded into the
- redirection URI, it may be exposed to the resource owner and other
- applications residing on the same device.
- """
-
- def prepare_request_uri(self, uri, redirect_uri=None, scope=None,
- state=None, **kwargs):
- """Prepare the implicit grant request URI.
-
- The client constructs the request URI by adding the following
- parameters to the query component of the authorization endpoint URI
- using the "application/x-www-form-urlencoded" format, per `Appendix B`_:
-
- :param redirect_uri: OPTIONAL. The redirect URI must be an absolute URI
- and it should have been registerd with the OAuth
- provider prior to use. As described in `Section 3.1.2`_.
-
- :param scope: OPTIONAL. The scope of the access request as described by
- Section 3.3`_. These may be any string but are commonly
- URIs or various categories such as ``videos`` or ``documents``.
-
- :param state: RECOMMENDED. An opaque value used by the client to maintain
- state between the request and callback. The authorization
- server includes this value when redirecting the user-agent back
- to the client. The parameter SHOULD be used for preventing
- cross-site request forgery as described in `Section 10.12`_.
-
- :param kwargs: Extra arguments to include in the request URI.
-
- In addition to supplied parameters, OAuthLib will append the ``client_id``
- that was provided in the constructor as well as the mandatory ``response_type``
- argument, set to ``token``::
-
- >>> from oauthlib.oauth2 import MobileApplicationClient
- >>> client = MobileApplicationClient('your_id')
- >>> client.prepare_request_uri('https://example.com')
- 'https://example.com?client_id=your_id&response_type=token'
- >>> client.prepare_request_uri('https://example.com', redirect_uri='https://a.b/callback')
- 'https://example.com?client_id=your_id&response_type=token&redirect_uri=https%3A%2F%2Fa.b%2Fcallback'
- >>> client.prepare_request_uri('https://example.com', scope=['profile', 'pictures'])
- 'https://example.com?client_id=your_id&response_type=token&scope=profile+pictures'
- >>> client.prepare_request_uri('https://example.com', foo='bar')
- 'https://example.com?client_id=your_id&response_type=token&foo=bar'
-
- .. _`Appendix B`: http://tools.ietf.org/html/rfc6749#appendix-B
- .. _`Section 2.2`: http://tools.ietf.org/html/rfc6749#section-2.2
- .. _`Section 3.1.2`: http://tools.ietf.org/html/rfc6749#section-3.1.2
- .. _`Section 3.3`: http://tools.ietf.org/html/rfc6749#section-3.3
- .. _`Section 10.12`: http://tools.ietf.org/html/rfc6749#section-10.12
- """
- return prepare_grant_uri(uri, self.client_id, 'token',
- redirect_uri=redirect_uri, state=state, scope=scope, **kwargs)
-
- def parse_request_uri_response(self, uri, state=None, scope=None):
- """Parse the response URI fragment.
-
- If the resource owner grants the access request, the authorization
- server issues an access token and delivers it to the client by adding
- the following parameters to the fragment component of the redirection
- URI using the "application/x-www-form-urlencoded" format:
-
- :param uri: The callback URI that resulted from the user being redirected
- back from the provider to you, the client.
- :param state: The state provided in the authorization request.
- :param scope: The scopes provided in the authorization request.
- :return: Dictionary of token parameters.
- :raises: Warning if scope has changed. OAuth2Error if response is invalid.
-
- A successful response should always contain
-
- **access_token**
- The access token issued by the authorization server. Often
- a random string.
-
- **token_type**
- The type of the token issued as described in `Section 7.1`_.
- Commonly ``Bearer``.
-
- **state**
- If you provided the state parameter in the authorization phase, then
- the provider is required to include that exact state value in the
- response.
-
- While it is not mandated it is recommended that the provider include
-
- **expires_in**
- The lifetime in seconds of the access token. For
- example, the value "3600" denotes that the access token will
- expire in one hour from the time the response was generated.
- If omitted, the authorization server SHOULD provide the
- expiration time via other means or document the default value.
-
- **scope**
- Providers may supply this in all responses but are required to only
- if it has changed since the authorization request.
-
- A few example responses can be seen below::
-
- >>> response_uri = 'https://example.com/callback#access_token=sdlfkj452&state=ss345asyht&token_type=Bearer&scope=hello+world'
- >>> from oauthlib.oauth2 import MobileApplicationClient
- >>> client = MobileApplicationClient('your_id')
- >>> client.parse_request_uri_response(response_uri)
- {
- 'access_token': 'sdlfkj452',
- 'token_type': 'Bearer',
- 'state': 'ss345asyht',
- 'scope': [u'hello', u'world']
- }
- >>> client.parse_request_uri_response(response_uri, state='other')
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "oauthlib/oauth2/rfc6749/__init__.py", line 598, in parse_request_uri_response
- **scope**
- File "oauthlib/oauth2/rfc6749/parameters.py", line 197, in parse_implicit_response
- raise ValueError("Mismatching or missing state in params.")
- ValueError: Mismatching or missing state in params.
- >>> client.parse_request_uri_response(response_uri, scope=['other'])
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "oauthlib/oauth2/rfc6749/__init__.py", line 598, in parse_request_uri_response
- **scope**
- File "oauthlib/oauth2/rfc6749/parameters.py", line 199, in parse_implicit_response
- validate_token_parameters(params, scope)
- File "oauthlib/oauth2/rfc6749/parameters.py", line 285, in validate_token_parameters
- raise Warning("Scope has changed to %s." % new_scope)
- Warning: Scope has changed to [u'hello', u'world'].
-
- .. _`Section 7.1`: http://tools.ietf.org/html/rfc6749#section-7.1
- .. _`Section 3.3`: http://tools.ietf.org/html/rfc6749#section-3.3
- """
- self.token = parse_implicit_response(uri, state=state, scope=scope)
- self._populate_attributes(self.token)
- return self.token
-
-
-class BackendApplicationClient(Client):
- """A public client utilizing the client credentials grant workflow.
-
- The client can request an access token using only its client
- credentials (or other supported means of authentication) when the
- client is requesting access to the protected resources under its
- control, or those of another resource owner which has been previously
- arranged with the authorization server (the method of which is beyond
- the scope of this specification).
-
- The client credentials grant type MUST only be used by confidential
- clients.
-
- Since the client authentication is used as the authorization grant,
- no additional authorization request is needed.
- """
-
- def prepare_request_body(self, body='', scope=None, **kwargs):
- """Add the client credentials to the request body.
-
- The client makes a request to the token endpoint by adding the
- following parameters using the "application/x-www-form-urlencoded"
- format per `Appendix B`_ in the HTTP request entity-body:
-
- :param scope: The scope of the access request as described by
- `Section 3.3`_.
- :param kwargs: Extra credentials to include in the token request.
-
- The client MUST authenticate with the authorization server as
- described in `Section 3.2.1`_.
-
- The prepared body will include all provided credentials as well as
- the ``grant_type`` parameter set to ``client_credentials``::
-
- >>> from oauthlib.oauth2 import BackendApplicationClient
- >>> client = BackendApplicationClient('your_id')
- >>> client.prepare_request_body(scope=['hello', 'world'])
- 'grant_type=client_credentials&scope=hello+world'
-
- .. _`Appendix B`: http://tools.ietf.org/html/rfc6749#appendix-B
- .. _`Section 3.3`: http://tools.ietf.org/html/rfc6749#section-3.3
- .. _`Section 3.2.1`: http://tools.ietf.org/html/rfc6749#section-3.2.1
- """
- return prepare_token_request('client_credentials', body=body,
- scope=scope, **kwargs)
-
- def parse_request_body_response(self, body, scope=None):
- """Parse the JSON response body.
-
- If the access token request is valid and authorized, the
- authorization server issues an access token as described in
- `Section 5.1`_. A refresh token SHOULD NOT be included. If the request
- failed client authentication or is invalid, the authorization server
- returns an error response as described in `Section 5.2`_.
-
- :param body: The response body from the token request.
- :param scope: Scopes originally requested.
- :return: Dictionary of token parameters.
- :raises: Warning if scope has changed. OAuth2Error if response is invalid.
-
- These response are json encoded and could easily be parsed without
- the assistance of OAuthLib. However, there are a few subtle issues
- to be aware of regarding the response which are helpfully addressed
- through the raising of various errors.
-
- A successful response should always contain
-
- **access_token**
- The access token issued by the authorization server. Often
- a random string.
-
- **token_type**
- The type of the token issued as described in `Section 7.1`_.
- Commonly ``Bearer``.
-
- While it is not mandated it is recommended that the provider include
-
- **expires_in**
- The lifetime in seconds of the access token. For
- example, the value "3600" denotes that the access token will
- expire in one hour from the time the response was generated.
- If omitted, the authorization server SHOULD provide the
- expiration time via other means or document the default value.
-
- **scope**
- Providers may supply this in all responses but are required to only
- if it has changed since the authorization request.
-
- A normal response might look like::
-
- >>> json.loads(response_body)
- {
- 'access_token': 'sdfkjh345',
- 'token_type': 'Bearer',
- 'expires_in': '3600',
- 'refresh_token': 'x345dgasd',
- 'scope': 'hello world',
- }
- >>> from oauthlib.oauth2 import BackendApplicationClient
- >>> client = BackendApplicationClient('your_id')
- >>> client.parse_request_body_response(response_body)
- {
- 'access_token': 'sdfkjh345',
- 'token_type': 'Bearer',
- 'expires_in': '3600',
- 'refresh_token': 'x345dgasd',
- 'scope': ['hello', 'world'], # note the list
- }
-
- If there was a scope change you will be notified with a warning::
-
- >>> client.parse_request_body_response(response_body, scope=['images'])
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "oauthlib/oauth2/rfc6749/__init__.py", line 421, in parse_request_body_response
- .. _`Section 5.2`: http://tools.ietf.org/html/rfc6749#section-5.2
- File "oauthlib/oauth2/rfc6749/parameters.py", line 263, in parse_token_response
- validate_token_parameters(params, scope)
- File "oauthlib/oauth2/rfc6749/parameters.py", line 285, in validate_token_parameters
- raise Warning("Scope has changed to %s." % new_scope)
- Warning: Scope has changed to [u'hello', u'world'].
-
- If there was an error on the providers side you will be notified with
- an error. For example, if there was no ``token_type`` provided::
-
- >>> client.parse_request_body_response(response_body)
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "oauthlib/oauth2/rfc6749/__init__.py", line 421, in parse_request_body_response
- File "oauthlib/oauth2/rfc6749/__init__.py", line 421, in parse_request_body_response
- File "oauthlib/oauth2/rfc6749/parameters.py", line 263, in parse_token_response
- validate_token_parameters(params, scope)
- File "oauthlib/oauth2/rfc6749/parameters.py", line 276, in validate_token_parameters
- raise MissingTokenTypeError()
- oauthlib.oauth2.rfc6749.errors.MissingTokenTypeError
-
- .. _`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
- """
- self.token = parse_token_response(body, scope=scope)
- self._populate_attributes(self.token)
- return self.token
-
-
-class LegacyApplicationClient(Client):
- """A public client using the resource owner password and username directly.
-
- The resource owner password credentials grant type is suitable in
- cases where the resource owner has a trust relationship with the
- client, such as the device operating system or a highly privileged
- application. The authorization server should take special care when
- enabling this grant type, and only allow it when other flows are not
- viable.
-
- The grant type is suitable for clients capable of obtaining the
- resource owner's credentials (username and password, typically using
- an interactive form). It is also used to migrate existing clients
- using direct authentication schemes such as HTTP Basic or Digest
- authentication to OAuth by converting the stored credentials to an
- access token.
-
- The method through which the client obtains the resource owner
- credentials is beyond the scope of this specification. The client
- MUST discard the credentials once an access token has been obtained.
- """
-
- def __init__(self, client_id, **kwargs):
- super(LegacyApplicationClient, self).__init__(client_id, **kwargs)
-
- def prepare_request_body(self, username, password, body='', scope=None, **kwargs):
- """Add the resource owner password and username to the request body.
-
- The client makes a request to the token endpoint by adding the
- following parameters using the "application/x-www-form-urlencoded"
- format per `Appendix B`_ in the HTTP request entity-body:
-
- :param username: The resource owner username.
- :param password: The resource owner password.
- :param scope: The scope of the access request as described by
- `Section 3.3`_.
- :param kwargs: Extra credentials to include in the token request.
-
- If the client type is confidential or the client was issued client
- credentials (or assigned other authentication requirements), the
- client MUST authenticate with the authorization server as described
- in `Section 3.2.1`_.
-
- The prepared body will include all provided credentials as well as
- the ``grant_type`` parameter set to ``password``::
-
- >>> from oauthlib.oauth2 import LegacyApplicationClient
- >>> client = LegacyApplicationClient('your_id')
- >>> client.prepare_request_body(username='foo', password='bar', scope=['hello', 'world'])
- 'grant_type=password&username=foo&scope=hello+world&password=bar'
-
- .. _`Appendix B`: http://tools.ietf.org/html/rfc6749#appendix-B
- .. _`Section 3.3`: http://tools.ietf.org/html/rfc6749#section-3.3
- .. _`Section 3.2.1`: http://tools.ietf.org/html/rfc6749#section-3.2.1
- """
- return prepare_token_request('password', body=body, username=username,
- password=password, scope=scope, **kwargs)
-
- def parse_request_body_response(self, body, scope=None):
- """Parse the JSON response body.
-
- If the access token request is valid and authorized, the
- authorization server issues an access token and optional refresh
- token as described in `Section 5.1`_. If the request failed client
- authentication or is invalid, the authorization server returns an
- error response as described in `Section 5.2`_.
-
- :param body: The response body from the token request.
- :param scope: Scopes originally requested.
- :return: Dictionary of token parameters.
- :raises: Warning if scope has changed. OAuth2Error if response is invalid.
-
- These response are json encoded and could easily be parsed without
- the assistance of OAuthLib. However, there are a few subtle issues
- to be aware of regarding the response which are helpfully addressed
- through the raising of various errors.
-
- A successful response should always contain
-
- **access_token**
- The access token issued by the authorization server. Often
- a random string.
-
- **token_type**
- The type of the token issued as described in `Section 7.1`_.
- Commonly ``Bearer``.
-
- While it is not mandated it is recommended that the provider include
-
- **expires_in**
- The lifetime in seconds of the access token. For
- example, the value "3600" denotes that the access token will
- expire in one hour from the time the response was generated.
- If omitted, the authorization server SHOULD provide the
- expiration time via other means or document the default value.
-
- **scope**
- Providers may supply this in all responses but are required to only
- if it has changed since the authorization request.
-
- A normal response might look like::
-
- >>> json.loads(response_body)
- {
- 'access_token': 'sdfkjh345',
- 'token_type': 'Bearer',
- 'expires_in': '3600',
- 'refresh_token': 'x345dgasd',
- 'scope': 'hello world',
- }
- >>> from oauthlib.oauth2 import LegacyApplicationClient
- >>> client = LegacyApplicationClient('your_id')
- >>> client.parse_request_body_response(response_body)
- {
- 'access_token': 'sdfkjh345',
- 'token_type': 'Bearer',
- 'expires_in': '3600',
- 'refresh_token': 'x345dgasd',
- 'scope': ['hello', 'world'], # note the list
- }
-
- If there was a scope change you will be notified with a warning::
-
- >>> client.parse_request_body_response(response_body, scope=['images'])
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "oauthlib/oauth2/rfc6749/__init__.py", line 421, in parse_request_body_response
- .. _`Section 5.2`: http://tools.ietf.org/html/rfc6749#section-5.2
- File "oauthlib/oauth2/rfc6749/parameters.py", line 263, in parse_token_response
- validate_token_parameters(params, scope)
- File "oauthlib/oauth2/rfc6749/parameters.py", line 285, in validate_token_parameters
- raise Warning("Scope has changed to %s." % new_scope)
- Warning: Scope has changed to [u'hello', u'world'].
-
- If there was an error on the providers side you will be notified with
- an error. For example, if there was no ``token_type`` provided::
-
- >>> client.parse_request_body_response(response_body)
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "oauthlib/oauth2/rfc6749/__init__.py", line 421, in parse_request_body_response
- File "oauthlib/oauth2/rfc6749/__init__.py", line 421, in parse_request_body_response
- File "oauthlib/oauth2/rfc6749/parameters.py", line 263, in parse_token_response
- validate_token_parameters(params, scope)
- File "oauthlib/oauth2/rfc6749/parameters.py", line 276, in validate_token_parameters
- raise MissingTokenTypeError()
- oauthlib.oauth2.rfc6749.errors.MissingTokenTypeError
-
- .. _`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
- """
- self.token = parse_token_response(body, scope=scope)
- self._populate_attributes(self.token)
- return self.token
-
-
-# TODO(ib-lundgren): Deprecate these names
-class UserAgentClient(MobileApplicationClient):
- pass
-
-
-class PasswordCredentialsClient(LegacyApplicationClient):
- pass
-
-
-class ClientCredentialsClient(BackendApplicationClient):
- pass
class BaseEndpoint(object):
@@ -1010,351 +59,3 @@ def catch_errors_and_unavailability(f):
else:
return f(endpoint, uri, *args, **kwargs)
return wrapper
-
-
-class AuthorizationEndpoint(BaseEndpoint):
- """Authorization endpoint - used by the client to obtain authorization
- from the resource owner via user-agent redirection.
-
- The authorization endpoint is used to interact with the resource
- owner and obtain an authorization grant. The authorization server
- MUST first verify the identity of the resource owner. The way in
- which the authorization server authenticates the resource owner (e.g.
- username and password login, session cookies) is beyond the scope of
- this specification.
-
- The endpoint URI MAY include an "application/x-www-form-urlencoded"
- formatted (per `Appendix B`_) query component,
- which MUST be retained when adding additional query parameters. The
- endpoint URI MUST NOT include a fragment component::
-
- https://example.com/path?query=component # OK
- https://example.com/path?query=component#fragment # Not OK
-
- Since requests to the authorization endpoint result in user
- authentication and the transmission of clear-text credentials (in the
- HTTP response), the authorization server MUST require the use of TLS
- as described in Section 1.6 when sending requests to the
- authorization endpoint::
-
- # We will deny any request which URI schema is not with https
-
- The authorization server MUST support the use of the HTTP "GET"
- method [RFC2616] for the authorization endpoint, and MAY support the
- use of the "POST" method as well::
-
- # HTTP method is currently not enforced
-
- Parameters sent without a value MUST be treated as if they were
- omitted from the request. The authorization server MUST ignore
- unrecognized request parameters. Request and response parameters
- MUST NOT be included more than once::
-
- # Enforced through the design of oauthlib.common.Request
-
- .. _`Appendix B`: http://tools.ietf.org/html/rfc6749#appendix-B
- """
-
- def __init__(self, default_response_type, default_token_type,
- response_types):
- BaseEndpoint.__init__(self)
- self._response_types = response_types
- self._default_response_type = default_response_type
- self._default_token_type = default_token_type
-
- @property
- def response_types(self):
- return self._response_types
-
- @property
- def default_response_type(self):
- return self._default_response_type
-
- @property
- def default_response_type_handler(self):
- return self.response_types.get(self.default_response_type)
-
- @property
- def default_token_type(self):
- return self._default_token_type
-
- @catch_errors_and_unavailability
- def create_authorization_response(self, uri, http_method='GET', body=None,
- headers=None, scopes=None, credentials=None):
- """Extract response_type and route to the designated handler."""
- request = Request(uri, http_method=http_method, body=body, headers=headers)
- request.scopes = scopes
- # TODO: decide whether this should be a required argument
- request.user = None # TODO: explain this in docs
- for k, v in (credentials or {}).items():
- setattr(request, k, v)
- response_type_handler = self.response_types.get(
- request.response_type, self.default_response_type_handler)
- log.debug('Dispatching response_type %s request to %r.',
- request.response_type, response_type_handler)
- return response_type_handler.create_authorization_response(
- request, self.default_token_type)
-
- @catch_errors_and_unavailability
- def validate_authorization_request(self, uri, http_method='GET', body=None,
- headers=None):
- """Extract response_type and route to the designated handler."""
- request = Request(uri, http_method=http_method, body=body, headers=headers)
- request.scopes = None
- response_type_handler = self.response_types.get(
- request.response_type, self.default_response_type_handler)
- return response_type_handler.validate_authorization_request(request)
-
-
-class TokenEndpoint(BaseEndpoint):
- """Token issuing endpoint.
-
- The token endpoint is used by the client to obtain an access token by
- presenting its authorization grant or refresh token. The token
- endpoint is used with every authorization grant except for the
- implicit grant type (since an access token is issued directly).
-
- The means through which the client obtains the location of the token
- endpoint are beyond the scope of this specification, but the location
- is typically provided in the service documentation.
-
- The endpoint URI MAY include an "application/x-www-form-urlencoded"
- formatted (per `Appendix B`_) query component,
- which MUST be retained when adding additional query parameters. The
- endpoint URI MUST NOT include a fragment component::
-
- https://example.com/path?query=component # OK
- https://example.com/path?query=component#fragment # Not OK
-
- Since requests to the authorization endpoint result in user
- Since requests to the token endpoint result in the transmission of
- clear-text credentials (in the HTTP request and response), the
- authorization server MUST require the use of TLS as described in
- Section 1.6 when sending requests to the token endpoint::
-
- # We will deny any request which URI schema is not with https
-
- The client MUST use the HTTP "POST" method when making access token
- requests::
-
- # HTTP method is currently not enforced
-
- Parameters sent without a value MUST be treated as if they were
- omitted from the request. The authorization server MUST ignore
- unrecognized request parameters. Request and response parameters
- MUST NOT be included more than once::
-
- # Delegated to each grant type.
-
- .. _`Appendix B`: http://tools.ietf.org/html/rfc6749#appendix-B
- """
-
- def __init__(self, default_grant_type, default_token_type, grant_types):
- BaseEndpoint.__init__(self)
- self._grant_types = grant_types
- self._default_token_type = default_token_type
- self._default_grant_type = default_grant_type
-
- @property
- def grant_types(self):
- return self._grant_types
-
- @property
- def default_grant_type(self):
- return self._default_grant_type
-
- @property
- def default_grant_type_handler(self):
- return self.grant_types.get(self.default_grant_type)
-
- @property
- def default_token_type(self):
- return self._default_token_type
-
- @catch_errors_and_unavailability
- def create_token_response(self, uri, http_method='GET', body=None,
- headers=None, credentials=None):
- """Extract grant_type and route to the designated handler."""
- request = Request(uri, http_method=http_method, body=body, headers=headers)
- request.extra_credentials = credentials
- grant_type_handler = self.grant_types.get(request.grant_type,
- self.default_grant_type_handler)
- log.debug('Dispatching grant_type %s request to %r.',
- request.grant_type, grant_type_handler)
- return grant_type_handler.create_token_response(
- request, self.default_token_type)
-
-
-class ResourceEndpoint(BaseEndpoint):
- """Authorizes access to protected resources.
-
- The client accesses protected resources by presenting the access
- token to the resource server. The resource server MUST validate the
- access token and ensure that it has not expired and that its scope
- covers the requested resource. The methods used by the resource
- server to validate the access token (as well as any error responses)
- are beyond the scope of this specification but generally involve an
- interaction or coordination between the resource server and the
- authorization server::
-
- # For most cases, returning a 403 should suffice.
-
- The method in which the client utilizes the access token to
- authenticate with the resource server depends on the type of access
- token issued by the authorization server. Typically, it involves
- using the HTTP "Authorization" request header field [RFC2617] with an
- authentication scheme defined by the specification of the access
- token type used, such as [RFC6750]::
-
- # Access tokens may also be provided in query and body
- https://example.com/protected?access_token=kjfch2345sdf # Query
- access_token=sdf23409df # Body
- """
- def __init__(self, default_token, token_types):
- BaseEndpoint.__init__(self)
- self._tokens = token_types
- self._default_token = default_token
-
- @property
- def default_token(self):
- return self._default_token
-
- @property
- def default_token_type_handler(self):
- return self.tokens.get(self.default_token)
-
- @property
- def tokens(self):
- return self._tokens
-
- @catch_errors_and_unavailability
- def verify_request(self, uri, http_method='GET', body=None, headers=None,
- scopes=None):
- """Validate client, code etc, return body + headers"""
- request = Request(uri, http_method, body, headers)
- request.token_type = self.find_token_type(request)
- request.scopes = scopes
- token_type_handler = self.tokens.get(request.token_type,
- self.default_token_type_handler)
- log.debug('Dispatching token_type %s request to %r.',
- request.token_type, token_type_handler)
- return token_type_handler.validate_request(request), request
-
- def find_token_type(self, request):
- """Token type identification.
-
- RFC 6749 does not provide a method for easily differentiating between
- different token types during protected resource access. We estimate
- the most likely token type (if any) by asking each known token type
- to give an estimation based on the request.
- """
- estimates = sorted(((t.estimate_type(request), n) for n, t in self.tokens.items()))
- return estimates[0][1] if len(estimates) else None
-
-
-class Server(AuthorizationEndpoint, TokenEndpoint, ResourceEndpoint):
- """An all-in-one endpoint featuring all four major grant types."""
-
- def __init__(self, request_validator, token_expires_in=None,
- *args, **kwargs):
- auth_grant = grant_types.AuthorizationCodeGrant(request_validator)
- implicit_grant = grant_types.ImplicitGrant(request_validator)
- password_grant = grant_types.ResourceOwnerPasswordCredentialsGrant(request_validator)
- credentials_grant = grant_types.ClientCredentialsGrant(request_validator)
- refresh_grant = grant_types.RefreshTokenGrant(request_validator)
- bearer = tokens.BearerToken(request_validator,
- expires_in=token_expires_in)
- AuthorizationEndpoint.__init__(self, default_response_type='code',
- response_types={
- 'code': auth_grant,
- 'token': implicit_grant,
- },
- default_token_type=bearer)
- TokenEndpoint.__init__(self, default_grant_type='authorization_code',
- grant_types={
- 'authorization_code': auth_grant,
- 'password': password_grant,
- 'client_credentials': credentials_grant,
- 'refresh_token': refresh_grant,
- },
- default_token_type=bearer)
- ResourceEndpoint.__init__(self, default_token='Bearer',
- token_types={'Bearer': bearer})
-
-
-class WebApplicationServer(AuthorizationEndpoint, TokenEndpoint, ResourceEndpoint):
- """An all-in-one endpoint featuring Authorization code grant and Bearer tokens."""
-
- def __init__(self, request_validator, token_generator=None,
- token_expires_in=None, **kwargs):
- """Construct a new web application server.
-
- :param request_validator: An implementation of oauthlib.oauth2.RequestValidator.
- :param token_generator: A function to generate a token from a request.
- :param kwargs: Extra parameters to pass to authorization endpoint,
- token endpoint and resource endpoint constructors.
- """
- auth_grant = grant_types.AuthorizationCodeGrant(request_validator)
- refresh_grant = grant_types.RefreshTokenGrant(request_validator)
- bearer = tokens.BearerToken(request_validator, token_generator,
- expires_in=token_expires_in)
- AuthorizationEndpoint.__init__(self, default_response_type='code',
- response_types={'code': auth_grant},
- default_token_type=bearer)
- TokenEndpoint.__init__(self, default_grant_type='authorization_code',
- grant_types={
- 'authorization_code': auth_grant,
- 'refresh_token': refresh_grant,
- },
- default_token_type=bearer)
- ResourceEndpoint.__init__(self, default_token='Bearer',
- token_types={'Bearer': bearer})
-
-
-class MobileApplicationServer(AuthorizationEndpoint, ResourceEndpoint):
- """An all-in-one endpoint featuring Implicit code grant and Bearer tokens."""
-
- def __init__(self, request_validator, token_generator=None,
- token_expires_in=None, **kwargs):
- implicit_grant = grant_types.ImplicitGrant(request_validator)
- bearer = tokens.BearerToken(request_validator, token_generator,
- expires_in=token_expires_in)
- AuthorizationEndpoint.__init__(self, default_response_type='token',
- response_types={'token': implicit_grant},
- default_token_type=bearer)
- ResourceEndpoint.__init__(self, default_token='Bearer',
- token_types={'Bearer': bearer})
-
-
-class LegacyApplicationServer(TokenEndpoint, ResourceEndpoint):
- """An all-in-one endpoint featuring Resource Owner Password Credentials grant and Bearer tokens."""
-
- def __init__(self, request_validator, token_generator=None,
- token_expires_in=None, **kwargs):
- password_grant = grant_types.ResourceOwnerPasswordCredentialsGrant(request_validator)
- refresh_grant = grant_types.RefreshTokenGrant(request_validator)
- bearer = tokens.BearerToken(request_validator, token_generator,
- expires_in=token_expires_in)
- TokenEndpoint.__init__(self, default_grant_type='password',
- grant_types={
- 'password': password_grant,
- 'refresh_token': refresh_grant,
- },
- default_token_type=bearer)
- ResourceEndpoint.__init__(self, default_token='Bearer',
- token_types={'Bearer': bearer})
-
-
-class BackendApplicationServer(TokenEndpoint, ResourceEndpoint):
- """An all-in-one endpoint featuring Client Credentials grant and Bearer tokens."""
-
- def __init__(self, request_validator, token_generator=None,
- token_expires_in=None, **kwargs):
- credentials_grant = grant_types.ClientCredentialsGrant(request_validator)
- bearer = tokens.BearerToken(request_validator, token_generator,
- expires_in=token_expires_in)
- TokenEndpoint.__init__(self, default_grant_type='client_credentials',
- grant_types={'client_credentials': credentials_grant},
- default_token_type=bearer)
- ResourceEndpoint.__init__(self, default_token='Bearer',
- token_types={'Bearer': bearer})