From a1e570dea799832793ed7450e7ca60e1b6d2ed9e Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Fri, 16 Jun 2017 16:30:03 +0100 Subject: [PATCH] persist created_by_id when using the one off notification endpoint --- app/models.py | 5 + app/notifications/process_notifications.py | 3 +- app/service/send_notification.py | 17 +++- .../rest/test_send_notification.py | 92 +++++++++---------- tests/app/service/test_rest.py | 3 +- 5 files changed, 71 insertions(+), 49 deletions(-) diff --git a/app/models.py b/app/models.py index 0828f11a1..4faa05abb 100644 --- a/app/models.py +++ b/app/models.py @@ -95,6 +95,11 @@ class User(db.Model): platform_admin = db.Column(db.Boolean, nullable=False, default=False) current_session_id = db.Column(UUID(as_uuid=True), nullable=True) + services = db.relationship( + 'Service', + secondary='user_to_service', + backref=db.backref('user_to_service', lazy='dynamic')) + @property def password(self): raise AttributeError("Password not readable") diff --git a/app/notifications/process_notifications.py b/app/notifications/process_notifications.py index 86291b46f..b1cf05e84 100644 --- a/app/notifications/process_notifications.py +++ b/app/notifications/process_notifications.py @@ -49,7 +49,8 @@ def persist_notification( reference=None, client_reference=None, notification_id=None, - simulated=False + simulated=False, + created_by_id=None ): notification_created_at = created_at or datetime.utcnow() diff --git a/app/service/send_notification.py b/app/service/send_notification.py index 0e5f46659..1ca19661c 100644 --- a/app/service/send_notification.py +++ b/app/service/send_notification.py @@ -16,6 +16,18 @@ from app.models import ( ) from app.dao.services_dao import dao_fetch_service_by_id from app.dao.templates_dao import dao_get_template_by_id_and_service_id +from app.dao.users_dao import get_user_by_id +from app.v2.errors import BadRequestError + + +def validate_created_by(service, created_by_id): + user = get_user_by_id(created_by_id) + if service not in user.services: + message = 'Can’t create notification - {} is not part of the "{}" service'.format( + user.name, + service.name + ) + raise BadRequestError(message=message) def send_one_off_notification(service_id, post_data): @@ -38,6 +50,8 @@ def send_one_off_notification(service_id, post_data): notification_type=template.template_type ) + validate_created_by(service, post_data['created_by']) + notification = persist_notification( template_id=template.id, template_version=template.version, @@ -46,7 +60,8 @@ def send_one_off_notification(service_id, post_data): personalisation=personalisation, notification_type=template.template_type, api_key_id=None, - key_type=KEY_TYPE_NORMAL + key_type=KEY_TYPE_NORMAL, + created_by_id=post_data['created_by'] ) queue_name = QueueNames.PRIORITY if template.process_type == PRIORITY else None diff --git a/tests/app/notifications/rest/test_send_notification.py b/tests/app/notifications/rest/test_send_notification.py index 6a9fe1f2d..5781770f5 100644 --- a/tests/app/notifications/rest/test_send_notification.py +++ b/tests/app/notifications/rest/test_send_notification.py @@ -1095,69 +1095,69 @@ def test_returns_a_429_limit_exceeded_if_rate_limit_exceeded( def test_should_allow_store_original_number_on_sms_notification(client, sample_template, mocker): - mocked = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') + mocked = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') - data = { - 'to': '+(44) 7700-900 855', - 'template': str(sample_template.id) - } + data = { + 'to': '+(44) 7700-900 855', + 'template': str(sample_template.id) + } - auth_header = create_authorization_header(service_id=sample_template.service_id) + auth_header = create_authorization_header(service_id=sample_template.service_id) - response = client.post( - path='/notifications/sms', - data=json.dumps(data), - headers=[('Content-Type', 'application/json'), auth_header]) + response = client.post( + path='/notifications/sms', + data=json.dumps(data), + headers=[('Content-Type', 'application/json'), auth_header]) - response_data = json.loads(response.data)['data'] - notification_id = response_data['notification']['id'] + response_data = json.loads(response.data)['data'] + notification_id = response_data['notification']['id'] - mocked.assert_called_once_with([notification_id], queue='send-tasks') - assert response.status_code == 201 - assert notification_id - notifications = Notification.query.all() - assert len(notifications) == 1 - assert '+(44) 7700-900 855' == notifications[0].to + mocked.assert_called_once_with([notification_id], queue='send-tasks') + assert response.status_code == 201 + assert notification_id + notifications = Notification.query.all() + assert len(notifications) == 1 + assert '+(44) 7700-900 855' == notifications[0].to def test_should_not_allow_international_number_on_sms_notification(client, sample_template, mocker): - mocked = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') + mocked = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') - data = { - 'to': '20-12-1234-1234', - 'template': str(sample_template.id) - } + data = { + 'to': '20-12-1234-1234', + 'template': str(sample_template.id) + } - auth_header = create_authorization_header(service_id=sample_template.service_id) + auth_header = create_authorization_header(service_id=sample_template.service_id) - response = client.post( - path='/notifications/sms', - data=json.dumps(data), - headers=[('Content-Type', 'application/json'), auth_header]) + response = client.post( + path='/notifications/sms', + data=json.dumps(data), + headers=[('Content-Type', 'application/json'), auth_header]) - assert not mocked.called - assert response.status_code == 400 - error_json = json.loads(response.get_data(as_text=True)) - assert error_json['result'] == 'error' - assert error_json['message']['to'][0] == 'Cannot send to international mobile numbers' + assert not mocked.called + assert response.status_code == 400 + error_json = json.loads(response.get_data(as_text=True)) + assert error_json['result'] == 'error' + assert error_json['message']['to'][0] == 'Cannot send to international mobile numbers' def test_should_allow_international_number_on_sms_notification(client, notify_db, notify_db_session, mocker): - mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') + mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') - service = sample_service(notify_db, notify_db_session, can_send_international_sms=True) - template = create_sample_template(notify_db, notify_db_session, service=service) + service = sample_service(notify_db, notify_db_session, can_send_international_sms=True) + template = create_sample_template(notify_db, notify_db_session, service=service) - data = { - 'to': '20-12-1234-1234', - 'template': str(template.id) - } + data = { + 'to': '20-12-1234-1234', + 'template': str(template.id) + } - auth_header = create_authorization_header(service_id=service.id) + auth_header = create_authorization_header(service_id=service.id) - response = client.post( - path='/notifications/sms', - data=json.dumps(data), - headers=[('Content-Type', 'application/json'), auth_header]) + response = client.post( + path='/notifications/sms', + data=json.dumps(data), + headers=[('Content-Type', 'application/json'), auth_header]) - assert response.status_code == 201 + assert response.status_code == 201 diff --git a/tests/app/service/test_rest.py b/tests/app/service/test_rest.py index d932efb4b..b948ec2f3 100644 --- a/tests/app/service/test_rest.py +++ b/tests/app/service/test_rest.py @@ -2257,7 +2257,8 @@ def test_send_one_off_notification(admin_request, sample_template): }, data={ 'template_id': str(sample_template.id), - 'to': '07700900001' + 'to': '07700900001', + 'created_by': str(sample_template.service.created_by_id) }, expected_status=201 )