Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/oauthlib/oauth2/rfc6749/errors.py: 64%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

145 statements  

1""" 

2oauthlib.oauth2.rfc6749.errors 

3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

4 

5Error used both by OAuth 2 clients and providers to represent the spec 

6defined error responses for all four core grant types. 

7""" 

8import json 

9import inspect 

10import sys 

11 

12from oauthlib.common import add_params_to_uri, urlencode 

13 

14 

15class OAuth2Error(Exception): 

16 error = None 

17 status_code = 400 

18 description = '' 

19 

20 def __init__(self, description=None, uri=None, state=None, 

21 status_code=None, request=None): 

22 """ 

23 :param description: A human-readable ASCII [USASCII] text providing 

24 additional information, used to assist the client 

25 developer in understanding the error that occurred. 

26 Values for the "error_description" parameter 

27 MUST NOT include characters outside the set 

28 x20-21 / x23-5B / x5D-7E. 

29 

30 :param uri: A URI identifying a human-readable web page with information 

31 about the error, used to provide the client developer with 

32 additional information about the error. Values for the 

33 "error_uri" parameter MUST conform to the URI- Reference 

34 syntax, and thus MUST NOT include characters outside the set 

35 x21 / x23-5B / x5D-7E. 

36 

37 :param state: A CSRF protection value received from the client. 

38 

39 :param status_code: 

40 

41 :param request: OAuthlib request. 

42 :type request: oauthlib.common.Request 

43 """ 

44 if description is not None: 

45 self.description = description 

46 

47 message = '({}) {}'.format(self.error, self.description) 

48 if request: 

49 message += ' ' + repr(request) 

50 super().__init__(message) 

51 

52 self.uri = uri 

53 self.state = state 

54 

55 if status_code: 

56 self.status_code = status_code 

57 

58 if request: 

59 self.redirect_uri = request.redirect_uri 

60 self.client_id = request.client_id 

61 self.scopes = request.scopes 

62 self.response_type = request.response_type 

63 self.response_mode = request.response_mode 

64 self.grant_type = request.grant_type 

65 if state is None: 

66 self.state = request.state 

67 else: 

68 self.redirect_uri = None 

69 self.client_id = None 

70 self.scopes = None 

71 self.response_type = None 

72 self.response_mode = None 

73 self.grant_type = None 

74 

75 def in_uri(self, uri): 

76 fragment = self.response_mode == "fragment" 

77 return add_params_to_uri(uri, self.twotuples, fragment) 

78 

79 @property 

80 def twotuples(self): 

81 error = [('error', self.error)] 

82 if self.description: 

83 error.append(('error_description', self.description)) 

84 if self.uri: 

85 error.append(('error_uri', self.uri)) 

86 if self.state: 

87 error.append(('state', self.state)) 

88 return error 

89 

90 @property 

91 def urlencoded(self): 

92 return urlencode(self.twotuples) 

93 

94 @property 

95 def json(self): 

96 return json.dumps(dict(self.twotuples)) 

97 

98 @property 

99 def headers(self): 

100 if self.status_code == 401: 

101 """ 

102 https://tools.ietf.org/html/rfc6750#section-3 

103 

104 All challenges defined by this specification MUST use the auth-scheme 

105 value "Bearer". This scheme MUST be followed by one or more 

106 auth-param values. 

107 """ 

108 authvalues = ['error="{}"'.format(self.error)] 

109 if self.description: 

110 authvalues.append('error_description="{}"'.format(self.description)) 

111 if self.uri: 

112 authvalues.append('error_uri="{}"'.format(self.uri)) 

113 return {"WWW-Authenticate": "Bearer " + ", ".join(authvalues)} 

114 return {} 

115 

116 

117class TokenExpiredError(OAuth2Error): 

118 error = 'token_expired' 

119 

120 

121class InsecureTransportError(OAuth2Error): 

122 error = 'insecure_transport' 

123 description = 'OAuth 2 MUST utilize https.' 

124 

125 

126class MismatchingStateError(OAuth2Error): 

127 error = 'mismatching_state' 

128 description = 'CSRF Warning! State not equal in request and response.' 

129 

130 

131class MissingCodeError(OAuth2Error): 

132 error = 'missing_code' 

133 

134 

135class MissingTokenError(OAuth2Error): 

136 error = 'missing_token' 

137 

138 

139class MissingTokenTypeError(OAuth2Error): 

140 error = 'missing_token_type' 

141 

142 

143class FatalClientError(OAuth2Error): 

144 """ 

145 Errors during authorization where user should not be redirected back. 

146 

147 If the request fails due to a missing, invalid, or mismatching 

148 redirection URI, or if the client identifier is missing or invalid, 

149 the authorization server SHOULD inform the resource owner of the 

150 error and MUST NOT automatically redirect the user-agent to the 

151 invalid redirection URI. 

152 

153 Instead the user should be informed of the error by the provider itself. 

154 """ 

155 

156 

157class InvalidRequestFatalError(FatalClientError): 

158 """ 

159 For fatal errors, the request is missing a required parameter, includes 

160 an invalid parameter value, includes a parameter more than once, or is 

161 otherwise malformed. 

162 """ 

163 error = 'invalid_request' 

164 

165 

166class InvalidRedirectURIError(InvalidRequestFatalError): 

167 description = 'Invalid redirect URI.' 

168 

169 

170class MissingRedirectURIError(InvalidRequestFatalError): 

171 description = 'Missing redirect URI.' 

172 

173 

174class MismatchingRedirectURIError(InvalidRequestFatalError): 

175 description = 'Mismatching redirect URI.' 

176 

177 

178class InvalidClientIdError(InvalidRequestFatalError): 

179 description = 'Invalid client_id parameter value.' 

180 

181 

182class MissingClientIdError(InvalidRequestFatalError): 

183 description = 'Missing client_id parameter.' 

184 

185 

186class InvalidRequestError(OAuth2Error): 

187 """ 

188 The request is missing a required parameter, includes an invalid 

189 parameter value, includes a parameter more than once, or is 

190 otherwise malformed. 

191 """ 

192 error = 'invalid_request' 

193 

194 

195class MissingResponseTypeError(InvalidRequestError): 

196 description = 'Missing response_type parameter.' 

197 

198 

199class MissingCodeChallengeError(InvalidRequestError): 

200 """ 

201 If the server requires Proof Key for Code Exchange (PKCE) by OAuth 

202 public clients and the client does not send the "code_challenge" in 

203 the request, the authorization endpoint MUST return the authorization 

204 error response with the "error" value set to "invalid_request". The 

205 "error_description" or the response of "error_uri" SHOULD explain the 

206 nature of error, e.g., code challenge required. 

207 """ 

208 description = 'Code challenge required.' 

209 

210 

211class MissingCodeVerifierError(InvalidRequestError): 

212 """ 

213 The request to the token endpoint, when PKCE is enabled, has 

214 the parameter `code_verifier` REQUIRED. 

215 """ 

216 description = 'Code verifier required.' 

217 

218 

219class AccessDeniedError(OAuth2Error): 

220 """ 

221 The resource owner or authorization server denied the request. 

222 """ 

223 error = 'access_denied' 

224 

225 

226class UnsupportedResponseTypeError(OAuth2Error): 

227 """ 

228 The authorization server does not support obtaining an authorization 

229 code using this method. 

230 """ 

231 error = 'unsupported_response_type' 

232 

233 

234class UnsupportedCodeChallengeMethodError(InvalidRequestError): 

235 """ 

236 If the server supporting PKCE does not support the requested 

237 transformation, the authorization endpoint MUST return the 

238 authorization error response with "error" value set to 

239 "invalid_request". The "error_description" or the response of 

240 "error_uri" SHOULD explain the nature of error, e.g., transform 

241 algorithm not supported. 

242 """ 

243 description = 'Transform algorithm not supported.' 

244 

245 

246class InvalidScopeError(OAuth2Error): 

247 """ 

248 The requested scope is invalid, unknown, or malformed, or 

249 exceeds the scope granted by the resource owner. 

250 

251 https://tools.ietf.org/html/rfc6749#section-5.2 

252 """ 

253 error = 'invalid_scope' 

254 

255 

256class ServerError(OAuth2Error): 

257 """ 

258 The authorization server encountered an unexpected condition that 

259 prevented it from fulfilling the request. (This error code is needed 

260 because a 500 Internal Server Error HTTP status code cannot be returned 

261 to the client via a HTTP redirect.) 

262 """ 

263 error = 'server_error' 

264 

265 

266class TemporarilyUnavailableError(OAuth2Error): 

267 """ 

268 The authorization server is currently unable to handle the request 

269 due to a temporary overloading or maintenance of the server. 

270 (This error code is needed because a 503 Service Unavailable HTTP 

271 status code cannot be returned to the client via a HTTP redirect.) 

272 """ 

273 error = 'temporarily_unavailable' 

274 

275 

276class InvalidClientError(FatalClientError): 

277 """ 

278 Client authentication failed (e.g. unknown client, no client 

279 authentication included, or unsupported authentication method). 

280 The authorization server MAY return an HTTP 401 (Unauthorized) status 

281 code to indicate which HTTP authentication schemes are supported. 

282 If the client attempted to authenticate via the "Authorization" request 

283 header field, the authorization server MUST respond with an 

284 HTTP 401 (Unauthorized) status code, and include the "WWW-Authenticate" 

285 response header field matching the authentication scheme used by the 

286 client. 

287 """ 

288 error = 'invalid_client' 

289 status_code = 401 

290 

291 

292class InvalidGrantError(OAuth2Error): 

293 """ 

294 The provided authorization grant (e.g. authorization code, resource 

295 owner credentials) or refresh token is invalid, expired, revoked, does 

296 not match the redirection URI used in the authorization request, or was 

297 issued to another client. 

298 

299 https://tools.ietf.org/html/rfc6749#section-5.2 

300 """ 

301 error = 'invalid_grant' 

302 status_code = 400 

303 

304 

305class UnauthorizedClientError(OAuth2Error): 

306 """ 

307 The authenticated client is not authorized to use this authorization 

308 grant type. 

309 """ 

310 error = 'unauthorized_client' 

311 

312 

313class UnsupportedGrantTypeError(OAuth2Error): 

314 """ 

315 The authorization grant type is not supported by the authorization 

316 server. 

317 """ 

318 error = 'unsupported_grant_type' 

319 

320 

321class UnsupportedTokenTypeError(OAuth2Error): 

322 """ 

323 The authorization server does not support the hint of the 

324 presented token type. I.e. the client tried to revoke an access token 

325 on a server not supporting this feature. 

326 """ 

327 error = 'unsupported_token_type' 

328 

329 

330class InvalidTokenError(OAuth2Error): 

331 """ 

332 The access token provided is expired, revoked, malformed, or 

333 invalid for other reasons. The resource SHOULD respond with 

334 the HTTP 401 (Unauthorized) status code. The client MAY 

335 request a new access token and retry the protected resource 

336 request. 

337 """ 

338 error = 'invalid_token' 

339 status_code = 401 

340 description = ("The access token provided is expired, revoked, malformed, " 

341 "or invalid for other reasons.") 

342 

343 

344class InsufficientScopeError(OAuth2Error): 

345 """ 

346 The request requires higher privileges than provided by the 

347 access token. The resource server SHOULD respond with the HTTP 

348 403 (Forbidden) status code and MAY include the "scope" 

349 attribute with the scope necessary to access the protected 

350 resource. 

351 """ 

352 error = 'insufficient_scope' 

353 status_code = 403 

354 description = ("The request requires higher privileges than provided by " 

355 "the access token.") 

356 

357 

358class ConsentRequired(OAuth2Error): 

359 """ 

360 The Authorization Server requires End-User consent. 

361 

362 This error MAY be returned when the prompt parameter value in the 

363 Authentication Request is none, but the Authentication Request cannot be 

364 completed without displaying a user interface for End-User consent. 

365 """ 

366 error = 'consent_required' 

367 

368 

369class LoginRequired(OAuth2Error): 

370 """ 

371 The Authorization Server requires End-User authentication. 

372 

373 This error MAY be returned when the prompt parameter value in the 

374 Authentication Request is none, but the Authentication Request cannot be 

375 completed without displaying a user interface for End-User authentication. 

376 """ 

377 error = 'login_required' 

378 

379 

380class CustomOAuth2Error(OAuth2Error): 

381 """ 

382 This error is a placeholder for all custom errors not described by the RFC. 

383 Some of the popular OAuth2 providers are using custom errors. 

384 """ 

385 def __init__(self, error, *args, **kwargs): 

386 self.error = error 

387 super().__init__(*args, **kwargs) 

388 

389 

390def raise_from_error(error, params=None): 

391 kwargs = { 

392 'description': params.get('error_description'), 

393 'uri': params.get('error_uri'), 

394 'state': params.get('state') 

395 } 

396 for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass): 

397 if cls.error == error: 

398 raise cls(**kwargs) 

399 raise CustomOAuth2Error(error=error, **kwargs)