mirror of
https://github.com/inventree/InvenTree.git
synced 2026-08-10 07:26:14 +00:00
Improve validation for import session (#12492)
- Ensure that validated data is a dict shape
This commit is contained in:
@@ -98,7 +98,10 @@ class DataImportSessionSerializer(InvenTreeModelSerializer):
|
||||
if type(defaults) is not dict:
|
||||
try:
|
||||
defaults = json.loads(str(defaults))
|
||||
except:
|
||||
except json.JSONDecodeError:
|
||||
raise ValidationError(_('Invalid field defaults'))
|
||||
|
||||
if type(defaults) is not dict:
|
||||
raise ValidationError(_('Invalid field defaults'))
|
||||
|
||||
return defaults
|
||||
@@ -111,7 +114,10 @@ class DataImportSessionSerializer(InvenTreeModelSerializer):
|
||||
if type(overrides) is not dict:
|
||||
try:
|
||||
overrides = json.loads(str(overrides))
|
||||
except:
|
||||
except json.JSONDecodeError:
|
||||
raise ValidationError(_('Invalid field overrides'))
|
||||
|
||||
if type(overrides) is not dict:
|
||||
raise ValidationError(_('Invalid field overrides'))
|
||||
|
||||
return overrides
|
||||
@@ -124,7 +130,10 @@ class DataImportSessionSerializer(InvenTreeModelSerializer):
|
||||
if type(filters) is not dict:
|
||||
try:
|
||||
filters = json.loads(str(filters))
|
||||
except:
|
||||
except json.JSONDecodeError:
|
||||
raise ValidationError(_('Invalid field filters'))
|
||||
|
||||
if type(filters) is not dict:
|
||||
raise ValidationError(_('Invalid field filters'))
|
||||
|
||||
return filters
|
||||
|
||||
@@ -152,7 +152,47 @@ class ImporterTest(ImporterMixin, InvenTreeTestCase):
|
||||
self.assertEqual(n + 12, Company.objects.count())
|
||||
|
||||
def test_field_defaults(self):
|
||||
"""Test default field values."""
|
||||
"""Test default field values.
|
||||
|
||||
Regression test for bug #30 (dev/todo/bugs.md): validate_field_defaults
|
||||
must reject any parsed JSON value that isn't actually a dict, not just
|
||||
values which fail to parse as JSON at all.
|
||||
"""
|
||||
from django.core.exceptions import ValidationError as DjangoValidationError
|
||||
|
||||
def data_file():
|
||||
# full_clean() reads the file eagerly, so each session needs its own
|
||||
# freshly-opened (binary) copy
|
||||
content = self.helper_file('companies.csv').read()
|
||||
return ContentFile(content.encode(), 'companies.csv')
|
||||
|
||||
# A dict value is accepted as-is
|
||||
session = DataImportSession(
|
||||
data_file=data_file(), model_type='company', field_defaults={'name': 'Test'}
|
||||
)
|
||||
session.full_clean()
|
||||
|
||||
# A JSON-encoded dict string is also accepted (de-stringified)
|
||||
session = DataImportSession(
|
||||
data_file=data_file(),
|
||||
model_type='company',
|
||||
field_defaults='{"name": "Test"}',
|
||||
)
|
||||
session.full_clean()
|
||||
|
||||
# A JSON-encoded list is valid JSON, but not a dict - must be rejected
|
||||
session = DataImportSession(
|
||||
data_file=data_file(), model_type='company', field_defaults='[1, 2, 3]'
|
||||
)
|
||||
with self.assertRaises(DjangoValidationError):
|
||||
session.full_clean()
|
||||
|
||||
# Garbage which does not even parse as JSON must also be rejected
|
||||
session = DataImportSession(
|
||||
data_file=data_file(), model_type='company', field_defaults='not valid json'
|
||||
)
|
||||
with self.assertRaises(DjangoValidationError):
|
||||
session.full_clean()
|
||||
|
||||
def test_lookup_field_ambiguous_match(self):
|
||||
"""Test the behavior of lookup_related_field for ambiguous and pinned matches."""
|
||||
|
||||
@@ -6,7 +6,7 @@ from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Define maximum limits for imported file data
|
||||
IMPORTER_MAX_FILE_SIZE = 32 * 1024 * 1042
|
||||
IMPORTER_MAX_FILE_SIZE = 32 * 1024 * 1024
|
||||
IMPORTER_MAX_ROWS = 5000
|
||||
IMPORTER_MAX_COLS = 1000
|
||||
|
||||
@@ -46,8 +46,11 @@ def validate_field_defaults(value):
|
||||
return
|
||||
|
||||
if type(value) is not dict:
|
||||
# OK if we can parse it as JSON
|
||||
# OK if we can parse it as JSON - but the result must be a dict
|
||||
try:
|
||||
value = json.loads(value)
|
||||
except json.JSONDecodeError:
|
||||
except (TypeError, json.JSONDecodeError):
|
||||
raise ValidationError(_('Value must be a valid dictionary object'))
|
||||
|
||||
if type(value) is not dict:
|
||||
raise ValidationError(_('Value must be a valid dictionary object'))
|
||||
|
||||
Reference in New Issue
Block a user