mirror of
https://github.com/inventree/InvenTree.git
synced 2026-08-10 15:36:17 +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:
|
if type(defaults) is not dict:
|
||||||
try:
|
try:
|
||||||
defaults = json.loads(str(defaults))
|
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'))
|
raise ValidationError(_('Invalid field defaults'))
|
||||||
|
|
||||||
return defaults
|
return defaults
|
||||||
@@ -111,7 +114,10 @@ class DataImportSessionSerializer(InvenTreeModelSerializer):
|
|||||||
if type(overrides) is not dict:
|
if type(overrides) is not dict:
|
||||||
try:
|
try:
|
||||||
overrides = json.loads(str(overrides))
|
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'))
|
raise ValidationError(_('Invalid field overrides'))
|
||||||
|
|
||||||
return overrides
|
return overrides
|
||||||
@@ -124,7 +130,10 @@ class DataImportSessionSerializer(InvenTreeModelSerializer):
|
|||||||
if type(filters) is not dict:
|
if type(filters) is not dict:
|
||||||
try:
|
try:
|
||||||
filters = json.loads(str(filters))
|
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'))
|
raise ValidationError(_('Invalid field filters'))
|
||||||
|
|
||||||
return filters
|
return filters
|
||||||
|
|||||||
@@ -152,7 +152,47 @@ class ImporterTest(ImporterMixin, InvenTreeTestCase):
|
|||||||
self.assertEqual(n + 12, Company.objects.count())
|
self.assertEqual(n + 12, Company.objects.count())
|
||||||
|
|
||||||
def test_field_defaults(self):
|
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):
|
def test_lookup_field_ambiguous_match(self):
|
||||||
"""Test the behavior of lookup_related_field for ambiguous and pinned matches."""
|
"""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 _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
# Define maximum limits for imported file data
|
# 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_ROWS = 5000
|
||||||
IMPORTER_MAX_COLS = 1000
|
IMPORTER_MAX_COLS = 1000
|
||||||
|
|
||||||
@@ -46,8 +46,11 @@ def validate_field_defaults(value):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if type(value) is not dict:
|
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:
|
try:
|
||||||
value = json.loads(value)
|
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'))
|
raise ValidationError(_('Value must be a valid dictionary object'))
|
||||||
|
|||||||
Reference in New Issue
Block a user