Mercurial > libervia-pubsub
diff sat_pubsub/backend.py @ 285:a87c155d0fd5
replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 31 Mar 2015 17:31:56 +0200 |
parents | 002c59dbc23f |
children | 073161f6f143 |
line wrap: on
line diff
--- a/sat_pubsub/backend.py Tue Mar 31 17:30:27 2015 +0200 +++ b/sat_pubsub/backend.py Tue Mar 31 17:31:56 2015 +0200 @@ -82,13 +82,13 @@ from copy import deepcopy + def _getAffiliation(node, entity): d = node.getAffiliation(entity) d.addCallback(lambda affiliation: (node, affiliation)) return d - class BackendService(service.Service, utility.EventDispatcher): """ Generic publish-subscribe backend service. @@ -294,7 +294,7 @@ if not item.getAttribute("id"): item["id"] = str(uuid.uuid4()) access_model, item_config = self.parseItemConfig(item) - parsed_items.append((access_model, item_config, item)) + parsed_items.append((access_model, item_config, item)) if persistItems: d = node.storeItems(parsed_items, requestor) @@ -326,8 +326,8 @@ set()) subs.add(subscription) - notifications = [(subscriber, subscriptions, items) - for subscriber, subscriptions + notifications = [(subscriber, subscriptions_, items) + for subscriber, subscriptions_ in subsBySubscriber.iteritems()] return notifications @@ -346,11 +346,9 @@ d.addCallback(toNotifications, nodeIdentifier, items) return d - def registerNotifier(self, observerfn, *args, **kwargs): self.addObserver('//event/pubsub/notify', observerfn, *args, **kwargs) - def subscribe(self, nodeIdentifier, subscriber, requestor): subscriberEntity = subscriber.userhostJID() if subscriberEntity != requestor.userhostJID(): @@ -445,7 +443,7 @@ is_user_jid = False else: is_user_jid = bool(nodeIdentifierJID.user) - + if is_user_jid and nodeIdentifierJID.userhostJID() != requestor.userhostJID(): #we have an user jid node, but not created by the owner of this jid print "Wrong creator" @@ -512,15 +510,15 @@ def checkGroup(self, roster_groups, entity): """Check that entity is authorized and in roster @param roster_group: tuple which 2 items: - - roster: mapping of jid to RosterItem as given by self.roster.getRoster + - roster: mapping of jid to RosterItem as given by self.privilege.getRoster - groups: list of authorized groups - @param entity: entity which must be in group + @param entity: entity which must be in group @return: (True, roster) if entity is in roster and authorized (False, roster) if entity is in roster but not authorized @raise: error.NotInRoster if entity is not in roster""" roster, authorized_groups = roster_groups _entity = entity.userhostJID() - + if not _entity in roster: raise error.NotInRoster return (roster[_entity].groups.intersection(authorized_groups), roster) @@ -530,6 +528,10 @@ d.addCallback(lambda groups: (roster, groups)) return d + def _rosterEb(self, failure): + log.msg("Error while getting roster: {}".format(failure.value)) + return {} + def _doGetItems(self, result, requestor, maxItems, itemIdentifiers, ext_data): node, affiliation = result @@ -552,7 +554,7 @@ raise NotImplementedError else: raise error.BadAccessTypeError(access_model) - + ret.append(item) return ret @@ -590,7 +592,8 @@ access_model = node.getConfiguration()["pubsub#access_model"] d = node.getNodeOwner() - d.addCallback(self.roster.getRoster) + d.addCallback(self.privilege.getRoster) + d.addErrback(self._rosterEb) if access_model == 'open' or affiliation == 'owner': d.addCallback(lambda roster: (True, roster)) @@ -837,7 +840,7 @@ self.backend.registerNotifier(self._notify) self.backend.registerPreDelete(self._preDelete) - + if self.backend.supportsCreatorCheck(): self.features.append("creator-jid-check") #SàT custom feature: Check that a node (which correspond to # a jid in this server) is created by the right jid @@ -866,12 +869,12 @@ def _notify(self, data): items = data['items'] node = data['node'] - + def _notifyAllowed(result): """Check access of subscriber for each item, and notify only allowed ones""" notifications, (owner_jid,roster) = result - + #we filter items not allowed for the subscribers notifications_filtered = [] @@ -889,24 +892,24 @@ authorized_groups = item_config[const.OPT_ROSTER_GROUPS_ALLOWED] if roster[_subscriber].groups.intersection(authorized_groups): allowed_items.append(item) - + else: #unknown access_model raise NotImplementedError if allowed_items: notifications_filtered.append((subscriber, subscriptions, allowed_items)) - + #we notify the owner #FIXME: check if this comply with XEP-0060 (option needed ?) #TODO: item's access model have to be sent back to owner #TODO: same thing for getItems - + def getFullItem(item_data): """ Attach item configuration to this item Used to give item configuration back to node's owner (and *only* to owner) """ #TODO: a test should check that only the owner get the item configuration back - + access_model, item_config, item = item_data new_item = deepcopy(item) if item_config: @@ -914,28 +917,29 @@ return new_item notifications_filtered.append((owner_jid, - set([Subscription(node.nodeIdentifier, + set([Subscription(node.nodeIdentifier, owner_jid, 'subscribed')]), - [getFullItem(item_data) for item_data in items])) + [getFullItem(item_data) for item_data in items])) return self.pubsubService.notifyPublish( self.serviceJID, node.nodeIdentifier, notifications_filtered) - + if 'subscription' not in data: d1 = self.backend.getNotifications(node.nodeIdentifier, items) else: subscription = data['subscription'] d1 = defer.succeed([(subscription.subscriber, [subscription], items)]) - + def _got_owner(owner_jid): #return a tuple with owner_jid and roster - d = self.backend.roster.getRoster(owner_jid) - return d.addCallback(lambda roster: (owner_jid,roster)) + d = self.backend.privilege.getRoster(owner_jid) + d.addErrback(self._rosterEb) + d.addCallback(lambda roster: (owner_jid,roster)) d2 = node.getNodeOwner() d2.addCallback(_got_owner) @@ -943,7 +947,6 @@ d = defer.gatherResults([d1, d2]) d.addCallback(_notifyAllowed) - def _preDelete(self, data): nodeIdentifier = data['node'].nodeIdentifier redirectURI = data.get('redirectURI', None)