diff src/backend.py @ 403:1dc606612405

implemented experimental "consistent_publisher" option: /!\ pgsql schema needs to be updated /!\ New "consistent_publisher" option has been implemented to allow node owners + admins to modify an item while preserving the original publisher. This way, original publisher can still edit the item. In addition to `consistent_publisher`, `max_items` has been added to PGQSL schema to prepare for future implementation.
author Goffi <goffi@goffi.org>
date Wed, 12 Jun 2019 21:51:50 +0200
parents a4980d03b3a3
children
line wrap: on
line diff
--- a/src/backend.py	Thu May 23 08:58:29 2019 +0200
+++ b/src/backend.py	Wed Jun 12 21:51:50 2019 +0200
@@ -176,6 +176,9 @@
             const.OPT_SERIAL_IDS:
                 {"type": "boolean",
                  "label": "Use serial ids"},
+            const.OPT_CONSISTENT_PUBLISHER:
+                {"type": "boolean",
+                 "label": "Keep publisher on update"},
             }
 
     subscriptionOptions = {
@@ -379,8 +382,10 @@
         item_elt.addChild(item_form.toElement())
 
     def _checkOverwrite(self, node, itemIdentifiers, publisher):
-        """Check that the itemIdentifiers correspond to items published
-        by the current publisher"""
+        """Check that publisher can overwrite items
+
+        current publisher must correspond to each item publisher
+        """
         def doCheck(item_pub_map):
             for item_publisher in item_pub_map.itervalues():
                 if item_publisher.userhost() != publisher.userhost():
@@ -445,10 +450,30 @@
 
         if persistItems:
 
-            if check_overwrite and affiliation != 'owner' and not self.isAdmin(requestor):
-                # we don't want a publisher to overwrite the item
-                # of an other publisher
-                yield self._checkOverwrite(node, [item['id'] for item in items if item.getAttribute('id')], requestor)
+            if check_overwrite:
+                itemIdentifiers = [item['id'] for item in items
+                                   if item.getAttribute('id')]
+
+                if affiliation == 'owner' or self.isAdmin(requestor):
+                    if configuration[const.OPT_CONSISTENT_PUBLISHER]:
+                        pub_map = yield node.getItemsPublishers(itemIdentifiers)
+                        publishers = set(pub_map.values())
+                        if len(publishers) != 1:
+                            # TODO: handle multiple items publishing (from several
+                            #       publishers)
+                            raise error.NoPublishing(
+                                u"consistent_publisher is currently only possible when "
+                                u"publishing items from a single publisher. Try to "
+                                u"publish one item at a time")
+                        # we replace requestor and new payload's publisher by original
+                        # item publisher to keep publisher consistent
+                        requestor = publishers.pop()
+                        for item in items:
+                            item['publisher'] = requestor.full()
+                else:
+                    # we don't want a publisher to overwrite the item
+                    # of an other publisher
+                    yield self._checkOverwrite(node, itemIdentifiers, requestor)
 
             # TODO: check conflict and recalculate max id if serial_ids is set
             yield node.storeItems(items_data, requestor)