323 lines
8.8 KiB
Python
323 lines
8.8 KiB
Python
# Copyright (c) 2014 Mirantis Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from oslo_log import log
|
|
from six.moves import http_client
|
|
from six.moves.urllib.parse import urlparse
|
|
from wsme.exc import ClientSideError
|
|
|
|
from storyboard._i18n import _
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
class StoryboardException(ClientSideError):
|
|
"""Base Exception for the project
|
|
|
|
To correctly use this class, inherit from it and define
|
|
the 'message' property.
|
|
"""
|
|
|
|
message = _("An unknown exception occurred")
|
|
|
|
def __str__(self):
|
|
return self.message
|
|
|
|
def __init__(self, message=None, status_code=None):
|
|
super(StoryboardException, self).__init__(msg=message,
|
|
status_code=status_code)
|
|
|
|
|
|
class NotFound(StoryboardException):
|
|
message = _("Object not found")
|
|
|
|
def __init__(self, message=None):
|
|
super(NotFound, self).__init__(message, 404)
|
|
|
|
|
|
class NotEmpty(StoryboardException):
|
|
message = _("Database object must be empty")
|
|
|
|
def __init__(self, message=None):
|
|
if message:
|
|
self.message = message
|
|
|
|
|
|
class DBException(StoryboardException):
|
|
# Base exception for database errors
|
|
|
|
message = _("Database Exception")
|
|
|
|
def __init__(self, message=None, status_code=None):
|
|
"""Constructor for base exception class
|
|
|
|
:param: message: exception message.
|
|
:param: status_code: code of exception.
|
|
"""
|
|
if not status_code:
|
|
status_code = 400
|
|
|
|
super(DBException, self).__init__(message=message,
|
|
status_code=status_code)
|
|
|
|
|
|
class DBDuplicateEntry(DBException):
|
|
"""Duplicate entry exception
|
|
|
|
This exception wraps the same exception from database.
|
|
"""
|
|
|
|
message = _("Database object already exists.")
|
|
|
|
def __init__(self, message=None, object_name=None, value=None,
|
|
status_code=None):
|
|
"""Constructor for duplicate entry exception
|
|
|
|
:param : message: This message will be shown after exception raised.
|
|
:param : object_name: This parameter is name of object, in which
|
|
exception was raised.
|
|
:param: value: Invalid value.
|
|
:param: status_code: code of exception.
|
|
|
|
If object_name or value is not 'None', to message will be appended with
|
|
new message with information about object name or invalid value
|
|
"""
|
|
|
|
super(DBDuplicateEntry, self).__init__(message=message,
|
|
status_code=status_code)
|
|
db_message = None
|
|
|
|
if object_name or value:
|
|
db_message_list = [_("Database object")]
|
|
|
|
if object_name:
|
|
db_message_list.append(_("\'%s\'") % object_name)
|
|
|
|
if value:
|
|
db_message_list.append(_("with field value \'%s\'") % value)
|
|
else:
|
|
db_message_list.append(_("with some of unique fields"))
|
|
|
|
db_message_list.append(_("already exists."))
|
|
db_message = _(" ").join(db_message_list)
|
|
|
|
if db_message:
|
|
message_list = []
|
|
|
|
if message:
|
|
message_list.append(message)
|
|
|
|
message_list.append(db_message)
|
|
self.msg = " ".join(message_list)
|
|
|
|
|
|
class DBConnectionError(DBException):
|
|
"""Connection error exception
|
|
|
|
This exception wraps the same exception from database.
|
|
"""
|
|
|
|
message = _("Connection to database failed.")
|
|
|
|
|
|
class ColumnError(DBException):
|
|
"""Column error exception
|
|
|
|
This exception wraps the same exception from database.
|
|
"""
|
|
|
|
message = _("Column is invalid or not found")
|
|
|
|
|
|
class DBDeadLock(DBException):
|
|
"""Deadlock exception
|
|
|
|
This exception wraps the same exception from database.
|
|
"""
|
|
|
|
message = _("Database in dead lock")
|
|
|
|
|
|
class DBInvalidUnicodeParameter(DBException):
|
|
"""Invalid unicode parameter exception
|
|
|
|
This exception wraps the same exception from database.
|
|
"""
|
|
|
|
message = _("Unicode parameter is passed to "
|
|
"a database without encoding directive")
|
|
|
|
|
|
class DBMigrationError(DBException):
|
|
"""Migration error exception
|
|
|
|
This exception wraps the same exception from database.
|
|
"""
|
|
|
|
message = _("migrations could not be completed successfully")
|
|
|
|
|
|
class DBReferenceError(DBException):
|
|
"""Reference error exception
|
|
|
|
This exception wraps the same exception from database.
|
|
"""
|
|
|
|
message = _("Foreign key error.")
|
|
|
|
def __init__(self, message=None, object_name=None, value=None,
|
|
key=None, status_code=None):
|
|
"""Constructor for duplicate entry exception
|
|
|
|
:param : message: This message will be shown after exception raised.
|
|
:param : object_name: This parameter is name of object, in which
|
|
exception was raised.
|
|
:param: value: Invalid value.
|
|
:param : key: Field with invalid value.
|
|
:param : status_code: code of exception.
|
|
|
|
If object_name or value or key is not 'None', to message will be
|
|
appended with new message with information about object name or
|
|
invalid value or field with invalid value.
|
|
"""
|
|
|
|
super(DBReferenceError, self).__init__(message=message,
|
|
status_code=status_code)
|
|
db_message = None
|
|
|
|
if object_name or value or key:
|
|
db_message_list = []
|
|
|
|
if object_name:
|
|
db_message_list.append(
|
|
_("Error in object"))
|
|
db_message_list.append(_("\'%s\'.") % object_name)
|
|
|
|
if value or key:
|
|
db_message_list.append(_("Field"))
|
|
|
|
if key:
|
|
db_message_list.append(_("\'%s\'") % key)
|
|
|
|
if value:
|
|
db_message_list.append(_("value"))
|
|
db_message_list.append(_("\'%s\'") % value)
|
|
|
|
db_message_list.append(_("is invalid."))
|
|
|
|
db_message = " ".join(db_message_list)
|
|
|
|
if db_message:
|
|
message_list = []
|
|
|
|
if message:
|
|
message_list.append(message)
|
|
else:
|
|
message_list.append(self.message)
|
|
|
|
message_list.append(db_message)
|
|
self.msg = " ".join(message_list)
|
|
|
|
|
|
class DBInvalidSortKey(DBException):
|
|
"""Invalid sortkey error exception
|
|
|
|
This exception wraps the same exception from database.
|
|
"""
|
|
|
|
message = _("Invalid sort field")
|
|
|
|
|
|
class DBValueError(DBException):
|
|
"""Value error exception
|
|
|
|
This exception wraps standard ValueError exception.
|
|
"""
|
|
|
|
message = _("Unknown value.")
|
|
|
|
|
|
class OAuthException(ClientSideError):
|
|
"""Base Exception for our OAuth response handling. All of the error codes
|
|
used for this exception type are defined in the OAuth 2.0 Specification.
|
|
https://tools.ietf.org/html/rfc6749#section-5.2
|
|
|
|
To use, extend and override the 'error' field. Specific error description
|
|
messages need to be added when the exception is raised.
|
|
"""
|
|
|
|
error = "server_error"
|
|
|
|
redirect_uri = None
|
|
|
|
def __init__(self, message=None, redirect_uri=None):
|
|
|
|
if not redirect_uri:
|
|
code = http_client.BAD_REQUEST
|
|
else:
|
|
try:
|
|
parts = urlparse(redirect_uri)
|
|
if parts.scheme not in ['http', 'https']:
|
|
raise ValueError('Invalid scheme')
|
|
self.redirect_uri = redirect_uri
|
|
code = http_client.SEE_OTHER
|
|
except ValueError:
|
|
LOG.warning('Provided redirect_uri is invalid: %s'
|
|
% (redirect_uri,))
|
|
code = http_client.BAD_REQUEST
|
|
|
|
super(OAuthException, self) \
|
|
.__init__(msg=message, status_code=code)
|
|
|
|
|
|
class InvalidRequest(OAuthException):
|
|
error = "invalid_request"
|
|
|
|
|
|
class AccessDenied(OAuthException):
|
|
error = "access_denied"
|
|
|
|
|
|
class UnsupportedResponseType(OAuthException):
|
|
error = "unsupported_response_type"
|
|
|
|
|
|
class InvalidScope(OAuthException):
|
|
error = "invalid_scope"
|
|
|
|
|
|
class InvalidClient(OAuthException):
|
|
error = "invalid_client"
|
|
|
|
|
|
class UnauthorizedClient(OAuthException):
|
|
error = "unauthorized_client"
|
|
|
|
|
|
class InvalidGrant(OAuthException):
|
|
error = "invalid_grant"
|
|
|
|
|
|
class UnsupportedGrantType(OAuthException):
|
|
error = "unsupported_grant_type"
|
|
|
|
|
|
class ServerError(OAuthException):
|
|
error = "server_error"
|
|
|
|
|
|
class TemporarilyUnavailable(OAuthException):
|
|
error = "temporarily_unavailable"
|