comparison sat/plugins/plugin_xep_0100.py @ 2624:56f94936df1e

code style reformatting using black
author Goffi <goffi@goffi.org>
date Wed, 27 Jun 2018 20:14:46 +0200
parents 26edcf3a30eb
children 003b8b4b56a7
comparison
equal deleted inserted replaced
2623:49533de4540b 2624:56f94936df1e
20 from sat.core.i18n import _, D_ 20 from sat.core.i18n import _, D_
21 from sat.core.constants import Const as C 21 from sat.core.constants import Const as C
22 from sat.core import exceptions 22 from sat.core import exceptions
23 from sat.tools import xml_tools 23 from sat.tools import xml_tools
24 from sat.core.log import getLogger 24 from sat.core.log import getLogger
25
25 log = getLogger(__name__) 26 log = getLogger(__name__)
26 from twisted.words.protocols.jabber import jid 27 from twisted.words.protocols.jabber import jid
27 from twisted.internet import reactor, defer 28 from twisted.internet import reactor, defer
28 29
29 PLUGIN_INFO = { 30 PLUGIN_INFO = {
31 C.PI_IMPORT_NAME: "XEP-0100", 32 C.PI_IMPORT_NAME: "XEP-0100",
32 C.PI_TYPE: "XEP", 33 C.PI_TYPE: "XEP",
33 C.PI_PROTOCOLS: ["XEP-0100"], 34 C.PI_PROTOCOLS: ["XEP-0100"],
34 C.PI_DEPENDENCIES: ["XEP-0077"], 35 C.PI_DEPENDENCIES: ["XEP-0077"],
35 C.PI_MAIN: "XEP_0100", 36 C.PI_MAIN: "XEP_0100",
36 C.PI_DESCRIPTION: _("""Implementation of Gateways protocol""") 37 C.PI_DESCRIPTION: _("""Implementation of Gateways protocol"""),
37 } 38 }
38 39
39 WARNING_MSG = D_(u"""Be careful ! Gateways allow you to use an external IM (legacy IM), so you can see your contact as XMPP contacts. 40 WARNING_MSG = D_(
40 But when you do this, all your messages go throught the external legacy IM server, it is a huge privacy issue (i.e.: all your messages throught the gateway can be monitored, recorded, analysed by the external server, most of time a private company).""") 41 u"""Be careful ! Gateways allow you to use an external IM (legacy IM), so you can see your contact as XMPP contacts.
42 But when you do this, all your messages go throught the external legacy IM server, it is a huge privacy issue (i.e.: all your messages throught the gateway can be monitored, recorded, analysed by the external server, most of time a private company)."""
43 )
41 44
42 GATEWAY_TIMEOUT = 10 # time to wait before cancelling a gateway disco info, in seconds 45 GATEWAY_TIMEOUT = 10 # time to wait before cancelling a gateway disco info, in seconds
43 46
44 TYPE_DESCRIPTIONS = {'irc': D_("Internet Relay Chat"), 47 TYPE_DESCRIPTIONS = {
45 'xmpp': D_("XMPP"), 48 "irc": D_("Internet Relay Chat"),
46 'qq': D_("Tencent QQ"), 49 "xmpp": D_("XMPP"),
47 'simple': D_("SIP/SIMPLE"), 50 "qq": D_("Tencent QQ"),
48 'icq': D_("ICQ"), 51 "simple": D_("SIP/SIMPLE"),
49 'yahoo': D_("Yahoo! Messenger"), 52 "icq": D_("ICQ"),
50 'gadu-gadu': D_("Gadu-Gadu"), 53 "yahoo": D_("Yahoo! Messenger"),
51 'aim': D_("AOL Instant Messenger"), 54 "gadu-gadu": D_("Gadu-Gadu"),
52 'msn': D_("Windows Live Messenger"), 55 "aim": D_("AOL Instant Messenger"),
53 } 56 "msn": D_("Windows Live Messenger"),
57 }
54 58
55 59
56 class XEP_0100(object): 60 class XEP_0100(object):
57
58 def __init__(self, host): 61 def __init__(self, host):
59 log.info(_("Gateways plugin initialization")) 62 log.info(_("Gateways plugin initialization"))
60 self.host = host 63 self.host = host
61 self.__gateways = {} # dict used to construct the answer to findGateways. Key = target jid 64 self.__gateways = {} # dict used to construct the answer to findGateways. Key = target jid
62 host.bridge.addMethod("findGateways", ".plugin", in_sign='ss', out_sign='s', method=self._findGateways) 65 host.bridge.addMethod(
63 host.bridge.addMethod("gatewayRegister", ".plugin", in_sign='ss', out_sign='s', method=self._gatewayRegister) 66 "findGateways",
67 ".plugin",
68 in_sign="ss",
69 out_sign="s",
70 method=self._findGateways,
71 )
72 host.bridge.addMethod(
73 "gatewayRegister",
74 ".plugin",
75 in_sign="ss",
76 out_sign="s",
77 method=self._gatewayRegister,
78 )
64 self.__menu_id = host.registerCallback(self._gatewaysMenu, with_data=True) 79 self.__menu_id = host.registerCallback(self._gatewaysMenu, with_data=True)
65 self.__selected_id = host.registerCallback(self._gatewaySelectedCb, with_data=True) 80 self.__selected_id = host.registerCallback(
66 host.importMenu((D_("Service"), D_("Gateways")), self._gatewaysMenu, security_limit=1, help_string=D_("Find gateways")) 81 self._gatewaySelectedCb, with_data=True
82 )
83 host.importMenu(
84 (D_("Service"), D_("Gateways")),
85 self._gatewaysMenu,
86 security_limit=1,
87 help_string=D_("Find gateways"),
88 )
67 89
68 def _gatewaysMenu(self, data, profile): 90 def _gatewaysMenu(self, data, profile):
69 """ XMLUI activated by menu: return Gateways UI 91 """ XMLUI activated by menu: return Gateways UI
70 92
71 @param profile: %(doc_profile)s 93 @param profile: %(doc_profile)s
72 """ 94 """
73 client = self.host.getClient(profile) 95 client = self.host.getClient(profile)
74 try: 96 try:
75 jid_ = jid.JID(data.get(xml_tools.formEscape('external_jid'), client.jid.host)) 97 jid_ = jid.JID(
98 data.get(xml_tools.formEscape("external_jid"), client.jid.host)
99 )
76 except RuntimeError: 100 except RuntimeError:
77 raise exceptions.DataError(_("Invalid JID")) 101 raise exceptions.DataError(_("Invalid JID"))
78 d = self.findGateways(jid_, profile) 102 d = self.findGateways(jid_, profile)
79 d.addCallback(self._gatewaysResult2XMLUI, jid_) 103 d.addCallback(self._gatewaysResult2XMLUI, jid_)
80 d.addCallback(lambda xmlui: {'xmlui': xmlui.toXml()}) 104 d.addCallback(lambda xmlui: {"xmlui": xmlui.toXml()})
81 return d 105 return d
82 106
83 def _gatewaysResult2XMLUI(self, result, entity): 107 def _gatewaysResult2XMLUI(self, result, entity):
84 xmlui = xml_tools.XMLUI(title=_('Gateways manager (%s)') % entity.full()) 108 xmlui = xml_tools.XMLUI(title=_("Gateways manager (%s)") % entity.full())
85 xmlui.addText(_(WARNING_MSG)) 109 xmlui.addText(_(WARNING_MSG))
86 xmlui.addDivider('dash') 110 xmlui.addDivider("dash")
87 adv_list = xmlui.changeContainer('advanced_list', columns=3, selectable='single', callback_id=self.__selected_id) 111 adv_list = xmlui.changeContainer(
112 "advanced_list",
113 columns=3,
114 selectable="single",
115 callback_id=self.__selected_id,
116 )
88 for success, gateway_data in result: 117 for success, gateway_data in result:
89 if not success: 118 if not success:
90 fail_cond, disco_item = gateway_data 119 fail_cond, disco_item = gateway_data
91 xmlui.addJid(disco_item.entity) 120 xmlui.addJid(disco_item.entity)
92 xmlui.addText(_('Failed (%s)') % fail_cond) 121 xmlui.addText(_("Failed (%s)") % fail_cond)
93 xmlui.addEmpty() 122 xmlui.addEmpty()
94 else: 123 else:
95 jid_, data = gateway_data 124 jid_, data = gateway_data
96 for datum in data: 125 for datum in data:
97 identity, name = datum 126 identity, name = datum
98 adv_list.setRowIndex(jid_.full()) 127 adv_list.setRowIndex(jid_.full())
99 xmlui.addJid(jid_) 128 xmlui.addJid(jid_)
100 xmlui.addText(name) 129 xmlui.addText(name)
101 xmlui.addText(self._getIdentityDesc(identity)) 130 xmlui.addText(self._getIdentityDesc(identity))
102 adv_list.end() 131 adv_list.end()
103 xmlui.addDivider('blank') 132 xmlui.addDivider("blank")
104 xmlui.changeContainer('advanced_list', columns=3) 133 xmlui.changeContainer("advanced_list", columns=3)
105 xmlui.addLabel(_('Use external XMPP server')) 134 xmlui.addLabel(_("Use external XMPP server"))
106 xmlui.addString('external_jid') 135 xmlui.addString("external_jid")
107 xmlui.addButton(self.__menu_id, _(u'Go !'), fields_back=('external_jid',)) 136 xmlui.addButton(self.__menu_id, _(u"Go !"), fields_back=("external_jid",))
108 return xmlui 137 return xmlui
109 138
110 def _gatewaySelectedCb(self, data, profile): 139 def _gatewaySelectedCb(self, data, profile):
111 try: 140 try:
112 target_jid = jid.JID(data['index']) 141 target_jid = jid.JID(data["index"])
113 except (KeyError, RuntimeError): 142 except (KeyError, RuntimeError):
114 log.warning(_("No gateway index selected")) 143 log.warning(_("No gateway index selected"))
115 return {} 144 return {}
116 145
117 d = self.gatewayRegister(target_jid, profile) 146 d = self.gatewayRegister(target_jid, profile)
118 d.addCallback(lambda xmlui: {'xmlui': xmlui.toXml()}) 147 d.addCallback(lambda xmlui: {"xmlui": xmlui.toXml()})
119 return d 148 return d
120 149
121 def _getIdentityDesc(self, identity): 150 def _getIdentityDesc(self, identity):
122 """ Return a human readable description of identity 151 """ Return a human readable description of identity
123 @param identity: tuple as returned by Disco identities (category, type) 152 @param identity: tuple as returned by Disco identities (category, type)
124 153
125 """ 154 """
126 category, type_ = identity 155 category, type_ = identity
127 if category != 'gateway': 156 if category != "gateway":
128 log.error(_(u'INTERNAL ERROR: identity category should always be "gateway" in _getTypeString, got "%s"') % category) 157 log.error(
158 _(
159 u'INTERNAL ERROR: identity category should always be "gateway" in _getTypeString, got "%s"'
160 )
161 % category
162 )
129 try: 163 try:
130 return _(TYPE_DESCRIPTIONS[type_]) 164 return _(TYPE_DESCRIPTIONS[type_])
131 except KeyError: 165 except KeyError:
132 return _("Unknown IM") 166 return _("Unknown IM")
133 167
143 return d 177 return d
144 178
145 def gatewayRegister(self, target_jid, profile_key=C.PROF_KEY_NONE): 179 def gatewayRegister(self, target_jid, profile_key=C.PROF_KEY_NONE):
146 """Register gateway using in-band registration, then log-in to gateway""" 180 """Register gateway using in-band registration, then log-in to gateway"""
147 profile = self.host.memory.getProfileName(profile_key) 181 profile = self.host.memory.getProfileName(profile_key)
148 assert(profile) 182 assert profile
149 d = self.host.plugins["XEP-0077"].inBandRegister(target_jid, self._registrationSuccessful, profile) 183 d = self.host.plugins["XEP-0077"].inBandRegister(
184 target_jid, self._registrationSuccessful, profile
185 )
150 return d 186 return d
151 187
152 def _infosReceived(self, dl_result, items, target, client): 188 def _infosReceived(self, dl_result, items, target, client):
153 """Find disco infos about entity, to check if it is a gateway""" 189 """Find disco infos about entity, to check if it is a gateway"""
154 190
163 except AttributeError: 199 except AttributeError:
164 msg = str(result) 200 msg = str(result)
165 ret.append((success, (msg, items[idx]))) 201 ret.append((success, (msg, items[idx])))
166 else: 202 else:
167 entity = items[idx].entity 203 entity = items[idx].entity
168 gateways = [(identity, result.identities[identity]) for identity in result.identities if identity[0] == 'gateway'] 204 gateways = [
205 (identity, result.identities[identity])
206 for identity in result.identities
207 if identity[0] == "gateway"
208 ]
169 if gateways: 209 if gateways:
170 log.info(_(u"Found gateway [%(jid)s]: %(identity_name)s") % {'jid': entity.full(), 'identity_name': ' - '.join([gateway[1] for gateway in gateways])}) 210 log.info(
211 _(u"Found gateway [%(jid)s]: %(identity_name)s")
212 % {
213 "jid": entity.full(),
214 "identity_name": " - ".join(
215 [gateway[1] for gateway in gateways]
216 ),
217 }
218 )
171 ret.append((success, (entity, gateways))) 219 ret.append((success, (entity, gateways)))
172 else: 220 else:
173 log.info(_(u"Skipping [%(jid)s] which is not a gateway") % {'jid': entity.full()}) 221 log.info(
222 _(u"Skipping [%(jid)s] which is not a gateway")
223 % {"jid": entity.full()}
224 )
174 return ret 225 return ret
175 226
176 def _itemsReceived(self, disco, target, client): 227 def _itemsReceived(self, disco, target, client):
177 """Look for items with disco protocol, and ask infos for each one""" 228 """Look for items with disco protocol, and ask infos for each one"""
178 229
183 _defers = [] 234 _defers = []
184 for item in disco._items: 235 for item in disco._items:
185 log.debug(_(u"item found: %s") % item.entity) 236 log.debug(_(u"item found: %s") % item.entity)
186 _defers.append(client.disco.requestInfo(item.entity)) 237 _defers.append(client.disco.requestInfo(item.entity))
187 dl = defer.DeferredList(_defers) 238 dl = defer.DeferredList(_defers)
188 dl.addCallback(self._infosReceived, items=disco._items, target=target, client=client) 239 dl.addCallback(
240 self._infosReceived, items=disco._items, target=target, client=client
241 )
189 reactor.callLater(GATEWAY_TIMEOUT, dl.cancel) 242 reactor.callLater(GATEWAY_TIMEOUT, dl.cancel)
190 return dl 243 return dl
191 244
192 def _findGateways(self, target_jid_s, profile_key): 245 def _findGateways(self, target_jid_s, profile_key):
193 target_jid = jid.JID(target_jid_s) 246 target_jid = jid.JID(target_jid_s)
201 254
202 def findGateways(self, target, profile): 255 def findGateways(self, target, profile):
203 """Find gateways in the target JID, using discovery protocol 256 """Find gateways in the target JID, using discovery protocol
204 """ 257 """
205 client = self.host.getClient(profile) 258 client = self.host.getClient(profile)
206 log.debug(_(u"find gateways (target = %(target)s, profile = %(profile)s)") % {'target': target.full(), 'profile': profile}) 259 log.debug(
260 _(u"find gateways (target = %(target)s, profile = %(profile)s)")
261 % {"target": target.full(), "profile": profile}
262 )
207 d = client.disco.requestItems(target) 263 d = client.disco.requestItems(target)
208 d.addCallback(self._itemsReceived, target=target, client=client) 264 d.addCallback(self._itemsReceived, target=target, client=client)
209 return d 265 return d