mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-04-20 09:10:52 -04:00
We mostly rely on the API returning a 404 to generate 404s for trying to get things with non-UUID IDs. This is fine, except our tests often mock these API calls. So it could look like everything is working fine, except the thing your passing in might never be a valid UUID, and thus would 404 in a non-test environment. So this commit: 1. uses the `uuid` URL converter everywhere there’s something that looks like an ID in a URL parameter 2. adds a test which automates checking for 1.
133 lines
4.7 KiB
Python
133 lines
4.7 KiB
Python
from flask import jsonify, redirect, render_template, session, url_for
|
|
from flask_login import current_user
|
|
from notifications_python_client.errors import HTTPError
|
|
from notifications_utils.recipients import format_phone_number_human_readable
|
|
from notifications_utils.template import SMSPreviewTemplate
|
|
|
|
from app import current_service, notification_api_client, service_api_client
|
|
from app.main import main
|
|
from app.main.forms import SearchByNameForm
|
|
from app.models.template_list import TemplateList
|
|
from app.utils import user_has_permissions
|
|
|
|
|
|
@main.route("/services/<uuid:service_id>/conversation/<uuid:notification_id>")
|
|
@user_has_permissions('view_activity')
|
|
def conversation(service_id, notification_id):
|
|
|
|
user_number = get_user_number(service_id, notification_id)
|
|
|
|
return render_template(
|
|
'views/conversations/conversation.html',
|
|
user_number=user_number,
|
|
partials=get_conversation_partials(service_id, user_number),
|
|
updates_url=url_for('.conversation_updates', service_id=service_id, notification_id=notification_id),
|
|
notification_id=notification_id,
|
|
)
|
|
|
|
|
|
@main.route("/services/<uuid:service_id>/conversation/<uuid:notification_id>.json")
|
|
@user_has_permissions('view_activity')
|
|
def conversation_updates(service_id, notification_id):
|
|
|
|
return jsonify(get_conversation_partials(
|
|
service_id,
|
|
get_user_number(service_id, notification_id)
|
|
))
|
|
|
|
|
|
@main.route("/services/<uuid:service_id>/conversation/<uuid:notification_id>/reply-with")
|
|
@main.route("/services/<uuid:service_id>/conversation/<uuid:notification_id>/reply-with/from-folder/<uuid:from_folder>")
|
|
@user_has_permissions('send_messages')
|
|
def conversation_reply(
|
|
service_id,
|
|
notification_id,
|
|
from_folder=None,
|
|
):
|
|
return render_template(
|
|
'views/templates/choose-reply.html',
|
|
templates_and_folders=TemplateList(
|
|
current_service,
|
|
template_folder_id=from_folder,
|
|
user=current_user,
|
|
template_type='sms'
|
|
),
|
|
template_folder_path=current_service.get_template_folder_path(from_folder),
|
|
search_form=SearchByNameForm(),
|
|
notification_id=notification_id,
|
|
template_type='sms'
|
|
)
|
|
|
|
|
|
@main.route("/services/<uuid:service_id>/conversation/<uuid:notification_id>/reply-with/<uuid:template_id>")
|
|
@user_has_permissions('send_messages')
|
|
def conversation_reply_with_template(
|
|
service_id,
|
|
notification_id,
|
|
template_id,
|
|
):
|
|
|
|
session['recipient'] = get_user_number(service_id, notification_id)
|
|
session['placeholders'] = {'phone number': session['recipient']}
|
|
|
|
return redirect(url_for(
|
|
'main.send_one_off_step',
|
|
service_id=service_id,
|
|
template_id=template_id,
|
|
step_index=1,
|
|
))
|
|
|
|
|
|
def get_conversation_partials(service_id, user_number):
|
|
|
|
return {
|
|
'messages': render_template(
|
|
'views/conversations/messages.html',
|
|
conversation=get_sms_thread(service_id, user_number),
|
|
)
|
|
}
|
|
|
|
|
|
def get_user_number(service_id, notification_id):
|
|
try:
|
|
user_number = service_api_client.get_inbound_sms_by_id(service_id, notification_id)['user_number']
|
|
except HTTPError as e:
|
|
if e.status_code != 404:
|
|
raise
|
|
user_number = notification_api_client.get_notification(service_id, notification_id)['to']
|
|
return format_phone_number_human_readable(user_number)
|
|
|
|
|
|
def get_sms_thread(service_id, user_number):
|
|
|
|
for notification in sorted((
|
|
notification_api_client.get_notifications_for_service(service_id,
|
|
to=user_number,
|
|
template_type='sms')['notifications'] +
|
|
service_api_client.get_inbound_sms(service_id, user_number=user_number)['data']
|
|
), key=lambda notification: notification['created_at']):
|
|
|
|
is_inbound = ('notify_number' in notification)
|
|
redact_personalisation = not is_inbound and notification['template']['redact_personalisation']
|
|
|
|
if redact_personalisation:
|
|
notification['personalisation'] = {}
|
|
|
|
yield {
|
|
'inbound': is_inbound,
|
|
'content': SMSPreviewTemplate(
|
|
{
|
|
'content': (
|
|
notification['content'] if is_inbound else
|
|
notification['template']['content']
|
|
)
|
|
},
|
|
notification.get('personalisation'),
|
|
downgrade_non_sms_characters=(not is_inbound),
|
|
redact_missing_personalisation=redact_personalisation,
|
|
),
|
|
'created_at': notification['created_at'],
|
|
'status': notification.get('status'),
|
|
'id': notification['id'],
|
|
}
|