# HG changeset patch # User Goffi # Date 1504850525 -7200 # Node ID 18b983fe9e1b628eaaeb0e6b29851de94a31cb7f # Parent 7c5d85c6fb3a331471330d707f8fd36e40f6e9fc backend: added "presence" access_model: - move presence checking method in separated method so they can be use for get and subscriptions - added VAL_AMODEL_PRESENCE constant diff -r 7c5d85c6fb3a -r 18b983fe9e1b sat_pubsub/backend.py --- a/sat_pubsub/backend.py Fri Sep 08 08:02:05 2017 +0200 +++ b/sat_pubsub/backend.py Fri Sep 08 08:02:05 2017 +0200 @@ -124,6 +124,7 @@ "label": "Who can subscribe to this node", "options": { const.VAL_AMODEL_OPEN: "Public node", + const.VAL_AMODEL_PRESENCE: "Node restricted to entites subscribed to owner presence", const.VAL_AMODEL_PUBLISHER_ROSTER: "Node restricted to some groups of publisher's roster", const.VAL_AMODEL_WHITELIST: "Node restricted to some jids", } @@ -471,7 +472,15 @@ access_model = node.getAccessModel() - if access_model != const.VAL_AMODEL_OPEN: + if access_model == const.VAL_AMODEL_OPEN: + d = defer.succeed(None) + elif access_model == const.VAL_AMODEL_PRESENCE: + d = self.checkPresenceSubscription(node, subscriber) + elif access_model == const.VAL_AMODEL_PUBLISHER_ROSTER: + d = self.checkRosterGroups(node, subscriber) + elif access_model == const.VAL_AMODEL_WHITELIST: + d = self.checkNodeAffiliations(node, subscriber) + else: raise NotImplementedError def trapExists(failure): @@ -766,6 +775,67 @@ for item_data in items_to_remove: items_data.remove(item_data) + def checkPresenceSubscription(self, node, requestor): + """check if requestor has presence subscription from node owner + + @param node(Node): node to check + @param requestor(jid.JID): entity who want to access node + """ + def gotRoster(roster): + if roster is None: + raise error.Forbidden() + + if requestor not in roster: + raise error.Forbidden() + + if not roster[requestor].subscriptionFrom: + raise error.Forbidden() + + d = self.getOwnerRoster(node) + d.addCallback(gotRoster) + return d + + @defer.inlineCallbacks + def checkRosterGroups(self, node, requestor): + """check if requestor is in allowed groups of a node + + @param node(Node): node to check + @param requestor(jid.JID): entity who want to access node + """ + roster = yield self.getOwnerRoster(node) + + if roster is None: + raise error.Forbidden() + + if requestor not in roster: + raise error.Forbidden() + + authorized_groups = yield node.getAuthorizedGroups() + + if not roster[requestor].groups.intersection(authorized_groups): + # requestor is in roster but not in one of the allowed groups + raise error.Forbidden() + + @defer.inlineCallbacks + def checkNodeAffiliations(self, node, requestor): + """check if requestor is in white list of a node + + @param node(Node): node to check + @param requestor(jid.JID): entity who want to access node + """ + def gotAffiliations(affiliations): + try: + affiliation = affiliations[requestor.userhostJID()] + except KeyError: + raise error.Forbidden() + else: + if affiliation not in ('owner', 'publisher', 'member'): + raise error.Forbidden() + + d = node.getAffiliations() + d.addCallback(gotAffiliations) + return d + @defer.inlineCallbacks def checkNodeAccess(self, node, requestor): """check if a requestor can access data of a node @@ -795,30 +865,13 @@ if access_model == const.VAL_AMODEL_OPEN or owner: pass + elif access_model == const.VAL_AMODEL_PRESENCE: + yield self.checkPresenceSubscription(node, requestor) elif access_model == const.VAL_AMODEL_PUBLISHER_ROSTER: - # FIXME: publisher roster should be used, not owner - roster = yield self.getOwnerRoster(node) - - if roster is None: - raise error.Forbidden() - - if requestor not in roster: - raise error.Forbidden() - - authorized_groups = yield node.getAuthorizedGroups() - - if not roster[requestor].groups.intersection(authorized_groups): - # requestor is in roster but not in one of the allowed groups - raise error.Forbidden() + # FIXME: for node, access should be renamed owner-roster, not publisher + yield self.checkRosterGroups(node, requestor) elif access_model == const.VAL_AMODEL_WHITELIST: - affiliations = yield node.getAffiliations() - try: - affiliation = affiliations[requestor.userhostJID()] - except KeyError: - raise error.Forbidden() - else: - if affiliation not in ('owner', 'publisher', 'member'): - raise error.Forbidden() + yield self.checkNodeAffiliations(node, requestor) else: raise Exception(u"Unknown access_model") @@ -1501,8 +1554,9 @@ return d.addErrback(self._mapErrors) def subscriptions(self, request): - d = self.backend.getSubscriptions(self._isPep(request), - request.sender) + d = self.backend.getSubscriptions(request.sender, + self._isPep(request), + request.recipient) return d.addErrback(self._mapErrors) def affiliations(self, request): diff -r 7c5d85c6fb3a -r 18b983fe9e1b sat_pubsub/const.py --- a/sat_pubsub/const.py Fri Sep 08 08:02:05 2017 +0200 +++ b/sat_pubsub/const.py Fri Sep 08 08:02:05 2017 +0200 @@ -67,6 +67,7 @@ OPT_SEND_LAST_PUBLISHED_ITEM = "pubsub#send_last_published_item" OPT_PUBLISH_MODEL = 'pubsub#publish_model' VAL_AMODEL_OPEN = 'open' +VAL_AMODEL_PRESENCE = 'presence' VAL_AMODEL_PUBLISHER_ROSTER = 'publisher-roster' VAL_AMODEL_WHITELIST = 'whitelist' VAL_AMODEL_PUBLISH_ONLY = 'publish-only'