]> projects.mako.cc - twitter-api-cdsw-solutions/blob - oauthlib/oauth1/rfc5849/endpoints/authorization.py
Merge pull request #3 from guyrt/master
[twitter-api-cdsw-solutions] / oauthlib / oauth1 / rfc5849 / endpoints / authorization.py
1 # -*- coding: utf-8 -*-
2 """
3 oauthlib.oauth1.rfc5849.endpoints.authorization
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 This module is an implementation of various logic needed
7 for signing and checking OAuth 1.0 RFC 5849 requests.
8 """
9 from __future__ import absolute_import, unicode_literals
10
11 from oauthlib.common import Request, add_params_to_uri
12
13 from .base import BaseEndpoint
14 from .. import errors
15 try:
16     from urllib import urlencode
17 except ImportError:
18     from urllib.parse import urlencode
19
20
21 class AuthorizationEndpoint(BaseEndpoint):
22
23     """An endpoint responsible for letting authenticated users authorize access
24     to their protected resources to a client.
25
26     Typical use would be to have two views, one for displaying the authorization
27     form and one to process said form on submission.
28
29     The first view will want to utilize ``get_realms_and_credentials`` to fetch
30     requested realms and useful client credentials, such as name and
31     description, to be used when creating the authorization form.
32
33     During form processing you can use ``create_authorization_response`` to
34     validate the request, create a verifier as well as prepare the final
35     redirection URI used to send the user back to the client.
36
37     See :doc:`/oauth1/validator` for details on which validator methods to implement
38     for this endpoint.
39     """
40
41     def create_verifier(self, request, credentials):
42         """Create and save a new request token.
43
44         :param request: An oauthlib.common.Request object.
45         :param credentials: A dict of extra token credentials.
46         :returns: The verifier as a dict.
47         """
48         verifier = {
49             'oauth_token': request.resource_owner_key,
50             'oauth_verifier': self.token_generator(),
51         }
52         verifier.update(credentials)
53         self.request_validator.save_verifier(
54             request.resource_owner_key, verifier, request)
55         return verifier
56
57     def create_authorization_response(self, uri, http_method='GET', body=None,
58                                       headers=None, realms=None, credentials=None):
59         """Create an authorization response, with a new request token if valid.
60
61         :param uri: The full URI of the token request.
62         :param http_method: A valid HTTP verb, i.e. GET, POST, PUT, HEAD, etc.
63         :param body: The request body as a string.
64         :param headers: The request headers as a dict.
65         :param credentials: A list of credentials to include in the verifier.
66         :returns: A tuple of 3 elements.
67                   1. A dict of headers to set on the response.
68                   2. The response body as a string.
69                   3. The response status code as an integer.
70
71         If the callback URI tied to the current token is "oob", a response with
72         a 200 status code will be returned. In this case, it may be desirable to
73         modify the response to better display the verifier to the client.
74
75         An example of an authorization request::
76
77             >>> from your_validator import your_validator
78             >>> from oauthlib.oauth1 import AuthorizationEndpoint
79             >>> endpoint = AuthorizationEndpoint(your_validator)
80             >>> h, b, s = endpoint.create_authorization_response(
81             ...     'https://your.provider/authorize?oauth_token=...',
82             ...     credentials={
83             ...         'extra': 'argument',
84             ...     })
85             >>> h
86             {'Location': 'https://the.client/callback?oauth_verifier=...&extra=argument'}
87             >>> b
88             None
89             >>> s
90             302
91
92         An example of a request with an "oob" callback::
93
94             >>> from your_validator import your_validator
95             >>> from oauthlib.oauth1 import AuthorizationEndpoint
96             >>> endpoint = AuthorizationEndpoint(your_validator)
97             >>> h, b, s = endpoint.create_authorization_response(
98             ...     'https://your.provider/authorize?foo=bar',
99             ...     credentials={
100             ...         'extra': 'argument',
101             ...     })
102             >>> h
103             {'Content-Type': 'application/x-www-form-urlencoded'}
104             >>> b
105             'oauth_verifier=...&extra=argument'
106             >>> s
107             200
108         """
109         request = self._create_request(uri, http_method=http_method, body=body,
110                                        headers=headers)
111
112         if not request.resource_owner_key:
113             raise errors.InvalidRequestError(
114                 'Missing mandatory parameter oauth_token.')
115         if not self.request_validator.verify_request_token(
116                 request.resource_owner_key, request):
117             raise errors.InvalidClientError()
118
119         request.realms = realms
120         if (request.realms and not self.request_validator.verify_realms(
121                 request.resource_owner_key, request.realms, request)):
122             raise errors.InvalidRequestError(
123                 description=('User granted access to realms outside of '
124                              'what the client may request.'))
125
126         verifier = self.create_verifier(request, credentials or {})
127         redirect_uri = self.request_validator.get_redirect_uri(
128             request.resource_owner_key, request)
129         if redirect_uri == 'oob':
130             response_headers = {
131                 'Content-Type': 'application/x-www-form-urlencoded'}
132             response_body = urlencode(verifier)
133             return response_headers, response_body, 200
134         else:
135             populated_redirect = add_params_to_uri(
136                 redirect_uri, verifier.items())
137             return {'Location': populated_redirect}, None, 302
138
139     def get_realms_and_credentials(self, uri, http_method='GET', body=None,
140                                    headers=None):
141         """Fetch realms and credentials for the presented request token.
142
143         :param uri: The full URI of the token request.
144         :param http_method: A valid HTTP verb, i.e. GET, POST, PUT, HEAD, etc.
145         :param body: The request body as a string.
146         :param headers: The request headers as a dict.
147         :returns: A tuple of 2 elements.
148                   1. A list of request realms.
149                   2. A dict of credentials which may be useful in creating the
150                   authorization form.
151         """
152         request = self._create_request(uri, http_method=http_method, body=body,
153                                        headers=headers)
154
155         if not self.request_validator.verify_request_token(
156                 request.resource_owner_key, request):
157             raise errors.InvalidClientError()
158
159         realms = self.request_validator.get_realms(
160             request.resource_owner_key, request)
161         return realms, {'resource_owner_key': request.resource_owner_key}

Benjamin Mako Hill || Want to submit a patch?