Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture attachment file names whose name exceeds 100 chars #2003

Merged
merged 2 commits into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions onadata/apps/logger/xform_instance_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ class InstanceFormatError(Exception):
pass


class AttachmentNameError(Exception):
pass


class InstanceEncryptionError(Exception):
pass

Expand Down
46 changes: 46 additions & 0 deletions onadata/libs/tests/utils/test_logger_tools.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import re
from io import BytesIO

Expand All @@ -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):
Expand Down Expand Up @@ -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 = """
<data id="{}">
<meta>
<instanceID>uuid:UJ5jSMAJ1Jz4EszdgHy8n851AsKaqBPO5</instanceID>
</meta>
<image1>1300221157303.jpg</image1>
<image2>1300375832136.jpg</image2>
</data>
""".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])
10 changes: 9 additions & 1 deletion onadata/libs/utils/logger_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down