diff --git a/app/v2/notifications/post_notifications.py b/app/v2/notifications/post_notifications.py index 80da6c16a..e12110a74 100644 --- a/app/v2/notifications/post_notifications.py +++ b/app/v2/notifications/post_notifications.py @@ -224,6 +224,12 @@ def process_letter_notification(*, letter_data, api_key, template, reply_to_text if not api_key.service.research_mode and api_key.service.restricted and api_key.key_type != KEY_TYPE_TEST: raise BadRequestError(message='Cannot send letters when service is in trial mode', status_code=403) + if precompiled: + try: + letter_content = base64.b64decode(letter_data['content']) + except ValueError: + raise BadRequestError(message='Cannot decode letter content (invalid base64 encoding)', status_code=400) + should_send = not (api_key.service.research_mode or api_key.key_type == KEY_TYPE_TEST) # if we don't want to actually send the letter, then start it off in SENDING so we don't pick it up @@ -236,7 +242,7 @@ def process_letter_notification(*, letter_data, api_key, template, reply_to_text if should_send: if precompiled: - upload_letter_pdf(notification, base64.b64decode(letter_data['content'])) + upload_letter_pdf(notification, letter_content) else: create_letters_pdf.apply_async( [str(notification.id)], diff --git a/tests/app/v2/notifications/test_post_notifications.py b/tests/app/v2/notifications/test_post_notifications.py index 493aedf15..b9da9f9c7 100644 --- a/tests/app/v2/notifications/test_post_notifications.py +++ b/tests/app/v2/notifications/test_post_notifications.py @@ -714,6 +714,27 @@ def test_post_precompiled_letter_requires_permission(client, sample_service, not assert resp_json['errors'][0]['message'] == 'Cannot send precompiled_letters' +def test_post_precompiled_letter_with_invalid_base64(client, notify_user, mocker): + sample_service = create_service(service_permissions=['letter', 'precompiled_letter']) + mocker.patch('app.v2.notifications.post_notifications.upload_letter_pdf') + + data = { + "reference": "letter-reference", + "content": "hi" + } + auth_header = create_authorization_header(service_id=sample_service.id) + response = client.post( + path="v2/notifications/letter", + data=json.dumps(data), + headers=[('Content-Type', 'application/json'), auth_header]) + + assert response.status_code == 400, response.get_data(as_text=True) + resp_json = json.loads(response.get_data(as_text=True)) + assert resp_json['errors'][0]['message'] == 'Cannot decode letter content (invalid base64 encoding)' + + assert not Notification.query.first() + + def test_post_precompiled_letter_notification_returns_201(client, notify_user, mocker): sample_service = create_service(service_permissions=['letter', 'precompiled_letter']) s3mock = mocker.patch('app.v2.notifications.post_notifications.upload_letter_pdf') @@ -731,10 +752,12 @@ def test_post_precompiled_letter_notification_returns_201(client, notify_user, m s3mock.assert_called_once_with(ANY, b'letter-content') + notification = Notification.query.first() + resp_json = json.loads(response.get_data(as_text=True)) assert resp_json == { 'content': {'body': None, 'subject': 'Pre-compiled PDF'}, - 'id': ANY, + 'id': str(notification.id), 'reference': 'letter-reference', 'scheduled_for': None, 'template': {