Mercurial > libervia-pubsub
annotate sat_pubsub/pubsub_admin.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 | 412d26a9b2c2 |
children | b544109ab4c4 |
rev | line source |
---|---|
414 | 1 #!/usr/bin/env python3 |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
2 #-*- coding: utf-8 -*- |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
3 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
4 # Copyright (c) 2019 Jérôme Poisson |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
5 # |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
6 # This program is free software: you can redistribute it and/or modify |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
7 # it under the terms of the GNU Affero General Public License as published by |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
8 # the Free Software Foundation, either version 3 of the License, or |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
9 # (at your option) any later version. |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
10 # |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
11 # This program is distributed in the hope that it will be useful, |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
14 # GNU Affero General Public License for more details. |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
15 # |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
16 # You should have received a copy of the GNU Affero General Public License |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
18 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
19 """ |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
20 Pubsub Admin experimental protocol implementation |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
21 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
22 """ |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
23 |
414 | 24 from zope.interface import implementer |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
25 from twisted.python import log |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
26 from twisted.internet import defer |
391
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
27 from twisted.words.protocols.jabber import jid, error as jabber_error, xmlstream |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
28 from sat_pubsub import error |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
29 from wokkel.subprotocols import XMPPHandler |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
30 from wokkel import disco, iwokkel, pubsub |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
31 |
414 | 32 NS_PUBSUB_ADMIN = "https://salut-a-toi.org/spec/pubsub_admin:0" |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
33 ADMIN_REQUEST = '/iq[@type="set"]/admin[@xmlns="{}"]'.format(NS_PUBSUB_ADMIN) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
34 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
35 |
414 | 36 @implementer(iwokkel.IDisco) |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
37 class PubsubAdminHandler(XMPPHandler): |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
38 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
39 def __init__(self, backend): |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
40 super(PubsubAdminHandler, self).__init__() |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
41 self.backend = backend |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
42 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
43 def connectionInitialized(self): |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
44 self.xmlstream.addObserver(ADMIN_REQUEST, self.onAdminRequest) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
45 |
414 | 46 def sendError(self, iq_elt, condition='bad-request'): |
391
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
47 stanza_error = jabber_error.StanzaError(condition) |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
48 iq_error = stanza_error.toResponse(iq_elt) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
49 self.parent.xmlstream.send(iq_error) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
50 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
51 @defer.inlineCallbacks |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
52 def onAdminRequest(self, iq_elt): |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
53 """Pubsub Admin request received""" |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
54 iq_elt.handled = True |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
55 try: |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
56 pep = bool(iq_elt.delegated) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
57 except AttributeError: |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
58 pep = False |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
59 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
60 # is the sender really an admin? |
414 | 61 admins = self.backend.config['admins_jids_list'] |
62 from_jid = jid.JID(iq_elt['from']) | |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
63 if from_jid.userhostJID() not in admins: |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
64 log.msg("WARNING: admin request done by non admin entity {from_jid}" |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
65 .format(from_jid=from_jid.full())) |
414 | 66 self.sendError(iq_elt, 'forbidden') |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
67 return |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
68 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
69 # alright, we can proceed |
414 | 70 recipient = jid.JID(iq_elt['to']) |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
71 admin_elt = iq_elt.admin |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
72 try: |
414 | 73 pubsub_elt = next(admin_elt.elements(pubsub.NS_PUBSUB, 'pubsub')) |
74 publish_elt = next(pubsub_elt.elements(pubsub.NS_PUBSUB, 'publish')) | |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
75 except StopIteration: |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
76 self.sendError(iq_elt) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
77 return |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
78 try: |
414 | 79 node = publish_elt['node'] |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
80 except KeyError: |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
81 self.sendError(iq_elt) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
82 return |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
83 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
84 # we prepare the result IQ request, we will fill it with item ids |
414 | 85 iq_result_elt = xmlstream.toResponse(iq_elt, 'result') |
86 result_admin_elt = iq_result_elt.addElement((NS_PUBSUB_ADMIN, 'admin')) | |
87 result_pubsub_elt = result_admin_elt.addElement((pubsub.NS_PUBSUB, 'pubsub')) | |
88 result_publish_elt = result_pubsub_elt.addElement('publish') | |
89 result_publish_elt['node'] = node | |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
90 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
91 # now we can send the items |
414 | 92 for item in publish_elt.elements(pubsub.NS_PUBSUB, 'item'): |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
93 try: |
414 | 94 requestor = jid.JID(item.attributes.pop('publisher')) |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
95 except Exception as e: |
414 | 96 log.msg("WARNING: invalid jid in publisher ({requestor}): {msg}" |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
97 .format(requestor=requestor, msg=e)) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
98 self.sendError(iq_elt) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
99 return |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
100 except KeyError: |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
101 requestor = from_jid |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
102 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
103 # we don't use a DeferredList because we want to be sure that |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
104 # each request is done in order |
391
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
105 try: |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
106 payload = yield self.backend.publish( |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
107 nodeIdentifier=node, |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
108 items=[item], |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
109 requestor=requestor, |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
110 pep=pep, |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
111 recipient=recipient) |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
112 except (error.Forbidden, error.ItemForbidden): |
414 | 113 self.sendError(iq_elt, "forbidden") |
391
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
114 return |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
115 except Exception as e: |
414 | 116 self.sendError(iq_elt, "internal-server-error") |
117 log.msg("INTERNAL ERROR: {msg}".format(msg=e)) | |
391
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
118 return |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
119 |
414 | 120 result_item_elt = result_publish_elt.addElement('item') |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
121 # either the id was given and it is available in item |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
122 # either it's a new item, and we can retrieve it from return payload |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
123 try: |
414 | 124 result_item_elt['id'] = item['id'] |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
125 except KeyError: |
414 | 126 result_item_elt = payload.publish.item['id'] |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
127 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
128 self.xmlstream.send(iq_result_elt) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
129 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
130 def getDiscoInfo(self, requestor, service, nodeIdentifier=''): |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
131 return [disco.DiscoFeature(NS_PUBSUB_ADMIN)] |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
132 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
133 def getDiscoItems(self, requestor, service, nodeIdentifier=''): |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
134 return [] |