Merge pull request #3 from guyrt/master
[twitter-api-cdsw-solutions] / oauthlib / oauth2 / rfc6749 / errors.py
1 # coding=utf-8
2 """
3 oauthlib.oauth2.rfc6749.errors
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 Error used both by OAuth 2 clients and provicers to represent the spec
7 defined error responses for all four core grant types.
8 """
9 from __future__ import unicode_literals
10 import json
11 from oauthlib.common import urlencode, add_params_to_uri
12
13
14 class OAuth2Error(Exception):
15     error = None
16     status_code = 400
17     description = ''
18
19     def __init__(self, description=None, uri=None, state=None, status_code=None,
20                  request=None):
21         """
22         description:    A human-readable ASCII [USASCII] text providing
23                         additional information, used to assist the client
24                         developer in understanding the error that occurred.
25                         Values for the "error_description" parameter MUST NOT
26                         include characters outside the set
27                         x20-21 / x23-5B / x5D-7E.
28
29         uri:    A URI identifying a human-readable web page with information
30                 about the error, used to provide the client developer with
31                 additional information about the error.  Values for the
32                 "error_uri" parameter MUST conform to the URI- Reference
33                 syntax, and thus MUST NOT include characters outside the set
34                 x21 / x23-5B / x5D-7E.
35
36         state:  A CSRF protection value received from the client.
37
38         request:  Oauthlib Request object
39         """
40         self.description = description or self.description
41         message = '(%s) %s' % (self.error, self.description)
42         if request:
43             message += ' ' + repr(request)
44         super(OAuth2Error, self).__init__(message)
45
46         self.uri = uri
47         self.state = state
48
49         if status_code:
50             self.status_code = status_code
51
52         if request:
53             self.redirect_uri = request.redirect_uri
54             self.client_id = request.client_id
55             self.scopes = request.scopes
56             self.response_type = request.response_type
57             self.grant_type = request.grant_type
58             if not state:
59                 self.state = request.state
60
61     def in_uri(self, uri):
62         return add_params_to_uri(uri, self.twotuples)
63
64     @property
65     def twotuples(self):
66         error = [('error', self.error)]
67         if self.description:
68             error.append(('error_description', self.description))
69         if self.uri:
70             error.append(('error_uri', self.uri))
71         if self.state:
72             error.append(('state', self.state))
73         return error
74
75     @property
76     def urlencoded(self):
77         return urlencode(self.twotuples)
78
79     @property
80     def json(self):
81         return json.dumps(dict(self.twotuples))
82
83
84 class TokenExpiredError(OAuth2Error):
85     error = 'token_expired'
86
87
88 class InsecureTransportError(OAuth2Error):
89     error = 'insecure_transport'
90     description = 'OAuth 2 MUST utilize https.'
91
92
93 class MismatchingStateError(OAuth2Error):
94     error = 'mismatching_state'
95     description = 'CSRF Warning! State not equal in request and response.'
96
97
98 class MissingCodeError(OAuth2Error):
99     error = 'missing_code'
100
101
102 class MissingTokenError(OAuth2Error):
103     error = 'missing_token'
104
105
106 class MissingTokenTypeError(OAuth2Error):
107     error = 'missing_token_type'
108
109
110 class FatalClientError(OAuth2Error):
111
112     """Errors during authorization where user should not be redirected back.
113
114     If the request fails due to a missing, invalid, or mismatching
115     redirection URI, or if the client identifier is missing or invalid,
116     the authorization server SHOULD inform the resource owner of the
117     error and MUST NOT automatically redirect the user-agent to the
118     invalid redirection URI.
119
120     Instead the user should be informed of the error by the provider itself.
121     """
122     pass
123
124
125 class InvalidRedirectURIError(FatalClientError):
126     error = 'invalid_redirect_uri'
127
128
129 class MissingRedirectURIError(FatalClientError):
130     error = 'missing_redirect_uri'
131
132
133 class MismatchingRedirectURIError(FatalClientError):
134     error = 'mismatching_redirect_uri'
135
136
137 class MissingClientIdError(FatalClientError):
138     error = 'invalid_client_id'
139
140
141 class InvalidClientIdError(FatalClientError):
142     error = 'invalid_client_id'
143
144
145 class InvalidRequestError(OAuth2Error):
146
147     """The request is missing a required parameter, includes an invalid
148     parameter value, includes a parameter more than once, or is
149     otherwise malformed.
150     """
151     error = 'invalid_request'
152
153
154 class AccessDeniedError(OAuth2Error):
155
156     """The resource owner or authorization server denied the request."""
157     error = 'access_denied'
158     status_code = 401
159
160
161 class UnsupportedResponseTypeError(OAuth2Error):
162
163     """The authorization server does not support obtaining an authorization
164     code using this method.
165     """
166     error = 'unsupported_response_type'
167
168
169 class InvalidScopeError(OAuth2Error):
170
171     """The requested scope is invalid, unknown, or malformed."""
172     error = 'invalid_scope'
173     status_code = 401
174
175
176 class ServerError(OAuth2Error):
177
178     """The authorization server encountered an unexpected condition that
179     prevented it from fulfilling the request.  (This error code is needed
180     because a 500 Internal Server Error HTTP status code cannot be returned
181     to the client via a HTTP redirect.)
182     """
183     error = 'server_error'
184
185
186 class TemporarilyUnavailableError(OAuth2Error):
187
188     """The authorization server is currently unable to handle the request
189     due to a temporary overloading or maintenance of the server.
190     (This error code is needed because a 503 Service Unavailable HTTP
191     status code cannot be returned to the client via a HTTP redirect.)
192     """
193     error = 'temporarily_unavailable'
194
195
196 class InvalidClientError(OAuth2Error):
197
198     """Client authentication failed (e.g. unknown client, no client
199     authentication included, or unsupported authentication method).
200     The authorization server MAY return an HTTP 401 (Unauthorized) status
201     code to indicate which HTTP authentication schemes are supported.
202     If the client attempted to authenticate via the "Authorization" request
203     header field, the authorization server MUST respond with an
204     HTTP 401 (Unauthorized) status code, and include the "WWW-Authenticate"
205     response header field matching the authentication scheme used by the
206     client.
207     """
208     error = 'invalid_client'
209     status_code = 401
210
211
212 class InvalidGrantError(OAuth2Error):
213
214     """The provided authorization grant (e.g. authorization code, resource
215     owner credentials) or refresh token is invalid, expired, revoked, does
216     not match the redirection URI used in the authorization request, or was
217     issued to another client.
218     """
219     error = 'invalid_grant'
220     status_code = 401
221
222
223 class UnauthorizedClientError(OAuth2Error):
224
225     """The authenticated client is not authorized to use this authorization
226     grant type.
227     """
228     error = 'unauthorized_client'
229     status_code = 401
230
231
232 class UnsupportedGrantTypeError(OAuth2Error):
233
234     """The authorization grant type is not supported by the authorization
235     server.
236     """
237     error = 'unsupported_grant_type'
238
239
240 class UnsupportedTokenTypeError(OAuth2Error):
241
242     """The authorization server does not support the revocation of the
243     presented token type.  I.e. the client tried to revoke an access token
244     on a server not supporting this feature.
245     """
246     error = 'unsupported_token_type'
247
248
249 def raise_from_error(error, params=None):
250     import inspect
251     import sys
252     kwargs = {
253         'description': params.get('error_description'),
254         'uri': params.get('error_uri'),
255         'state': params.get('state')
256     }
257     for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass):
258         if cls.error == error:
259             raise cls(**kwargs)

Benjamin Mako Hill || Want to submit a patch?