mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-24 01:11:38 -05:00
Merge pull request #3136 from alphagov/validate-template-length-broadcast-api
Validate content length on broadcast API
This commit is contained in:
@@ -40,7 +40,6 @@ post_broadcast_schema = {
|
||||
"content": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 1395,
|
||||
},
|
||||
"web": {
|
||||
"type": "string",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from itertools import chain
|
||||
from flask import current_app, jsonify, request
|
||||
from notifications_utils.polygons import Polygons
|
||||
from notifications_utils.template import BroadcastMessageTemplate
|
||||
from app import authenticated_service, api_user
|
||||
from app.broadcast_message.translators import cap_xml_to_dict
|
||||
from app.dao.dao_utils import dao_save_object
|
||||
@@ -9,7 +10,7 @@ from app.models import BROADCAST_TYPE, BroadcastMessage, BroadcastStatusType
|
||||
from app.schema_validation import validate
|
||||
from app.v2.broadcast import v2_broadcast_blueprint
|
||||
from app.v2.broadcast.broadcast_schemas import post_broadcast_schema
|
||||
from app.v2.errors import BadRequestError
|
||||
from app.v2.errors import BadRequestError, ValidationError
|
||||
from app.xml_schemas import validate_xml
|
||||
|
||||
|
||||
@@ -43,6 +44,22 @@ def create_broadcast():
|
||||
area['polygons'] for area in broadcast_json['areas']
|
||||
))))
|
||||
|
||||
template = BroadcastMessageTemplate.from_content(
|
||||
broadcast_json['content']
|
||||
)
|
||||
|
||||
if template.content_too_long:
|
||||
raise ValidationError(
|
||||
message=(
|
||||
f'description must be {template.max_content_count:,.0f} '
|
||||
f'characters or fewer'
|
||||
) + (
|
||||
' (because it could not be GSM7 encoded)'
|
||||
if template.non_gsm_characters else ''
|
||||
),
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
broadcast_message = BroadcastMessage(
|
||||
service_id=authenticated_service.id,
|
||||
content=broadcast_json['content'],
|
||||
|
||||
@@ -33,7 +33,7 @@ notifications-python-client==5.7.1
|
||||
# PaaS
|
||||
awscli-cwlogs==1.4.6
|
||||
|
||||
git+https://github.com/alphagov/notifications-utils.git@43.8.3#egg=notifications-utils==43.8.3
|
||||
git+https://github.com/alphagov/notifications-utils.git@43.9.0#egg=notifications-utils==43.9.0
|
||||
|
||||
# gds-metrics requires prometheseus 0.2.0, override that requirement as 0.7.1 brings significant performance gains
|
||||
prometheus-client==0.9.0
|
||||
|
||||
@@ -35,7 +35,7 @@ notifications-python-client==5.7.1
|
||||
# PaaS
|
||||
awscli-cwlogs==1.4.6
|
||||
|
||||
git+https://github.com/alphagov/notifications-utils.git@43.8.3#egg=notifications-utils==43.8.3
|
||||
git+https://github.com/alphagov/notifications-utils.git@43.9.0#egg=notifications-utils==43.9.0
|
||||
|
||||
# gds-metrics requires prometheseus 0.2.0, override that requirement as 0.7.1 brings significant performance gains
|
||||
prometheus-client==0.9.0
|
||||
@@ -46,14 +46,14 @@ alembic==1.5.4
|
||||
amqp==1.4.9
|
||||
anyjson==0.3.3
|
||||
attrs==20.3.0
|
||||
awscli==1.19.5
|
||||
awscli==1.19.8
|
||||
bcrypt==3.2.0
|
||||
billiard==3.3.0.23
|
||||
bleach==3.3.0
|
||||
blinker==1.4
|
||||
boto==2.49.0
|
||||
boto3==1.17.5
|
||||
botocore==1.20.5
|
||||
boto3==1.17.8
|
||||
botocore==1.20.8
|
||||
certifi==2020.12.5
|
||||
chardet==4.0.0
|
||||
click==7.1.2
|
||||
|
||||
@@ -198,3 +198,40 @@ CANCEL = """
|
||||
</info>
|
||||
</alert>
|
||||
"""
|
||||
|
||||
WITH_PLACEHOLDER_FOR_CONTENT = """
|
||||
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.2">
|
||||
<identifier>50385fcb0ab7aa447bbd46d848ce8466E</identifier>
|
||||
<sender>www.gov.uk/environment-agency</sender>
|
||||
<sent>2020-02-16T23:01:13-00:00</sent>
|
||||
<status>Actual</status>
|
||||
<msgType>Alert</msgType>
|
||||
<source>Flood warning service</source>
|
||||
<scope>Public</scope>
|
||||
<references>www.gov.uk/environment-agency,4f6d28b10ab7aa447bbd46d85f1e9effE,2020-02-16T19:20:03+00:00</references>
|
||||
<info>
|
||||
<language>en-GB</language>
|
||||
<category>Met</category>
|
||||
<event>053/055 Issue Severe Flood Warning EA</event>
|
||||
<urgency>Immediate</urgency>
|
||||
<severity>Severe</severity>
|
||||
<certainty>Likely</certainty>
|
||||
<expires>2020-02-26T23:01:14-00:00</expires>
|
||||
<senderName>Environment Agency</senderName>
|
||||
<description>{}</description>
|
||||
<web>https://flood-warning-information.service.gov.uk</web>
|
||||
<contact>0345 988 1188</contact>
|
||||
<area>
|
||||
<areaDesc>River Steeping in Wainfleet All Saints</areaDesc>
|
||||
<polygon>53.10569,0.24453 53.10593,0.24430 53.10601,0.24375 53.10615,0.24349 53.10629,0.24356 53.10656,0.24336 53.10697,0.24354 53.10684,0.24298 53.10694,0.24264 53.10721,0.24302 53.10752,0.24310 53.10777,0.24308 53.10805,0.24320 53.10803,0.24187 53.10776,0.24085 53.10774,0.24062 53.10702,0.24056 53.10679,0.24088 53.10658,0.24071 53.10651,0.24049 53.10656,0.24022 53.10642,0.24022 53.10632,0.24052 53.10629,0.24082 53.10612,0.24093 53.10583,0.24133 53.10564,0.24178 53.10541,0.24282 53.10569,0.24453</polygon>
|
||||
<geocode>
|
||||
<valueName>TargetAreaCode</valueName>
|
||||
<value>053FWFSTEEP4</value>
|
||||
</geocode>
|
||||
</area>
|
||||
</info>
|
||||
</alert>
|
||||
"""
|
||||
|
||||
LONG_GSM7 = WITH_PLACEHOLDER_FOR_CONTENT.format('a' * 1396)
|
||||
LONG_UCS2 = WITH_PLACEHOLDER_FOR_CONTENT.format('ŵ' * 616)
|
||||
|
||||
@@ -190,3 +190,34 @@ def test_unsupported_message_types_400(
|
||||
} in (
|
||||
json.loads(response.get_data(as_text=True))['errors']
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('xml_document, expected_error', (
|
||||
(sample_cap_xml_documents.LONG_UCS2, (
|
||||
'description must be 615 characters or fewer (because it '
|
||||
'could not be GSM7 encoded)'
|
||||
)),
|
||||
(sample_cap_xml_documents.LONG_GSM7, (
|
||||
'description must be 1,395 characters or fewer'
|
||||
)),
|
||||
))
|
||||
def test_content_too_long_returns_400(
|
||||
client,
|
||||
sample_broadcast_service,
|
||||
xml_document,
|
||||
expected_error,
|
||||
):
|
||||
auth_header = create_authorization_header(service_id=sample_broadcast_service.id)
|
||||
response = client.post(
|
||||
path='/v2/broadcast',
|
||||
data=xml_document,
|
||||
headers=[('Content-Type', 'application/cap+xml'), auth_header],
|
||||
)
|
||||
|
||||
assert json.loads(response.get_data(as_text=True)) == {
|
||||
'errors': [{
|
||||
'error': 'ValidationError',
|
||||
'message': expected_error,
|
||||
}],
|
||||
'status_code': 400,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user