comparison 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
comparison
equal deleted inserted replaced
402:724e39d596a9 403:1dc606612405
174 } 174 }
175 }, 175 },
176 const.OPT_SERIAL_IDS: 176 const.OPT_SERIAL_IDS:
177 {"type": "boolean", 177 {"type": "boolean",
178 "label": "Use serial ids"}, 178 "label": "Use serial ids"},
179 const.OPT_CONSISTENT_PUBLISHER:
180 {"type": "boolean",
181 "label": "Keep publisher on update"},
179 } 182 }
180 183
181 subscriptionOptions = { 184 subscriptionOptions = {
182 "pubsub#subscription_type": 185 "pubsub#subscription_type":
183 {"type": "list-single", 186 {"type": "list-single",
377 for field in to_remove: 380 for field in to_remove:
378 item_form.removeField(field) 381 item_form.removeField(field)
379 item_elt.addChild(item_form.toElement()) 382 item_elt.addChild(item_form.toElement())
380 383
381 def _checkOverwrite(self, node, itemIdentifiers, publisher): 384 def _checkOverwrite(self, node, itemIdentifiers, publisher):
382 """Check that the itemIdentifiers correspond to items published 385 """Check that publisher can overwrite items
383 by the current publisher""" 386
387 current publisher must correspond to each item publisher
388 """
384 def doCheck(item_pub_map): 389 def doCheck(item_pub_map):
385 for item_publisher in item_pub_map.itervalues(): 390 for item_publisher in item_pub_map.itervalues():
386 if item_publisher.userhost() != publisher.userhost(): 391 if item_publisher.userhost() != publisher.userhost():
387 raise error.ItemForbidden() 392 raise error.ItemForbidden()
388 393
443 self.enforceSchema(item, schema, affiliation) 448 self.enforceSchema(item, schema, affiliation)
444 items_data.append(container.ItemData(item, access_model, item_config, categories, new=new_item)) 449 items_data.append(container.ItemData(item, access_model, item_config, categories, new=new_item))
445 450
446 if persistItems: 451 if persistItems:
447 452
448 if check_overwrite and affiliation != 'owner' and not self.isAdmin(requestor): 453 if check_overwrite:
449 # we don't want a publisher to overwrite the item 454 itemIdentifiers = [item['id'] for item in items
450 # of an other publisher 455 if item.getAttribute('id')]
451 yield self._checkOverwrite(node, [item['id'] for item in items if item.getAttribute('id')], requestor) 456
457 if affiliation == 'owner' or self.isAdmin(requestor):
458 if configuration[const.OPT_CONSISTENT_PUBLISHER]:
459 pub_map = yield node.getItemsPublishers(itemIdentifiers)
460 publishers = set(pub_map.values())
461 if len(publishers) != 1:
462 # TODO: handle multiple items publishing (from several
463 # publishers)
464 raise error.NoPublishing(
465 u"consistent_publisher is currently only possible when "
466 u"publishing items from a single publisher. Try to "
467 u"publish one item at a time")
468 # we replace requestor and new payload's publisher by original
469 # item publisher to keep publisher consistent
470 requestor = publishers.pop()
471 for item in items:
472 item['publisher'] = requestor.full()
473 else:
474 # we don't want a publisher to overwrite the item
475 # of an other publisher
476 yield self._checkOverwrite(node, itemIdentifiers, requestor)
452 477
453 # TODO: check conflict and recalculate max id if serial_ids is set 478 # TODO: check conflict and recalculate max id if serial_ids is set
454 yield node.storeItems(items_data, requestor) 479 yield node.storeItems(items_data, requestor)
455 480
456 yield self._doNotify(node, items_data, deliverPayloads, pep, recipient) 481 yield self._doNotify(node, items_data, deliverPayloads, pep, recipient)