Allow rate limiting on a per env basis

- switched off on prod by default
This commit is contained in:
Martyn Inglis
2017-04-25 09:54:09 +01:00
parent 926b8a60f9
commit 803c21865b
3 changed files with 35 additions and 12 deletions

View File

@@ -215,6 +215,7 @@ class Development(Config):
Queue('research-mode', Exchange('default'), routing_key='research-mode') Queue('research-mode', Exchange('default'), routing_key='research-mode')
] ]
API_HOST_NAME = "http://localhost:6011" API_HOST_NAME = "http://localhost:6011"
API_RATE_LIMIT_ENABLED = True
class Test(Config): class Test(Config):
@@ -237,6 +238,7 @@ class Test(Config):
Queue('research-mode', Exchange('default'), routing_key='research-mode') Queue('research-mode', Exchange('default'), routing_key='research-mode')
] ]
REDIS_ENABLED = True REDIS_ENABLED = True
API_RATE_LIMIT_ENABLED = True
API_HOST_NAME = "http://localhost:6011" API_HOST_NAME = "http://localhost:6011"
API_KEY_LIMITS = { API_KEY_LIMITS = {
@@ -260,6 +262,7 @@ class Preview(Config):
NOTIFY_ENVIRONMENT = 'preview' NOTIFY_ENVIRONMENT = 'preview'
CSV_UPLOAD_BUCKET_NAME = 'preview-notifications-csv-upload' CSV_UPLOAD_BUCKET_NAME = 'preview-notifications-csv-upload'
FROM_NUMBER = 'preview' FROM_NUMBER = 'preview'
API_RATE_LIMIT_ENABLED = True
class Staging(Config): class Staging(Config):
@@ -268,6 +271,7 @@ class Staging(Config):
CSV_UPLOAD_BUCKET_NAME = 'staging-notify-csv-upload' CSV_UPLOAD_BUCKET_NAME = 'staging-notify-csv-upload'
STATSD_ENABLED = True STATSD_ENABLED = True
FROM_NUMBER = 'stage' FROM_NUMBER = 'stage'
API_RATE_LIMIT_ENABLED = True
class Live(Config): class Live(Config):
@@ -279,6 +283,7 @@ class Live(Config):
FUNCTIONAL_TEST_PROVIDER_SERVICE_ID = '6c1d81bb-dae2-4ee9-80b0-89a4aae9f649' FUNCTIONAL_TEST_PROVIDER_SERVICE_ID = '6c1d81bb-dae2-4ee9-80b0-89a4aae9f649'
FUNCTIONAL_TEST_PROVIDER_SMS_TEMPLATE_ID = 'ba9e1789-a804-40b8-871f-cc60d4c1286f' FUNCTIONAL_TEST_PROVIDER_SMS_TEMPLATE_ID = 'ba9e1789-a804-40b8-871f-cc60d4c1286f'
PERFORMANCE_PLATFORM_ENABLED = True PERFORMANCE_PLATFORM_ENABLED = True
API_RATE_LIMIT_ENABLED = False
class CloudFoundryConfig(Config): class CloudFoundryConfig(Config):

View File

@@ -10,17 +10,18 @@ from notifications_utils.clients import redis
def check_service_over_api_rate_limit(service, api_key): def check_service_over_api_rate_limit(service, api_key):
cache_key = redis.rate_limit_cache_key(service.id, api_key.key_type) if current_app.config['API_RATE_LIMIT_ENABLED']:
rate_limit = current_app.config['API_KEY_LIMITS'][api_key.key_type]['limit'] cache_key = redis.rate_limit_cache_key(service.id, api_key.key_type)
interval = current_app.config['API_KEY_LIMITS'][api_key.key_type]['interval'] rate_limit = current_app.config['API_KEY_LIMITS'][api_key.key_type]['limit']
if redis_store.exceeded_rate_limit( interval = current_app.config['API_KEY_LIMITS'][api_key.key_type]['interval']
cache_key, if redis_store.exceeded_rate_limit(
rate_limit, cache_key,
interval): rate_limit,
raise RateLimitError( interval):
rate_limit, raise RateLimitError(
interval, rate_limit,
api_key.key_type) interval,
api_key.key_type)
def check_service_over_daily_message_limit(key_type, service): def check_service_over_daily_message_limit(key_type, service):

View File

@@ -1,6 +1,6 @@
import pytest import pytest
from freezegun import freeze_time from freezegun import freeze_time
from flask import current_app
import app import app
from app.notifications.validators import ( from app.notifications.validators import (
check_service_over_daily_message_limit, check_service_over_daily_message_limit,
@@ -320,3 +320,20 @@ def test_that_when_not_exceeded_rate_limit_request_succeeds(
limit, limit,
interval interval
) )
def test_should_not_rate_limit_if_limiting_is_disabled(
notify_db,
notify_db_session,
mocker):
with freeze_time("2016-01-01 12:00:00.000000"):
current_app.config['API_RATE_LIMIT_ENABLED'] = False
mocker.patch('app.redis_store.exceeded_rate_limit', return_value=False)
mocker.patch('app.notifications.validators.services_dao')
service = create_service(notify_db, notify_db_session, restricted=True)
api_key = sample_api_key(notify_db, notify_db_session, service=service)
check_service_over_api_rate_limit(service, api_key)
assert not app.redis_store.exceeded_rate_limit.called