diff --git a/tests/test_utils.py b/tests/test_utils.py index 83eff6acf..bc6b3999c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -326,6 +326,18 @@ def test_env_var_split(self): result = utils.split_env_var(test_case) self.assertEqual(result, expected) + def test_empty_env_var_split(self): + "When env var is blank or falsy, return empty list" + test_cases = [ + None, + "", + [], + ] + expected = [] + for test_case in test_cases: + result = utils.split_env_var(test_case) + self.assertEqual(result, expected) + class TestPercentages(TestCase): def test_get_percentage(self): diff --git a/webservices/rest.py b/webservices/rest.py index 2ba181c1b..2a720f1a3 100644 --- a/webservices/rest.py +++ b/webservices/rest.py @@ -145,9 +145,13 @@ def handle_error(error): RESTRICT_MESSAGE = "We apologize for the inconvenience, but we are temporarily " \ "blocking API traffic. Please contact apiinfo@fec.gov if this is an urgent issue." +# list of blocked user agent strings: ex: Googlebot, Bingbot, etc that will be result in the request +# being blocked if the user-agent header contains any of the specified strings +BLOCKED_USER_AGENTS = utils.split_env_var(env.get_credential('FEC_API_BLOCKED_USER_AGENTS')) + @app.before_request -def limit_remote_addr(): +def limit_access_based_on_request(): """ If `FEC_API_USE_PROXY` is set: - Reject all requests that are not routed through the API Umbrella @@ -176,6 +180,12 @@ def limit_remote_addr(): if request_api_key_id not in BYPASS_RESTRICTION_API_KEY_IDS: # Service unavailable abort(503, RESTRICT_MESSAGE) + user_agent = request.headers.get('User-Agent') + if user_agent and BLOCKED_USER_AGENTS: + for blocked_agent in BLOCKED_USER_AGENTS: + # user agent contains blocked agent string + if blocked_agent in user_agent: + abort(403) # Forbidden def get_cache_header(url): diff --git a/webservices/utils.py b/webservices/utils.py index 1540b8613..d0d8f430e 100644 --- a/webservices/utils.py +++ b/webservices/utils.py @@ -572,8 +572,14 @@ def post_to_slack(message, channel): def split_env_var(env_var): - """ Remove whitespace and split to a list based of comma delimiter""" - return env_var.replace(" ", "").split(",") + """ + Remove whitespace and split to a list based of comma delimiter. + If env var is None or blank string, return empty list + """ + if env_var: + return env_var.replace(" ", "").split(",") + else: + return [] # To display the open_date and close_date of JSON format inside object "mur"