Merge pull request #3325 from alphagov/prevent-empty-areas-178986763

Add validation to prevent blank area names
This commit is contained in:
Ben Thorner
2021-09-17 15:20:15 +01:00
committed by GitHub
4 changed files with 45 additions and 17 deletions

View File

@@ -76,6 +76,7 @@ post_broadcast_schema = {
"properties": { "properties": {
"name": { "name": {
"type": "string", "type": "string",
"pattern": "([a-zA-Z1-9]+ )*[a-zA-Z1-9]+",
}, },
"polygons": { "polygons": {
"type": "array", "type": "array",

View File

@@ -41,27 +41,12 @@ def create_broadcast():
broadcast_json = cap_xml_to_dict(cap_xml) broadcast_json = cap_xml_to_dict(cap_xml)
validate(broadcast_json, post_broadcast_schema) validate(broadcast_json, post_broadcast_schema)
_validate_template(broadcast_json)
polygons = Polygons(list(chain.from_iterable(( polygons = Polygons(list(chain.from_iterable((
area['polygons'] for area in broadcast_json['areas'] 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( broadcast_message = BroadcastMessage(
service_id=authenticated_service.id, service_id=authenticated_service.id,
content=broadcast_json['content'], content=broadcast_json['content'],
@@ -89,3 +74,21 @@ def create_broadcast():
) )
return jsonify(broadcast_message.serialize()), 201 return jsonify(broadcast_message.serialize()), 201
def _validate_template(broadcast_json):
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,
)

View File

@@ -1,3 +1,5 @@
import re
WAINFLEET = """ WAINFLEET = """
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.2"> <alert xmlns="urn:oasis:names:tc:emergency:cap:1.2">
<identifier>50385fcb0ab7aa447bbd46d848ce8466E</identifier> <identifier>50385fcb0ab7aa447bbd46d848ce8466E</identifier>
@@ -235,3 +237,4 @@ WITH_PLACEHOLDER_FOR_CONTENT = """
LONG_GSM7 = WITH_PLACEHOLDER_FOR_CONTENT.format('a' * 1396) LONG_GSM7 = WITH_PLACEHOLDER_FOR_CONTENT.format('a' * 1396)
LONG_UCS2 = WITH_PLACEHOLDER_FOR_CONTENT.format('ŵ' * 616) LONG_UCS2 = WITH_PLACEHOLDER_FOR_CONTENT.format('ŵ' * 616)
MISSING_AREA_NAMES = re.sub("<areaDesc>.*</areaDesc>", "<areaDesc> </areaDesc>", WAINFLEET)

View File

@@ -28,7 +28,7 @@ def test_broadcast_for_service_without_permission_returns_400(
) )
def test_valid_post_broadcast_returns_201( def test_post_broadcast_non_cap_xml_returns_415(
client, client,
sample_broadcast_service, sample_broadcast_service,
): ):
@@ -229,3 +229,24 @@ def test_content_too_long_returns_400(
}], }],
'status_code': 400, 'status_code': 400,
} }
def test_invalid_areas_returns_400(
client,
sample_broadcast_service
):
auth_header = create_service_authorization_header(service_id=sample_broadcast_service.id)
response = client.post(
path='/v2/broadcast',
data=sample_cap_xml_documents.MISSING_AREA_NAMES,
headers=[('Content-Type', 'application/cap+xml'), auth_header],
)
assert json.loads(response.get_data(as_text=True)) == {
'errors': [{
'error': 'ValidationError',
# the blank spaces represent the blank areaDesc in the XML
'message': 'areas does not match ([a-zA-Z1-9]+ )*[a-zA-Z1-9]+',
}],
'status_code': 400,
}