Exemple #1
0
def test_request_delete_limit_email(_set_up_client, _reset_limits, _clear_db):
    client = app.test_client()
    limit = int(app.config['CREATE_EMAIL_RATE_LIMIT'].split('/')[0])
    ip_limit = int(app.config['IP_RATE_LIMIT'].split('/')[0])
    # Must hit email limit first
    assert limit < ip_limit
    response = create_email_alias()
    data = json.loads(response.data)
    email = data['email']
    assert response.status_code == status.HTTP_201_CREATED

    # Valid requests
    for _ in range(limit):
        data = dict(email=email, )
        data = json.dumps(data)
        response = client.post('/api/request_delete',
                               data=data,
                               content_type='application/json')
        assert response.status_code == status.HTTP_200_OK

    # Invalid request
    data = dict(email=email, )
    data = json.dumps(data)
    response = client.post('/api/request_delete',
                           data=data,
                           content_type='application/json')
    assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS
    assert 'Exceeded limit for same email address' in str(response.data)
    limit = str(limits.parse(app.config['REQUEST_DELETE_RATE_LIMIT']))
    assert limit in str(response.data)
Exemple #2
0
def test_create_rate_limit_ip(_set_up_client, _reset_limits, _clear_db):
    limit = int(app.config['IP_RATE_LIMIT'].split('/')[0])
    # Need to extend possibilities to hit rate limit
    app.config['BEAUTIFURL_FORMAT'] = 'www'
    for i in range(limit):
        response = create_email_alias(prefix=i)
        assert response.status_code == status.HTTP_201_CREATED
    response = create_email_alias()
    assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS
    assert 'Exceeded limit from same ip address' in str(response.data)
    limit = str(limits.parse(app.config['IP_RATE_LIMIT']))
    assert limit in str(response.data)
Exemple #3
0
def limiter(frequency):
    frequency = parse(frequency)

    def decorator(function):
        def wrapper(request, *args, **kwargs):
            namespace = f"{function.__module__}.{function.__name__}"
            ip = request.ip[0] or '127.0.0.1'
            ip = request.headers.get("X-Forwarded-For", ip)
            if not _MOVING_WINDOW.hit(frequency, namespace, ip):
                raise TooManyRequests(_LIMIT_MESSAGE)
            return function(request, *args, **kwargs)

        return wrapper

    return decorator
Exemple #4
0
def test_request_delete_rate_limit_ip(_set_up_client, _reset_limits,
                                      _clear_db):
    client = app.test_client()
    limit = int(app.config['IP_RATE_LIMIT'].split('/')[0])
    for i in range(limit):
        # Ensure each email unique to avoid email rate limit
        # Binary just for fun
        data = dict(email='{0:b}@shadowmail.co.uk'.format(i), )
        data = json.dumps(data)
        response = client.post('/api/request_delete',
                               data=data,
                               content_type='application/json')
        assert response.status_code == status.HTTP_400_BAD_REQUEST
        assert 'Email address not found' in str(response.data)
    data = dict(email='{0:b}@shadowmail.co.uk'.format(i + 1), )
    data = json.dumps(data)
    response = client.post('/api/request_delete',
                           data=data,
                           content_type='application/json')
    assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS
    assert 'Exceeded limit from same ip address' in str(response.data)
    limit = str(limits.parse(app.config['IP_RATE_LIMIT']))
    assert limit in str(response.data)
Exemple #5
0
 def get_limiter(self, limit, *args):
     return LimitWrapper(self.limiter, limits.parse(limit), *args)
Exemple #6
0
EMAIL_REGEX = '.+@.+'


@email_limiter.request_filter
def no_email_whitelist():
    data = request.get_json()
    return data is None or 'email' not in data


def get_email_from_request():
    data = request.get_json(force=True)
    return data['email']


IP_ERROR_MESSAGE = 'Exceeded limit from same ip address: {}'.format(
    limits.parse(app.config['IP_RATE_LIMIT']))

CREATE_EMAIL_ERROR_MESSAGE = 'Exceeded limit for same email address: {}'.format(
    limits.parse(app.config['CREATE_EMAIL_RATE_LIMIT']))

REQUEST_DELETE_ERROR_MESSAGE = 'Exceeded limit for same email address: {}'.format(
    limits.parse(app.config['REQUEST_DELETE_RATE_LIMIT']))


@app.route('/api/new', methods=['POST'])
@ip_limiter.limit(app.config['IP_RATE_LIMIT'],
                  get_remote_address,
                  error_message=IP_ERROR_MESSAGE)
@email_limiter.limit(app.config['CREATE_EMAIL_RATE_LIMIT'],
                     get_email_from_request,
                     error_message=CREATE_EMAIL_ERROR_MESSAGE)
Exemple #7
0
 def init_app(self, app):
     self.storage = limits.storage.storage_from_string(app.config["RATELIMIT_STORAGE_URL"])
     self.limiter = limits.strategies.MovingWindowRateLimiter(self.storage)
     self.rate = limits.parse(app.config["AUTH_RATELIMIT"])
     self.rate_limit_subnet = str(app.config["AUTH_RATELIMIT_SUBNET"])!='False'
     self.subnet = ipaddress.ip_network(app.config["SUBNET"])