mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-07 16:28:25 -04:00
Merge pull request #1643 from alphagov/add_proxy_header_check
Add proxy header check
This commit is contained in:
@@ -158,6 +158,7 @@ def init_app(application):
|
|||||||
application.after_request(useful_headers_after_request)
|
application.after_request(useful_headers_after_request)
|
||||||
application.after_request(save_service_after_request)
|
application.after_request(save_service_after_request)
|
||||||
application.before_request(load_service_before_request)
|
application.before_request(load_service_before_request)
|
||||||
|
application.before_request(request_helper.check_proxy_header_before_request)
|
||||||
|
|
||||||
@application.context_processor
|
@application.context_processor
|
||||||
def _attach_current_service():
|
def _attach_current_service():
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ def extract_notify_config(notify_config):
|
|||||||
os.environ['ADMIN_BASE_URL'] = notify_config['credentials']['admin_base_url']
|
os.environ['ADMIN_BASE_URL'] = notify_config['credentials']['admin_base_url']
|
||||||
os.environ['SECRET_KEY'] = notify_config['credentials']['secret_key']
|
os.environ['SECRET_KEY'] = notify_config['credentials']['secret_key']
|
||||||
os.environ['DANGEROUS_SALT'] = notify_config['credentials']['dangerous_salt']
|
os.environ['DANGEROUS_SALT'] = notify_config['credentials']['dangerous_salt']
|
||||||
|
os.environ['ROUTE_SECRET_KEY_1'] = notify_config['credentials']['route_secret_key_1']
|
||||||
|
os.environ['ROUTE_SECRET_KEY_2'] = notify_config['credentials']['route_secret_key_2']
|
||||||
|
|
||||||
|
|
||||||
def extract_notify_aws_config(aws_config):
|
def extract_notify_aws_config(aws_config):
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ class Config(object):
|
|||||||
]
|
]
|
||||||
|
|
||||||
LOGO_UPLOAD_BUCKET_NAME = 'public-logos-local'
|
LOGO_UPLOAD_BUCKET_NAME = 'public-logos-local'
|
||||||
|
ROUTE_SECRET_KEY_1 = os.environ.get('ROUTE_SECRET_KEY_1', '')
|
||||||
|
ROUTE_SECRET_KEY_2 = os.environ.get('ROUTE_SECRET_KEY_2', '')
|
||||||
|
CHECK_PROXY_HEADER = False
|
||||||
|
|
||||||
|
|
||||||
class Development(Config):
|
class Development(Config):
|
||||||
@@ -128,6 +131,7 @@ class Preview(Config):
|
|||||||
CSV_UPLOAD_BUCKET_NAME = 'preview-notifications-csv-upload'
|
CSV_UPLOAD_BUCKET_NAME = 'preview-notifications-csv-upload'
|
||||||
LOGO_UPLOAD_BUCKET_NAME = 'public-logos-preview'
|
LOGO_UPLOAD_BUCKET_NAME = 'public-logos-preview'
|
||||||
NOTIFY_ENVIRONMENT = 'preview'
|
NOTIFY_ENVIRONMENT = 'preview'
|
||||||
|
CHECK_PROXY_HEADER = True
|
||||||
|
|
||||||
|
|
||||||
class Staging(Config):
|
class Staging(Config):
|
||||||
@@ -138,6 +142,7 @@ class Staging(Config):
|
|||||||
CSV_UPLOAD_BUCKET_NAME = 'staging-notify-csv-upload'
|
CSV_UPLOAD_BUCKET_NAME = 'staging-notify-csv-upload'
|
||||||
LOGO_UPLOAD_BUCKET_NAME = 'public-logos-staging'
|
LOGO_UPLOAD_BUCKET_NAME = 'public-logos-staging'
|
||||||
NOTIFY_ENVIRONMENT = 'staging'
|
NOTIFY_ENVIRONMENT = 'staging'
|
||||||
|
CHECK_PROXY_HEADER = True
|
||||||
|
|
||||||
|
|
||||||
class Live(Config):
|
class Live(Config):
|
||||||
@@ -148,6 +153,7 @@ class Live(Config):
|
|||||||
CSV_UPLOAD_BUCKET_NAME = 'live-notifications-csv-upload'
|
CSV_UPLOAD_BUCKET_NAME = 'live-notifications-csv-upload'
|
||||||
LOGO_UPLOAD_BUCKET_NAME = 'public-logos-production'
|
LOGO_UPLOAD_BUCKET_NAME = 'public-logos-production'
|
||||||
NOTIFY_ENVIRONMENT = 'live'
|
NOTIFY_ENVIRONMENT = 'live'
|
||||||
|
CHECK_PROXY_HEADER = False
|
||||||
|
|
||||||
|
|
||||||
class CloudFoundryConfig(Config):
|
class CloudFoundryConfig(Config):
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from flask import jsonify, request
|
from flask import jsonify, request, current_app
|
||||||
from app import (version, status_api_client)
|
from app import (version, status_api_client)
|
||||||
from app.status import status
|
from app.status import status
|
||||||
from notifications_python_client.errors import HTTPError
|
from notifications_python_client.errors import HTTPError
|
||||||
@@ -12,6 +12,7 @@ def show_status():
|
|||||||
try:
|
try:
|
||||||
api_status = status_api_client.get_status()
|
api_status = status_api_client.get_status()
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
|
current_app.logger.exception("API failed to respond")
|
||||||
return jsonify(status="error", message=str(e.message)), 500
|
return jsonify(status="error", message=str(e.message)), 500
|
||||||
return jsonify(
|
return jsonify(
|
||||||
status="ok",
|
status="ok",
|
||||||
|
|||||||
@@ -21,4 +21,4 @@ notifications-python-client==4.6.0
|
|||||||
awscli>=1.11,<1.12
|
awscli>=1.11,<1.12
|
||||||
awscli-cwlogs>=1.4,<1.5
|
awscli-cwlogs>=1.4,<1.5
|
||||||
|
|
||||||
git+https://github.com/alphagov/notifications-utils.git@23.0.0#egg=notifications-utils==23.0.0
|
git+https://github.com/alphagov/notifications-utils.git@23.0.1#egg=notifications-utils==23.0.1
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from freezegun import freeze_time
|
|||||||
|
|
||||||
|
|
||||||
@freeze_time("2016-01-01 11:09:00.061258")
|
@freeze_time("2016-01-01 11:09:00.061258")
|
||||||
def test_form_contains_next_24h():
|
def test_form_contains_next_24h(app_):
|
||||||
|
|
||||||
choices = ChooseTimeForm().scheduled_for.choices
|
choices = ChooseTimeForm().scheduled_for.choices
|
||||||
|
|
||||||
@@ -34,12 +34,12 @@ def test_form_contains_next_24h():
|
|||||||
|
|
||||||
|
|
||||||
@freeze_time("2016-01-01 11:09:00.061258")
|
@freeze_time("2016-01-01 11:09:00.061258")
|
||||||
def test_form_defaults_to_now(client):
|
def test_form_defaults_to_now(app_):
|
||||||
assert ChooseTimeForm().scheduled_for.data == ''
|
assert ChooseTimeForm().scheduled_for.data == ''
|
||||||
|
|
||||||
|
|
||||||
@freeze_time("2016-01-01 11:09:00.061258")
|
@freeze_time("2016-01-01 11:09:00.061258")
|
||||||
def test_form_contains_next_three_days():
|
def test_form_contains_next_three_days(app_):
|
||||||
assert ChooseTimeForm().scheduled_for.categories == [
|
assert ChooseTimeForm().scheduled_for.categories == [
|
||||||
'Later today', 'Tomorrow', 'Sunday', 'Monday'
|
'Later today', 'Tomorrow', 'Sunday', 'Monday'
|
||||||
]
|
]
|
||||||
|
|||||||
26
tests/app/main/test_request_header.py
Normal file
26
tests/app/main/test_request_header.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from tests.conftest import set_config_values
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('check_proxy_header,header_value,expected_code', [
|
||||||
|
(True, 'key_1', 200),
|
||||||
|
(True, 'wrong_key', 403),
|
||||||
|
(False, 'wrong_key', 200),
|
||||||
|
(False, 'key_1', 200),
|
||||||
|
])
|
||||||
|
def test_route_correct_secret_key(app_, check_proxy_header, header_value, expected_code):
|
||||||
|
with set_config_values(app_, {
|
||||||
|
'ROUTE_SECRET_KEY_1': 'key_1',
|
||||||
|
'ROUTE_SECRET_KEY_2': '',
|
||||||
|
'CHECK_PROXY_HEADER': check_proxy_header,
|
||||||
|
}):
|
||||||
|
|
||||||
|
with app_.test_client() as client:
|
||||||
|
response = client.get(
|
||||||
|
path='/_status?elb=True',
|
||||||
|
headers=[
|
||||||
|
('X-Custom-forwarder', header_value),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
assert response.status_code == expected_code
|
||||||
@@ -16,6 +16,8 @@ def notify_config():
|
|||||||
'admin_client_secret': 'admin client secret',
|
'admin_client_secret': 'admin client secret',
|
||||||
'secret_key': 'secret key',
|
'secret_key': 'secret key',
|
||||||
'dangerous_salt': 'dangerous salt',
|
'dangerous_salt': 'dangerous salt',
|
||||||
|
'route_secret_key_1': 'key 1',
|
||||||
|
'route_secret_key_2': 'key 2',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +120,8 @@ def test_notify_config():
|
|||||||
assert os.environ['ADMIN_CLIENT_SECRET'] == 'admin client secret'
|
assert os.environ['ADMIN_CLIENT_SECRET'] == 'admin client secret'
|
||||||
assert os.environ['SECRET_KEY'] == 'secret key'
|
assert os.environ['SECRET_KEY'] == 'secret key'
|
||||||
assert os.environ['DANGEROUS_SALT'] == 'dangerous salt'
|
assert os.environ['DANGEROUS_SALT'] == 'dangerous salt'
|
||||||
|
assert os.environ['ROUTE_SECRET_KEY_1'] == 'key 1'
|
||||||
|
assert os.environ['ROUTE_SECRET_KEY_2'] == 'key 2'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('os_environ', 'cloudfoundry_environ')
|
@pytest.mark.usefixtures('os_environ', 'cloudfoundry_environ')
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ from notifications_utils.url_safe_token import generate_token
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture
|
||||||
def app_(request):
|
def app_(request):
|
||||||
app = Flask('app')
|
app = Flask('app')
|
||||||
create_app(app)
|
create_app(app)
|
||||||
@@ -2482,6 +2482,20 @@ def set_config(app, name, value):
|
|||||||
app.config[name] = old_val
|
app.config[name] = old_val
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def set_config_values(app, dict):
|
||||||
|
old_values = {}
|
||||||
|
|
||||||
|
for key in dict:
|
||||||
|
old_values[key] = app.config.get(key)
|
||||||
|
app.config[key] = dict[key]
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
for key in dict:
|
||||||
|
app.config[key] = old_values[key]
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='function')
|
@pytest.fixture(scope='function')
|
||||||
def valid_token(app_, fake_uuid):
|
def valid_token(app_, fake_uuid):
|
||||||
return generate_token(
|
return generate_token(
|
||||||
|
|||||||
Reference in New Issue
Block a user