comparison sat_pubsub/backend.py @ 309:890b24b37b56

Re-implemented feature which allows an entity to retract an item from somebody else node (i.e. a node from which he is neither owner or publisher) if he is the publisher of the item.
author Goffi <goffi@goffi.org>
date Mon, 21 Dec 2015 13:41:15 +0100
parents 087b705493a6
children a776544d84e5
comparison
equal deleted inserted replaced
308:087b705493a6 309:890b24b37b56
729 return defer.DeferredList(d_list).addCallback(render) 729 return defer.DeferredList(d_list).addCallback(render)
730 730
731 def retractItem(self, nodeIdentifier, itemIdentifiers, requestor, notify, pep, recipient): 731 def retractItem(self, nodeIdentifier, itemIdentifiers, requestor, notify, pep, recipient):
732 d = self.storage.getNode(nodeIdentifier, pep, recipient) 732 d = self.storage.getNode(nodeIdentifier, pep, recipient)
733 d.addCallback(_getAffiliation, requestor) 733 d.addCallback(_getAffiliation, requestor)
734 # FIXME: to be checked 734 d.addCallback(self._doRetract, itemIdentifiers, requestor, notify, pep, recipient)
735 # if const.FLAG_RETRACT_ALLOW_PUBLISHER: 735 return d
736 # d.addCallback(self._doRetractAllowPublisher, itemIdentifiers, requestor) 736
737 # else: 737 def _doRetract(self, result, itemIdentifiers, requestor, notify, pep, recipient):
738 # d.addCallback(self._doRetract, itemIdentifiers)
739 d.addCallback(self._doRetract, itemIdentifiers, notify, pep, recipient)
740 return d
741
742 # FIXME: to be checked
743 # def _doRetractAllowPublisher(self, result, itemIdentifiers, requestor):
744 # """This method has been added to allow the publisher
745 # of an item to retract it, even if he has no affiliation
746 # to that item. For instance, this allows you to delete
747 # an item you posted in a node of "open" publish model.
748 # """
749 # node, affiliation = result
750 # if affiliation in ['owner', 'publisher']:
751 # return self._doRetract(result, itemIdentifiers)
752 # d = node.filterItemsWithPublisher(itemIdentifiers, requestor)
753 # def filterCb(filteredItems):
754 # if not filteredItems:
755 # return self._doRetract(result, itemIdentifiers)
756 # # XXX: fake an affiliation that does NOT exist
757 # return self._doRetract((node, 'publisher'), filteredItems)
758 # d.addCallback(filterCb)
759 # return d
760
761 def _doRetract(self, result, itemIdentifiers, notify, pep, recipient):
762 node, affiliation = result 738 node, affiliation = result
763 persistItems = node.getConfiguration()[const.OPT_PERSIST_ITEMS] 739 persistItems = node.getConfiguration()[const.OPT_PERSIST_ITEMS]
764
765 if affiliation not in ['owner', 'publisher']:
766 raise error.Forbidden()
767 740
768 if not persistItems: 741 if not persistItems:
769 raise error.NodeNotPersistent() 742 raise error.NodeNotPersistent()
770 743
771 # we need to get the items before removing them, for the notifications 744 # we need to get the items before removing them, for the notifications
774 """Remove the items and keep only actually removed ones in items_data""" 747 """Remove the items and keep only actually removed ones in items_data"""
775 d = node.removeItems(itemIdentifiers) 748 d = node.removeItems(itemIdentifiers)
776 d.addCallback(lambda removed: [item_data for item_data in items_data if item_data.item["id"] in removed]) 749 d.addCallback(lambda removed: [item_data for item_data in items_data if item_data.item["id"] in removed])
777 return d 750 return d
778 751
779 d = node.getItemsById(None, True, itemIdentifiers) 752 def checkPublishers(publishers_map):
753 """Called when requestor is neither owner neither publisher of the Node
754
755 We check that requestor is publisher of all the items he wants to retract
756 and raise error.Forbidden if it is not the case
757 """
758 # TODO: the behaviour should be configurable (per node ?)
759 if any((requestor.userhostJID() != publisher.userhostJID() for publisher in publishers_map.itervalues())):
760 raise error.Forbidden()
761
762 if affiliation in ['owner', 'publisher']:
763 # the requestor is owner or publisher of the node
764 # he can retract what he wants
765 d = defer.succeed(None)
766 else:
767 # the requestor doesn't have right to retract on the whole node
768 # we check if he is a publisher for all items he wants to retract
769 # and forbid the retraction else.
770 d = node.getItemsPublishers(itemIdentifiers)
771 d.addCallback(checkPublishers)
772 d.addCallback(lambda dummy: node.getItemsById(None, True, itemIdentifiers))
780 d.addCallback(self._tuple2ItemData) 773 d.addCallback(self._tuple2ItemData)
781 d.addCallback(removeItems) 774 d.addCallback(removeItems)
782 775
783 if notify: 776 if notify:
784 d.addCallback(self._doNotifyRetraction, node, pep, recipient) 777 d.addCallback(self._doNotifyRetraction, node, pep, recipient)