From 9fc75fa0903c114d96904ee3ea3b183ac882f8f2 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 7 Mar 2019 00:57:22 +0100 Subject: [PATCH] mpdh13: validate date syntax (#31186) --- passerelle/contrib/mdph13/models.py | 26 ++++++++++++++++++++++++++ tests/test_mdph13.py | 15 +++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/passerelle/contrib/mdph13/models.py b/passerelle/contrib/mdph13/models.py index 88f5051..65092b8 100644 --- a/passerelle/contrib/mdph13/models.py +++ b/passerelle/contrib/mdph13/models.py @@ -31,12 +31,25 @@ from passerelle.utils.api import endpoint from passerelle.base.models import BaseResource, HTTPResource +def json_walker(value, func, path=None): + path = path or [] + if isinstance(value, dict): + for key in value: + json_walker(value[key], func, path + [key]) + elif isinstance(value, list): + for i, v in enumerate(value): + json_walker(v, func, path + ['[%s]' % i]) + else: + func(value, path) + + class MDPH13Resource(BaseResource, HTTPResource): category = _('Business Process Connectors') webservice_base_url = models.URLField(_('Webservice Base URL')) EMAIL_RE = re.compile(r'^[^@\s]+@[^@\s]+\.[^@\s]+$') + DATE_RE = re.compile(r'^\d{4}-\d{2}-\d{2}$') class Meta: verbose_name = _('MDPH CD13') @@ -155,6 +168,19 @@ class MDPH13Resource(BaseResource, HTTPResource): [] ).append(demande) data['demandes'] = new_demandes + + # Check some syntaxes + errors = [] + + def check(value, path): + if path[-1].startswith('date_'): + if (not isinstance(value, six.text_type) + or not self.DATE_RE.match(value)): + errors.append('%s is not a date string' % '.'.join(path)) + json_walker(data, check) + if errors: + raise APIError('invalid-response-format', data={'errors': errors}) + return data def check_status(self): diff --git a/tests/test_mdph13.py b/tests/test_mdph13.py index 173b47d..b890471 100644 --- a/tests/test_mdph13.py +++ b/tests/test_mdph13.py @@ -473,3 +473,18 @@ def test_dossier_partial_failure(mdph13, mock_http): assert response['data'][0]['err'] == 0 assert response['data'][1]['id'] == str(link2.pk) assert response['data'][1]['err'] == 1 + + +def test_dossier_bad_date(mdph13, mock_http): + link = Link.objects.create( + resource=mdph13, + name_id=NAME_ID, + file_number=FILE_NUMBER, + secret=SECRET, + dob=DOB) + INVALID_RESPONSE = json.loads(VALID_RESPONSE) + INVALID_RESPONSE['data']['demandes'][0]['date_demande'] = 'xxx' + mock_http.add_response(json.dumps(INVALID_RESPONSE)) + with pytest.raises(APIError) as exc_info: + mdph13.dossiers(None, NAME_ID, EMAIL, link_id=str(link.pk)) + assert str(exc_info.value) == 'invalid-response-format' -- 2.20.1