From 429cdf3f49964799e3e8451adbb596ca096a3480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Wed, 2 Dec 2015 12:31:04 +0100 Subject: [PATCH 1/3] formdef: check datasources are defined on import (#9173) --- tests/test_formdef_import.py | 18 +++++++++++++++++- wcs/admin/forms.py | 8 ++++++-- wcs/formdef.py | 22 ++++++++++++++++++++-- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/tests/test_formdef_import.py b/tests/test_formdef_import.py index ca495ff..e048d8f 100644 --- a/tests/test_formdef_import.py +++ b/tests/test_formdef_import.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- +import pytest import sys import shutil import StringIO @@ -9,7 +10,7 @@ import xml.etree.ElementTree as ET from quixote import cleanup from wcs.categories import Category -from wcs.formdef import FormDef, fields +from wcs.formdef import FormDef, fields, FormdefImportError from wcs.workflows import Workflow from qommon.misc import indent_xml as indent @@ -241,3 +242,18 @@ def test_file_field(): assert_xml_import_export_works(formdef) assert_json_import_export_works(formdef, include_id=True) assert_json_import_export_works(formdef) + +def test_unknown_data_source(): + formdef = FormDef() + formdef.name = 'foo' + formdef.fields = [fields.StringField(id='1', type='string', + data_source={'type': 'json', 'value': 'http://example.net'})] + export = ET.tostring(export_to_indented_xml(formdef)) + + FormDef.import_from_xml(StringIO.StringIO(export)) + + formdef.fields = [fields.StringField(id='1', type='string', + data_source={'type': 'foobar'})] + export = ET.tostring(export_to_indented_xml(formdef)) + with pytest.raises(FormdefImportError): + FormDef.import_from_xml(StringIO.StringIO(export)) diff --git a/wcs/admin/forms.py b/wcs/admin/forms.py index fac4e44..53cc82e 100644 --- a/wcs/admin/forms.py +++ b/wcs/admin/forms.py @@ -846,7 +846,9 @@ class FormDefPage(Directory): new_formdef = FormDef.import_from_xml(fp, include_id=True) except FormdefImportError, e: error = True - reason = _(e) + reason = _(e.msg) + if e.details: + reason += ' [%s]' % e.details except ValueError: error = True @@ -1592,7 +1594,9 @@ class FormsDirectory(AccessControlled, Directory): formdef = FormDef.import_from_xml(fp) except FormdefImportError, e: error = True - reason = _(e) + reason = _(e.msg) + if e.details: + reason += ' [%s]' % e.details except ValueError: error = True diff --git a/wcs/formdef.py b/wcs/formdef.py index 37c6c3c..4c23850 100644 --- a/wcs/formdef.py +++ b/wcs/formdef.py @@ -34,10 +34,13 @@ from formdata import FormData from roles import logged_users_role from categories import Category import fields +import data_sources class FormdefImportError(Exception): - pass + def __init__(self, msg, details=None): + self.msg = msg + self.details = details class FormField(object): @@ -683,8 +686,23 @@ class FormDef(StorableObject): tree = ET.parse(fd) except: raise ValueError() - return cls.import_from_xml_tree(tree, charset=charset, + formdef = cls.import_from_xml_tree(tree, charset=charset, include_id=include_id) + + # check if datasources are defined + unknown_datasources = set() + for field in formdef.fields: + data_source = getattr(field, 'data_source', None) + if data_source: + try: + data_sources.get_real(data_source) + except KeyError: + unknown_datasources.add(data_source.get('type')) + if unknown_datasources: + raise FormdefImportError(N_('Unknown datasources'), + details=', '.join(sorted(unknown_datasources))) + + return formdef import_from_xml = classmethod(import_from_xml) def import_from_xml_tree(cls, tree, include_id=False, charset=None): -- 2.6.2