Mercurial > libervia-pubsub
comparison 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 |
comparison
equal
deleted
inserted
replaced
413:a5edf5e1dd74 | 414:ccb2a22ea0fc |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/env python3 |
2 #-*- coding: utf-8 -*- | 2 #-*- coding: utf-8 -*- |
3 | 3 |
4 # Copyright (c) 2019 Jérôme Poisson | 4 # Copyright (c) 2019 Jérôme Poisson |
5 # | 5 # |
6 # This program is free software: you can redistribute it and/or modify | 6 # This program is free software: you can redistribute it and/or modify |
19 """ | 19 """ |
20 Pubsub Admin experimental protocol implementation | 20 Pubsub Admin experimental protocol implementation |
21 | 21 |
22 """ | 22 """ |
23 | 23 |
24 from zope.interface import implements | 24 from zope.interface import implementer |
25 from twisted.python import log | 25 from twisted.python import log |
26 from twisted.internet import defer | 26 from twisted.internet import defer |
27 from twisted.words.protocols.jabber import jid, error as jabber_error, xmlstream | 27 from twisted.words.protocols.jabber import jid, error as jabber_error, xmlstream |
28 from sat_pubsub import error | 28 from sat_pubsub import error |
29 from wokkel.subprotocols import XMPPHandler | 29 from wokkel.subprotocols import XMPPHandler |
30 from wokkel import disco, iwokkel, pubsub | 30 from wokkel import disco, iwokkel, pubsub |
31 | 31 |
32 NS_PUBSUB_ADMIN = u"https://salut-a-toi.org/spec/pubsub_admin:0" | 32 NS_PUBSUB_ADMIN = "https://salut-a-toi.org/spec/pubsub_admin:0" |
33 ADMIN_REQUEST = '/iq[@type="set"]/admin[@xmlns="{}"]'.format(NS_PUBSUB_ADMIN) | 33 ADMIN_REQUEST = '/iq[@type="set"]/admin[@xmlns="{}"]'.format(NS_PUBSUB_ADMIN) |
34 | 34 |
35 | 35 |
36 @implementer(iwokkel.IDisco) | |
36 class PubsubAdminHandler(XMPPHandler): | 37 class PubsubAdminHandler(XMPPHandler): |
37 implements(iwokkel.IDisco) | |
38 | 38 |
39 def __init__(self, backend): | 39 def __init__(self, backend): |
40 super(PubsubAdminHandler, self).__init__() | 40 super(PubsubAdminHandler, self).__init__() |
41 self.backend = backend | 41 self.backend = backend |
42 | 42 |
43 def connectionInitialized(self): | 43 def connectionInitialized(self): |
44 self.xmlstream.addObserver(ADMIN_REQUEST, self.onAdminRequest) | 44 self.xmlstream.addObserver(ADMIN_REQUEST, self.onAdminRequest) |
45 | 45 |
46 def sendError(self, iq_elt, condition=u'bad-request'): | 46 def sendError(self, iq_elt, condition='bad-request'): |
47 stanza_error = jabber_error.StanzaError(condition) | 47 stanza_error = jabber_error.StanzaError(condition) |
48 iq_error = stanza_error.toResponse(iq_elt) | 48 iq_error = stanza_error.toResponse(iq_elt) |
49 self.parent.xmlstream.send(iq_error) | 49 self.parent.xmlstream.send(iq_error) |
50 | 50 |
51 @defer.inlineCallbacks | 51 @defer.inlineCallbacks |
56 pep = bool(iq_elt.delegated) | 56 pep = bool(iq_elt.delegated) |
57 except AttributeError: | 57 except AttributeError: |
58 pep = False | 58 pep = False |
59 | 59 |
60 # is the sender really an admin? | 60 # is the sender really an admin? |
61 admins = self.backend.config[u'admins_jids_list'] | 61 admins = self.backend.config['admins_jids_list'] |
62 from_jid = jid.JID(iq_elt[u'from']) | 62 from_jid = jid.JID(iq_elt['from']) |
63 if from_jid.userhostJID() not in admins: | 63 if from_jid.userhostJID() not in admins: |
64 log.msg("WARNING: admin request done by non admin entity {from_jid}" | 64 log.msg("WARNING: admin request done by non admin entity {from_jid}" |
65 .format(from_jid=from_jid.full())) | 65 .format(from_jid=from_jid.full())) |
66 self.sendError(iq_elt, u'forbidden') | 66 self.sendError(iq_elt, 'forbidden') |
67 return | 67 return |
68 | 68 |
69 # alright, we can proceed | 69 # alright, we can proceed |
70 recipient = jid.JID(iq_elt[u'to']) | 70 recipient = jid.JID(iq_elt['to']) |
71 admin_elt = iq_elt.admin | 71 admin_elt = iq_elt.admin |
72 try: | 72 try: |
73 pubsub_elt = next(admin_elt.elements(pubsub.NS_PUBSUB, u'pubsub')) | 73 pubsub_elt = next(admin_elt.elements(pubsub.NS_PUBSUB, 'pubsub')) |
74 publish_elt = next(pubsub_elt.elements(pubsub.NS_PUBSUB, u'publish')) | 74 publish_elt = next(pubsub_elt.elements(pubsub.NS_PUBSUB, 'publish')) |
75 except StopIteration: | 75 except StopIteration: |
76 self.sendError(iq_elt) | 76 self.sendError(iq_elt) |
77 return | 77 return |
78 try: | 78 try: |
79 node = publish_elt[u'node'] | 79 node = publish_elt['node'] |
80 except KeyError: | 80 except KeyError: |
81 self.sendError(iq_elt) | 81 self.sendError(iq_elt) |
82 return | 82 return |
83 | 83 |
84 # we prepare the result IQ request, we will fill it with item ids | 84 # we prepare the result IQ request, we will fill it with item ids |
85 iq_result_elt = xmlstream.toResponse(iq_elt, u'result') | 85 iq_result_elt = xmlstream.toResponse(iq_elt, 'result') |
86 result_admin_elt = iq_result_elt.addElement((NS_PUBSUB_ADMIN, u'admin')) | 86 result_admin_elt = iq_result_elt.addElement((NS_PUBSUB_ADMIN, 'admin')) |
87 result_pubsub_elt = result_admin_elt.addElement((pubsub.NS_PUBSUB, u'pubsub')) | 87 result_pubsub_elt = result_admin_elt.addElement((pubsub.NS_PUBSUB, 'pubsub')) |
88 result_publish_elt = result_pubsub_elt.addElement(u'publish') | 88 result_publish_elt = result_pubsub_elt.addElement('publish') |
89 result_publish_elt[u'node'] = node | 89 result_publish_elt['node'] = node |
90 | 90 |
91 # now we can send the items | 91 # now we can send the items |
92 for item in publish_elt.elements(pubsub.NS_PUBSUB, u'item'): | 92 for item in publish_elt.elements(pubsub.NS_PUBSUB, 'item'): |
93 try: | 93 try: |
94 requestor = jid.JID(item.attributes.pop(u'publisher')) | 94 requestor = jid.JID(item.attributes.pop('publisher')) |
95 except Exception as e: | 95 except Exception as e: |
96 log.msg(u"WARNING: invalid jid in publisher ({requestor}): {msg}" | 96 log.msg("WARNING: invalid jid in publisher ({requestor}): {msg}" |
97 .format(requestor=requestor, msg=e)) | 97 .format(requestor=requestor, msg=e)) |
98 self.sendError(iq_elt) | 98 self.sendError(iq_elt) |
99 return | 99 return |
100 except KeyError: | 100 except KeyError: |
101 requestor = from_jid | 101 requestor = from_jid |
109 requestor=requestor, | 109 requestor=requestor, |
110 pep=pep, | 110 pep=pep, |
111 recipient=recipient) | 111 recipient=recipient) |
112 except (error.Forbidden, error.ItemForbidden): | 112 except (error.Forbidden, error.ItemForbidden): |
113 __import__('pudb').set_trace() | 113 __import__('pudb').set_trace() |
114 self.sendError(iq_elt, u"forbidden") | 114 self.sendError(iq_elt, "forbidden") |
115 return | 115 return |
116 except Exception as e: | 116 except Exception as e: |
117 self.sendError(iq_elt, u"internal-server-error") | 117 self.sendError(iq_elt, "internal-server-error") |
118 log.msg(u"INTERNAL ERROR: {msg}".format(msg=e)) | 118 log.msg("INTERNAL ERROR: {msg}".format(msg=e)) |
119 return | 119 return |
120 | 120 |
121 result_item_elt = result_publish_elt.addElement(u'item') | 121 result_item_elt = result_publish_elt.addElement('item') |
122 # either the id was given and it is available in item | 122 # either the id was given and it is available in item |
123 # either it's a new item, and we can retrieve it from return payload | 123 # either it's a new item, and we can retrieve it from return payload |
124 try: | 124 try: |
125 result_item_elt[u'id'] = item[u'id'] | 125 result_item_elt['id'] = item['id'] |
126 except KeyError: | 126 except KeyError: |
127 result_item_elt = payload.publish.item[u'id'] | 127 result_item_elt = payload.publish.item['id'] |
128 | 128 |
129 self.xmlstream.send(iq_result_elt) | 129 self.xmlstream.send(iq_result_elt) |
130 | 130 |
131 def getDiscoInfo(self, requestor, service, nodeIdentifier=''): | 131 def getDiscoInfo(self, requestor, service, nodeIdentifier=''): |
132 return [disco.DiscoFeature(NS_PUBSUB_ADMIN)] | 132 return [disco.DiscoFeature(NS_PUBSUB_ADMIN)] |