2017-02-23 19:43:48 -05:00
from __future__ import unicode_literals
2015-02-10 15:31:28 +02:00
from werkzeug . exceptions import HTTPException
from jinja2 import DictLoader , Environment
2020-11-05 11:20:18 +00:00
import json
2015-02-10 15:31:28 +02:00
2019-10-31 08:44:26 -07:00
SINGLE_ERROR_RESPONSE = """ <?xml version= " 1.0 " encoding= " UTF-8 " ?>
2016-07-08 19:32:34 +00:00
< Error >
< Code > { { error_type } } < / Code >
< Message > { { message } } < / Message >
{ % block extra % } { % endblock % }
< RequestID > 7 a62c49f - 347e-4 fc4 - 9331 - 6e8 eEXAMPLE < / RequestID >
< / Error >
"""
2019-10-31 08:44:26 -07:00
ERROR_RESPONSE = """ <?xml version= " 1.0 " encoding= " UTF-8 " ?>
2019-09-27 11:14:53 -07:00
< ErrorResponse >
2015-02-10 15:31:28 +02:00
< Errors >
< Error >
2016-01-17 18:00:57 -05:00
< Code > { { error_type } } < / Code >
2015-02-10 15:31:28 +02:00
< Message > { { message } } < / Message >
{ % block extra % } { % endblock % }
< / Error >
< / Errors >
< RequestID > 7 a62c49f - 347e-4 fc4 - 9331 - 6e8 eEXAMPLE < / RequestID >
2019-09-27 11:14:53 -07:00
< / ErrorResponse >
2015-02-10 15:31:28 +02:00
"""
2019-10-31 08:44:26 -07:00
ERROR_JSON_RESPONSE = """ {
2016-01-17 18:00:57 -05:00
" message " : " {{ message}} " ,
" __type " : " {{ error_type}} "
}
"""
2015-02-10 15:31:28 +02:00
2017-02-23 21:37:43 -05:00
2015-02-10 15:31:28 +02:00
class RESTError ( HTTPException ) :
2017-10-28 20:17:34 +01:00
code = 400
2015-02-10 15:31:28 +02:00
templates = {
2019-10-31 08:44:26 -07:00
" single_error " : SINGLE_ERROR_RESPONSE ,
" error " : ERROR_RESPONSE ,
" error_json " : ERROR_JSON_RESPONSE ,
2015-02-10 15:31:28 +02:00
}
2019-10-31 08:44:26 -07:00
def __init__ ( self , error_type , message , template = " error " , * * kwargs ) :
2015-02-10 15:31:28 +02:00
super ( RESTError , self ) . __init__ ( )
env = Environment ( loader = DictLoader ( self . templates ) )
2016-01-17 18:00:57 -05:00
self . error_type = error_type
self . message = message
2015-02-10 15:31:28 +02:00
self . description = env . get_template ( template ) . render (
2019-10-31 08:44:26 -07:00
error_type = error_type , message = message , * * kwargs
)
2016-01-17 18:00:57 -05:00
2017-02-23 19:43:48 -05:00
class DryRunClientError ( RESTError ) :
code = 400
2016-01-17 18:00:57 -05:00
class JsonRESTError ( RESTError ) :
2019-10-31 08:44:26 -07:00
def __init__ ( self , error_type , message , template = " error_json " , * * kwargs ) :
super ( JsonRESTError , self ) . __init__ ( error_type , message , template , * * kwargs )
2016-01-17 18:00:57 -05:00
def get_headers ( self , * args , * * kwargs ) :
2019-10-31 08:44:26 -07:00
return [ ( " Content-Type " , " application/json " ) ]
2016-01-17 18:00:57 -05:00
def get_body ( self , * args , * * kwargs ) :
return self . description
2019-07-02 17:40:08 +02:00
class SignatureDoesNotMatchError ( RESTError ) :
2019-07-24 17:21:33 +02:00
code = 403
2019-07-02 17:40:08 +02:00
def __init__ ( self ) :
super ( SignatureDoesNotMatchError , self ) . __init__ (
2019-10-31 08:44:26 -07:00
" SignatureDoesNotMatch " ,
" The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details. " ,
)
2019-07-02 17:40:08 +02:00
class InvalidClientTokenIdError ( RESTError ) :
2019-07-24 17:21:33 +02:00
code = 403
2019-07-02 17:40:08 +02:00
def __init__ ( self ) :
super ( InvalidClientTokenIdError , self ) . __init__ (
2019-10-31 08:44:26 -07:00
" InvalidClientTokenId " ,
" The security token included in the request is invalid. " ,
)
2019-07-02 17:40:08 +02:00
class AccessDeniedError ( RESTError ) :
code = 403
2019-07-08 19:57:14 +02:00
def __init__ ( self , user_arn , action ) :
2019-07-02 17:40:08 +02:00
super ( AccessDeniedError , self ) . __init__ (
2019-10-31 08:44:26 -07:00
" AccessDenied " ,
2019-07-08 19:57:14 +02:00
" User: {user_arn} is not authorized to perform: {operation} " . format (
2019-10-31 08:44:26 -07:00
user_arn = user_arn , operation = action
) ,
)
2019-07-08 19:57:14 +02:00
class AuthFailureError ( RESTError ) :
2019-07-24 17:21:33 +02:00
code = 401
2019-07-08 19:57:14 +02:00
def __init__ ( self ) :
super ( AuthFailureError , self ) . __init__ (
2019-10-31 08:44:26 -07:00
" AuthFailure " ,
" AWS was not able to validate the provided access credentials " ,
)
2019-09-23 17:16:20 -07:00
2020-11-05 11:20:18 +00:00
class AWSError ( Exception ) :
TYPE = None
STATUS = 400
def __init__ ( self , message , type = None , status = None ) :
self . message = message
self . type = type if type is not None else self . TYPE
self . status = status if status is not None else self . STATUS
def response ( self ) :
return (
json . dumps ( { " __type " : self . type , " message " : self . message } ) ,
dict ( status = self . status ) ,
)
2019-09-23 17:16:20 -07:00
class InvalidNextTokenException ( JsonRESTError ) :
""" For AWS Config resource listing. This will be used by many different resource types, and so it is in moto.core. """
2019-10-31 08:44:26 -07:00
2019-09-23 17:16:20 -07:00
code = 400
def __init__ ( self ) :
2019-10-31 08:44:26 -07:00
super ( InvalidNextTokenException , self ) . __init__ (
" InvalidNextTokenException " , " The nextToken provided is invalid "
)