Updated packages and code to python3. Won't work with python 2
[twitter-api-cdsw] / oauthlib / oauth2 / rfc6749 / clients / web_application.py
1 # -*- coding: utf-8 -*-
2 """
3 oauthlib.oauth2.rfc6749
4 ~~~~~~~~~~~~~~~~~~~~~~~
5
6 This module is an implementation of various logic needed
7 for consuming and providing OAuth 2.0 RFC6749.
8 """
9 from __future__ import absolute_import, unicode_literals
10
11 from .base import Client
12 from ..parameters import prepare_grant_uri, prepare_token_request
13 from ..parameters import parse_authorization_code_response
14 from ..parameters import parse_token_response
15
16
17 class WebApplicationClient(Client):
18
19     """A client utilizing the authorization code grant workflow.
20
21     A web application is a confidential client running on a web
22     server.  Resource owners access the client via an HTML user
23     interface rendered in a user-agent on the device used by the
24     resource owner.  The client credentials as well as any access
25     token issued to the client are stored on the web server and are
26     not exposed to or accessible by the resource owner.
27
28     The authorization code grant type is used to obtain both access
29     tokens and refresh tokens and is optimized for confidential clients.
30     As a redirection-based flow, the client must be capable of
31     interacting with the resource owner's user-agent (typically a web
32     browser) and capable of receiving incoming requests (via redirection)
33     from the authorization server.
34     """
35
36     def __init__(self, client_id, code=None, **kwargs):
37         super(WebApplicationClient, self).__init__(client_id, **kwargs)
38         self.code = code
39
40     def prepare_request_uri(self, uri, redirect_uri=None, scope=None,
41                             state=None, **kwargs):
42         """Prepare the authorization code request URI
43
44         The client constructs the request URI by adding the following
45         parameters to the query component of the authorization endpoint URI
46         using the "application/x-www-form-urlencoded" format, per `Appendix B`_:
47
48         :param redirect_uri:  OPTIONAL. The redirect URI must be an absolute URI
49                               and it should have been registerd with the OAuth
50                               provider prior to use. As described in `Section 3.1.2`_.
51
52         :param scope:  OPTIONAL. The scope of the access request as described by
53                        Section 3.3`_. These may be any string but are commonly
54                        URIs or various categories such as ``videos`` or ``documents``.
55
56         :param state:   RECOMMENDED.  An opaque value used by the client to maintain
57                         state between the request and callback.  The authorization
58                         server includes this value when redirecting the user-agent back
59                         to the client.  The parameter SHOULD be used for preventing
60                         cross-site request forgery as described in `Section 10.12`_.
61
62         :param kwargs:  Extra arguments to include in the request URI.
63
64         In addition to supplied parameters, OAuthLib will append the ``client_id``
65         that was provided in the constructor as well as the mandatory ``response_type``
66         argument, set to ``code``::
67
68             >>> from oauthlib.oauth2 import WebApplicationClient
69             >>> client = WebApplicationClient('your_id')
70             >>> client.prepare_request_uri('https://example.com')
71             'https://example.com?client_id=your_id&response_type=code'
72             >>> client.prepare_request_uri('https://example.com', redirect_uri='https://a.b/callback')
73             'https://example.com?client_id=your_id&response_type=code&redirect_uri=https%3A%2F%2Fa.b%2Fcallback'
74             >>> client.prepare_request_uri('https://example.com', scope=['profile', 'pictures'])
75             'https://example.com?client_id=your_id&response_type=code&scope=profile+pictures'
76             >>> client.prepare_request_uri('https://example.com', foo='bar')
77             'https://example.com?client_id=your_id&response_type=code&foo=bar'
78
79         .. _`Appendix B`: http://tools.ietf.org/html/rfc6749#appendix-B
80         .. _`Section 2.2`: http://tools.ietf.org/html/rfc6749#section-2.2
81         .. _`Section 3.1.2`: http://tools.ietf.org/html/rfc6749#section-3.1.2
82         .. _`Section 3.3`: http://tools.ietf.org/html/rfc6749#section-3.3
83         .. _`Section 10.12`: http://tools.ietf.org/html/rfc6749#section-10.12
84         """
85         return prepare_grant_uri(uri, self.client_id, 'code',
86                                  redirect_uri=redirect_uri, scope=scope, state=state, **kwargs)
87
88     def prepare_request_body(self, client_id=None, code=None, body='',
89                              redirect_uri=None, **kwargs):
90         """Prepare the access token request body.
91
92         The client makes a request to the token endpoint by adding the
93         following parameters using the "application/x-www-form-urlencoded"
94         format in the HTTP request entity-body:
95
96         :param client_id:   REQUIRED, if the client is not authenticating with the
97                             authorization server as described in `Section 3.2.1`_.
98
99         :param code:    REQUIRED. The authorization code received from the
100                         authorization server.
101
102         :param redirect_uri:    REQUIRED, if the "redirect_uri" parameter was included in the
103                                 authorization request as described in `Section 4.1.1`_, and their
104                                 values MUST be identical.
105
106         :param kwargs: Extra parameters to include in the token request.
107
108         In addition OAuthLib will add the ``grant_type`` parameter set to
109         ``authorization_code``.
110
111         If the client type is confidential or the client was issued client
112         credentials (or assigned other authentication requirements), the
113         client MUST authenticate with the authorization server as described
114         in `Section 3.2.1`_::
115
116             >>> from oauthlib.oauth2 import WebApplicationClient
117             >>> client = WebApplicationClient('your_id')
118             >>> client.prepare_request_body(code='sh35ksdf09sf')
119             'grant_type=authorization_code&code=sh35ksdf09sf'
120             >>> client.prepare_request_body(code='sh35ksdf09sf', foo='bar')
121             'grant_type=authorization_code&code=sh35ksdf09sf&foo=bar'
122
123         .. _`Section 4.1.1`: http://tools.ietf.org/html/rfc6749#section-4.1.1
124         .. _`Section 3.2.1`: http://tools.ietf.org/html/rfc6749#section-3.2.1
125         """
126         code = code or self.code
127         return prepare_token_request('authorization_code', code=code, body=body,
128                                      client_id=self.client_id, redirect_uri=redirect_uri, **kwargs)
129
130     def parse_request_uri_response(self, uri, state=None):
131         """Parse the URI query for code and state.
132
133         If the resource owner grants the access request, the authorization
134         server issues an authorization code and delivers it to the client by
135         adding the following parameters to the query component of the
136         redirection URI using the "application/x-www-form-urlencoded" format:
137
138         :param uri: The callback URI that resulted from the user being redirected
139                     back from the provider to you, the client.
140         :param state: The state provided in the authorization request.
141
142         **code**
143             The authorization code generated by the authorization server.
144             The authorization code MUST expire shortly after it is issued
145             to mitigate the risk of leaks. A maximum authorization code
146             lifetime of 10 minutes is RECOMMENDED. The client MUST NOT
147             use the authorization code more than once. If an authorization
148             code is used more than once, the authorization server MUST deny
149             the request and SHOULD revoke (when possible) all tokens
150             previously issued based on that authorization code.
151             The authorization code is bound to the client identifier and
152             redirection URI.
153
154         **state**
155                 If the "state" parameter was present in the authorization request.
156
157         This method is mainly intended to enforce strict state checking with
158         the added benefit of easily extracting parameters from the URI::
159
160             >>> from oauthlib.oauth2 import WebApplicationClient
161             >>> client = WebApplicationClient('your_id')
162             >>> uri = 'https://example.com/callback?code=sdfkjh345&state=sfetw45'
163             >>> client.parse_request_uri_response(uri, state='sfetw45')
164             {'state': 'sfetw45', 'code': 'sdfkjh345'}
165             >>> client.parse_request_uri_response(uri, state='other')
166             Traceback (most recent call last):
167                 File "<stdin>", line 1, in <module>
168                 File "oauthlib/oauth2/rfc6749/__init__.py", line 357, in parse_request_uri_response
169                     back from the provider to you, the client.
170                 File "oauthlib/oauth2/rfc6749/parameters.py", line 153, in parse_authorization_code_response
171                     raise MismatchingStateError()
172             oauthlib.oauth2.rfc6749.errors.MismatchingStateError
173         """
174         response = parse_authorization_code_response(uri, state=state)
175         self._populate_attributes(response)
176         return response

Benjamin Mako Hill || Want to submit a patch?