Mercurial > libervia-pubsub
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) |