Mercurial > libervia-pubsub
annotate sat_pubsub/pubsub_admin.py @ 414:ccb2a22ea0fc
Python 3 port:
/!\ Python 3.6+ is now needed to use SàT Pubsub
/!\ instability may occur and features may not be working anymore, this will improve with time
The same procedure as in backend has been applied (check backend commit ab2696e34d29 logs
for details).
Python minimal version has been updated in setup.py
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 16 Aug 2019 12:53:33 +0200 |
parents | c56a728412f1 |
children | 412d26a9b2c2 |
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): |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
113 __import__('pudb').set_trace() |
414 | 114 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
|
115 return |
1d2222a91e6b
pubsub_admin: catch errors on publish, and send an iq error
Goffi <goffi@goffi.org>
parents:
382
diff
changeset
|
116 except Exception as e: |
414 | 117 self.sendError(iq_elt, "internal-server-error") |
118 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
|
119 return |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
120 |
414 | 121 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
|
122 # 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
|
123 # 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
|
124 try: |
414 | 125 result_item_elt['id'] = item['id'] |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
126 except KeyError: |
414 | 127 result_item_elt = payload.publish.item['id'] |
382
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
128 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
129 self.xmlstream.send(iq_result_elt) |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
130 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
131 def getDiscoInfo(self, requestor, service, nodeIdentifier=''): |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
132 return [disco.DiscoFeature(NS_PUBSUB_ADMIN)] |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
133 |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
134 def getDiscoItems(self, requestor, service, nodeIdentifier=''): |
77b52dbda89a
pubsub_admin: Pubsub Admin experimental protocol first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
135 return [] |