Example #1
0
def key_resolver(func):
    @wrapt.decorator
    def wrapper(wrapped, _, args, kwargs):
        return wrapped(*args, **kwargs)

    wrapped_func = wrapper(func)
    get_metadata_storage().set('rate_limit_key_resolver', wrapped_func)

    return wrapped_func
Example #2
0
def provider(func):
    @wrapt.decorator
    def wrapper(wrapped, _, args, kwargs):
        return wrapped(*args, **kwargs)

    wrapped_func = wrapper(func)
    get_metadata_storage().set('auth_provider', wrapped_func)

    return wrapped_func
Example #3
0
        def wrapper(*args, **kwargs):
            instance = obj(*args, **kwargs)

            metadata = get_metadata_storage()
            blueprints = get_blueprints_storage()
            api_prefix = current_app.config.get('RESTLY_API_PREFIX').strip('/')

            if version not in blueprints.keys():
                bp = Blueprint('v%d' % version,
                               __name__,
                               url_prefix='/%s/v%d/' % (api_prefix, version))

                blueprints.set(version, bp)

            for key, value in metadata.get(obj.__name__, {}).items():
                route = _build_route(obj, value['path'])
                rule_name = _build_rule_name(obj, value['func'].__name__)
                view = _view_factory(instance, obj, value['func'],
                                     value['serialize'])

                blueprints.get(version).add_url_rule(
                    route,
                    rule_name,
                    view,
                    methods=[value['method']],
                )

            current_app.register_blueprint(blueprints.get(version))

            return instance
Example #4
0
def _view_factory(instance, obj, callback, serialize):
    serializer = current_app.config.get('RESTLY_SERIALIZER')
    deserialize = serializer.deserialize

    if serialize is None:
        serialize = serializer.serialize

    metadata = get_metadata_storage().get(obj.__name__).get(callback.__name__)
    outgoing = metadata.get('outgoing', None)
    incoming = metadata.get('incoming', None)
    skip_auth = metadata.get('skip_authorization', False)
    inject_identity = metadata.get('inject_identity', False)
    inject_body = metadata.get('inject_body', False)
    queued = metadata.get('queued', False)
    auth_provider = get_metadata_storage().get('auth_provider', lambda: True)
    identity_provider = get_metadata_storage().get('identity_provider', None)
    rate_limit_resolver = get_metadata_storage().get('rate_limit_resolver',
                                                     lambda: None)
    rate_limit_key_resolver = get_metadata_storage().get(
        'rate_limit_key_resolver', default_key_resolver)
    rating_limit = metadata.get('rating_limit', None)

    def wrapper(*args, **kwargs):
        if not skip_auth and auth_provider() is False:
            raise Forbidden()

        if inject_identity and identity_provider is not None:
            kwargs['identity'] = identity_provider()

        if rating_limit and rate_limit_resolver is not None:
            group = rating_limit.get('group', None)
            requests_limit = rating_limit.get(
                'requests',
                current_app.config.get('RESTLY_RATE_LIMIT_REQUESTS_AMOUNT'))
            window = rating_limit.get(
                'window',
                current_app.config.get('RESTLY_RATE_LIMIT_WINDOW_SECONDS'))

            key = rate_limit_key_resolver(group, kwargs.get('identity', None))

            requests_amount, valid_to = rate_limit_resolver(
                key, window, kwargs.get('identity', None))

            remaining = requests_limit - requests_amount

            if remaining < 0:
                raise TooManyRequests()

            request.rate_limit_headers = (requests_limit, remaining,
                                          int(valid_to))

        if inject_body:
            if len(request.get_data()) == 0:
                raise BadRequest(
                    "Body is required for given request but was not provided")

            kwargs['body'] = deserialize(request, incoming)

        response, code = callback(instance, *args, **kwargs)

        if isinstance(response, Response):
            return response, response.status_code

        return serialize(
            response, outgoing
        ) if response != '' else response, code if not queued else 202

    return wrapper