Mercurial > libervia-pubsub
annotate sat_pubsub/delegation.py @ 451:0e6e176cb572
pgsql: fix items order:
Due to a misinterpretation, items where returned in wrong order when RSM was used.
Pubsub vanilla `max_items` is reversing the items order to get last items, but when this
attribute is not used (RSM being used or not), the items must be in chronological order.
This patch fixes it, so RSM returns oldest items by defaut, and empty `<before/>` must be
used to get last page (and thus most recent items).
Items are always finally ordered chronologically inside the returned page (default by
`update` time, but this can be modified when a specific order is requested).
Reference field is also fixed to use `updated` instead of `item_id` when item are ordered
by `update`.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 06 Jun 2021 19:42:57 +0200 |
parents | ccb2a22ea0fc |
children | cebcb7f56889 |
rev | line source |
---|---|
414 | 1 #!/usr/bin/env python3 |
242 | 2 #-*- coding: utf-8 -*- |
3 # | |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
4 # Copyright (c) 2015 Jérôme Poisson |
242 | 5 |
6 | |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
7 # This program is free software: you can redistribute it and/or modify |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
8 # it under the terms of the GNU Affero General Public License as published by |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
9 # the Free Software Foundation, either version 3 of the License, or |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
10 # (at your option) any later version. |
242 | 11 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
12 # This program is distributed in the hope that it will be useful, |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
15 # GNU Affero General Public License for more details. |
242 | 16 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
17 # You should have received a copy of the GNU Affero General Public License |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
242 | 19 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
20 # --- |
242 | 21 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
310
diff
changeset
|
22 # This module implements XEP-0355 (Namespace delegation) to use SàT Pubsub as PEP service |
242 | 23 |
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
|
24 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
|
25 from wokkel import pubsub |
289
f08f8536cab8
mod delegation: extensions management (XEP-0128)
Goffi <goffi@goffi.org>
parents:
288
diff
changeset
|
26 from wokkel import data_form |
288
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
27 from wokkel import disco, iwokkel |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
28 from wokkel.iwokkel import IPubSubService |
322 | 29 from wokkel import mam |
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
|
30 from twisted.python import log |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
31 from twisted.words.protocols.jabber import jid, error |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
32 from twisted.words.protocols.jabber.xmlstream import toResponse |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
33 from twisted.words.xish import domish |
414 | 34 from zope.interface import implementer |
242 | 35 |
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
|
36 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
|
37 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
|
38 DELEGATION_ADV_XPATH = '/message/delegation[@xmlns="{}"]'.format(DELEGATION_NS) |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
39 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
|
40 |
288
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
41 DELEGATION_MAIN_SEP = "::" |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
42 DELEGATION_BARE_SEP = ":bare:" |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
43 |
322 | 44 TO_HACK = ((IPubSubService, pubsub, "PubSubRequest"), |
45 (mam.IMAMService, mam, "MAMRequest")) | |
46 | |
47 | |
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
|
48 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
|
49 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
|
50 |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
51 |
414 | 52 @implementer(iwokkel.IDisco) |
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
|
53 class DelegationsHandler(XMPPHandler): |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
54 _service_hacked = False |
242 | 55 |
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 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
|
57 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
|
58 |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
59 def _service_hack(self): |
322 | 60 """Patch the request classes of services to track delegated stanzas""" |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
61 # 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
|
62 # 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
|
63 # original wokkel.pubsub use directly pubsub.PubSubRequest, we need to |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
64 # check which version is used before monkeypatching |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
65 for handler in self.parent.handlers: |
322 | 66 for service, module, default_base_cls in TO_HACK: |
67 if service.providedBy(handler): | |
68 if hasattr(handler, '_request_class'): | |
69 request_base_class = handler._request_class | |
70 else: | |
71 request_base_class = getattr(module, default_base_cls) | |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
72 |
322 | 73 class RequestWithDelegation(request_base_class): |
74 """A XxxRequest which put an indicator if the stanza comme from delegation""" | |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
75 |
322 | 76 @classmethod |
77 def fromElement(cls, element): | |
78 """Check if element comme from delegation, and set a delegated flags | |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
79 |
322 | 80 delegated flag is either False, or it's a jid of the delegating server |
81 the delegated flag must be set on element before use | |
82 """ | |
83 try: | |
84 # __getattr__ is overriden in domish.Element, so we use __getattribute__ | |
85 delegated = element.__getattribute__('delegated') | |
86 except AttributeError: | |
87 delegated = False | |
88 instance = cls.__base__.fromElement(element) | |
89 instance.delegated = delegated | |
90 return instance | |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
91 |
322 | 92 if hasattr(handler, '_request_class'): |
93 handler._request_class = RequestWithDelegation | |
94 else: | |
95 setattr(module, default_base_cls, RequestWithDelegation) | |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
96 DelegationsHandler._service_hacked = True |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
97 |
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
|
98 def connectionInitialized(self): |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
99 if not self._service_hacked: |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
100 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
|
101 self.xmlstream.addObserver(DELEGATION_ADV_XPATH, self.onAdvertise) |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
102 self.xmlstream.addObserver(DELEGATION_FWD_XPATH, self._obsWrapper, 0, self.onForward) |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
103 self._current_iqs = {} # dict of iq being handler by delegation |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
104 self._xs_send = self.xmlstream.send |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
105 self.xmlstream.send = self._sendHack |
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 def _sendHack(self, elt): |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
108 """This method is called instead of xmlstream to control sending |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
109 |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
110 @param obj(domsish.Element, unicode, str): obj sent to real xmlstream |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
111 """ |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
112 if isinstance(elt, domish.Element) and elt.name=='iq': |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
113 try: |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
114 id_ = elt.getAttribute('id') |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
115 ori_iq, managed_entity = self._current_iqs[id_] |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
116 if jid.JID(elt['to']) != managed_entity: |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
117 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
|
118 .format(got=jid.JID(elt['to']), expected=managed_entity)) |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
119 raise KeyError |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
120 except KeyError: |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
121 # the iq is not a delegated one |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
122 self._xs_send(elt) |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
123 else: |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
124 del self._current_iqs[id_] |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
125 iq_result_elt = toResponse(ori_iq, 'result') |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
126 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
|
127 fwd_elt.addChild(elt) |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
128 elt.uri = elt.defaultUri = 'jabber:client' |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
129 self._xs_send(iq_result_elt) |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
130 else: |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
131 self._xs_send(elt) |
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 def _obsWrapper(self, observer, stanza): |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
134 """Wrapper to observer which catch StanzaError |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
135 |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
136 @param observer(callable): method to wrap |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
137 """ |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
138 try: |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
139 observer(stanza) |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
140 except error.StanzaError as e: |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
141 error_elt = e.toResponse(stanza) |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
142 self._xs_send(error_elt) |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
143 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
|
144 |
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
|
145 def onAdvertise(self, message): |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
146 """Manage the <message/> advertising delegations""" |
414 | 147 delegation_elt = next(message.elements(DELEGATION_NS, 'delegation')) |
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 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 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
|
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 if delegated_elt.name != 'delegated': |
414 | 152 raise InvalidStanza('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
|
153 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
|
154 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
|
155 except KeyError: |
414 | 156 raise InvalidStanza('was expecting a "namespace" attribute in delegated element') |
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
|
157 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
|
158 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
|
159 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
|
160 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
|
161 except KeyError: |
414 | 162 raise InvalidStanza('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
|
163 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
|
164 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
|
165 |
414 | 166 log.msg('delegations updated:\n{}'.format( |
167 '\n'.join([" - namespace {}{}".format(ns, | |
168 "" if not attributes else " with filtering on {} attribute(s)".format( | |
169 ", ".join(attributes))) for ns, attributes in list(delegated.items())]))) | |
242 | 170 |
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
|
171 if not pubsub.NS_PUBSUB in delegated: |
414 | 172 log.msg("Didn't got pubsub delegation from server, can't act as a PEP service") |
242 | 173 |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
174 def onForward(self, iq): |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
175 """Manage forwarded iq |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
176 |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
177 @param iq(domish.Element): full delegation stanza |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
178 """ |
310
e6a9a3c93314
delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents:
292
diff
changeset
|
179 |
e6a9a3c93314
delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents:
292
diff
changeset
|
180 # 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
|
181 # 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
|
182 # 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
|
183 # 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
|
184 _, 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
|
185 if jid.JID(iq['from']) != jid.JID(allowed): |
414 | 186 log.msg(("SECURITY WARNING: forwarded stanza doesn't come from our server: {}" |
310
e6a9a3c93314
delegation: fixed bad security check which was rejecting all delegations from external servers:
Goffi <goffi@goffi.org>
parents:
292
diff
changeset
|
187 .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
|
188 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
|
189 |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
190 try: |
414 | 191 delegation_elt = next(iq.elements(DELEGATION_NS, 'delegation')) |
192 forwarded_elt = next(delegation_elt.elements(FORWARDED_NS, 'forwarded')) | |
193 fwd_iq = next(forwarded_elt.elements('jabber:client', 'iq')) | |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
194 except StopIteration: |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
195 raise error.StanzaError('not-acceptable') |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
196 |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
197 managed_entity = jid.JID(fwd_iq['from']) |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
198 |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
199 self._current_iqs[fwd_iq['id']] = (iq, managed_entity) |
292
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
200 fwd_iq.delegated = True |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
201 |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
202 # we need a recipient in pubsub request for PEP |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
203 # so we set "to" attribute if it doesn't exist |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
204 if not fwd_iq.hasAttribute('to'): |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
205 fwd_iq["to"] = jid.JID(fwd_iq["from"]).userhost() |
6918a0dad359
delegation: delegated stanza are tracked
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
206 |
291
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
207 # we now inject the element in the stream |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
208 self.xmlstream.dispatch(fwd_iq) |
61fb4817b77f
delegation: iq forwarded management:
Goffi <goffi@goffi.org>
parents:
289
diff
changeset
|
209 |
288
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
210 def getDiscoInfo(self, requestor, target, nodeIdentifier=''): |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
211 """Manage disco nesting |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
212 |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
213 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
|
214 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
|
215 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
|
216 |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
217 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
|
218 """ |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
219 if not nodeIdentifier.startswith(DELEGATION_NS): |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
220 return [] |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
221 |
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_MAIN_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 try: |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
226 _, namespace = nodeIdentifier.split(DELEGATION_BARE_SEP, 1) |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
227 except ValueError: |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
228 log.msg("Unexpected disco node: {}".format(nodeIdentifier)) |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
229 raise error.StanzaError('not-acceptable') |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
230 |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
231 if not namespace: |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
232 log.msg("No namespace found in node {}".format(nodeIdentifier)) |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
233 return [] |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
234 |
334
0a93d71f9503
delegation: use same disco for all pubsub namespaces
Goffi <goffi@goffi.org>
parents:
322
diff
changeset
|
235 if namespace.startswith(pubsub.NS_PUBSUB): |
0a93d71f9503
delegation: use same disco for all pubsub namespaces
Goffi <goffi@goffi.org>
parents:
322
diff
changeset
|
236 # pubsub use several namespaces starting with NS_PUBSUB (e.g. http://jabber.org/protocol/pubsub#owner) |
0a93d71f9503
delegation: use same disco for all pubsub namespaces
Goffi <goffi@goffi.org>
parents:
322
diff
changeset
|
237 # we return the same disco for all of them |
0a93d71f9503
delegation: use same disco for all pubsub namespaces
Goffi <goffi@goffi.org>
parents:
322
diff
changeset
|
238 namespace = pubsub.NS_PUBSUB |
0a93d71f9503
delegation: use same disco for all pubsub namespaces
Goffi <goffi@goffi.org>
parents:
322
diff
changeset
|
239 |
288
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
240 def gotInfos(infos): |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
241 ns_features = [] |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
242 for info in infos: |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
243 if isinstance(info, disco.DiscoFeature) and info.startswith(namespace): |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
244 ns_features.append(info) |
289
f08f8536cab8
mod delegation: extensions management (XEP-0128)
Goffi <goffi@goffi.org>
parents:
288
diff
changeset
|
245 elif (isinstance(info, data_form.Form) and info.formNamespace |
f08f8536cab8
mod delegation: extensions management (XEP-0128)
Goffi <goffi@goffi.org>
parents:
288
diff
changeset
|
246 and info.formNamespace.startwith(namespace)): |
f08f8536cab8
mod delegation: extensions management (XEP-0128)
Goffi <goffi@goffi.org>
parents:
288
diff
changeset
|
247 # extensions management (XEP-0128) |
f08f8536cab8
mod delegation: extensions management (XEP-0128)
Goffi <goffi@goffi.org>
parents:
288
diff
changeset
|
248 ns_features.append(info) |
288
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
249 |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
250 if namespace == pubsub.NS_PUBSUB: |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
251 ns_features.append(disco.DiscoIdentity('pubsub', 'pep')) |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
252 |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
253 return ns_features |
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 for handler in self.parent.handlers: |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
256 if isinstance(handler, disco.DiscoHandler): |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
257 break |
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 if not isinstance(handler, disco.DiscoHandler): |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
260 log.err("Can't find DiscoHandler") |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
261 return [] |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
262 |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
263 d = handler.info(requestor, target, '') |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
264 d.addCallback(gotInfos) |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
265 return d |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
266 |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
267 def getDiscoItems(self, requestor, target, nodeIdentifier=''): |
073161f6f143
namespace delegation: disco nesting management
Goffi <goffi@goffi.org>
parents:
287
diff
changeset
|
268 return [] |
346 | 269 |
270 | |
271 # we monkeypatch DiscoHandler to add delegation informations | |
272 def _onDiscoItems(self, iq): | |
273 request = disco._DiscoRequest.fromElement(iq) | |
274 # it's really ugly to attach pep data to recipient | |
275 # but we don't have many options | |
276 request.recipient.pep = iq.delegated | |
277 | |
278 def toResponse(items): | |
279 response = disco.DiscoItems() | |
280 response.nodeIdentifier = request.nodeIdentifier | |
281 | |
282 for item in items: | |
283 response.append(item) | |
284 | |
285 return response.toElement() | |
286 | |
287 d = self.items(request.sender, request.recipient, | |
288 request.nodeIdentifier) | |
289 d.addCallback(toResponse) | |
290 return d | |
291 | |
292 | |
293 disco.DiscoHandler._onDiscoItems = _onDiscoItems |