def dispatch_request(self, request): adapter = self.urls.bind_to_environ(request.environ) try: endpoint, values = adapter.match() cors_enabled = endpoint in self.cors_endpoints if not request.method in self.methods[endpoint]: if not cors_is_valid(request, self.methods): raise E.MethodNotAllowed() resp = self.endpoints[endpoint](request, *(), **values) if cors_enabled: origin_present = "Access-Control-Allow-Origin" in resp.headers headers_present = "Access-Control-Allow-Headers" in resp.headers if not origin_present: resp.headers["Access-Control-Allow-Origin"] = "*" if not headers_present: resp.headers[ "Access-Control-Allow-Headers"] = "Content-Type, Accept" return resp except E.HTTPException as e: return Response(status=e.code, response=e.get_body(), mimetype="application/xml", content_type="application/xml")
def patch_node(node_id): # Parse the request node_id = str2id(node_id) patch = request.get_json() # Find the node type. node = mongo.find_one_or_404('nodes', node_id, projection={'node_type': 1}) try: node_type = node['node_type'] except KeyError: msg = 'Node %s has no node_type property' % node_id log.warning(msg) raise wz_exceptions.InternalServerError(msg) log.debug('User %s wants to PATCH %s node %s', authentication.current_user_id(), node_type, node_id) # Find the PATCH handler for the node type. try: patch_handler = custom.patch_handlers[node_type] except KeyError: log.info('No patch handler for node type %r', node_type) raise wz_exceptions.MethodNotAllowed( 'PATCH on node type %r not allowed' % node_type) # Let the PATCH handler do its thing. return patch_handler(node_id, patch)
def test_special_exceptions(self): exc = exceptions.MethodNotAllowed(['GET', 'HEAD', 'POST']) h = dict(exc.get_headers({})) self.assert_equal(h['Allow'], 'GET, HEAD, POST') self.assert_('The method DELETE is not allowed' in exc.get_description({ 'REQUEST_METHOD': 'DELETE' }))
def test_special_exceptions(): """Special HTTP exceptions""" exc = exceptions.MethodNotAllowed(['GET', 'HEAD', 'POST']) h = dict(exc.get_headers({})) assert h['Allow'] == 'GET, HEAD, POST' assert 'The method DELETE is not allowed' in exc.get_description({ 'REQUEST_METHOD': 'DELETE' })
def dispatch_request(self, *args, **kwargs): method = request.method.lower() if method == 'get': if self.pk in kwargs and kwargs[self.pk] is not None: return self.get(*args, **kwargs) raise exceptions.MethodNotAllowed()
def entrypoint(self, *args, **kwargs): allowed_methods = self.get_allowed_methods() try: method = allowed_methods[self.request.method] except KeyError: valid_methods = list(allowed_methods.keys()) raise exceptions.MethodNotAllowed(valid_methods) return method(*args, **kwargs)
def _validate_readonly_access(obj): """Return 405 MethodNotAllowed if object is marked as read-only""" if not isinstance(obj, WithReadOnlyAccess): return if obj.readonly: raise exceptions.MethodNotAllowed( "The object is in a read-only mode and is dedicated for SOX needs" )
def __init__(self, limit): self.limit = limit # Set defaults self.code = 429 self.body = self.get_body() self.headers = self.get_headers() # Get the description if limit.error_message: self.description = limit.error_message if not callable( limit.error_message) else limit.error_message() else: self.description = text_type(limit.limit) # If error is given, get body & headers if self.limit.error_code: self.code = limit.error_code exception = exceptions.HTTPException(description=self.description) # Some common error codes, can add more here if self.code == 400: exception = exceptions.BadRequest() elif self.code == 401: exception = exceptions.Unauthorized() elif self.code == 403: exception = exceptions.Forbidden() elif self.code == 404: exception = exceptions.NotFound() elif self.code == 405: exception = exceptions.MethodNotAllowed() elif self.code == 406: exception = exceptions.NotAcceptable() elif self.code == 418: exception = exceptions.ImATeapot() # <3 elif self.code == 500: exception = exceptions.InternalServerError() elif self.code == 501: exception = exceptions.NotImplemented() # Update body & headers self.body = exception.get_body() self.headers = exception.get_headers() else: exception = exceptions.TooManyRequests( description=self.description) # Update body & headers self.body = exception.get_body() self.headers = exception.get_headers() super(RateLimitExceeded, self).__init__(description=self.description, response=Response(self.body, self.code, self.headers))
def dispatch_request(self): # type: () -> Response """Method that handles request verification and routing. This method can be used as a function to register on the URL rule. The request is verified through the registered list of verifiers, before invoking the request handlers. The method returns a JSON response for the Alexa service to respond to the request. :return: The skill response for the input request :rtype: flask.Response :raises: :py:class:`werkzeug.exceptions.MethodNotAllowed` if the method is invoked for other than HTTP POST request. :py:class:`werkzeug.exceptions.BadRequest` if the verification fails. :py:class:`werkzeug.exceptions.InternalServerError` for any internal exception. """ if flask_request.method != "POST": raise exceptions.MethodNotAllowed() if self._webservice_handler is None: raise AskSdkException("app not configured with skill handlers") try: content = flask_request.data.decode( verifier_constants.CHARACTER_ENCODING) response = self._webservice_handler.verify_request_and_dispatch( http_request_headers=typing.cast(typing.Dict[str, typing.Any], flask_request.headers), http_request_body=content) return jsonify(response) except VerificationException: current_app.logger.error("Request verification failed", exc_info=True) raise exceptions.BadRequest( description="Incoming request failed verification") except AskSdkException: current_app.logger.error("Skill dispatch exception", exc_info=True) raise exceptions.InternalServerError( description="Exception occurred during skill dispatch")
def validate_object_type_ggrcq(mapper, content, target): """Validate object_type actions for GGRCQ.""" from ggrc import login as login_module from ggrc.models import get_model from ggrc.models.mixins import synchronizable model = get_model(target.object_type) user = login_module.get_current_user(False) if not user or user.is_anonymous(): return should_prevent = all([ issubclass(model, synchronizable.Synchronizable), not login_module.is_external_app_user() ]) if should_prevent: raise exceptions.MethodNotAllowed()
def validate_definition_type_ecad(mapper, content, target): """Validate actions for eCAD object with definition_type.""" from ggrc import login as login_module from ggrc.models import get_model del mapper, content model = get_model(target.definition_type) user = login_module.get_current_user(False) if not user or user.is_anonymous(): return should_prevent = ( not login_module.is_external_app_user() or issubclass(model, mixins.CustomAttributable) ) if should_prevent: raise exceptions.MethodNotAllowed()
def on_proxy(self, request, user_token, url): proxy_tile = self.proxy_url_and_coords(url) if not proxy_tile: raise exceptions.BadRequest('unknown proxy url') if request.method not in ('GET', 'HEAD'): raise exceptions.MethodNotAllowed(valid_methods=['GET', 'HEAD']) try: if not self.tile_coverages.is_permitted(user_token, proxy_tile.layer, proxy_tile.tile_coord): raise exceptions.Forbidden() except InvalidUserToken: raise exceptions.Unauthorized() headers = end_to_end_headers(request.headers) try: resp = requests.request(request.method, proxy_tile.url, headers=headers, stream=True) except requests.exceptions.RequestException, ex: raise exceptions.BadGateway('source returned: %s' % ex)
def test_method_not_allowed_methods(): exc = exceptions.MethodNotAllowed(["GET", "HEAD", "POST"]) h = dict(exc.get_headers({})) assert h["Allow"] == "GET, HEAD, POST" assert "The method is not allowed" in exc.get_description()
def test_basic_errors(): assert UseCaseError(CustomUseCaseError()).to_dict() == { TITLE_KEY: 'Custom Use Case Error', STATUS_KEY: 'Bad Request', CODE_KEY: 'use-case-error', DETAIL_KEY: CustomUseCaseError.detail, SOURCE_KEY: CustomUseCaseError.source } assert ValidationError(**ERROR_KWARGS).to_dict() == { STATUS_KEY: 'Bad Request', CODE_KEY: 'validation-error', TITLE_KEY: 'Validation Error', **ERROR_KWARGS } assert MissingAttributesError(['1', '2', '3']).to_dict() == { TITLE_KEY: 'Missing Attributes Error', CODE_KEY: 'missing-attributes-error', STATUS_KEY: 'Bad Request', DETAIL_KEY: "Missing required attributes: ['1', '2', '3'].", SOURCE_KEY: ['1', '2', '3'] } assert InternalServerError(Exception('Test')).to_dict() == { STATUS_KEY: 'Internal Server Error', CODE_KEY: 'internal-server-error', TITLE_KEY: 'Internal Server Error', SOURCE_KEY: [{ 'type': Exception.__name__, 'str': str(Exception('Test')) }], DETAIL_KEY: 'Unexpected server error occured.' } # testing generation of required fields using werkzeug.exceptions # used for error handler generic http excetions formatting assert GenericHTTPError(exceptions.MethodNotAllowed()).to_dict() == { STATUS_KEY: 'Method Not Allowed', CODE_KEY: 'generic-http-error', TITLE_KEY: 'Method Not Allowed' } # testing equality between 3 different creation methods assert GenericHTTPError( exceptions.NotFound()).to_dict() == GenericHTTPError(404).to_dict() assert GenericHTTPError( exceptions.NotFound()).to_dict() == GenericHTTPError( StatusCode.NOT_FOUND).to_dict() # testing exception cases with pytest.raises(ValueError) as e: GenericHTTPError(0) assert str( e ) == 'Non generic HTTP exception. Can\'t find class for status: "0"' with pytest.raises(TypeError) as e: GenericHTTPError("Not Found") assert str(e) == ( 'GenericHTTPError "exception" kwarg must be the instance of:' + "['werkzeug.exceptions.HTTPException', 'http.HTTPStatus', 'int']") # testing extension of standard errors not_found_extended_dict = GenericHTTPError(exceptions.NotFound(), detail='Something', source=['Something']).to_dict() assert not_found_extended_dict == { STATUS_KEY: 'Not Found', CODE_KEY: 'generic-http-error', TITLE_KEY: 'Not Found', DETAIL_KEY: 'Something', SOURCE_KEY: ['Something'] } # this way of creation is my favorite assert not_found_extended_dict == GenericHTTPError(StatusCode.NOT_FOUND, detail='Something', source=['Something' ]).to_dict() # this one is ok, but it's always better to use constants assert not_found_extended_dict == GenericHTTPError(404, detail='Something', source=['Something' ]).to_dict() # using enum item object assert not_found_extended_dict == GenericHTTPError(StatusCode(404), detail='Something', source=['Something' ]).to_dict() with pytest.raises(ValueError) as e: ErrorsList(Exception('Hello'), GenericHTTPError(404)) assert str(e.value) == 'All errors should be the instance of BaseError'
def patch(self, **kwargs): self._audit_before() raise http_exception.MethodNotAllowed(description='Unable to update/replace every resource in the entire collection')
def get(self): # GET is not allowed, however flask restful doesn't handle "GET" not # being allowed cleanly. Here we explicitly mark is as not allowed. All # other methods not defined would raise a method NotAllowed error and # this would not be needed. raise exceptions.MethodNotAllowed(valid_methods=['POST'])
def test_special_exceptions(): exc = exceptions.MethodNotAllowed(['GET', 'HEAD', 'POST']) h = dict(exc.get_headers({})) assert h['Allow'] == 'GET, HEAD, POST' assert 'The method is not allowed' in exc.get_description()
def get(self): # SPECIAL CASE: GET is not allowed, raise METHOD_NOT_ALLOWED raise exceptions.MethodNotAllowed(valid_methods=['POST'])
def get(self, user_id): # Special case, GET is not allowed. raise exceptions.MethodNotAllowed(valid_methods=['POST'])
def raise_method_is_not_allowed(*args, **kwargs): """Raise MethodNotAllowed exception for use with sa.event.listen""" del args, kwargs raise exceptions.MethodNotAllowed()
def delete(self, **kwargs): self._audit_before() return http_exception.MethodNotAllowed(description='Unable to delete the whole collection')
def test_special_exceptions(self): exc = exceptions.MethodNotAllowed(['GET', 'HEAD', 'POST']) h = dict(exc.get_headers({})) self.assert_equal(h['Allow'], 'GET, HEAD, POST') self.assert_true('The method is not allowed' in exc.get_description())
def call(self, path=None, query=None, data=None, method='GET'): # this avoids the request being sent as a GET when there is no data.. if method == 'POST' and (data is None or len(data) < 1): data = '{}' result = '{}' status = 200 request = Request(self._url(self.app.base_url + path, query), data=data, headers={ 'Content-Type': 'application/json', 'Authorization': 'bearer ' + self.access_token}) rate_limit = 0 rate_limit_remaining = 0 user_scopes = [] accepted_scopes = [] try: response = urlopen(request) result = response.read() response.close() status = response.code # parse info from github api response headers.. rate_limit = int(response.headers.dict.get( 'x-ratelimit-limit', 0)) rate_limit_remaining = int(response.headers.dict.get( 'x-ratelimit-remaining', 0)) user_scopes = response.headers.dict.get( 'x-oauth-scopes', '').split(',') accepted_scopes = response.headers.dict.get( 'x-accepted-oauth-scopes', '').split(',') print 'rate_limit: %s' % (rate_limit) print 'rate_limit_remaining: %s' % (rate_limit_remaining) print 'user_scopes: %s' % (user_scopes) print 'accepted_scopes: %s' % (accepted_scopes) except: import traceback print 'HttpError: %s' % traceback.format_exc() # response = self.app.request(self._url(path, query), # method=method, data=data, content_type='application/json', # headers={ # 'Accept': 'application/json', # 'Authorization': self.access_token}, # token=self.access_token) # result = dumps({'response': response.data}) # todo: i need a root node.. i don't knot if i can serialize anonymous # root lists.. so i'm serializing, adding root node, then encoding back # to a json str.. sorry for the waste. # status = response.status if status == 401: raise exceptions.Unauthorized('''Error with Github api request: 401, user is not authorized: %s.''' % result) elif status == 403: raise exceptions.MethodNotAllowed('''Error with Github api request: 403, user is authenticated, but doesn't have permissions.''') elif status == 404: raise exceptions.NotFound('''Error with Github api request: 404, data not found: %s''' % result) elif status > 299: raise exceptions.BadRequest( 'Error with github api request: %s, %s' % (status, result)) return '{"response": ' + result + '}'