From f0fb07d176858817a0de9d85ca63a5d3f2e458df Mon Sep 17 00:00:00 2001 From: WinnyTroy Date: Mon, 25 Jan 2021 18:22:08 +0300 Subject: [PATCH] Capture attachment file names whose name exceeds 100 chars --- onadata/apps/logger/xform_instance_parser.py | 4 ++ onadata/libs/tests/utils/test_logger_tools.py | 46 +++++++++++++++++++ onadata/libs/utils/logger_tools.py | 10 +++- 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/onadata/apps/logger/xform_instance_parser.py b/onadata/apps/logger/xform_instance_parser.py index 038d336b26..652ad42436 100644 --- a/onadata/apps/logger/xform_instance_parser.py +++ b/onadata/apps/logger/xform_instance_parser.py @@ -43,6 +43,10 @@ class InstanceFormatError(Exception): pass +class AttachmentNameError(Exception): + pass + + class InstanceEncryptionError(Exception): pass diff --git a/onadata/libs/tests/utils/test_logger_tools.py b/onadata/libs/tests/utils/test_logger_tools.py index 564b66c942..13f175d10a 100644 --- a/onadata/libs/tests/utils/test_logger_tools.py +++ b/onadata/libs/tests/utils/test_logger_tools.py @@ -1,3 +1,4 @@ +import os import re from io import BytesIO @@ -15,6 +16,8 @@ from onadata.libs.utils.logger_tools import ( create_instance, generate_content_disposition_header, get_first_record, safe_create_instance) +from onadata.apps.logger.xform_instance_parser import AttachmentNameError +from django.core.files.uploadedfile import InMemoryUploadedFile class TestLoggerTools(PyxformTestCase, TestBase): @@ -502,3 +505,46 @@ def test_check_encryption_status(self): self.assertIsNone(ret[1]) self.assertEqual(response.status_code, 400) self.assertIn(expected_error, str(response.content)) + + def test_attachment_file_name_validation(self): + """ + Test that a clear exception is raised when an attachement + is received whose file name exceeds 100 chars + """ + md = """ + | survey | | | | + | | type | name | label | + | | image | image1 | Photo | + | | image | image2 | Photo | + """ + self._create_user_and_login() + self.xform = self._publish_markdown(md, self.user) + + xml_string = """ + + + uuid:UJ5jSMAJ1Jz4EszdgHy8n851AsKaqBPO5 + + 1300221157303.jpg + 1300375832136.jpg + + """.format(self.xform.id_string) + + file_path = "{}/apps/logger/tests/Health_2011_03_13."\ + "xml_2011-03-15_20-30-28/1300221157303"\ + ".jpg".format(settings.PROJECT_ROOT) + f = open(file_path, 'rb') + media_file = InMemoryUploadedFile( + file=f, + field_name="image1", + name=f'{f.name} +\ + test_file_name_test_file_name_test_file_name_test_file_name_test_file_name_test_file_name', # noqa + content_type="image/jpeg", + size=os.path.getsize(file_path), + charset=None + ) + with self.assertRaises(AttachmentNameError): + create_instance( + self.user.username, + BytesIO(xml_string.strip().encode('utf-8')), + media_files=[media_file]) diff --git a/onadata/libs/utils/logger_tools.py b/onadata/libs/utils/logger_tools.py index 1557e53f85..bdab0dc464 100644 --- a/onadata/libs/utils/logger_tools.py +++ b/onadata/libs/utils/logger_tools.py @@ -41,7 +41,7 @@ DuplicateInstance, InstanceEmptyError, InstanceInvalidUserError, InstanceMultipleNodeError, InstanceEncryptionError, NonUniqueFormIdError, InstanceFormatError, clean_and_parse_xml, get_deprecated_uuid_from_xml, - get_submission_date_from_xml, get_uuid_from_xml) + get_submission_date_from_xml, get_uuid_from_xml, AttachmentNameError) from onadata.apps.messaging.constants import XFORM, \ SUBMISSION_EDITED, SUBMISSION_CREATED from onadata.apps.messaging.serializers import send_message @@ -336,6 +336,9 @@ def save_attachments(xform, instance, media_files, remove_deleted_media=False): xform.instances_with_osm = True xform.save() filename = os.path.basename(f.name) + # Validate Attachment file name length + if len(filename) > 100: + raise AttachmentNameError(filename) media_in_submission = ( filename in instance.get_expected_media() or [instance.xml.decode('utf-8').find(filename) != -1 if @@ -515,6 +518,11 @@ def safe_create_instance(username, xml_file, media_files, uuid, request): _(u"Form does not exist on this account")) except ExpatError: error = OpenRosaResponseBadRequest(_(u"Improperly formatted XML.")) + except AttachmentNameError: + response = OpenRosaResponseBadRequest( + _("Attachment file name exceeds 100 chars")) + response.status_code = 400 + error = response except DuplicateInstance: response = OpenRosaResponse(_(u"Duplicate submission")) response.status_code = 202