diff --git a/app/main/views/jobs.py b/app/main/views/jobs.py index d852bbb2a..926118e54 100644 --- a/app/main/views/jobs.py +++ b/app/main/views/jobs.py @@ -390,12 +390,29 @@ def get_job_partials(job): def add_preview_of_content_to_notifications(notifications): + for notification in notifications: - yield dict( - preview_of_content=( - str(Template(notification['template'], notification['personalisation'])) - if notification['template']['template_type'] == 'sms' else - WithSubjectTemplate(notification['template'], notification['personalisation']).subject - ), - **notification - ) + + if notification['template'].get('redact_personalisation'): + notification['personalisation'] = {} + + if notification['template']['template_type'] == 'sms': + yield dict( + preview_of_content=str(Template( + notification['template'], + notification['personalisation'], + redact_missing_personalisation=True, + )), + **notification + ) + else: + yield dict( + preview_of_content=( + WithSubjectTemplate( + notification['template'], + notification['personalisation'], + redact_missing_personalisation=True, + ).subject + ), + **notification + ) diff --git a/app/main/views/notifications.py b/app/main/views/notifications.py index e29f06ce0..0c910d6e2 100644 --- a/app/main/views/notifications.py +++ b/app/main/views/notifications.py @@ -56,6 +56,7 @@ def view_notification(service_id, notification_id): filetype='png', ), show_recipient=True, + redact_missing_personalisation=True, ) template.values = get_all_personalisation_from_notification(notification) if notification['job']: @@ -109,15 +110,21 @@ def get_single_notification_partials(notification): def get_all_personalisation_from_notification(notification): + + if notification['template'].get('redact_personalisation'): + notification['personalisation'] = {} + if notification['template']['template_type'] == 'email': return dict( email_address=notification['to'], **notification['personalisation'] ) + if notification['template']['template_type'] == 'sms': return dict( phone_number=notification['to'], **notification['personalisation'] ) + if notification['template']['template_type'] == 'letter': return notification['personalisation'] diff --git a/tests/__init__.py b/tests/__init__.py index c7006ea71..0864c373f 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -87,12 +87,12 @@ def template_json(service_id, id_, name="sample template", type_="sms", - content="template content", + content=None, subject=None, version=1, archived=False, process_type='normal', - redact_personalisation=False, + redact_personalisation=None, ): template = { 'id': id_, @@ -105,6 +105,8 @@ def template_json(service_id, 'archived': archived, 'process_type': process_type, } + if content is None: + template['content'] = "template content" if subject is None and type_ != 'sms': template['subject'] = "template subject" if subject is not None: diff --git a/tests/app/main/views/test_activity.py b/tests/app/main/views/test_activity.py index 960a340f9..8872b5296 100644 --- a/tests/app/main/views/test_activity.py +++ b/tests/app/main/views/test_activity.py @@ -8,7 +8,7 @@ from bs4 import BeautifulSoup from app.main.views.jobs import get_time_left, get_status_filters from tests import notification_json -from tests.conftest import SERVICE_ONE_ID +from tests.conftest import SERVICE_ONE_ID, mock_get_notifications from tests.app.test_utils import normalize_spaces from freezegun import freeze_time @@ -321,3 +321,27 @@ def test_html_contains_notification_id( notifications = page.tbody.find_all('tr') for tr in notifications: assert uuid.UUID(tr.attrs['id']) + + +def test_redacts_templates_that_should_be_redacted( + client_request, + mocker, + active_user_with_permissions, + mock_get_detailed_service, +): + _notifications_mock = mock_get_notifications( + mocker, + active_user_with_permissions, + template_content="hello ((name))", + personalisation={'name': 'Jo'}, + redact_personalisation=True, + ) + page = client_request.get( + 'main.view_notifications', + service_id=SERVICE_ONE_ID, + message_type='sms', + ) + + assert normalize_spaces(page.select('tbody tr th')[0].text) == ( + '07123456789 hello hidden' + ) diff --git a/tests/app/main/views/test_notifications.py b/tests/app/main/views/test_notifications.py index 5c36bb6f8..f318de260 100644 --- a/tests/app/main/views/test_notifications.py +++ b/tests/app/main/views/test_notifications.py @@ -57,3 +57,37 @@ def test_notification_status_page_shows_details( service_one['id'], fake_uuid ) + + +@pytest.mark.parametrize('template_redaction_setting, expected_content', [ + (False, 'service one: hello Jo'), + (True, 'service one: hello hidden'), +]) +@freeze_time("2016-01-01 11:09:00.061258") +def test_notification_status_page_respects_redaction( + client_request, + mocker, + service_one, + fake_uuid, + template_redaction_setting, + expected_content, +): + + _mock_get_notification = mock_get_notification( + mocker, + fake_uuid, + redact_personalisation=template_redaction_setting, + ) + + page = client_request.get( + 'main.view_notification', + service_id=service_one['id'], + notification_id=fake_uuid + ) + + assert normalize_spaces(page.select('.sms-message-wrapper')[0].text) == expected_content + + _mock_get_notification.assert_called_with( + service_one['id'], + fake_uuid, + ) diff --git a/tests/conftest.py b/tests/conftest.py index 7a8af5c7a..750535c9b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1079,7 +1079,13 @@ def mock_get_jobs(mocker, api_user_active): @pytest.fixture(scope='function') -def mock_get_notifications(mocker, api_user_active): +def mock_get_notifications( + mocker, + api_user_active, + template_content=None, + personalisation=None, + redact_personalisation=False, +): def _get_notifications( service_id, job_id=None, @@ -1096,17 +1102,28 @@ def mock_get_notifications(mocker, api_user_active): job = None if job_id is not None: job = job_json(service_id, api_user_active, job_id=job_id) - if template_type: - template = template_json(service_id, id_=str(generate_uuid()), type_=template_type[0]) + template = template_json( + service_id, + id_=str(generate_uuid()), + type_=template_type[0], + content=template_content, + redact_personalisation=redact_personalisation, + ) else: - template = template_json(service_id, id_=str(generate_uuid())) + template = template_json( + service_id, + id_=str(generate_uuid()), + content=template_content, + redact_personalisation=redact_personalisation, + ) return notification_json( service_id, template=template, rows=rows, - job=job + job=job, + personalisation=personalisation, ) return mocker.patch( @@ -1636,7 +1653,12 @@ def mock_reset_failed_login_count(mocker): @pytest.fixture -def mock_get_notification(mocker, fake_uuid, notification_status='delivered'): +def mock_get_notification( + mocker, + fake_uuid, + notification_status='delivered', + redact_personalisation=False, +): def _get_notification( service_id, notification_id, @@ -1654,7 +1676,12 @@ def mock_get_notification(mocker, fake_uuid, notification_status='delivered'): 'email_address': 'test@user.gov.uk' } noti['personalisation'] = {'name': 'Jo'} - noti['template'] = template_json(service_id, str(generate_uuid()), content='hello ((name))') + noti['template'] = template_json( + service_id, + str(generate_uuid()), + content='hello ((name))', + redact_personalisation=redact_personalisation, + ) return noti return mocker.patch(