mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-24 17:31:34 -05:00
Merge pull request #1409 from alphagov/add-firetext-inbound-sms-auth
Add FIRETEXT_INBOUND_SMS_AUTH config variable and auth check
This commit is contained in:
@@ -45,6 +45,7 @@ def extract_notify_config(notify_config):
|
||||
os.environ['SECRET_KEY'] = notify_config['credentials']['secret_key']
|
||||
os.environ['DANGEROUS_SALT'] = notify_config['credentials']['dangerous_salt']
|
||||
os.environ['SMS_INBOUND_WHITELIST'] = json.dumps(notify_config['credentials']['allow_ip_inbound_sms'])
|
||||
os.environ['FIRETEXT_INBOUND_SMS_AUTH'] = json.dumps(notify_config['credentials']['firetext_inbound_sms_auth'])
|
||||
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']
|
||||
|
||||
|
||||
@@ -295,6 +295,8 @@ class Config(object):
|
||||
FREE_SMS_TIER_FRAGMENT_COUNT = 250000
|
||||
|
||||
SMS_INBOUND_WHITELIST = json.loads(os.environ.get('SMS_INBOUND_WHITELIST', '[]'))
|
||||
FIRETEXT_INBOUND_SMS_AUTH = json.loads(os.environ.get('FIRETEXT_INBOUND_SMS_AUTH', '[]'))
|
||||
|
||||
ROUTE_SECRET_KEY_1 = os.environ.get('ROUTE_SECRET_KEY_1', '')
|
||||
ROUTE_SECRET_KEY_2 = os.environ.get('ROUTE_SECRET_KEY_2', '')
|
||||
|
||||
@@ -364,6 +366,7 @@ class Test(Config):
|
||||
}
|
||||
|
||||
SMS_INBOUND_WHITELIST = ['203.0.113.195']
|
||||
FIRETEXT_INBOUND_SMS_AUTH = ['testkey']
|
||||
|
||||
|
||||
class Preview(Config):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from urllib.parse import unquote
|
||||
|
||||
import iso8601
|
||||
from flask import jsonify, Blueprint, current_app, request
|
||||
from flask import jsonify, Blueprint, current_app, request, abort
|
||||
from notifications_utils.recipients import validate_and_format_phone_number
|
||||
|
||||
from app import statsd_client, firetext_client, mmg_client
|
||||
@@ -58,10 +58,12 @@ def receive_firetext_sms():
|
||||
|
||||
# This is pre-implementation test code to validate the provider is basic auth headers.
|
||||
auth = request.authorization
|
||||
if auth:
|
||||
current_app.logger.info("Inbound sms username: {}".format(auth.username))
|
||||
else:
|
||||
current_app.logger.info("Inbound sms no auth header")
|
||||
if not auth:
|
||||
current_app.logger.warning("Inbound sms no auth header")
|
||||
# abort(401)
|
||||
elif auth.username != 'notify' or auth.password not in current_app.config['FIRETEXT_INBOUND_SMS_AUTH']:
|
||||
current_app.logger.warning("Inbound sms incorrect username ({}) or password".format(auth.username))
|
||||
# abort(403)
|
||||
|
||||
inbound_number = strip_leading_forty_four(post_data['destination'])
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import uuid
|
||||
import base64
|
||||
from datetime import datetime
|
||||
from unittest.mock import call
|
||||
|
||||
@@ -16,18 +17,26 @@ from app.notifications.receive_notifications import (
|
||||
)
|
||||
|
||||
from app.models import InboundSms, EMAIL_TYPE, SMS_TYPE, INBOUND_SMS_TYPE
|
||||
from tests.conftest import set_config
|
||||
from tests.app.db import create_inbound_number, create_service, create_service_with_inbound_number
|
||||
from tests.app.conftest import sample_service
|
||||
|
||||
|
||||
def firetext_post(client, data):
|
||||
def firetext_post(client, data, auth=True, password='testkey'):
|
||||
headers = [
|
||||
('Content-Type', 'application/x-www-form-urlencoded'),
|
||||
('X-Forwarded-For', '203.0.113.195, 70.41.3.18, 150.172.238.178')
|
||||
]
|
||||
|
||||
if auth:
|
||||
auth_value = base64.b64encode("notify:{}".format(password).encode('utf-8')).decode('utf-8')
|
||||
headers.append(('Authorization', 'Basic ' + auth_value))
|
||||
|
||||
return client.post(
|
||||
path='/notifications/sms/receive/firetext',
|
||||
data=data,
|
||||
headers=[
|
||||
('Content-Type', 'application/x-www-form-urlencoded'),
|
||||
('X-Forwarded-For', '203.0.113.195, 70.41.3.18, 150.172.238.178')
|
||||
])
|
||||
headers=headers
|
||||
)
|
||||
|
||||
|
||||
def mmg_post(client, data):
|
||||
@@ -379,3 +388,28 @@ def test_returns_ok_to_firetext_if_mismatched_sms_sender(notify_db_session, clie
|
||||
)
|
||||
def test_strip_leading_country_code(number, expected):
|
||||
assert strip_leading_forty_four(number) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("auth, keys, status_code", [
|
||||
["testkey", ["testkey"], 200],
|
||||
["", ["testkey"], 401],
|
||||
["wrong", ["testkey"], 403],
|
||||
["testkey1", ["testkey1", "testkey2"], 200],
|
||||
["testkey2", ["testkey1", "testkey2"], 200],
|
||||
["wrong", ["testkey1", "testkey2"], 403],
|
||||
["", [], 401],
|
||||
["testkey", [], 403],
|
||||
])
|
||||
@pytest.mark.skip(reason="aborts are disabled at the moment")
|
||||
def test_firetext_inbound_sms_auth(notify_db_session, notify_api, client, mocker, auth, keys, status_code):
|
||||
mocker.patch("app.notifications.receive_notifications.tasks.send_inbound_sms_to_service.apply_async")
|
||||
|
||||
create_service_with_inbound_number(
|
||||
service_name='b', inbound_number='07111111111', service_permissions=[EMAIL_TYPE, SMS_TYPE, INBOUND_SMS_TYPE]
|
||||
)
|
||||
|
||||
data = "source=07999999999&destination=07111111111&message=this is a message&time=2017-01-01 12:00:00"
|
||||
|
||||
with set_config(notify_api, 'FIRETEXT_INBOUND_SMS_AUTH', keys):
|
||||
response = firetext_post(client, data, auth=bool(auth), password=auth)
|
||||
assert response.status_code == status_code
|
||||
|
||||
@@ -17,6 +17,7 @@ def notify_config():
|
||||
'secret_key': 'secret key',
|
||||
'dangerous_salt': 'dangerous salt',
|
||||
'allow_ip_inbound_sms': ['111.111.111.111', '100.100.100.100'],
|
||||
'firetext_inbound_sms_auth': ['testkey'],
|
||||
'route_secret_key_1': "key_1",
|
||||
'route_secret_key_2': ""
|
||||
}
|
||||
@@ -211,6 +212,13 @@ def test_sms_inbound_config():
|
||||
assert os.environ['SMS_INBOUND_WHITELIST'] == json.dumps(['111.111.111.111', '100.100.100.100'])
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('os_environ', 'cloudfoundry_environ')
|
||||
def test_firetext_inbound_sms_auth_config():
|
||||
extract_cloudfoundry_config()
|
||||
|
||||
assert os.environ['FIRETEXT_INBOUND_SMS_AUTH'] == json.dumps(['testkey'])
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('os_environ', 'cloudfoundry_environ')
|
||||
def test_performance_platform_config():
|
||||
extract_cloudfoundry_config()
|
||||
|
||||
Reference in New Issue
Block a user