django-oidc-provider/oidc_provider/lib/errors.py
Wojciech Bartosiak a829726be8 Merge develop to v0.5.x (#179)
* Log create_uri_response exceptions to logger.exception

* Support grant type password - basics

* Add tests for Resource Owner Password Credentials Flow

* Password Grant -Response according to specification

* Better tests for errors, disable grant type password by default

* Add documentation for grant type password

* User authentication failure to return 403

* Add id_token to response

* skipping consent only works for confidential clients

* fix URI fragment

example not working URL `http://localhost:8100/#/auth/callback/`

* OIDC_POST_END_SESSION_HOOK + tests

* Explicit function naming

* Remove print statements

* No need for semicolons, this is Python

* Update CHANGELOG.md

* fixed logger message

* Improved `exp` value calculation

* rename OIDC_POST_END_SESSION_HOOK to OIDC_AFTER_END_SESSION_HOOK

* added docs for OIDC_AFTER_END_SESSION_HOOK

*  Replaces `LOGIN_URL` with `OIDC_LOGIN_URL`
so users can use a different login path for their oidc requests.

* Adds a setting variable for custom template paths

* Updates documentation

* Fixed bad try/except/finally block

* Adds test for OIDC_TEMPLATES settings

* Determine value for op_browser_state from session_key or default

* Do not use cookie for browser_state. It may not yet be there

* Add docs on new setting

OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY

* Fix compatibility for older versions of Django

* solved merging typo for missing @property
2017-05-05 05:19:57 +02:00

182 lines
6.2 KiB
Python

try:
from urllib.parse import quote
except ImportError:
from urllib import quote
class RedirectUriError(Exception):
error = 'Redirect URI Error'
description = 'The request fails due to a missing, invalid, or mismatching redirection URI (redirect_uri).'
class ClientIdError(Exception):
error = 'Client ID Error'
description = 'The client identifier (client_id) is missing or invalid.'
class UserAuthError(Exception):
"""
Specific to the Resource Owner Password Credentials flow when
the Resource Owners credentials are not valid.
"""
error = 'access_denied'
description = 'The resource owner or authorization server denied ' \
'the request'
def create_dict(self):
return {
'error': self.error,
'error_description': self.description,
}
class AuthorizeError(Exception):
_errors = {
# Oauth2 errors.
# https://tools.ietf.org/html/rfc6749#section-4.1.2.1
'invalid_request': 'The request is otherwise malformed',
'unauthorized_client': 'The client is not authorized to request an '
'authorization code using this method',
'access_denied': 'The resource owner or authorization server denied '
'the request',
'unsupported_response_type': 'The authorization server does not '
'support obtaining an authorization code '
'using this method',
'invalid_scope': 'The requested scope is invalid, unknown, or '
'malformed',
'server_error': 'The authorization server encountered an error',
'temporarily_unavailable': 'The authorization server is currently '
'unable to handle the request due to a '
'temporary overloading or maintenance of '
'the server',
# OpenID errors.
# http://openid.net/specs/openid-connect-core-1_0.html#AuthError
'interaction_required': 'The Authorization Server requires End-User '
'interaction of some form to proceed',
'login_required': 'The Authorization Server requires End-User '
'authentication',
'account_selection_required': 'The End-User is required to select a '
'session at the Authorization Server',
'consent_required': 'The Authorization Server requires End-User'
'consent',
'invalid_request_uri': 'The request_uri in the Authorization Request '
'returns an error or contains invalid data',
'invalid_request_object': 'The request parameter contains an invalid '
'Request Object',
'request_not_supported': 'The provider does not support use of the '
'request parameter',
'request_uri_not_supported': 'The provider does not support use of the '
'request_uri parameter',
'registration_not_supported': 'The provider does not support use of '
'the registration parameter',
}
def __init__(self, redirect_uri, error, grant_type):
self.error = error
self.description = self._errors.get(error)
self.redirect_uri = redirect_uri
self.grant_type = grant_type
def create_uri(self, redirect_uri, state):
description = quote(self.description)
# See:
# http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthError
hash_or_question = '#' if self.grant_type == 'implicit' else '?'
uri = '{0}{1}error={2}&error_description={3}'.format(
redirect_uri,
hash_or_question,
self.error,
description)
# Add state if present.
uri = uri + ('&state={0}'.format(state) if state else '')
return uri
class TokenError(Exception):
"""
OAuth2 token endpoint errors.
https://tools.ietf.org/html/rfc6749#section-5.2
"""
_errors = {
'invalid_request': 'The request is otherwise malformed',
'invalid_client': 'Client authentication failed (e.g., unknown client, '
'no client authentication included, or unsupported '
'authentication method)',
'invalid_grant': 'The provided authorization grant or refresh token is '
'invalid, expired, revoked, does not match the '
'redirection URI used in the authorization request, '
'or was issued to another client',
'unauthorized_client': 'The authenticated client is not authorized to '
'use this authorization grant type',
'unsupported_grant_type': 'The authorization grant type is not '
'supported by the authorization server',
'invalid_scope': 'The requested scope is invalid, unknown, malformed, '
'or exceeds the scope granted by the resource owner',
}
def __init__(self, error):
self.error = error
self.description = self._errors.get(error)
def create_dict(self):
dic = {
'error': self.error,
'error_description': self.description,
}
return dic
class BearerTokenError(Exception):
"""
OAuth2 errors.
https://tools.ietf.org/html/rfc6750#section-3.1
"""
_errors = {
'invalid_request': (
'The request is otherwise malformed', 400
),
'invalid_token': (
'The access token provided is expired, revoked, malformed, '
'or invalid for other reasons', 401
),
'insufficient_scope': (
'The request requires higher privileges than provided by '
'the access token', 403
),
}
def __init__(self, code):
self.code = code
error_tuple = self._errors.get(code, ('', ''))
self.description = error_tuple[0]
self.status = error_tuple[1]