comparison sat_pubsub/delegation.py @ 288:073161f6f143

namespace delegation: disco nesting management
author Goffi <goffi@goffi.org>
date Fri, 17 Apr 2015 21:09:37 +0200
parents 61f92273fb69
children f08f8536cab8
comparison
equal deleted inserted replaced
287:61f92273fb69 288:073161f6f143
23 This module implements XEP-0355 (Namespace delegation) to use SàT Pubsub as PEP service 23 This module implements XEP-0355 (Namespace delegation) to use SàT Pubsub as PEP service
24 """ 24 """
25 25
26 from wokkel.subprotocols import XMPPHandler 26 from wokkel.subprotocols import XMPPHandler
27 from wokkel import pubsub 27 from wokkel import pubsub
28 from wokkel import disco, iwokkel
28 from twisted.python import log 29 from twisted.python import log
30 from twisted.words.protocols.jabber import error
31 from zope.interface import implements
29 32
30 DELEGATION_NS = 'urn:xmpp:delegation:1' 33 DELEGATION_NS = 'urn:xmpp:delegation:1'
31 FORWARDED_NS = 'urn:xmpp:forward:0' 34 FORWARDED_NS = 'urn:xmpp:forward:0'
32 DELEGATION_ADV_XPATH = '/message/delegation[@xmlns="{}"]'.format(DELEGATION_NS) 35 DELEGATION_ADV_XPATH = '/message/delegation[@xmlns="{}"]'.format(DELEGATION_NS)
33 36
37 DELEGATION_MAIN_SEP = "::"
38 DELEGATION_BARE_SEP = ":bare:"
39
34 class InvalidStanza(Exception): 40 class InvalidStanza(Exception):
35 pass 41 pass
36 42
37 class DelegationsHandler(XMPPHandler): 43 class DelegationsHandler(XMPPHandler):
44 implements(iwokkel.IDisco)
38 45
39 def __init__(self): 46 def __init__(self):
40 super(DelegationsHandler, self).__init__() 47 super(DelegationsHandler, self).__init__()
41 48
42 def connectionInitialized(self): 49 def connectionInitialized(self):
69 u", ".join(attributes))) for ns, attributes in delegated.items()]))) 76 u", ".join(attributes))) for ns, attributes in delegated.items()])))
70 77
71 if not pubsub.NS_PUBSUB in delegated: 78 if not pubsub.NS_PUBSUB in delegated:
72 log.msg(u"Didn't got pubsub delegation from server, can't act as a PEP service") 79 log.msg(u"Didn't got pubsub delegation from server, can't act as a PEP service")
73 80
81 def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
82 """Manage disco nesting
83
84 This method looks for DiscoHandler in sibling handlers and use it to
85 collect main disco infos. It then filters by delegated namespace and return it.
86 An identity is added for PEP if pubsub namespace is requested.
87
88 The same features/identities are returned for main and bare nodes
89 """
90 if not nodeIdentifier.startswith(DELEGATION_NS):
91 return []
92
93 try:
94 _, namespace = nodeIdentifier.split(DELEGATION_MAIN_SEP, 1)
95 except ValueError:
96 try:
97 _, namespace = nodeIdentifier.split(DELEGATION_BARE_SEP, 1)
98 except ValueError:
99 log.msg("Unexpected disco node: {}".format(nodeIdentifier))
100 raise error.StanzaError('not-acceptable')
101
102 if not namespace:
103 log.msg("No namespace found in node {}".format(nodeIdentifier))
104 return []
105
106 def gotInfos(infos):
107 ns_features = []
108 for info in infos:
109 if isinstance(info, disco.DiscoFeature) and info.startswith(namespace):
110 ns_features.append(info)
111
112 if namespace == pubsub.NS_PUBSUB:
113 ns_features.append(disco.DiscoIdentity('pubsub', 'pep'))
114
115 return ns_features
116
117 for handler in self.parent.handlers:
118 if isinstance(handler, disco.DiscoHandler):
119 break
120
121 if not isinstance(handler, disco.DiscoHandler):
122 log.err("Can't find DiscoHandler")
123 return []
124
125 d = handler.info(requestor, target, '')
126 d.addCallback(gotInfos)
127 return d
128
129 def getDiscoItems(self, requestor, target, nodeIdentifier=''):
130 return []