Esempio n. 1
0
    def decorator(func):
        from functools import wraps

        @wraps(func)
        def inner(*args, **kwargs):
            from flask import request
            user = None
            if authorization:
                bearer_token = request.headers.get('Authorization')
                if bearer_token and len(bearer_token.split(' ')) == 2:
                    token = bearer_token.split(' ')[1]
                    user = AuthorizationUtils.get_user_info(token)
                    request.user_extra = user
                else:
                    raise ErrorTokenException

            if permissions is not None and isinstance(permissions, List):
                if user and user.role and user.role.has_all_permissions:
                    return func(*args, **kwargs)
                user_permissions = []
                if user and user.permissions:
                    user_permissions = user.permissions
                accept = all([(item in user_permissions)
                              for item in permissions])
                if not accept:
                    raise NotPermissionException
            if schema:
                if has_request_params:
                    try:
                        obj = schema.load(request.args)
                        request.parse_args = obj
                    except ValidationError:
                        raise PhysicalValidationException(
                            message='The query param is not valid')

                else:
                    try:
                        obj = schema.load(request.get_json())
                        request.parse_obj = obj
                    except ValidationError as err:
                        raise PhysicalValidationException(extra=err.messages)

            return func(*args, **kwargs)

        if api and use_swagger:
            if schema:
                inner = api.doc(
                    params={qp["name"]: qp
                            for qp in query_params},
                    body=for_swagger(
                        schema=schema,
                        model_name=get_default_model_name(schema),
                        api=api,
                        operation="load",
                    ),
                )(inner)
            elif _parser:
                inner = api.expect(_parser)(inner)
        return inner
Esempio n. 2
0
    def decorator(func):

        # Check if we are decorating a class method
        _IS_METHOD = _is_method(func)

        @wraps(func)
        def inner(*args, **kwargs):
            rv = func(*args, **kwargs)

            # If a Flask response has been made already, it is passed through unchanged
            if isinstance(rv, Response):
                return rv
            if schema:
                serialized = schema.dump(rv)

                # Validate data if asked to (throws)
                if validate:
                    errs = schema.validate(serialized)
                    if errs:
                        raise InternalServerError(
                            description=
                            "Server attempted to return invalid data")

                # Apply the flask-restx mask after validation
                serialized = _apply_restx_mask(serialized)
            else:
                from flask_restx import marshal

                serialized = marshal(rv, model_from_parser)

            if not _is_method(func):
                # Regular route, need to manually create Response
                return jsonify(serialized), status_code
            return serialized, status_code

        # Add Swagger
        if api and use_swagger and _IS_METHOD:
            if schema:
                api_model = for_swagger(schema=schema,
                                        model_name=model_name,
                                        api=api,
                                        operation="dump")
                if schema.many is True:
                    api_model = [api_model]

                inner = _document_like_marshal_with(
                    api_model,
                    status_code=status_code,
                    description=description,
                )(inner)

            elif _parser:
                api.add_model(model_name, model_from_parser)
                inner = _document_like_marshal_with(
                    model_from_parser, status_code=status_code)(inner)

        return inner
Esempio n. 3
0
    def decorator(func):
        from functools import wraps

        # Check if we are decorating a class method
        _IS_METHOD = _is_method(func)

        @wraps(func)
        def inner(*args, **kwargs):
            from flask import request

            error = schema_error = None
            # Handle arguments
            try:
                request.parsed_args = _parser.parse_args()
            except Exception as e:
                error = e

            # Handle Marshmallow schema
            if schema:
                try:
                    obj = schema.load(request.get_json())
                    request.parsed_obj = obj
                except ValidationError as ex:
                    schema_error = ex.messages
                if schema_error:
                    error = error or BadRequest(
                        f"Invalid parsing error: {schema_error}")
                    if hasattr(error, "data"):
                        error.data["errors"].update(
                            {"schema_errors": schema_error})
                    else:
                        error.data = {"schema_errors": schema_error}

            # If any parsing produced an error, combine them and re-raise
            if error:
                raise error

            return func(*args, **kwargs)

        # Add Swagger
        if api and use_swagger and _IS_METHOD:
            if schema:
                inner = api.doc(
                    params={qp["name"]: qp
                            for qp in query_params},
                    body=for_swagger(
                        schema=schema,
                        model_name=model_name
                        or get_default_model_name(schema),
                        api=api,
                        operation="load",
                    ),
                )(inner)
            elif _parser:
                inner = api.expect(_parser)(inner)
        return inner
Esempio n. 4
0
    def decorator(func):
        from functools import wraps

        # Check if we are decorating a class method
        _IS_METHOD = _is_method(func)

        @wraps(func)
        def inner(*args, **kwargs):
            from flask import request

            error = None
            # Handle arguments
            try:
                request.parsed_args = _parser.parse_args()
            except Exception as e:
                error = e

            # Handle Marshmallow schema
            if schema:
                obj, err = schema(many=many).load(request.get_json())
                if err:
                    error = error or ValueError("Invalid parsing error.")
                    if hasattr(error, "data"):
                        error.data["message"].update({"schema_errors": err})
                    else:
                        error.data = {"schema_errors": err}
                request.parsed_obj = obj

            # If any parsing produced an error, combine them and re-raise
            if error:
                raise (error)

            return func(*args, **kwargs)

        # Add Swagger
        if api and use_swagger and _IS_METHOD:
            if schema:
                inner = api.doc(
                    params={qp["name"]: qp for qp in query_params},
                    body=for_swagger(schema=schema, api=api),
                )(inner)
            elif _parser:
                inner = api.expect(_parser)(inner)
        return inner
Esempio n. 5
0
    def decorator(func):

        # Check if we are decorating a class method
        _IS_METHOD = _is_method(func)

        @wraps(func)
        def inner(*args, **kwargs):
            rv = func(*args, **kwargs)

            # If a Flask response has been made already, it is passed through unchanged
            if isinstance(rv, Response):
                return rv
            if schema:
                serialized = schema.dump(rv)
            else:
                from flask_restplus import marshal

                serialized = marshal(rv, model_from_parser)

            if not _is_method(func):
                # Regular route, need to manually create Response
                return jsonify(serialized), status_code
            return serialized, status_code

        # Add Swagger
        if api and use_swagger and _IS_METHOD:
            if schema:
                inner = _document_like_marshal_with(
                    for_swagger(schema=schema,
                                model_name=model_name,
                                api=api,
                                operation="dump"),
                    status_code=status_code,
                    description=description,
                )(inner)

            elif _parser:
                api.add_model(model_name, model_from_parser)
                inner = _document_like_marshal_with(
                    model_from_parser, status_code=status_code)(inner)

        return inner
Esempio n. 6
0
    def decorator(func):
        from functools import wraps

        # Check if we are decorating a class method
        _IS_METHOD = _is_method(func)

        @wraps(func)
        def inner(*args, **kwargs):
            from flask import request

            error = schema_error = None

            # Handle arguments
            try:
                request.parsed_args = _parser.parse_args()
            except Exception as e:
                error = e

            # Handle Marshmallow schema for request body
            if schema:
                try:
                    obj = schema.load(request.get_json())
                    request.parsed_obj = obj
                except ValidationError as ex:
                    schema_error = ex.messages
                if schema_error:
                    error = error or BadRequest(
                        f"Error parsing request body: {schema_error}")
                    if hasattr(error, "data"):
                        error.data["errors"].update(
                            {"schema_errors": schema_error})
                    else:
                        error.data = {"schema_errors": schema_error}

            # Handle Marshmallow schema for query params
            if query_params_schema:
                request_args = _convert_multidict_values_to_schema(
                    request.args, query_params_schema)

                try:
                    obj = query_params_schema.load(request_args)
                    request.parsed_query_params = obj
                except ValidationError as ex:
                    schema_error = ex.messages
                if schema_error:
                    error = error or BadRequest(
                        f"Error parsing query params: {schema_error}")
                    if hasattr(error, "data"):
                        error.data["errors"].update(
                            {"schema_errors": schema_error})
                    else:
                        error.data = {"schema_errors": schema_error}

            # Handle Marshmallow schema for headers
            if headers_schema:
                request_headers = _convert_multidict_values_to_schema(
                    request.headers, headers_schema)

                try:
                    obj = headers_schema.load(request_headers)
                    request.parsed_headers = obj
                except ValidationError as ex:
                    schema_error = ex.messages
                if schema_error:
                    error = error or BadRequest(
                        f"Error parsing headers: {schema_error}")
                    if hasattr(error, "data"):
                        error.data["errors"].update(
                            {"schema_errors": schema_error})
                    else:
                        error.data = {"schema_errors": schema_error}

            # If any parsing produced an error, combine them and re-raise
            if error:
                raise error

            return func(*args, **kwargs)

        # Add Swagger
        if api and use_swagger and _IS_METHOD:
            if schema:
                body = for_swagger(
                    schema=schema,
                    model_name=model_name or get_default_model_name(schema),
                    api=api,
                    operation="load",
                )
                params = {
                    "expect": [body, _parser],
                }
                inner = api.doc(**params)(inner)
            elif _parser:
                inner = api.expect(_parser)(inner)
        return inner
Esempio n. 7
0
    def decorator(func):

        # Check if we are decorating a class method
        _IS_METHOD = _is_method(func)

        @wraps(func)
        def inner(*args, **kwargs):
            rv = func(*args, **kwargs)

            # If a Flask response has been made already, it is passed through unchanged
            if isinstance(rv, Response):
                return rv
            if schema:
                serialized = schema.dump(rv)

                # Validate data if asked to (throws)
                if validate:
                    errs = schema.validate(serialized)
                    if errs:
                        raise InternalServerError(
                            description=
                            "Server attempted to return invalid data")

                # Apply the flask-restx mask after validation
                serialized = _apply_restx_mask(serialized)
            else:
                from flask_restx import marshal

                serialized = marshal(rv, model_from_parser)

            if envelope:
                serialized = OrderedDict([(envelope,
                                           serialized)]) if ordered else {
                                               envelope: serialized
                                           }

            if skip_none:

                def remove_none(obj):
                    if isinstance(obj, list):
                        return [
                            remove_none(entry) for entry in obj
                            if entry is not None
                        ]
                    if isinstance(obj, dict):
                        result = {}
                        for key, value in obj.items():
                            value = remove_none(value)
                            if key is not None and value is not None:
                                result[key] = value
                        return result
                    return obj

                serialized = remove_none(serialized)

            if not _is_method(func):
                # Regular route, need to manually create Response
                return jsonify(serialized), status_code
            return serialized, status_code

        # Add Swagger
        if api and use_swagger and _IS_METHOD:
            if schema:
                api_model = for_swagger(schema=schema,
                                        model_name=model_name,
                                        api=api,
                                        operation="dump")
                if schema.many is True:
                    api_model = [api_model]

                inner = _document_like_marshal_with(
                    api_model,
                    status_code=status_code,
                    description=description,
                )(inner)

            elif _parser:
                api.add_model(model_name, model_from_parser)
                inner = _document_like_marshal_with(
                    model_from_parser,
                    status_code=status_code,
                    description=description)(inner)

        return inner
Esempio n. 8
0
    def decorator(func):
        from functools import wraps

        # Check if we are decorating a class method
        _IS_METHOD = _is_method(func)

        @wraps(func)
        def inner(*args, **kwargs):
            from flask import request

            error = schema_error = None

            # Handle arguments
            try:
                request.parsed_args = _parser.parse_args()
            except Exception as e:
                error = e

            # Handle Marshmallow schema for request body
            if schema:
                try:
                    headers = request.headers.get('content-type', '')
                    # allow parsing multipart/form-data and x-www-form-urlencoded
                    if 'form' in headers:
                        data = {**request.form}
                        # convert form data with value string of dict/list to object dict/list
                        for key, value in data.items():
                            if isinstance(value, str) and value.strip():
                                try:
                                    data[key] = literal_eval(value)
                                except (ValueError, SyntaxError):
                                    pass
                        # add files to data
                        data.update(request.files)
                    else:
                        data = request.get_json(force=True)

                    obj = schema.load(data)
                    request.parsed_obj = obj
                except ValidationError as ex:
                    schema_error = ex.messages
                if schema_error:
                    error = error or BadRequest(
                        f"Error parsing request body: {schema_error}")
                    if hasattr(error, "data"):
                        error.data["errors"].update(
                            {"schema_errors": schema_error})
                    else:
                        error.data = {"schema_errors": schema_error}

            # Handle Marshmallow schema for query params
            if query_params_schema:
                request_args = _convert_multidict_values_to_schema(
                    request.args, query_params_schema)

                try:
                    obj = query_params_schema.load(request_args)
                    request.parsed_query_params = obj
                except ValidationError as ex:
                    schema_error = ex.messages
                if schema_error:
                    error = error or BadRequest(
                        f"Error parsing query params: {schema_error}")
                    if hasattr(error, "data"):
                        error.data["errors"].update(
                            {"schema_errors": schema_error})
                    else:
                        error.data = {"schema_errors": schema_error}

            # Handle Marshmallow schema for headers
            if headers_schema:
                request_headers = _convert_multidict_values_to_schema(
                    request.headers, headers_schema)

                try:
                    obj = headers_schema.load(request_headers)
                    request.parsed_headers = obj
                except ValidationError as ex:
                    schema_error = ex.messages
                if schema_error:
                    error = error or BadRequest(
                        f"Error parsing headers: {schema_error}")
                    if hasattr(error, "data"):
                        error.data["errors"].update(
                            {"schema_errors": schema_error})
                    else:
                        error.data = {"schema_errors": schema_error}

            # If any parsing produced an error, combine them and re-raise
            if error:
                raise error

            return func(*args, **kwargs)

        # Add Swagger
        if api and use_swagger and _IS_METHOD:
            if schema:
                body = for_swagger(
                    schema=schema,
                    model_name=model_name or get_default_model_name(schema),
                    api=api,
                    operation="load",
                )
                if schema.many is True:
                    body = [body]

                params = {
                    "expect": [body, _parser],
                }
                inner = api.doc(**params)(inner)
            elif _parser:
                inner = api.expect(_parser)(inner)
        return inner