From 918c5617267774a4707aea16635a6037e517bcb0 Mon Sep 17 00:00:00 2001 From: Nicholas Staples Date: Fri, 12 Feb 2016 11:13:54 +0000 Subject: [PATCH 1/2] Code added to now check service id matches the authorization token service for sending an sms. --- app/schemas.py | 11 ++++++++- tests/app/notifications/test_rest.py | 34 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/app/schemas.py b/app/schemas.py index 3a0ab41df..83b9a764e 100644 --- a/app/schemas.py +++ b/app/schemas.py @@ -1,4 +1,5 @@ import re +from flask import current_app from flask_marshmallow.fields import fields from . import ma from . import models @@ -102,12 +103,15 @@ class SmsTemplateNotificationSchema(SmsNotificationSchema): @validates_schema def validate_schema(self, data): """ - Validate the to field is valid for this template + Validate the to field is valid for this notification """ + from app import api_user template_id = data.get('template', None) template = models.Template.query.filter_by(id=template_id).first() if template: service = template.service + # Validate restricted service, + # restricted services can only send to one of its users. if service.restricted: valid = False for usr in service.users: @@ -116,6 +120,11 @@ class SmsTemplateNotificationSchema(SmsNotificationSchema): break if not valid: raise ValidationError('Invalid phone number for restricted service', 'restricted') + # Assert the template is valid for the service which made the request. + service = api_user['client'] + if service != current_app.config.get('ADMIN_CLIENT_USER_NAME'): + if template.service != models.Service.query.filter_by(id=service).first(): + raise ValidationError('Invalid template', 'restricted') class SmsAdminNotificationSchema(SmsNotificationSchema): diff --git a/tests/app/notifications/test_rest.py b/tests/app/notifications/test_rest.py index d3c2170e8..33cef53b0 100644 --- a/tests/app/notifications/test_rest.py +++ b/tests/app/notifications/test_rest.py @@ -4,6 +4,8 @@ import uuid from tests import create_authorization_header from flask import url_for, json from app.models import Service +from tests.app.conftest import sample_service as create_sample_service +from tests.app.conftest import sample_template as create_sample_template def test_get_notifications( @@ -172,6 +174,38 @@ def test_send_notification_invalid_template_id(notify_api, assert 'Template not found' in json_resp['message']['template'] +@moto.mock_sqs +def test_should_not_allow_template_from_other_service(notify_api, + notify_db, + notify_db_session, + sample_template, + sample_admin_service_id, + mocker): + """ + Tests POST endpoint '/sms' with notifications. + """ + with notify_api.test_request_context(): + with notify_api.test_client() as client: + data = { + 'to': '+441234123123', + 'template': sample_template.id + } + auth_header = create_authorization_header( + service_id=sample_admin_service_id, + request_body=json.dumps(data), + path=url_for('notifications.create_sms_notification'), + method='POST') + + response = client.post( + url_for('notifications.create_sms_notification'), + data=json.dumps(data), + headers=[('Content-Type', 'application/json'), auth_header]) + + json_resp = json.loads(response.get_data(as_text=True)) + assert response.status_code == 400 + assert 'Invalid template' in json_resp['message']['restricted'] + + @moto.mock_sqs def test_should_allow_valid_message(notify_api, notify_db, From 1eb18e7f0766678cb3a2d758f0527dd59f47b91c Mon Sep 17 00:00:00 2001 From: Nicholas Staples Date: Fri, 12 Feb 2016 14:08:48 +0000 Subject: [PATCH 2/2] Code review fix. --- app/schemas.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/schemas.py b/app/schemas.py index 83b9a764e..050e35d48 100644 --- a/app/schemas.py +++ b/app/schemas.py @@ -122,9 +122,9 @@ class SmsTemplateNotificationSchema(SmsNotificationSchema): raise ValidationError('Invalid phone number for restricted service', 'restricted') # Assert the template is valid for the service which made the request. service = api_user['client'] - if service != current_app.config.get('ADMIN_CLIENT_USER_NAME'): - if template.service != models.Service.query.filter_by(id=service).first(): - raise ValidationError('Invalid template', 'restricted') + if (service != current_app.config.get('ADMIN_CLIENT_USER_NAME') and + template.service != models.Service.query.filter_by(id=service).first()): + raise ValidationError('Invalid template', 'restricted') class SmsAdminNotificationSchema(SmsNotificationSchema):