annotate sat_pubsub/delegation.py @ 310:e6a9a3c93314

delegation: fixed bad security check which was rejecting all delegations from external servers: A hack is used to check delegation origin, but a better solution need to be implemented in the future. A list of trusted servers seems an acceptable solution.
author Goffi <goffi@goffi.org>
date Mon, 21 Dec 2015 13:44:21 +0100
parents 6918a0dad359
children 5d7c3787672e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/python
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
2 #-*- coding: utf-8 -*-
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
3 #
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
4 """
286
2f87fa282dfd updated old docstring (privilege is actually a new (2015) module not derivated from idavoll)
Goffi <goffi@goffi.org>
parents: 285
diff changeset
5 Copyright (c) 2015 Jérôme Poisson
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
6
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
7
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
8 This program is free software: you can redistribute it and/or modify
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
9 it under the terms of the GNU Affero General Public License as published by
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
10 the Free Software Foundation, either version 3 of the License, or
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
11 (at your option) any later version.
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
12
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
13 This program is distributed in the hope that it will be useful,
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
16 GNU Affero General Public License for more details.
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
17
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
18 You should have received a copy of the GNU Affero General Public License
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
20
286
2f87fa282dfd updated old docstring (privilege is actually a new (2015) module not derivated from idavoll)
Goffi <goffi@goffi.org>
parents: 285
diff changeset
21 ---
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
22
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
23 This module implements XEP-0355 (Namespace delegation) to use SàT Pubsub as PEP service
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
24 """
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
25
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
26 from wokkel.subprotocols import XMPPHandler
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
27 from wokkel import pubsub
289
f08f8536cab8 mod delegation: extensions management (XEP-0128)
Goffi <goffi@goffi.org>
parents: 288
diff changeset
28 from wokkel import data_form
288
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
29 from wokkel import disco, iwokkel
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
30 from wokkel.iwokkel import IPubSubService
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
31 from twisted.python import log
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
32 from twisted.words.protocols.jabber import jid, error
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
33 from twisted.words.protocols.jabber.xmlstream import toResponse
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
34 from twisted.words.xish import domish
288
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
35 from zope.interface import implements
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
36
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
37 DELEGATION_NS = 'urn:xmpp:delegation:1'
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
38 FORWARDED_NS = 'urn:xmpp:forward:0'
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
39 DELEGATION_ADV_XPATH = '/message/delegation[@xmlns="{}"]'.format(DELEGATION_NS)
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
40 DELEGATION_FWD_XPATH = '/iq[@type="set"]/delegation[@xmlns="{}"]/forwarded[@xmlns="{}"]'.format(DELEGATION_NS, FORWARDED_NS)
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
41
288
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
42 DELEGATION_MAIN_SEP = "::"
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
43 DELEGATION_BARE_SEP = ":bare:"
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
44
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
45 class InvalidStanza(Exception):
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
46 pass
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
47
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
48
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
49
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
50 class DelegationsHandler(XMPPHandler):
288
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
51 implements(iwokkel.IDisco)
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
52 _service_hacked = False
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
53
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
54 def __init__(self):
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
55 super(DelegationsHandler, self).__init__()
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
56
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
57 def _service_hack(self):
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
58 """Patch the PubSubService to track delegated stanzas"""
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
59 # XXX: we need to monkey patch to track origin of the stanza in PubSubRequest.
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
60 # As PubSubRequest from sat.tmp.wokkel.pubsub use _request_class while
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
61 # original wokkel.pubsub use directly pubsub.PubSubRequest, we need to
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
62 # check which version is used before monkeypatching
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
63 for handler in self.parent.handlers:
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
64 if IPubSubService.providedBy(handler):
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
65 if hasattr(handler, '_request_class'):
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
66 request_base_class = handler._request_class
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
67 else:
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
68 request_base_class = pubsub.PubSubRequest
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
69
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
70 class PubSubRequestWithDelegation(request_base_class):
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
71 """A PubSubReques which put an indicator if the stanza comme from delegation"""
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
72
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
73 @classmethod
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
74 def fromElement(cls, element):
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
75 """Check if element comme from delegation, and set a delegated flags
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
76
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
77 delegated flaf is either False, or it's a jid of the delegating server
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
78 the delegated flag must be set on element before use
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
79 """
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
80 try:
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
81 # __getattr__ is overriden in domish.Element, so we use __getattribute__
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
82 delegated = element.__getattribute__('delegated')
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
83 except AttributeError:
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
84 delegated = False
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
85 instance = cls.__base__.fromElement(element)
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
86 instance.delegated = delegated
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
87 return instance
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
88
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
89 if hasattr(handler, '_request_class'):
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
90 handler._request_class = PubSubRequestWithDelegation
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
91 else:
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
92 pubsub.PubSubRequest = PubSubRequestWithDelegation
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
93 DelegationsHandler._service_hacked = True
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
94
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
95 def connectionInitialized(self):
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
96 if not self._service_hacked:
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
97 self._service_hack()
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
98 self.xmlstream.addObserver(DELEGATION_ADV_XPATH, self.onAdvertise)
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
99 self.xmlstream.addObserver(DELEGATION_FWD_XPATH, self._obsWrapper, 0, self.onForward)
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
100 self._current_iqs = {} # dict of iq being handler by delegation
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
101 self._xs_send = self.xmlstream.send
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
102 self.xmlstream.send = self._sendHack
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
103
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
104 def _sendHack(self, elt):
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
105 """This method is called instead of xmlstream to control sending
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
106
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
107 @param obj(domsish.Element, unicode, str): obj sent to real xmlstream
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
108 """
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
109 if isinstance(elt, domish.Element) and elt.name=='iq':
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
110 try:
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
111 id_ = elt.getAttribute('id')
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
112 ori_iq, managed_entity = self._current_iqs[id_]
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
113 if jid.JID(elt['to']) != managed_entity:
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
114 log.msg("IQ id conflict: the managed entity doesn't match (got {got} was expecting {expected})"
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
115 .format(got=jid.JID(elt['to']), expected=managed_entity))
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
116 raise KeyError
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
117 except KeyError:
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
118 # the iq is not a delegated one
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
119 self._xs_send(elt)
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
120 else:
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
121 del self._current_iqs[id_]
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
122 iq_result_elt = toResponse(ori_iq, 'result')
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
123 fwd_elt = iq_result_elt.addElement('delegation', DELEGATION_NS).addElement('forwarded', FORWARDED_NS)
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
124 fwd_elt.addChild(elt)
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
125 elt.uri = elt.defaultUri = 'jabber:client'
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
126 self._xs_send(iq_result_elt)
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
127 else:
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
128 self._xs_send(elt)
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
129
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
130 def _obsWrapper(self, observer, stanza):
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
131 """Wrapper to observer which catch StanzaError
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
132
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
133 @param observer(callable): method to wrap
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
134 """
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
135 try:
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
136 observer(stanza)
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
137 except error.StanzaError as e:
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
138 error_elt = e.toResponse(stanza)
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
139 self._xs_send(error_elt)
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
140 stanza.handled = True
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
141
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
142 def onAdvertise(self, message):
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
143 """Manage the <message/> advertising delegations"""
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
144 delegation_elt = message.elements(DELEGATION_NS, 'delegation').next()
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
145 delegated = {}
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
146 for delegated_elt in delegation_elt.elements(DELEGATION_NS):
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
147 try:
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
148 if delegated_elt.name != 'delegated':
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
149 raise InvalidStanza(u'unexpected element {}'.format(delegated_elt.name))
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
150 try:
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
151 namespace = delegated_elt['namespace']
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
152 except KeyError:
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
153 raise InvalidStanza(u'was expecting a "namespace" attribute in delegated element')
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
154 delegated[namespace] = []
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
155 for attribute_elt in delegated_elt.elements(DELEGATION_NS, 'attribute'):
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
156 try:
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
157 delegated[namespace].append(attribute_elt["name"])
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
158 except KeyError:
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
159 raise InvalidStanza(u'was expecting a "name" attribute in attribute element')
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
160 except InvalidStanza as e:
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
161 log.msg("Invalid stanza received ({})".format(e))
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
162
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
163 log.msg(u'delegations updated:\n{}'.format(
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
164 u'\n'.join([u" - namespace {}{}".format(ns,
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
165 u"" if not attributes else u" with filtering on {} attribute(s)".format(
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
166 u", ".join(attributes))) for ns, attributes in delegated.items()])))
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
167
287
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
168 if not pubsub.NS_PUBSUB in delegated:
61f92273fb69 implementation of XEP-0355 (Namespace Delegation) to use SàT Pubsub as PEP service, first draft
Goffi <goffi@goffi.org>
parents: 286
diff changeset
169 log.msg(u"Didn't got pubsub delegation from server, can't act as a PEP service")
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
170
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
171 def onForward(self, iq):
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
172 """Manage forwarded iq
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
173
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
174 @param iq(domish.Element): full delegation stanza
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
175 """
310
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
176
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
177 # FIXME: we use a hack supposing that our delegation come from hostname
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
178 # and we are a component named [name].hostname
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
179 # but we need to manage properly allowed servers
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
180 # TODO: do proper origin security check
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
181 _, allowed = iq['to'].split('.', 1)
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
182 if jid.JID(iq['from']) != jid.JID(allowed):
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
183 log.msg((u"SECURITY WARNING: forwarded stanza doesn't come from our server: {}"
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
184 .format(iq.toXml())).encode('utf-8'))
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
185 raise error.StanzaError('not-allowed')
e6a9a3c93314 delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents: 292
diff changeset
186
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
187 try:
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
188 fwd_iq = (iq.elements(DELEGATION_NS, 'delegation').next()
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
189 .elements(FORWARDED_NS, 'forwarded').next()
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
190 .elements('jabber:client', 'iq').next())
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
191 except StopIteration:
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
192 raise error.StanzaError('not-acceptable')
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
193
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
194 managed_entity = jid.JID(fwd_iq['from'])
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
195
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
196 self._current_iqs[fwd_iq['id']] = (iq, managed_entity)
292
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
197 fwd_iq.delegated = True
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
198
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
199 # we need a recipient in pubsub request for PEP
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
200 # so we set "to" attribute if it doesn't exist
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
201 if not fwd_iq.hasAttribute('to'):
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
202 fwd_iq["to"] = jid.JID(fwd_iq["from"]).userhost()
6918a0dad359 delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents: 291
diff changeset
203
291
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
204 # we now inject the element in the stream
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
205 self.xmlstream.dispatch(fwd_iq)
61fb4817b77f delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents: 289
diff changeset
206
288
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
207 def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
208 """Manage disco nesting
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
209
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
210 This method looks for DiscoHandler in sibling handlers and use it to
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
211 collect main disco infos. It then filters by delegated namespace and return it.
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
212 An identity is added for PEP if pubsub namespace is requested.
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
213
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
214 The same features/identities are returned for main and bare nodes
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
215 """
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
216 if not nodeIdentifier.startswith(DELEGATION_NS):
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
217 return []
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
218
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
219 try:
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
220 _, namespace = nodeIdentifier.split(DELEGATION_MAIN_SEP, 1)
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
221 except ValueError:
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
222 try:
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
223 _, namespace = nodeIdentifier.split(DELEGATION_BARE_SEP, 1)
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
224 except ValueError:
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
225 log.msg("Unexpected disco node: {}".format(nodeIdentifier))
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
226 raise error.StanzaError('not-acceptable')
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
227
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
228 if not namespace:
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
229 log.msg("No namespace found in node {}".format(nodeIdentifier))
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
230 return []
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
231
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
232 def gotInfos(infos):
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
233 ns_features = []
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
234 for info in infos:
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
235 if isinstance(info, disco.DiscoFeature) and info.startswith(namespace):
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
236 ns_features.append(info)
289
f08f8536cab8 mod delegation: extensions management (XEP-0128)
Goffi <goffi@goffi.org>
parents: 288
diff changeset
237 elif (isinstance(info, data_form.Form) and info.formNamespace
f08f8536cab8 mod delegation: extensions management (XEP-0128)
Goffi <goffi@goffi.org>
parents: 288
diff changeset
238 and info.formNamespace.startwith(namespace)):
f08f8536cab8 mod delegation: extensions management (XEP-0128)
Goffi <goffi@goffi.org>
parents: 288
diff changeset
239 # extensions management (XEP-0128)
f08f8536cab8 mod delegation: extensions management (XEP-0128)
Goffi <goffi@goffi.org>
parents: 288
diff changeset
240 ns_features.append(info)
288
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
241
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
242 if namespace == pubsub.NS_PUBSUB:
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
243 ns_features.append(disco.DiscoIdentity('pubsub', 'pep'))
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
244
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
245 return ns_features
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
246
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
247 for handler in self.parent.handlers:
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
248 if isinstance(handler, disco.DiscoHandler):
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
249 break
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
250
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
251 if not isinstance(handler, disco.DiscoHandler):
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
252 log.err("Can't find DiscoHandler")
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
253 return []
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
254
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
255 d = handler.info(requestor, target, '')
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
256 d.addCallback(gotInfos)
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
257 return d
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
258
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
259 def getDiscoItems(self, requestor, target, nodeIdentifier=''):
073161f6f143 namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents: 287
diff changeset
260 return []