mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-04 10:21:14 -05:00
Merge pull request #203 from alphagov/double-check-restricted-mode
Catch sending to restricted recipients in Celery
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import itertools
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
@@ -12,7 +13,8 @@ from utils.template import Template
|
|||||||
|
|
||||||
from utils.recipients import (
|
from utils.recipients import (
|
||||||
RecipientCSV,
|
RecipientCSV,
|
||||||
validate_and_format_phone_number
|
validate_and_format_phone_number,
|
||||||
|
allowed_to_send_to
|
||||||
)
|
)
|
||||||
|
|
||||||
from app import (
|
from app import (
|
||||||
@@ -195,9 +197,16 @@ def remove_job(job_id):
|
|||||||
def send_sms(service_id, notification_id, encrypted_notification, created_at):
|
def send_sms(service_id, notification_id, encrypted_notification, created_at):
|
||||||
notification = encryption.decrypt(encrypted_notification)
|
notification = encryption.decrypt(encrypted_notification)
|
||||||
service = dao_fetch_service_by_id(service_id)
|
service = dao_fetch_service_by_id(service_id)
|
||||||
|
|
||||||
client = firetext_client
|
client = firetext_client
|
||||||
|
|
||||||
|
restricted = False
|
||||||
|
|
||||||
|
if not service_allowed_to_send_to(notification['to'], service):
|
||||||
|
current_app.logger.info(
|
||||||
|
"SMS {} failed as restricted service".format(notification_id)
|
||||||
|
)
|
||||||
|
restricted = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sent_at = datetime.utcnow()
|
sent_at = datetime.utcnow()
|
||||||
notification_db_object = Notification(
|
notification_db_object = Notification(
|
||||||
@@ -206,7 +215,7 @@ def send_sms(service_id, notification_id, encrypted_notification, created_at):
|
|||||||
to=notification['to'],
|
to=notification['to'],
|
||||||
service_id=service_id,
|
service_id=service_id,
|
||||||
job_id=notification.get('job', None),
|
job_id=notification.get('job', None),
|
||||||
status='sent',
|
status='failed' if restricted else 'sent',
|
||||||
created_at=datetime.strptime(created_at, DATETIME_FORMAT),
|
created_at=datetime.strptime(created_at, DATETIME_FORMAT),
|
||||||
sent_at=sent_at,
|
sent_at=sent_at,
|
||||||
sent_by=client.get_name()
|
sent_by=client.get_name()
|
||||||
@@ -214,6 +223,9 @@ def send_sms(service_id, notification_id, encrypted_notification, created_at):
|
|||||||
|
|
||||||
dao_create_notification(notification_db_object, TEMPLATE_TYPE_SMS)
|
dao_create_notification(notification_db_object, TEMPLATE_TYPE_SMS)
|
||||||
|
|
||||||
|
if restricted:
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
template = Template(
|
template = Template(
|
||||||
dao_get_template_by_id(notification['template']).__dict__,
|
dao_get_template_by_id(notification['template']).__dict__,
|
||||||
@@ -245,6 +257,15 @@ def send_sms(service_id, notification_id, encrypted_notification, created_at):
|
|||||||
def send_email(service_id, notification_id, subject, from_address, encrypted_notification, created_at):
|
def send_email(service_id, notification_id, subject, from_address, encrypted_notification, created_at):
|
||||||
notification = encryption.decrypt(encrypted_notification)
|
notification = encryption.decrypt(encrypted_notification)
|
||||||
client = aws_ses_client
|
client = aws_ses_client
|
||||||
|
service = dao_fetch_service_by_id(service_id)
|
||||||
|
|
||||||
|
restricted = False
|
||||||
|
|
||||||
|
if not service_allowed_to_send_to(notification['to'], service):
|
||||||
|
current_app.logger.info(
|
||||||
|
"Email {} failed as restricted service".format(notification_id)
|
||||||
|
)
|
||||||
|
restricted = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sent_at = datetime.utcnow()
|
sent_at = datetime.utcnow()
|
||||||
@@ -254,13 +275,16 @@ def send_email(service_id, notification_id, subject, from_address, encrypted_not
|
|||||||
to=notification['to'],
|
to=notification['to'],
|
||||||
service_id=service_id,
|
service_id=service_id,
|
||||||
job_id=notification.get('job', None),
|
job_id=notification.get('job', None),
|
||||||
status='sent',
|
status='failed' if restricted else 'sent',
|
||||||
created_at=datetime.strptime(created_at, DATETIME_FORMAT),
|
created_at=datetime.strptime(created_at, DATETIME_FORMAT),
|
||||||
sent_at=sent_at,
|
sent_at=sent_at,
|
||||||
sent_by=client.get_name()
|
sent_by=client.get_name()
|
||||||
)
|
)
|
||||||
dao_create_notification(notification_db_object, TEMPLATE_TYPE_EMAIL)
|
dao_create_notification(notification_db_object, TEMPLATE_TYPE_EMAIL)
|
||||||
|
|
||||||
|
if restricted:
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
template = Template(
|
template = Template(
|
||||||
dao_get_template_by_id(notification['template']).__dict__,
|
dao_get_template_by_id(notification['template']).__dict__,
|
||||||
@@ -395,3 +419,16 @@ def email_registration_verification(encrypted_verification_message):
|
|||||||
url=verification_message['url']))
|
url=verification_message['url']))
|
||||||
except AwsSesClientException as e:
|
except AwsSesClientException as e:
|
||||||
current_app.logger.exception(e)
|
current_app.logger.exception(e)
|
||||||
|
|
||||||
|
|
||||||
|
def service_allowed_to_send_to(recipient, service):
|
||||||
|
|
||||||
|
if not service.restricted:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return allowed_to_send_to(
|
||||||
|
recipient,
|
||||||
|
itertools.chain.from_iterable(
|
||||||
|
[user.mobile_number, user.email_address] for user in service.users
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|||||||
@@ -359,6 +359,31 @@ def test_should_send_sms_if_restricted_service_and_valid_number(notify_db, notif
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_should_not_send_sms_if_restricted_service_and_invalid_number(notify_db, notify_db_session, mocker):
|
||||||
|
user = sample_user(notify_db, notify_db_session, mobile_numnber="07700 900205")
|
||||||
|
service = sample_service(notify_db, notify_db_session, user=user, restricted=True)
|
||||||
|
template = sample_template(notify_db, notify_db_session, service=service)
|
||||||
|
|
||||||
|
notification = {
|
||||||
|
"template": template.id,
|
||||||
|
"to": "07700 900849"
|
||||||
|
}
|
||||||
|
mocker.patch('app.encryption.decrypt', return_value=notification)
|
||||||
|
mocker.patch('app.firetext_client.send_sms')
|
||||||
|
mocker.patch('app.firetext_client.get_name', return_value="firetext")
|
||||||
|
|
||||||
|
notification_id = uuid.uuid4()
|
||||||
|
now = datetime.utcnow()
|
||||||
|
send_sms(
|
||||||
|
service.id,
|
||||||
|
notification_id,
|
||||||
|
"encrypted-in-reality",
|
||||||
|
now.strftime(DATETIME_FORMAT)
|
||||||
|
)
|
||||||
|
|
||||||
|
firetext_client.send_sms.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_should_send_email_if_restricted_service_and_valid_email(notify_db, notify_db_session, mocker):
|
def test_should_send_email_if_restricted_service_and_valid_email(notify_db, notify_db_session, mocker):
|
||||||
user = sample_user(notify_db, notify_db_session, email="test@restricted.com")
|
user = sample_user(notify_db, notify_db_session, email="test@restricted.com")
|
||||||
service = sample_service(notify_db, notify_db_session, user=user, restricted=True)
|
service = sample_service(notify_db, notify_db_session, user=user, restricted=True)
|
||||||
@@ -391,6 +416,32 @@ def test_should_send_email_if_restricted_service_and_valid_email(notify_db, noti
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_should_not_send_email_if_restricted_service_and_invalid_email_address(notify_db, notify_db_session, mocker):
|
||||||
|
user = sample_user(notify_db, notify_db_session)
|
||||||
|
service = sample_service(notify_db, notify_db_session, user=user, restricted=True)
|
||||||
|
template = sample_template(
|
||||||
|
notify_db, notify_db_session, service=service, template_type='email', subject_line='Hello'
|
||||||
|
)
|
||||||
|
|
||||||
|
notification = {
|
||||||
|
"template": template.id,
|
||||||
|
"to": "test@example.com"
|
||||||
|
}
|
||||||
|
mocker.patch('app.encryption.decrypt', return_value=notification)
|
||||||
|
mocker.patch('app.aws_ses_client.send_email')
|
||||||
|
|
||||||
|
notification_id = uuid.uuid4()
|
||||||
|
now = datetime.utcnow()
|
||||||
|
send_sms(
|
||||||
|
service.id,
|
||||||
|
notification_id,
|
||||||
|
"encrypted-in-reality",
|
||||||
|
now.strftime(DATETIME_FORMAT)
|
||||||
|
)
|
||||||
|
|
||||||
|
aws_ses_client.send_email.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_should_send_template_to_correct_sms_provider_and_persist_with_job_id(sample_job, mocker):
|
def test_should_send_template_to_correct_sms_provider_and_persist_with_job_id(sample_job, mocker):
|
||||||
notification = {
|
notification = {
|
||||||
"template": sample_job.template.id,
|
"template": sample_job.template.id,
|
||||||
|
|||||||
Reference in New Issue
Block a user