comparison sat/plugins/plugin_xep_0115.py @ 3028:ab2696e34d29

Python 3 port: /!\ this is a huge commit /!\ starting from this commit, SàT is needs Python 3.6+ /!\ SàT maybe be instable or some feature may not work anymore, this will improve with time This patch port backend, bridge and frontends to Python 3. Roughly this has been done this way: - 2to3 tools has been applied (with python 3.7) - all references to python2 have been replaced with python3 (notably shebangs) - fixed files not handled by 2to3 (notably the shell script) - several manual fixes - fixed issues reported by Python 3 that where not handled in Python 2 - replaced "async" with "async_" when needed (it's a reserved word from Python 3.7) - replaced zope's "implements" with @implementer decorator - temporary hack to handle data pickled in database, as str or bytes may be returned, to be checked later - fixed hash comparison for password - removed some code which is not needed anymore with Python 3 - deactivated some code which needs to be checked (notably certificate validation) - tested with jp, fixed reported issues until some basic commands worked - ported Primitivus (after porting dependencies like urwid satext) - more manual fixes
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 19:08:41 +0200
parents 770ec685ff1f
children 9d0df638c8b4
comparison
equal deleted inserted replaced
3027:ff5bcb12ae60 3028:ab2696e34d29
1 #!/usr/bin/env python2 1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 3
4 # SAT plugin for managing xep-0115 4 # SAT plugin for managing xep-0115
5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) 5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org)
6 6
23 23
24 log = getLogger(__name__) 24 log = getLogger(__name__)
25 from twisted.words.xish import domish 25 from twisted.words.xish import domish
26 from twisted.words.protocols.jabber import jid 26 from twisted.words.protocols.jabber import jid
27 from twisted.internet import defer, error 27 from twisted.internet import defer, error
28 from zope.interface import implements 28 from zope.interface import implementer
29 from wokkel import disco, iwokkel 29 from wokkel import disco, iwokkel
30 30
31 try: 31 try:
32 from twisted.words.protocols.xmlstream import XMPPHandler 32 from twisted.words.protocols.xmlstream import XMPPHandler
33 except ImportError: 33 except ImportError:
68 # because disco infos/identities may change between clients 68 # because disco infos/identities may change between clients
69 69
70 # optimize check 70 # optimize check
71 client._caps_optimize = yield self.host.hasFeature(client, NS_CAPS_OPTIMIZE) 71 client._caps_optimize = yield self.host.hasFeature(client, NS_CAPS_OPTIMIZE)
72 if client._caps_optimize: 72 if client._caps_optimize:
73 log.info(_(u"Caps optimisation enabled")) 73 log.info(_("Caps optimisation enabled"))
74 client._caps_sent = False 74 client._caps_sent = False
75 else: 75 else:
76 log.warning(_(u"Caps optimisation not available")) 76 log.warning(_("Caps optimisation not available"))
77 77
78 # hash generation 78 # hash generation
79 _infos = yield client.discoHandler.info(client.jid, client.jid, "") 79 _infos = yield client.discoHandler.info(client.jid, client.jid, "")
80 disco_infos = disco.DiscoInfo() 80 disco_infos = disco.DiscoInfo()
81 for item in _infos: 81 for item in _infos:
82 disco_infos.append(item) 82 disco_infos.append(item)
83 cap_hash = client._caps_hash = self.host.memory.disco.generateHash(disco_infos) 83 cap_hash = client._caps_hash = self.host.memory.disco.generateHash(disco_infos)
84 log.info( 84 log.info(
85 u"Our capability hash has been generated: [{cap_hash}]".format( 85 "Our capability hash has been generated: [{cap_hash}]".format(
86 cap_hash=cap_hash 86 cap_hash=cap_hash
87 ) 87 )
88 ) 88 )
89 log.debug(u"Generating capability domish.Element") 89 log.debug("Generating capability domish.Element")
90 c_elt = domish.Element((NS_ENTITY_CAPABILITY, "c")) 90 c_elt = domish.Element((NS_ENTITY_CAPABILITY, "c"))
91 c_elt["hash"] = "sha-1" 91 c_elt["hash"] = "sha-1"
92 c_elt["node"] = C.APP_URL 92 c_elt["node"] = C.APP_URL
93 c_elt["ver"] = cap_hash 93 c_elt["ver"] = cap_hash
94 client._caps_elt = c_elt 94 client._caps_elt = c_elt
113 113
114 presence_d.addCallback(lambda __: self._presenceAddElt(client, obj)) 114 presence_d.addCallback(lambda __: self._presenceAddElt(client, obj))
115 return True 115 return True
116 116
117 117
118 @implementer(iwokkel.IDisco)
118 class XEP_0115_handler(XMPPHandler): 119 class XEP_0115_handler(XMPPHandler):
119 implements(iwokkel.IDisco)
120 120
121 def __init__(self, plugin_parent, profile): 121 def __init__(self, plugin_parent, profile):
122 self.plugin_parent = plugin_parent 122 self.plugin_parent = plugin_parent
123 self.host = plugin_parent.host 123 self.host = plugin_parent.host
124 self.profile = profile 124 self.profile = profile
140 Manage the capabilities of the entity 140 Manage the capabilities of the entity
141 141
142 Check if we know the version of this capabilities and get the capabilities if necessary 142 Check if we know the version of this capabilities and get the capabilities if necessary
143 """ 143 """
144 from_jid = jid.JID(presence["from"]) 144 from_jid = jid.JID(presence["from"])
145 c_elem = presence.elements(NS_ENTITY_CAPABILITY, "c").next() 145 c_elem = next(presence.elements(NS_ENTITY_CAPABILITY, "c"))
146 try: 146 try:
147 c_ver = c_elem["ver"] 147 c_ver = c_elem["ver"]
148 c_hash = c_elem["hash"] 148 c_hash = c_elem["hash"]
149 c_node = c_elem["node"] 149 c_node = c_elem["node"]
150 except KeyError: 150 except KeyError:
151 log.warning(_(u"Received invalid capabilities tag: %s") % c_elem.toXml()) 151 log.warning(_("Received invalid capabilities tag: %s") % c_elem.toXml())
152 return 152 return
153 153
154 if c_ver in self.host.memory.disco.hashes: 154 if c_ver in self.host.memory.disco.hashes:
155 # we already know the hash, we update the jid entity 155 # we already know the hash, we update the jid entity
156 log.debug( 156 log.debug(
157 u"hash [%(hash)s] already in cache, updating entity [%(jid)s]" 157 "hash [%(hash)s] already in cache, updating entity [%(jid)s]"
158 % {"hash": c_ver, "jid": from_jid.full()} 158 % {"hash": c_ver, "jid": from_jid.full()}
159 ) 159 )
160 self.host.memory.updateEntityData( 160 self.host.memory.updateEntityData(
161 from_jid, C.ENTITY_CAP_HASH, c_ver, profile_key=self.profile 161 from_jid, C.ENTITY_CAP_HASH, c_ver, profile_key=self.profile
162 ) 162 )
163 return 163 return
164 164
165 if c_hash != "sha-1": # unknown hash method 165 if c_hash != "sha-1": # unknown hash method
166 log.warning( 166 log.warning(
167 _( 167 _(
168 u"Unknown hash method for entity capabilities: [{hash_method}] " 168 "Unknown hash method for entity capabilities: [{hash_method}] "
169 u"(entity: {entity_jid}, node: {node})" 169 "(entity: {entity_jid}, node: {node})"
170 ) 170 )
171 .format(hash_method = c_hash, entity_jid = from_jid, node = c_node) 171 .format(hash_method = c_hash, entity_jid = from_jid, node = c_node)
172 ) 172 )
173 173
174 def cb(__): 174 def cb(__):
176 from_jid, C.ENTITY_CAP_HASH, self.profile 176 from_jid, C.ENTITY_CAP_HASH, self.profile
177 ) 177 )
178 if computed_hash != c_ver: 178 if computed_hash != c_ver:
179 log.warning( 179 log.warning(
180 _( 180 _(
181 u"Computed hash differ from given hash:\n" 181 "Computed hash differ from given hash:\n"
182 u"given: [{given}]\n" 182 "given: [{given}]\n"
183 u"computed: [{computed}]\n" 183 "computed: [{computed}]\n"
184 u"(entity: {entity_jid}, node: {node})" 184 "(entity: {entity_jid}, node: {node})"
185 ).format( 185 ).format(
186 given = c_ver, 186 given = c_ver,
187 computed = computed_hash, 187 computed = computed_hash,
188 entity_jid = from_jid, 188 entity_jid = from_jid,
189 node = c_node, 189 node = c_node,
197 failure.value.condition 197 failure.value.condition
198 if hasattr(failure.value, "condition") 198 if hasattr(failure.value, "condition")
199 else failure.getErrorMessage() 199 else failure.getErrorMessage()
200 ) 200 )
201 log.error( 201 log.error(
202 _(u"Couldn't retrieve disco info for {jid}: {error}").format( 202 _("Couldn't retrieve disco info for {jid}: {error}").format(
203 jid=from_jid.full(), error=msg 203 jid=from_jid.full(), error=msg
204 ) 204 )
205 ) 205 )
206 206
207 d = self.host.getDiscoInfos(self.parent, from_jid) 207 d = self.host.getDiscoInfos(self.parent, from_jid)