changeset 2386:2e05921df16a

plugin schema, core(xmlui): deep copy base form when reused to avoid accidental modification
author Goffi <goffi@goffi.org>
date Fri, 20 Oct 2017 08:39:05 +0200
parents 39d30cf722cb
children a59f2abd970e
files src/plugins/plugin_exp_pubsub_schema.py src/tools/xml_tools.py
diffstat 2 files changed, 10 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_exp_pubsub_schema.py	Mon Oct 16 07:48:09 2017 +0200
+++ b/src/plugins/plugin_exp_pubsub_schema.py	Fri Oct 20 08:39:05 2017 +0200
@@ -31,6 +31,7 @@
 from wokkel import generic
 from zope.interface import implements
 from collections import Iterable
+import copy
 
 NS_SCHEMA = 'https://salut-a-toi/protocol/schema:0'
 NS_SCHEMA_FORM = 'https://salut-a-toi/protocol/schema#schema:0'
@@ -126,7 +127,7 @@
         return d
 
     @defer.inlineCallbacks
-    def getSchemaForm(self, client, service, nodeIdentifier, schema=None, form_type='form'):
+    def getSchemaForm(self, client, service, nodeIdentifier, schema=None, form_type='form', copy_form=True):
         """get data form from node's schema
 
         @param service(None, jid.JID): PubSub service
@@ -135,7 +136,11 @@
             if domish.Element, will be converted to data form
             if data_form.Form it will be returned without modification
             if None, it will be retrieved from node (imply one additional XMPP request)
+        @param form_type(unicode): type of the form
+        @param copy_form(bool): if True and if schema is already a data_form.Form, will deep copy it before returning
+            needed when the form is reused and it will be modified (e.g. in sendDataFormItem)
         @return(data_form.Form): data form
+            the form should not be modified if copy_form is not set
         """
         if schema is None:
             log.debug(_(u"unspecified schema, we need to request it"))
@@ -143,6 +148,8 @@
             if schema is None:
                 raise exceptions.DataError(_(u"no schema specified, and this node has no schema either, we can't construct the data form"))
         elif isinstance(schema, data_form.Form):
+            if copy_form:
+                schema = copy.deepcopy(schema)
             defer.returnValue(schema)
 
         try:
@@ -219,7 +226,7 @@
             it will be skipped
         """
         # we need the initial form to get options of fields when suitable
-        schema_form = yield self.getSchemaForm(client, service, nodeIdentifier, schema, form_type='result')
+        schema_form = yield self.getSchemaForm(client, service, nodeIdentifier, schema, form_type='result', copy_form=False)
         items_data = yield self._p.getItems(client, service, nodeIdentifier, max_items, item_ids, sub_id, rsm_request, extra)
         items, metadata = items_data
         items_xmlui = []
--- a/src/tools/xml_tools.py	Mon Oct 16 07:48:09 2017 +0200
+++ b/src/tools/xml_tools.py	Fri Oct 20 08:39:05 2017 +0200
@@ -251,7 +251,7 @@
             base_field = base_form.fields[name]
         except KeyError:
             continue
-        field.options = base_field.options
+        field.options = base_field.options[:]
     xml_ui = XMLUI("window", "vertical", session_id=session_id)
     dataForm2Widgets(xml_ui, form, read_only=True, prepend=prepend)
     return xml_ui