comparison sat/plugins/plugin_xep_0280.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 114cdde9ff96
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-0280 4 # SAT plugin for managing xep-0280
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
24 from sat.core import exceptions 24 from sat.core import exceptions
25 from sat.core.constants import Const as C 25 from sat.core.constants import Const as C
26 from twisted.words.protocols.jabber.error import StanzaError 26 from twisted.words.protocols.jabber.error import StanzaError
27 from twisted.internet import defer 27 from twisted.internet import defer
28 from wokkel import disco, iwokkel 28 from wokkel import disco, iwokkel
29 from zope.interface import implements 29 from zope.interface import implementer
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:
34 from wokkel.subprotocols import XMPPHandler 34 from wokkel.subprotocols import XMPPHandler
35 35
36 36
37 PARAM_CATEGORY = "Misc" 37 PARAM_CATEGORY = "Misc"
38 PARAM_NAME = "carbon" 38 PARAM_NAME = "carbon"
39 PARAM_LABEL = D_(u"Message carbons") 39 PARAM_LABEL = D_("Message carbons")
40 NS_CARBONS = "urn:xmpp:carbons:2" 40 NS_CARBONS = "urn:xmpp:carbons:2"
41 41
42 PLUGIN_INFO = { 42 PLUGIN_INFO = {
43 C.PI_NAME: u"XEP-0280 Plugin", 43 C.PI_NAME: "XEP-0280 Plugin",
44 C.PI_IMPORT_NAME: u"XEP-0280", 44 C.PI_IMPORT_NAME: "XEP-0280",
45 C.PI_TYPE: u"XEP", 45 C.PI_TYPE: "XEP",
46 C.PI_PROTOCOLS: [u"XEP-0280"], 46 C.PI_PROTOCOLS: ["XEP-0280"],
47 C.PI_DEPENDENCIES: [], 47 C.PI_DEPENDENCIES: [],
48 C.PI_MAIN: u"XEP_0280", 48 C.PI_MAIN: "XEP_0280",
49 C.PI_HANDLER: u"yes", 49 C.PI_HANDLER: "yes",
50 C.PI_DESCRIPTION: D_(u"""Implementation of Message Carbons"""), 50 C.PI_DESCRIPTION: D_("""Implementation of Message Carbons"""),
51 } 51 }
52 52
53 53
54 class XEP_0280(object): 54 class XEP_0280(object):
55 #  TODO: param is only checked at profile connection 55 #  TODO: param is only checked at profile connection
85 85
86 this method is intented to be called on final domish.Element by other plugins 86 this method is intented to be called on final domish.Element by other plugins
87 (in particular end 2 end encryption plugins) 87 (in particular end 2 end encryption plugins)
88 @param message_elt(domish.Element): <message> stanza 88 @param message_elt(domish.Element): <message> stanza
89 """ 89 """
90 if message_elt.name != u"message": 90 if message_elt.name != "message":
91 log.error(u"addPrivateElt must be used with <message> stanzas") 91 log.error("addPrivateElt must be used with <message> stanzas")
92 return 92 return
93 message_elt.addElement((NS_CARBONS, u"private")) 93 message_elt.addElement((NS_CARBONS, "private"))
94 94
95 @defer.inlineCallbacks 95 @defer.inlineCallbacks
96 def profileConnected(self, client): 96 def profileConnected(self, client):
97 """activate message carbons on connection if possible and activated in config""" 97 """activate message carbons on connection if possible and activated in config"""
98 activate = self.host.memory.getParamA( 98 activate = self.host.memory.getParamA(
99 PARAM_NAME, PARAM_CATEGORY, profile_key=client.profile 99 PARAM_NAME, PARAM_CATEGORY, profile_key=client.profile
100 ) 100 )
101 if not activate: 101 if not activate:
102 log.info(_(u"Not activating message carbons as requested in params")) 102 log.info(_("Not activating message carbons as requested in params"))
103 return 103 return
104 try: 104 try:
105 yield self.host.checkFeatures(client, (NS_CARBONS,)) 105 yield self.host.checkFeatures(client, (NS_CARBONS,))
106 except exceptions.FeatureNotFound: 106 except exceptions.FeatureNotFound:
107 log.warning(_(u"server doesn't handle message carbons")) 107 log.warning(_("server doesn't handle message carbons"))
108 else: 108 else:
109 log.info(_(u"message carbons available, enabling it")) 109 log.info(_("message carbons available, enabling it"))
110 iq_elt = client.IQ() 110 iq_elt = client.IQ()
111 iq_elt.addElement((NS_CARBONS, "enable")) 111 iq_elt.addElement((NS_CARBONS, "enable"))
112 try: 112 try:
113 yield iq_elt.send() 113 yield iq_elt.send()
114 except StanzaError as e: 114 except StanzaError as e:
115 log.warning(u"Can't activate message carbons: {}".format(e)) 115 log.warning("Can't activate message carbons: {}".format(e))
116 else: 116 else:
117 log.info(_(u"message carbons activated")) 117 log.info(_("message carbons activated"))
118 118
119 def messageReceivedTrigger(self, client, message_elt, post_treat): 119 def messageReceivedTrigger(self, client, message_elt, post_treat):
120 """get message and handle it if carbons namespace is present""" 120 """get message and handle it if carbons namespace is present"""
121 carbons_elt = None 121 carbons_elt = None
122 for e in message_elt.elements(): 122 for e in message_elt.elements():
129 # we continue normal behaviour 129 # we continue normal behaviour
130 return True 130 return True
131 131
132 if message_elt["from"] != client.jid.userhost(): 132 if message_elt["from"] != client.jid.userhost():
133 log.warning( 133 log.warning(
134 u"The message carbon received is not from our server, hack attempt?\n{xml}".format( 134 "The message carbon received is not from our server, hack attempt?\n{xml}".format(
135 xml=message_elt.toXml() 135 xml=message_elt.toXml()
136 ) 136 )
137 ) 137 )
138 return 138 return
139 forwarded_elt = next(carbons_elt.elements(C.NS_FORWARD, "forwarded")) 139 forwarded_elt = next(carbons_elt.elements(C.NS_FORWARD, "forwarded"))
145 message_elt["from"] = cc_message_elt["from"] 145 message_elt["from"] = cc_message_elt["from"]
146 elif carbons_elt.name == "sent": 146 elif carbons_elt.name == "sent":
147 message_elt["to"] = cc_message_elt["to"] 147 message_elt["to"] = cc_message_elt["to"]
148 else: 148 else:
149 log.warning( 149 log.warning(
150 u"invalid message carbons received:\n{xml}".format( 150 "invalid message carbons received:\n{xml}".format(
151 xml=message_elt.toXml() 151 xml=message_elt.toXml()
152 ) 152 )
153 ) 153 )
154 return False 154 return False
155 155
157 for c in cc_message_elt.children: 157 for c in cc_message_elt.children:
158 message_elt.addChild(c) 158 message_elt.addChild(c)
159 159
160 return True 160 return True
161 161
162 @implementer(iwokkel.IDisco)
162 class XEP_0280_handler(XMPPHandler): 163 class XEP_0280_handler(XMPPHandler):
163 implements(iwokkel.IDisco)
164 164
165 def getDiscoInfo(self, requestor, target, nodeIdentifier=""): 165 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
166 return [disco.DiscoFeature(NS_CARBONS)] 166 return [disco.DiscoFeature(NS_CARBONS)]
167 167
168 def getDiscoItems(self, requestor, target, nodeIdentifier=""): 168 def getDiscoItems(self, requestor, target, nodeIdentifier=""):