def problems_middleware(request, handler): try: response = yield from handler(request) except ProblemException as exc: response = problem(status=exc.status, detail=exc.detail, title=exc.title, type=exc.type, instance=exc.instance, headers=exc.headers, ext=exc.ext) except (werkzeug_HTTPException, _HttpNotFoundError) as exc: response = problem(status=exc.code, title=exc.name, detail=exc.description) except web.HTTPError as exc: if exc.text == "{}: {}".format(exc.status, exc.reason): detail = HTTPStatus(exc.status).description else: detail = exc.text response = problem(status=exc.status, title=exc.reason, detail=detail) except ( web.HTTPException, # eg raised HTTPRedirection or HTTPSuccessful asyncio.CancelledError, # skipped in default web_protocol ): # leave this to default handling in aiohttp.web_protocol.RequestHandler.start() raise except asyncio.TimeoutError as exc: # overrides 504 from aiohttp.web_protocol.RequestHandler.start() logger.debug('Request handler timed out.', exc_info=exc) response = _generic_problem(HTTPStatus.GATEWAY_TIMEOUT, exc) except Exception as exc: # overrides 500 from aiohttp.web_protocol.RequestHandler.start() logger.exception('Error handling request', exc_info=exc) response = _generic_problem(HTTPStatus.INTERNAL_SERVER_ERROR, exc) if isinstance(response, ConnexionResponse): response = yield from AioHttpApi.get_response(response) return response
def common_error_handler(e): """ :type e: Exception """ if not isinstance(e, werkzeug.exceptions.HTTPException): e = werkzeug.exceptions.InternalServerError() return problem(title=e.name, detail=e.description, status=e.code)
def error_method_not_allowed(exception): return FlaskApi.get_response( problem( status=exception.code, title="Invalid input", detail=exception.description, headers={"Allow": "POST"}, ))
def validate_schema(self, data, schema): """ :type schema: dict :rtype: flask.Response | None """ schema_type = schema.get('type') log_extra = {'url': flask.request.url, 'schema_type': schema_type} expected_type = TYPE_MAP.get(schema_type) # type: type actual_type = type(data) # type: type if expected_type and not isinstance(data, expected_type): expected_type_name = expected_type.__name__ actual_type_name = actual_type.__name__ logger.error("'%s' is not a '%s'", data, expected_type_name) return problem(400, 'Bad Request', "Wrong type, expected '{}' got '{}'".format(schema_type, actual_type_name)) if schema_type == 'array': for item in data: error = self.validate_schema(item, schema.get('items')) if error: return error elif schema_type == 'object': # verify if required keys are present required_keys = schema.get('required', []) logger.debug('... required keys: %s', required_keys) log_extra['required_keys'] = required_keys for required_key in schema.get('required', required_keys): if required_key not in data: logger.error("Missing parameter '%s'", required_key, extra=log_extra) return problem(400, 'Bad Request', "Missing parameter '{}'".format(required_key)) # verify if value types are correct for key in data.keys(): key_properties = schema.get('properties', {}).get(key) if key_properties: error = self.validate_schema(data[key], key_properties) if error: return error else: for func in VALIDATORS: error = func(schema, data) if error: return problem(400, 'Bad Request', error)
def test_verify_oauth_invalid_auth_header(monkeypatch): def func(): pass wrapped_func = verify_oauth('https://example.org/tokeninfo', set(['admin']), func) request = MagicMock() app = MagicMock() monkeypatch.setattr('connexion.decorators.security.request', request) monkeypatch.setattr('flask.current_app', app) resp = wrapped_func() assert resp == problem(401, 'Unauthorized', 'Invalid authorization header')
def validate_schema(self, data, url): if self.is_null_value_valid and is_null(data): return None try: print(data) self.validator.validate(data) except ValidationError as exception: print("{url} validation error: {error}".format(url=url, error=exception)) return problem(400, "Bad Request", str(exception)) return None
def wrapper(*args, **kwargs): logger.debug("%s Oauth verification...", request.url) authorization = request.headers.get('Authorization') if authorization is None: logger.error("... No auth provided. Aborting with 401.") return problem(401, 'Unauthorized', "No authorization token provided") else: _, token = authorization.split() logger.debug("... Getting token '%s' from %s", token, token_info_url) token_request = requests.get(token_info_url, params={'access_token': token}) logger.debug("... Token info (%d): %s", token_request.status_code, token_request.text) if not token_request.ok: return problem(401, 'Unauthorized', "Provided oauth token is not valid") token_info = token_request.json() user_scopes = set(token_info['scope']) scopes_intersection = user_scopes & allowed_scopes logger.debug("... Scope intersection: %s", scopes_intersection) if not scopes_intersection: logger.error("... User scopes (%s) don't include one of the allowed scopes (%s). Aborting with 401.", user_scopes, allowed_scopes) return problem(403, 'Forbidden', "Provided token doesn't have the required scope") logger.info("... Token authenticated.") return function(*args, **kwargs)
def validate_formdata_parameter(self, param, request): print("param", param) print("request", request) try: if param.get('type') == 'file': val = request.files.get(param['name']) else: val = request.form.get(param['name']) res = self.validate_parameter('formdata', val, param) print(res) return res except ValidationError as e: print(e) return problem(400, "Bad Request", str(e))
def _generic_problem(http_status: HTTPStatus, exc: Exception = None): extra = None if exc is not None: loop = asyncio.get_event_loop() if loop.get_debug(): tb = None with suppress(Exception): tb = traceback.format_exc() if tb: extra = {"traceback": tb} return problem( status=http_status.value, title=http_status.phrase, detail=http_status.description, ext=extra, )