Exemplo n.º 1
0
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
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
def error_method_not_allowed(exception):
    return FlaskApi.get_response(
        problem(
            status=exception.code,
            title="Invalid input",
            detail=exception.description,
            headers={"Allow": "POST"},
        ))
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
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')
Exemplo n.º 6
0
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')
Exemplo n.º 7
0
    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
Exemplo n.º 8
0
 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)
Exemplo n.º 9
0
    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))
Exemplo n.º 10
0
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,
    )