# HG changeset patch # User Goffi # Date 1429297777 -7200 # Node ID 073161f6f14304e5755900e9b67e1378de4d403b # Parent 61f92273fb6964906677e75da9bfcfb8a7d8b9af namespace delegation: disco nesting management diff -r 61f92273fb69 -r 073161f6f143 sat_pubsub/backend.py --- a/sat_pubsub/backend.py Thu Apr 16 21:06:19 2015 +0200 +++ b/sat_pubsub/backend.py Fri Apr 17 21:09:37 2015 +0200 @@ -973,6 +973,9 @@ raise exc def getInfo(self, requestor, service, nodeIdentifier): + if not requestor.resource: + # this avoid error when getting a disco request from server during namespace delegation + return [] info = {} def saveType(result): diff -r 61f92273fb69 -r 073161f6f143 sat_pubsub/delegation.py --- a/sat_pubsub/delegation.py Thu Apr 16 21:06:19 2015 +0200 +++ b/sat_pubsub/delegation.py Fri Apr 17 21:09:37 2015 +0200 @@ -25,16 +25,23 @@ from wokkel.subprotocols import XMPPHandler from wokkel import pubsub +from wokkel import disco, iwokkel from twisted.python import log +from twisted.words.protocols.jabber import error +from zope.interface import implements DELEGATION_NS = 'urn:xmpp:delegation:1' FORWARDED_NS = 'urn:xmpp:forward:0' DELEGATION_ADV_XPATH = '/message/delegation[@xmlns="{}"]'.format(DELEGATION_NS) +DELEGATION_MAIN_SEP = "::" +DELEGATION_BARE_SEP = ":bare:" + class InvalidStanza(Exception): pass class DelegationsHandler(XMPPHandler): + implements(iwokkel.IDisco) def __init__(self): super(DelegationsHandler, self).__init__() @@ -71,3 +78,53 @@ if not pubsub.NS_PUBSUB in delegated: log.msg(u"Didn't got pubsub delegation from server, can't act as a PEP service") + def getDiscoInfo(self, requestor, target, nodeIdentifier=''): + """Manage disco nesting + + This method looks for DiscoHandler in sibling handlers and use it to + collect main disco infos. It then filters by delegated namespace and return it. + An identity is added for PEP if pubsub namespace is requested. + + The same features/identities are returned for main and bare nodes + """ + if not nodeIdentifier.startswith(DELEGATION_NS): + return [] + + try: + _, namespace = nodeIdentifier.split(DELEGATION_MAIN_SEP, 1) + except ValueError: + try: + _, namespace = nodeIdentifier.split(DELEGATION_BARE_SEP, 1) + except ValueError: + log.msg("Unexpected disco node: {}".format(nodeIdentifier)) + raise error.StanzaError('not-acceptable') + + if not namespace: + log.msg("No namespace found in node {}".format(nodeIdentifier)) + return [] + + def gotInfos(infos): + ns_features = [] + for info in infos: + if isinstance(info, disco.DiscoFeature) and info.startswith(namespace): + ns_features.append(info) + + if namespace == pubsub.NS_PUBSUB: + ns_features.append(disco.DiscoIdentity('pubsub', 'pep')) + + return ns_features + + for handler in self.parent.handlers: + if isinstance(handler, disco.DiscoHandler): + break + + if not isinstance(handler, disco.DiscoHandler): + log.err("Can't find DiscoHandler") + return [] + + d = handler.info(requestor, target, '') + d.addCallback(gotInfos) + return d + + def getDiscoItems(self, requestor, target, nodeIdentifier=''): + return []