Updated packages and code to python3. Won't work with python 2
[twitter-api-cdsw] / oauthlib / oauth2 / rfc6749 / grant_types / refresh_token.py
1 # -*- coding: utf-8 -*-
2 """
3 oauthlib.oauth2.rfc6749.grant_types
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 """
6 from __future__ import unicode_literals, absolute_import
7
8 import json
9 import logging
10
11 from .base import GrantTypeBase
12 from .. import errors, utils
13 from ..request_validator import RequestValidator
14
15 log = logging.getLogger(__name__)
16
17
18 class RefreshTokenGrant(GrantTypeBase):
19
20     """`Refresh token grant`_
21
22     .. _`Refresh token grant`: http://tools.ietf.org/html/rfc6749#section-6
23     """
24
25     @property
26     def issue_new_refresh_tokens(self):
27         return True
28
29     def __init__(self, request_validator=None, issue_new_refresh_tokens=True):
30         self.request_validator = request_validator or RequestValidator()
31
32     def create_token_response(self, request, token_handler):
33         """Create a new access token from a refresh_token.
34
35         If valid and authorized, the authorization server issues an access
36         token as described in `Section 5.1`_. If the request failed
37         verification or is invalid, the authorization server returns an error
38         response as described in `Section 5.2`_.
39
40         The authorization server MAY issue a new refresh token, in which case
41         the client MUST discard the old refresh token and replace it with the
42         new refresh token. The authorization server MAY revoke the old
43         refresh token after issuing a new refresh token to the client. If a
44         new refresh token is issued, the refresh token scope MUST be
45         identical to that of the refresh token included by the client in the
46         request.
47
48         .. _`Section 5.1`: http://tools.ietf.org/html/rfc6749#section-5.1
49         .. _`Section 5.2`: http://tools.ietf.org/html/rfc6749#section-5.2
50         """
51         headers = {
52             'Content-Type': 'application/json',
53             'Cache-Control': 'no-store',
54             'Pragma': 'no-cache',
55         }
56         try:
57             log.debug('Validating refresh token request, %r.', request)
58             self.validate_token_request(request)
59         except errors.OAuth2Error as e:
60             return headers, e.json, e.status_code
61
62         token = token_handler.create_token(request,
63                                            refresh_token=self.issue_new_refresh_tokens)
64         log.debug('Issuing new token to client id %r (%r), %r.',
65                   request.client_id, request.client, token)
66         return headers, json.dumps(token), 200
67
68     def validate_token_request(self, request):
69         # REQUIRED. Value MUST be set to "refresh_token".
70         if request.grant_type != 'refresh_token':
71             raise errors.UnsupportedGrantTypeError(request=request)
72
73         if request.refresh_token is None:
74             raise errors.InvalidRequestError(
75                 description='Missing refresh token parameter.',
76                 request=request)
77
78         # Because refresh tokens are typically long-lasting credentials used to
79         # request additional access tokens, the refresh token is bound to the
80         # client to which it was issued.  If the client type is confidential or
81         # the client was issued client credentials (or assigned other
82         # authentication requirements), the client MUST authenticate with the
83         # authorization server as described in Section 3.2.1.
84         # http://tools.ietf.org/html/rfc6749#section-3.2.1
85         if self.request_validator.client_authentication_required(request):
86             log.debug('Authenticating client, %r.', request)
87             if not self.request_validator.authenticate_client(request):
88                 log.debug('Invalid client (%r), denying access.', request)
89                 raise errors.InvalidClientError(request=request)
90         elif not self.request_validator.authenticate_client_id(request.client_id, request):
91             log.debug('Client authentication failed, %r.', request)
92             raise errors.InvalidClientError(request=request)
93
94         # Ensure client is authorized use of this grant type
95         self.validate_grant_type(request)
96
97         # REQUIRED. The refresh token issued to the client.
98         log.debug('Validating refresh token %s for client %r.',
99                   request.refresh_token, request.client)
100         if not self.request_validator.validate_refresh_token(
101                 request.refresh_token, request.client, request):
102             log.debug('Invalid refresh token, %s, for client %r.',
103                       request.refresh_token, request.client)
104             raise errors.InvalidGrantError(request=request)
105
106         original_scopes = utils.scope_to_list(
107             self.request_validator.get_original_scopes(
108                 request.refresh_token, request))
109
110         if request.scope:
111             request.scopes = utils.scope_to_list(request.scope)
112             if (not all((s in original_scopes for s in request.scopes))
113                 and not self.request_validator.is_within_original_scope(
114                     request.scopes, request.refresh_token, request)):
115                 log.debug('Refresh token %s lack requested scopes, %r.',
116                           request.refresh_token, request.scopes)
117                 raise errors.InvalidScopeError(request=request)
118         else:
119             request.scopes = original_scopes

Benjamin Mako Hill || Want to submit a patch?