comparison sat_pubsub/delegation.py @ 414:ccb2a22ea0fc

Python 3 port: /!\ Python 3.6+ is now needed to use SàT Pubsub /!\ instability may occur and features may not be working anymore, this will improve with time The same procedure as in backend has been applied (check backend commit ab2696e34d29 logs for details). Python minimal version has been updated in setup.py
author Goffi <goffi@goffi.org>
date Fri, 16 Aug 2019 12:53:33 +0200
parents c56a728412f1
children cebcb7f56889
comparison
equal deleted inserted replaced
413:a5edf5e1dd74 414:ccb2a22ea0fc
1 #!/usr/bin/python 1 #!/usr/bin/env python3
2 #-*- coding: utf-8 -*- 2 #-*- coding: utf-8 -*-
3 # 3 #
4 # Copyright (c) 2015 Jérôme Poisson 4 # Copyright (c) 2015 Jérôme Poisson
5 5
6 6
29 from wokkel import mam 29 from wokkel import mam
30 from twisted.python import log 30 from twisted.python import log
31 from twisted.words.protocols.jabber import jid, error 31 from twisted.words.protocols.jabber import jid, error
32 from twisted.words.protocols.jabber.xmlstream import toResponse 32 from twisted.words.protocols.jabber.xmlstream import toResponse
33 from twisted.words.xish import domish 33 from twisted.words.xish import domish
34 from zope.interface import implements 34 from zope.interface import implementer
35 35
36 DELEGATION_NS = 'urn:xmpp:delegation:1' 36 DELEGATION_NS = 'urn:xmpp:delegation:1'
37 FORWARDED_NS = 'urn:xmpp:forward:0' 37 FORWARDED_NS = 'urn:xmpp:forward:0'
38 DELEGATION_ADV_XPATH = '/message/delegation[@xmlns="{}"]'.format(DELEGATION_NS) 38 DELEGATION_ADV_XPATH = '/message/delegation[@xmlns="{}"]'.format(DELEGATION_NS)
39 DELEGATION_FWD_XPATH = '/iq[@type="set"]/delegation[@xmlns="{}"]/forwarded[@xmlns="{}"]'.format(DELEGATION_NS, FORWARDED_NS) 39 DELEGATION_FWD_XPATH = '/iq[@type="set"]/delegation[@xmlns="{}"]/forwarded[@xmlns="{}"]'.format(DELEGATION_NS, FORWARDED_NS)
47 47
48 class InvalidStanza(Exception): 48 class InvalidStanza(Exception):
49 pass 49 pass
50 50
51 51
52 @implementer(iwokkel.IDisco)
52 class DelegationsHandler(XMPPHandler): 53 class DelegationsHandler(XMPPHandler):
53 implements(iwokkel.IDisco)
54 _service_hacked = False 54 _service_hacked = False
55 55
56 def __init__(self): 56 def __init__(self):
57 super(DelegationsHandler, self).__init__() 57 super(DelegationsHandler, self).__init__()
58 58
142 self._xs_send(error_elt) 142 self._xs_send(error_elt)
143 stanza.handled = True 143 stanza.handled = True
144 144
145 def onAdvertise(self, message): 145 def onAdvertise(self, message):
146 """Manage the <message/> advertising delegations""" 146 """Manage the <message/> advertising delegations"""
147 delegation_elt = message.elements(DELEGATION_NS, 'delegation').next() 147 delegation_elt = next(message.elements(DELEGATION_NS, 'delegation'))
148 delegated = {} 148 delegated = {}
149 for delegated_elt in delegation_elt.elements(DELEGATION_NS): 149 for delegated_elt in delegation_elt.elements(DELEGATION_NS):
150 try: 150 try:
151 if delegated_elt.name != 'delegated': 151 if delegated_elt.name != 'delegated':
152 raise InvalidStanza(u'unexpected element {}'.format(delegated_elt.name)) 152 raise InvalidStanza('unexpected element {}'.format(delegated_elt.name))
153 try: 153 try:
154 namespace = delegated_elt['namespace'] 154 namespace = delegated_elt['namespace']
155 except KeyError: 155 except KeyError:
156 raise InvalidStanza(u'was expecting a "namespace" attribute in delegated element') 156 raise InvalidStanza('was expecting a "namespace" attribute in delegated element')
157 delegated[namespace] = [] 157 delegated[namespace] = []
158 for attribute_elt in delegated_elt.elements(DELEGATION_NS, 'attribute'): 158 for attribute_elt in delegated_elt.elements(DELEGATION_NS, 'attribute'):
159 try: 159 try:
160 delegated[namespace].append(attribute_elt["name"]) 160 delegated[namespace].append(attribute_elt["name"])
161 except KeyError: 161 except KeyError:
162 raise InvalidStanza(u'was expecting a "name" attribute in attribute element') 162 raise InvalidStanza('was expecting a "name" attribute in attribute element')
163 except InvalidStanza as e: 163 except InvalidStanza as e:
164 log.msg("Invalid stanza received ({})".format(e)) 164 log.msg("Invalid stanza received ({})".format(e))
165 165
166 log.msg(u'delegations updated:\n{}'.format( 166 log.msg('delegations updated:\n{}'.format(
167 u'\n'.join([u" - namespace {}{}".format(ns, 167 '\n'.join([" - namespace {}{}".format(ns,
168 u"" if not attributes else u" with filtering on {} attribute(s)".format( 168 "" if not attributes else " with filtering on {} attribute(s)".format(
169 u", ".join(attributes))) for ns, attributes in delegated.items()]))) 169 ", ".join(attributes))) for ns, attributes in list(delegated.items())])))
170 170
171 if not pubsub.NS_PUBSUB in delegated: 171 if not pubsub.NS_PUBSUB in delegated:
172 log.msg(u"Didn't got pubsub delegation from server, can't act as a PEP service") 172 log.msg("Didn't got pubsub delegation from server, can't act as a PEP service")
173 173
174 def onForward(self, iq): 174 def onForward(self, iq):
175 """Manage forwarded iq 175 """Manage forwarded iq
176 176
177 @param iq(domish.Element): full delegation stanza 177 @param iq(domish.Element): full delegation stanza
181 # and we are a component named [name].hostname 181 # and we are a component named [name].hostname
182 # but we need to manage properly allowed servers 182 # but we need to manage properly allowed servers
183 # TODO: do proper origin security check 183 # TODO: do proper origin security check
184 _, allowed = iq['to'].split('.', 1) 184 _, allowed = iq['to'].split('.', 1)
185 if jid.JID(iq['from']) != jid.JID(allowed): 185 if jid.JID(iq['from']) != jid.JID(allowed):
186 log.msg((u"SECURITY WARNING: forwarded stanza doesn't come from our server: {}" 186 log.msg(("SECURITY WARNING: forwarded stanza doesn't come from our server: {}"
187 .format(iq.toXml())).encode('utf-8')) 187 .format(iq.toXml())).encode('utf-8'))
188 raise error.StanzaError('not-allowed') 188 raise error.StanzaError('not-allowed')
189 189
190 try: 190 try:
191 fwd_iq = (iq.elements(DELEGATION_NS, 'delegation').next() 191 delegation_elt = next(iq.elements(DELEGATION_NS, 'delegation'))
192 .elements(FORWARDED_NS, 'forwarded').next() 192 forwarded_elt = next(delegation_elt.elements(FORWARDED_NS, 'forwarded'))
193 .elements('jabber:client', 'iq').next()) 193 fwd_iq = next(forwarded_elt.elements('jabber:client', 'iq'))
194 except StopIteration: 194 except StopIteration:
195 raise error.StanzaError('not-acceptable') 195 raise error.StanzaError('not-acceptable')
196 196
197 managed_entity = jid.JID(fwd_iq['from']) 197 managed_entity = jid.JID(fwd_iq['from'])
198 198