Mercurial > libervia-pubsub
diff 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 |
line wrap: on
line diff
--- a/sat_pubsub/backend.py Fri Dec 18 13:01:02 2015 +0100 +++ b/sat_pubsub/backend.py Mon Dec 21 13:41:15 2015 +0100 @@ -731,40 +731,13 @@ def retractItem(self, nodeIdentifier, itemIdentifiers, requestor, notify, pep, recipient): d = self.storage.getNode(nodeIdentifier, pep, recipient) d.addCallback(_getAffiliation, requestor) - # FIXME: to be checked - # if const.FLAG_RETRACT_ALLOW_PUBLISHER: - # d.addCallback(self._doRetractAllowPublisher, itemIdentifiers, requestor) - # else: - # d.addCallback(self._doRetract, itemIdentifiers) - d.addCallback(self._doRetract, itemIdentifiers, notify, pep, recipient) + d.addCallback(self._doRetract, itemIdentifiers, requestor, notify, pep, recipient) return d - # FIXME: to be checked - # def _doRetractAllowPublisher(self, result, itemIdentifiers, requestor): - # """This method has been added to allow the publisher - # of an item to retract it, even if he has no affiliation - # to that item. For instance, this allows you to delete - # an item you posted in a node of "open" publish model. - # """ - # node, affiliation = result - # if affiliation in ['owner', 'publisher']: - # return self._doRetract(result, itemIdentifiers) - # d = node.filterItemsWithPublisher(itemIdentifiers, requestor) - # def filterCb(filteredItems): - # if not filteredItems: - # return self._doRetract(result, itemIdentifiers) - # # XXX: fake an affiliation that does NOT exist - # return self._doRetract((node, 'publisher'), filteredItems) - # d.addCallback(filterCb) - # return d - - def _doRetract(self, result, itemIdentifiers, notify, pep, recipient): + def _doRetract(self, result, itemIdentifiers, requestor, notify, pep, recipient): node, affiliation = result persistItems = node.getConfiguration()[const.OPT_PERSIST_ITEMS] - if affiliation not in ['owner', 'publisher']: - raise error.Forbidden() - if not persistItems: raise error.NodeNotPersistent() @@ -776,7 +749,27 @@ d.addCallback(lambda removed: [item_data for item_data in items_data if item_data.item["id"] in removed]) return d - d = node.getItemsById(None, True, itemIdentifiers) + def checkPublishers(publishers_map): + """Called when requestor is neither owner neither publisher of the Node + + We check that requestor is publisher of all the items he wants to retract + and raise error.Forbidden if it is not the case + """ + # TODO: the behaviour should be configurable (per node ?) + if any((requestor.userhostJID() != publisher.userhostJID() for publisher in publishers_map.itervalues())): + raise error.Forbidden() + + if affiliation in ['owner', 'publisher']: + # the requestor is owner or publisher of the node + # he can retract what he wants + d = defer.succeed(None) + else: + # the requestor doesn't have right to retract on the whole node + # we check if he is a publisher for all items he wants to retract + # and forbid the retraction else. + d = node.getItemsPublishers(itemIdentifiers) + d.addCallback(checkPublishers) + d.addCallback(lambda dummy: node.getItemsById(None, True, itemIdentifiers)) d.addCallback(self._tuple2ItemData) d.addCallback(removeItems)