Mercurial > libervia-backend
comparison sat/plugins/plugin_sec_otr.py @ 4037:524856bd7b19
massive refactoring to switch from camelCase to snake_case:
historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a
pre-PEP8 code, to use the same coding style as in Twisted.
However, snake_case is more readable and it's better to follow PEP8 best practices, so it
has been decided to move on full snake_case. Because Libervia has a huge codebase, this
ended with a ugly mix of camelCase and snake_case.
To fix that, this patch does a big refactoring by renaming every function and method
(including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case.
This is a massive change, and may result in some bugs.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 08 Apr 2023 13:54:42 +0200 |
parents | 967a8e109cda |
children | c23cad65ae99 |
comparison
equal
deleted
inserted
replaced
4036:c4464d7ae97b | 4037:524856bd7b19 |
---|---|
90 | 90 |
91 @property | 91 @property |
92 def _p_carbons(self): | 92 def _p_carbons(self): |
93 return self.context_manager.parent._p_carbons | 93 return self.context_manager.parent._p_carbons |
94 | 94 |
95 def getPolicy(self, key): | 95 def get_policy(self, key): |
96 if key in DEFAULT_POLICY_FLAGS: | 96 if key in DEFAULT_POLICY_FLAGS: |
97 return DEFAULT_POLICY_FLAGS[key] | 97 return DEFAULT_POLICY_FLAGS[key] |
98 else: | 98 else: |
99 return False | 99 return False |
100 | 100 |
121 "subject": {}, | 121 "subject": {}, |
122 "type": "chat", | 122 "type": "chat", |
123 "extra": {}, | 123 "extra": {}, |
124 "timestamp": time.time(), | 124 "timestamp": time.time(), |
125 } | 125 } |
126 client.generateMessageXML(mess_data) | 126 client.generate_message_xml(mess_data) |
127 xml = mess_data['xml'] | 127 xml = mess_data['xml'] |
128 self._p_carbons.setPrivate(xml) | 128 self._p_carbons.set_private(xml) |
129 self._p_hints.addHintElements(xml, [ | 129 self._p_hints.add_hint_elements(xml, [ |
130 self._p_hints.HINT_NO_COPY, | 130 self._p_hints.HINT_NO_COPY, |
131 self._p_hints.HINT_NO_PERMANENT_STORE]) | 131 self._p_hints.HINT_NO_PERMANENT_STORE]) |
132 client.send(mess_data["xml"]) | 132 client.send(mess_data["xml"]) |
133 else: | 133 else: |
134 message_elt = appdata["xml"] | 134 message_elt = appdata["xml"] |
135 assert message_elt.name == "message" | 135 assert message_elt.name == "message" |
136 message_elt.addElement("body", content=msg) | 136 message_elt.addElement("body", content=msg) |
137 | 137 |
138 def stopCb(self, __, feedback): | 138 def stop_cb(self, __, feedback): |
139 client = self.user.client | 139 client = self.user.client |
140 self.host.bridge.otrState( | 140 self.host.bridge.otr_state( |
141 OTR_STATE_UNENCRYPTED, self.peer.full(), client.profile | 141 OTR_STATE_UNENCRYPTED, self.peer.full(), client.profile |
142 ) | 142 ) |
143 client.feedback(self.peer, feedback) | 143 client.feedback(self.peer, feedback) |
144 | 144 |
145 def stopEb(self, failure_): | 145 def stop_eb(self, failure_): |
146 # encryption may be already stopped in case of manual stop | 146 # encryption may be already stopped in case of manual stop |
147 if not failure_.check(exceptions.NotFound): | 147 if not failure_.check(exceptions.NotFound): |
148 log.error("Error while stopping OTR encryption: {msg}".format(msg=failure_)) | 148 log.error("Error while stopping OTR encryption: {msg}".format(msg=failure_)) |
149 | 149 |
150 def isTrusted(self): | 150 def is_trusted(self): |
151 # we have to check value because potr code says that a 2-tuples should be | 151 # we have to check value because potr code says that a 2-tuples should be |
152 # returned while in practice it's either None or u"trusted" | 152 # returned while in practice it's either None or u"trusted" |
153 trusted = self.getCurrentTrust() | 153 trusted = self.getCurrentTrust() |
154 if trusted is None: | 154 if trusted is None: |
155 return False | 155 return False |
158 else: | 158 else: |
159 log.error("Unexpected getCurrentTrust() value: {value}".format( | 159 log.error("Unexpected getCurrentTrust() value: {value}".format( |
160 value=trusted)) | 160 value=trusted)) |
161 return False | 161 return False |
162 | 162 |
163 def setState(self, state): | 163 def set_state(self, state): |
164 client = self.user.client | 164 client = self.user.client |
165 old_state = self.state | 165 old_state = self.state |
166 super(Context, self).setState(state) | 166 super(Context, self).set_state(state) |
167 log.debug("setState: %s (old_state=%s)" % (state, old_state)) | 167 log.debug("set_state: %s (old_state=%s)" % (state, old_state)) |
168 | 168 |
169 if state == potr.context.STATE_PLAINTEXT: | 169 if state == potr.context.STATE_PLAINTEXT: |
170 feedback = _("/!\\ conversation with %(other_jid)s is now UNENCRYPTED") % { | 170 feedback = _("/!\\ conversation with %(other_jid)s is now UNENCRYPTED") % { |
171 "other_jid": self.peer.full() | 171 "other_jid": self.peer.full() |
172 } | 172 } |
173 d = defer.ensureDeferred(client.encryption.stop(self.peer, NS_OTR)) | 173 d = defer.ensureDeferred(client.encryption.stop(self.peer, NS_OTR)) |
174 d.addCallback(self.stopCb, feedback=feedback) | 174 d.addCallback(self.stop_cb, feedback=feedback) |
175 d.addErrback(self.stopEb) | 175 d.addErrback(self.stop_eb) |
176 return | 176 return |
177 elif state == potr.context.STATE_ENCRYPTED: | 177 elif state == potr.context.STATE_ENCRYPTED: |
178 defer.ensureDeferred(client.encryption.start(self.peer, NS_OTR)) | 178 defer.ensureDeferred(client.encryption.start(self.peer, NS_OTR)) |
179 try: | 179 try: |
180 trusted = self.isTrusted() | 180 trusted = self.is_trusted() |
181 except TypeError: | 181 except TypeError: |
182 trusted = False | 182 trusted = False |
183 trusted_str = _("trusted") if trusted else _("untrusted") | 183 trusted_str = _("trusted") if trusted else _("untrusted") |
184 | 184 |
185 if old_state == potr.context.STATE_ENCRYPTED: | 185 if old_state == potr.context.STATE_ENCRYPTED: |
193 ).format( | 193 ).format( |
194 trusted=trusted_str, | 194 trusted=trusted_str, |
195 other_jid=self.peer.full(), | 195 other_jid=self.peer.full(), |
196 extra_info=NO_ADV_FEATURES, | 196 extra_info=NO_ADV_FEATURES, |
197 ) | 197 ) |
198 self.host.bridge.otrState( | 198 self.host.bridge.otr_state( |
199 OTR_STATE_ENCRYPTED, self.peer.full(), client.profile | 199 OTR_STATE_ENCRYPTED, self.peer.full(), client.profile |
200 ) | 200 ) |
201 elif state == potr.context.STATE_FINISHED: | 201 elif state == potr.context.STATE_FINISHED: |
202 feedback = D_("OTR conversation with {other_jid} is FINISHED").format( | 202 feedback = D_("OTR conversation with {other_jid} is FINISHED").format( |
203 other_jid=self.peer.full() | 203 other_jid=self.peer.full() |
204 ) | 204 ) |
205 d = defer.ensureDeferred(client.encryption.stop(self.peer, NS_OTR)) | 205 d = defer.ensureDeferred(client.encryption.stop(self.peer, NS_OTR)) |
206 d.addCallback(self.stopCb, feedback=feedback) | 206 d.addCallback(self.stop_cb, feedback=feedback) |
207 d.addErrback(self.stopEb) | 207 d.addErrback(self.stop_eb) |
208 return | 208 return |
209 else: | 209 else: |
210 log.error(D_("Unknown OTR state")) | 210 log.error(D_("Unknown OTR state")) |
211 return | 211 return |
212 | 212 |
238 log.warning("Account created without resource") | 238 log.warning("Account created without resource") |
239 super(Account, self).__init__(str(client.jid), "xmpp", 1024) | 239 super(Account, self).__init__(str(client.jid), "xmpp", 1024) |
240 self.host = host | 240 self.host = host |
241 self.client = client | 241 self.client = client |
242 | 242 |
243 def loadPrivkey(self): | 243 def load_privkey(self): |
244 log.debug("loadPrivkey") | 244 log.debug("load_privkey") |
245 return self.privkey | 245 return self.privkey |
246 | 246 |
247 def savePrivkey(self): | 247 def save_privkey(self): |
248 log.debug("savePrivkey") | 248 log.debug("save_privkey") |
249 if self.privkey is None: | 249 if self.privkey is None: |
250 raise exceptions.InternalError(_("Save is called but privkey is None !")) | 250 raise exceptions.InternalError(_("Save is called but privkey is None !")) |
251 priv_key = hexlify(self.privkey.serializePrivateKey()) | 251 priv_key = hexlify(self.privkey.serializePrivateKey()) |
252 encrypted_priv_key = self.host.memory.encryptValue(priv_key, self.client.profile) | 252 encrypted_priv_key = self.host.memory.encrypt_value(priv_key, self.client.profile) |
253 self.client._otr_data[PRIVATE_KEY] = encrypted_priv_key | 253 self.client._otr_data[PRIVATE_KEY] = encrypted_priv_key |
254 | 254 |
255 def loadTrusts(self): | 255 def load_trusts(self): |
256 trust_data = self.client._otr_data.get("trust", {}) | 256 trust_data = self.client._otr_data.get("trust", {}) |
257 for jid_, jid_data in trust_data.items(): | 257 for jid_, jid_data in trust_data.items(): |
258 for fingerprint, trust_level in jid_data.items(): | 258 for fingerprint, trust_level in jid_data.items(): |
259 log.debug( | 259 log.debug( |
260 'setting trust for {jid}: [{fingerprint}] = "{trust_level}"'.format( | 260 'setting trust for {jid}: [{fingerprint}] = "{trust_level}"'.format( |
261 jid=jid_, fingerprint=fingerprint, trust_level=trust_level | 261 jid=jid_, fingerprint=fingerprint, trust_level=trust_level |
262 ) | 262 ) |
263 ) | 263 ) |
264 self.trusts.setdefault(jid.JID(jid_), {})[fingerprint] = trust_level | 264 self.trusts.setdefault(jid.JID(jid_), {})[fingerprint] = trust_level |
265 | 265 |
266 def saveTrusts(self): | 266 def save_trusts(self): |
267 log.debug("saving trusts for {profile}".format(profile=self.client.profile)) | 267 log.debug("saving trusts for {profile}".format(profile=self.client.profile)) |
268 log.debug("trusts = {}".format(self.client._otr_data["trust"])) | 268 log.debug("trusts = {}".format(self.client._otr_data["trust"])) |
269 self.client._otr_data.force("trust") | 269 self.client._otr_data.force("trust") |
270 | 270 |
271 def setTrust(self, other_jid, fingerprint, trustLevel): | 271 def set_trust(self, other_jid, fingerprint, trustLevel): |
272 try: | 272 try: |
273 trust_data = self.client._otr_data["trust"] | 273 trust_data = self.client._otr_data["trust"] |
274 except KeyError: | 274 except KeyError: |
275 trust_data = {} | 275 trust_data = {} |
276 self.client._otr_data["trust"] = trust_data | 276 self.client._otr_data["trust"] = trust_data |
277 jid_data = trust_data.setdefault(other_jid.full(), {}) | 277 jid_data = trust_data.setdefault(other_jid.full(), {}) |
278 jid_data[fingerprint] = trustLevel | 278 jid_data[fingerprint] = trustLevel |
279 super(Account, self).setTrust(other_jid, fingerprint, trustLevel) | 279 super(Account, self).set_trust(other_jid, fingerprint, trustLevel) |
280 | 280 |
281 | 281 |
282 class ContextManager(object): | 282 class ContextManager(object): |
283 def __init__(self, parent, client): | 283 def __init__(self, parent, client): |
284 self.parent = parent | 284 self.parent = parent |
287 | 287 |
288 @property | 288 @property |
289 def host(self): | 289 def host(self): |
290 return self.parent.host | 290 return self.parent.host |
291 | 291 |
292 def startContext(self, other_jid): | 292 def start_context(self, other_jid): |
293 assert isinstance(other_jid, jid.JID) | 293 assert isinstance(other_jid, jid.JID) |
294 context = self.contexts.setdefault( | 294 context = self.contexts.setdefault( |
295 other_jid, Context(self, other_jid) | 295 other_jid, Context(self, other_jid) |
296 ) | 296 ) |
297 return context | 297 return context |
298 | 298 |
299 def getContextForUser(self, other): | 299 def get_context_for_user(self, other): |
300 log.debug("getContextForUser [%s]" % other) | 300 log.debug("get_context_for_user [%s]" % other) |
301 if not other.resource: | 301 if not other.resource: |
302 log.warning("getContextForUser called with a bare jid: %s" % other.full()) | 302 log.warning("get_context_for_user called with a bare jid: %s" % other.full()) |
303 return self.startContext(other) | 303 return self.start_context(other) |
304 | 304 |
305 | 305 |
306 class OTR(object): | 306 class OTR(object): |
307 | 307 |
308 def __init__(self, host): | 308 def __init__(self, host): |
312 self.skipped_profiles = ( | 312 self.skipped_profiles = ( |
313 set() | 313 set() |
314 ) # FIXME: OTR should not be skipped per profile, this need to be refactored | 314 ) # FIXME: OTR should not be skipped per profile, this need to be refactored |
315 self._p_hints = host.plugins["XEP-0334"] | 315 self._p_hints = host.plugins["XEP-0334"] |
316 self._p_carbons = host.plugins["XEP-0280"] | 316 self._p_carbons = host.plugins["XEP-0280"] |
317 host.trigger.add("messageReceived", self.messageReceivedTrigger, priority=100000) | 317 host.trigger.add("messageReceived", self.message_received_trigger, priority=100000) |
318 host.trigger.add("sendMessage", self.sendMessageTrigger, priority=100000) | 318 host.trigger.add("sendMessage", self.send_message_trigger, priority=100000) |
319 host.trigger.add("sendMessageData", self._sendMessageDataTrigger) | 319 host.trigger.add("send_message_data", self._send_message_data_trigger) |
320 host.bridge.addMethod( | 320 host.bridge.add_method( |
321 "skipOTR", ".plugin", in_sign="s", out_sign="", method=self._skipOTR | 321 "skip_otr", ".plugin", in_sign="s", out_sign="", method=self._skip_otr |
322 ) # FIXME: must be removed, must be done on per-message basis | 322 ) # FIXME: must be removed, must be done on per-message basis |
323 host.bridge.addSignal( | 323 host.bridge.add_signal( |
324 "otrState", ".plugin", signature="sss" | 324 "otr_state", ".plugin", signature="sss" |
325 ) # args: state, destinee_jid, profile | 325 ) # args: state, destinee_jid, profile |
326 # XXX: menus are disabled in favor to the new more generic encryption menu | 326 # XXX: menus are disabled in favor to the new more generic encryption menu |
327 # there are let here commented for a little while as a reference | 327 # there are let here commented for a little while as a reference |
328 # host.importMenu( | 328 # host.import_menu( |
329 # (OTR_MENU, D_(u"Start/Refresh")), | 329 # (OTR_MENU, D_(u"Start/Refresh")), |
330 # self._otrStartRefresh, | 330 # self._otr_start_refresh, |
331 # security_limit=0, | 331 # security_limit=0, |
332 # help_string=D_(u"Start or refresh an OTR session"), | 332 # help_string=D_(u"Start or refresh an OTR session"), |
333 # type_=C.MENU_SINGLE, | 333 # type_=C.MENU_SINGLE, |
334 # ) | 334 # ) |
335 # host.importMenu( | 335 # host.import_menu( |
336 # (OTR_MENU, D_(u"End session")), | 336 # (OTR_MENU, D_(u"End session")), |
337 # self._otrSessionEnd, | 337 # self._otr_session_end, |
338 # security_limit=0, | 338 # security_limit=0, |
339 # help_string=D_(u"Finish an OTR session"), | 339 # help_string=D_(u"Finish an OTR session"), |
340 # type_=C.MENU_SINGLE, | 340 # type_=C.MENU_SINGLE, |
341 # ) | 341 # ) |
342 # host.importMenu( | 342 # host.import_menu( |
343 # (OTR_MENU, D_(u"Authenticate")), | 343 # (OTR_MENU, D_(u"Authenticate")), |
344 # self._otrAuthenticate, | 344 # self._otr_authenticate, |
345 # security_limit=0, | 345 # security_limit=0, |
346 # help_string=D_(u"Authenticate user/see your fingerprint"), | 346 # help_string=D_(u"Authenticate user/see your fingerprint"), |
347 # type_=C.MENU_SINGLE, | 347 # type_=C.MENU_SINGLE, |
348 # ) | 348 # ) |
349 # host.importMenu( | 349 # host.import_menu( |
350 # (OTR_MENU, D_(u"Drop private key")), | 350 # (OTR_MENU, D_(u"Drop private key")), |
351 # self._dropPrivKey, | 351 # self._drop_priv_key, |
352 # security_limit=0, | 352 # security_limit=0, |
353 # type_=C.MENU_SINGLE, | 353 # type_=C.MENU_SINGLE, |
354 # ) | 354 # ) |
355 host.trigger.add("presence_received", self._presenceReceivedTrigger) | 355 host.trigger.add("presence_received", self._presence_received_trigger) |
356 self.host.registerEncryptionPlugin(self, "OTR", NS_OTR, directed=True) | 356 self.host.register_encryption_plugin(self, "OTR", NS_OTR, directed=True) |
357 | 357 |
358 def _skipOTR(self, profile): | 358 def _skip_otr(self, profile): |
359 """Tell the backend to not handle OTR for this profile. | 359 """Tell the backend to not handle OTR for this profile. |
360 | 360 |
361 @param profile (str): %(doc_profile)s | 361 @param profile (str): %(doc_profile)s |
362 """ | 362 """ |
363 # FIXME: should not be done per profile but per message, using extra data | 363 # FIXME: should not be done per profile but per message, using extra data |
364 # for message received, profile wide hook may be need, but client | 364 # for message received, profile wide hook may be need, but client |
365 # should be used anyway instead of a class attribute | 365 # should be used anyway instead of a class attribute |
366 self.skipped_profiles.add(profile) | 366 self.skipped_profiles.add(profile) |
367 | 367 |
368 @defer.inlineCallbacks | 368 @defer.inlineCallbacks |
369 def profileConnecting(self, client): | 369 def profile_connecting(self, client): |
370 if client.profile in self.skipped_profiles: | 370 if client.profile in self.skipped_profiles: |
371 return | 371 return |
372 ctxMng = client._otr_context_manager = ContextManager(self, client) | 372 ctxMng = client._otr_context_manager = ContextManager(self, client) |
373 client._otr_data = persistent.PersistentBinaryDict(NS_OTR, client.profile) | 373 client._otr_data = persistent.PersistentBinaryDict(NS_OTR, client.profile) |
374 yield client._otr_data.load() | 374 yield client._otr_data.load() |
375 encrypted_priv_key = client._otr_data.get(PRIVATE_KEY, None) | 375 encrypted_priv_key = client._otr_data.get(PRIVATE_KEY, None) |
376 if encrypted_priv_key is not None: | 376 if encrypted_priv_key is not None: |
377 priv_key = self.host.memory.decryptValue( | 377 priv_key = self.host.memory.decrypt_value( |
378 encrypted_priv_key, client.profile | 378 encrypted_priv_key, client.profile |
379 ) | 379 ) |
380 ctxMng.account.privkey = potr.crypt.PK.parsePrivateKey( | 380 ctxMng.account.privkey = potr.crypt.PK.parsePrivateKey( |
381 unhexlify(priv_key.encode('utf-8')) | 381 unhexlify(priv_key.encode('utf-8')) |
382 )[0] | 382 )[0] |
383 else: | 383 else: |
384 ctxMng.account.privkey = None | 384 ctxMng.account.privkey = None |
385 ctxMng.account.loadTrusts() | 385 ctxMng.account.load_trusts() |
386 | 386 |
387 def profileDisconnected(self, client): | 387 def profile_disconnected(self, client): |
388 if client.profile in self.skipped_profiles: | 388 if client.profile in self.skipped_profiles: |
389 self.skipped_profiles.remove(client.profile) | 389 self.skipped_profiles.remove(client.profile) |
390 return | 390 return |
391 for context in list(client._otr_context_manager.contexts.values()): | 391 for context in list(client._otr_context_manager.contexts.values()): |
392 context.disconnect() | 392 context.disconnect() |
393 del client._otr_context_manager | 393 del client._otr_context_manager |
394 | 394 |
395 # encryption plugin methods | 395 # encryption plugin methods |
396 | 396 |
397 def startEncryption(self, client, entity_jid): | 397 def start_encryption(self, client, entity_jid): |
398 self.startRefresh(client, entity_jid) | 398 self.start_refresh(client, entity_jid) |
399 | 399 |
400 def stopEncryption(self, client, entity_jid): | 400 def stop_encryption(self, client, entity_jid): |
401 self.endSession(client, entity_jid) | 401 self.end_session(client, entity_jid) |
402 | 402 |
403 def getTrustUI(self, client, entity_jid): | 403 def get_trust_ui(self, client, entity_jid): |
404 if not entity_jid.resource: | 404 if not entity_jid.resource: |
405 entity_jid.resource = self.host.memory.getMainResource( | 405 entity_jid.resource = self.host.memory.main_resource_get( |
406 client, entity_jid | 406 client, entity_jid |
407 ) # FIXME: temporary and unsecure, must be changed when frontends | 407 ) # FIXME: temporary and unsecure, must be changed when frontends |
408 # are refactored | 408 # are refactored |
409 ctxMng = client._otr_context_manager | 409 ctxMng = client._otr_context_manager |
410 otrctx = ctxMng.getContextForUser(entity_jid) | 410 otrctx = ctxMng.get_context_for_user(entity_jid) |
411 priv_key = ctxMng.account.privkey | 411 priv_key = ctxMng.account.privkey |
412 | 412 |
413 if priv_key is None: | 413 if priv_key is None: |
414 # we have no private key yet | 414 # we have no private key yet |
415 dialog = xml_tools.XMLUI( | 415 dialog = xml_tools.XMLUI( |
442 }, | 442 }, |
443 title=_("Fingerprint"), | 443 title=_("Fingerprint"), |
444 ) | 444 ) |
445 return dialog | 445 return dialog |
446 | 446 |
447 def setTrust(raw_data, profile): | 447 def set_trust(raw_data, profile): |
448 if xml_tools.isXMLUICancelled(raw_data): | 448 if xml_tools.is_xmlui_cancelled(raw_data): |
449 return {} | 449 return {} |
450 # This method is called when authentication form is submited | 450 # This method is called when authentication form is submited |
451 data = xml_tools.XMLUIResult2DataFormResult(raw_data) | 451 data = xml_tools.xmlui_result_2_data_form_result(raw_data) |
452 if data["match"] == "yes": | 452 if data["match"] == "yes": |
453 otrctx.setCurrentTrust(OTR_STATE_TRUSTED) | 453 otrctx.setCurrentTrust(OTR_STATE_TRUSTED) |
454 note_msg = _("Your correspondent {correspondent} is now TRUSTED") | 454 note_msg = _("Your correspondent {correspondent} is now TRUSTED") |
455 self.host.bridge.otrState( | 455 self.host.bridge.otr_state( |
456 OTR_STATE_TRUSTED, entity_jid.full(), client.profile | 456 OTR_STATE_TRUSTED, entity_jid.full(), client.profile |
457 ) | 457 ) |
458 else: | 458 else: |
459 otrctx.setCurrentTrust("") | 459 otrctx.setCurrentTrust("") |
460 note_msg = _("Your correspondent {correspondent} is now UNTRUSTED") | 460 note_msg = _("Your correspondent {correspondent} is now UNTRUSTED") |
461 self.host.bridge.otrState( | 461 self.host.bridge.otr_state( |
462 OTR_STATE_UNTRUSTED, entity_jid.full(), client.profile | 462 OTR_STATE_UNTRUSTED, entity_jid.full(), client.profile |
463 ) | 463 ) |
464 note = xml_tools.XMLUI( | 464 note = xml_tools.XMLUI( |
465 C.XMLUI_DIALOG, | 465 C.XMLUI_DIALOG, |
466 dialog_opt={ | 466 dialog_opt={ |
468 C.XMLUI_DATA_MESS: note_msg.format(correspondent=otrctx.peer), | 468 C.XMLUI_DATA_MESS: note_msg.format(correspondent=otrctx.peer), |
469 }, | 469 }, |
470 ) | 470 ) |
471 return {"xmlui": note.toXml()} | 471 return {"xmlui": note.toXml()} |
472 | 472 |
473 submit_id = self.host.registerCallback(setTrust, with_data=True, one_shot=True) | 473 submit_id = self.host.register_callback(set_trust, with_data=True, one_shot=True) |
474 trusted = otrctx.isTrusted() | 474 trusted = otrctx.is_trusted() |
475 | 475 |
476 xmlui = xml_tools.XMLUI( | 476 xmlui = xml_tools.XMLUI( |
477 C.XMLUI_FORM, | 477 C.XMLUI_FORM, |
478 title=_("Authentication ({entity_jid})").format(entity_jid=entity_jid.full()), | 478 title=_("Authentication ({entity_jid})").format(entity_jid=entity_jid.full()), |
479 submit_id=submit_id, | 479 submit_id=submit_id, |
487 D_("Your correspondent fingerprint should be:\n{fingerprint}").format( | 487 D_("Your correspondent fingerprint should be:\n{fingerprint}").format( |
488 fingerprint=other_fingerprint | 488 fingerprint=other_fingerprint |
489 ) | 489 ) |
490 ) | 490 ) |
491 xmlui.addDivider("blank") | 491 xmlui.addDivider("blank") |
492 xmlui.changeContainer("pairs") | 492 xmlui.change_container("pairs") |
493 xmlui.addLabel(D_("Is your correspondent fingerprint the same as here ?")) | 493 xmlui.addLabel(D_("Is your correspondent fingerprint the same as here ?")) |
494 xmlui.addList( | 494 xmlui.addList( |
495 "match", [("yes", _("yes")), ("no", _("no"))], ["yes" if trusted else "no"] | 495 "match", [("yes", _("yes")), ("no", _("no"))], ["yes" if trusted else "no"] |
496 ) | 496 ) |
497 return xmlui | 497 return xmlui |
498 | 498 |
499 def _otrStartRefresh(self, menu_data, profile): | 499 def _otr_start_refresh(self, menu_data, profile): |
500 """Start or refresh an OTR session | 500 """Start or refresh an OTR session |
501 | 501 |
502 @param menu_data: %(menu_data)s | 502 @param menu_data: %(menu_data)s |
503 @param profile: %(doc_profile)s | 503 @param profile: %(doc_profile)s |
504 """ | 504 """ |
505 client = self.host.getClient(profile) | 505 client = self.host.get_client(profile) |
506 try: | 506 try: |
507 to_jid = jid.JID(menu_data["jid"]) | 507 to_jid = jid.JID(menu_data["jid"]) |
508 except KeyError: | 508 except KeyError: |
509 log.error(_("jid key is not present !")) | 509 log.error(_("jid key is not present !")) |
510 return defer.fail(exceptions.DataError) | 510 return defer.fail(exceptions.DataError) |
511 self.startRefresh(client, to_jid) | 511 self.start_refresh(client, to_jid) |
512 return {} | 512 return {} |
513 | 513 |
514 def startRefresh(self, client, to_jid): | 514 def start_refresh(self, client, to_jid): |
515 """Start or refresh an OTR session | 515 """Start or refresh an OTR session |
516 | 516 |
517 @param to_jid(jid.JID): jid to start encrypted session with | 517 @param to_jid(jid.JID): jid to start encrypted session with |
518 """ | 518 """ |
519 encrypted_session = client.encryption.getSession(to_jid.userhostJID()) | 519 encrypted_session = client.encryption.getSession(to_jid.userhostJID()) |
520 if encrypted_session and encrypted_session['plugin'].namespace != NS_OTR: | 520 if encrypted_session and encrypted_session['plugin'].namespace != NS_OTR: |
521 raise exceptions.ConflictError(_( | 521 raise exceptions.ConflictError(_( |
522 "Can't start an OTR session, there is already an encrypted session " | 522 "Can't start an OTR session, there is already an encrypted session " |
523 "with {name}").format(name=encrypted_session['plugin'].name)) | 523 "with {name}").format(name=encrypted_session['plugin'].name)) |
524 if not to_jid.resource: | 524 if not to_jid.resource: |
525 to_jid.resource = self.host.memory.getMainResource( | 525 to_jid.resource = self.host.memory.main_resource_get( |
526 client, to_jid | 526 client, to_jid |
527 ) # FIXME: temporary and unsecure, must be changed when frontends | 527 ) # FIXME: temporary and unsecure, must be changed when frontends |
528 # are refactored | 528 # are refactored |
529 otrctx = client._otr_context_manager.getContextForUser(to_jid) | 529 otrctx = client._otr_context_manager.get_context_for_user(to_jid) |
530 query = otrctx.sendMessage(0, b"?OTRv?") | 530 query = otrctx.sendMessage(0, b"?OTRv?") |
531 otrctx.inject(query) | 531 otrctx.inject(query) |
532 | 532 |
533 def _otrSessionEnd(self, menu_data, profile): | 533 def _otr_session_end(self, menu_data, profile): |
534 """End an OTR session | 534 """End an OTR session |
535 | 535 |
536 @param menu_data: %(menu_data)s | 536 @param menu_data: %(menu_data)s |
537 @param profile: %(doc_profile)s | 537 @param profile: %(doc_profile)s |
538 """ | 538 """ |
539 client = self.host.getClient(profile) | 539 client = self.host.get_client(profile) |
540 try: | 540 try: |
541 to_jid = jid.JID(menu_data["jid"]) | 541 to_jid = jid.JID(menu_data["jid"]) |
542 except KeyError: | 542 except KeyError: |
543 log.error(_("jid key is not present !")) | 543 log.error(_("jid key is not present !")) |
544 return defer.fail(exceptions.DataError) | 544 return defer.fail(exceptions.DataError) |
545 self.endSession(client, to_jid) | 545 self.end_session(client, to_jid) |
546 return {} | 546 return {} |
547 | 547 |
548 def endSession(self, client, to_jid): | 548 def end_session(self, client, to_jid): |
549 """End an OTR session""" | 549 """End an OTR session""" |
550 if not to_jid.resource: | 550 if not to_jid.resource: |
551 to_jid.resource = self.host.memory.getMainResource( | 551 to_jid.resource = self.host.memory.main_resource_get( |
552 client, to_jid | 552 client, to_jid |
553 ) # FIXME: temporary and unsecure, must be changed when frontends | 553 ) # FIXME: temporary and unsecure, must be changed when frontends |
554 # are refactored | 554 # are refactored |
555 otrctx = client._otr_context_manager.getContextForUser(to_jid) | 555 otrctx = client._otr_context_manager.get_context_for_user(to_jid) |
556 otrctx.disconnect() | 556 otrctx.disconnect() |
557 return {} | 557 return {} |
558 | 558 |
559 def _otrAuthenticate(self, menu_data, profile): | 559 def _otr_authenticate(self, menu_data, profile): |
560 """End an OTR session | 560 """End an OTR session |
561 | 561 |
562 @param menu_data: %(menu_data)s | 562 @param menu_data: %(menu_data)s |
563 @param profile: %(doc_profile)s | 563 @param profile: %(doc_profile)s |
564 """ | 564 """ |
565 client = self.host.getClient(profile) | 565 client = self.host.get_client(profile) |
566 try: | 566 try: |
567 to_jid = jid.JID(menu_data["jid"]) | 567 to_jid = jid.JID(menu_data["jid"]) |
568 except KeyError: | 568 except KeyError: |
569 log.error(_("jid key is not present !")) | 569 log.error(_("jid key is not present !")) |
570 return defer.fail(exceptions.DataError) | 570 return defer.fail(exceptions.DataError) |
571 return self.authenticate(client, to_jid) | 571 return self.authenticate(client, to_jid) |
572 | 572 |
573 def authenticate(self, client, to_jid): | 573 def authenticate(self, client, to_jid): |
574 """Authenticate other user and see our own fingerprint""" | 574 """Authenticate other user and see our own fingerprint""" |
575 xmlui = self.getTrustUI(client, to_jid) | 575 xmlui = self.get_trust_ui(client, to_jid) |
576 return {"xmlui": xmlui.toXml()} | 576 return {"xmlui": xmlui.toXml()} |
577 | 577 |
578 def _dropPrivKey(self, menu_data, profile): | 578 def _drop_priv_key(self, menu_data, profile): |
579 """Drop our private Key | 579 """Drop our private Key |
580 | 580 |
581 @param menu_data: %(menu_data)s | 581 @param menu_data: %(menu_data)s |
582 @param profile: %(doc_profile)s | 582 @param profile: %(doc_profile)s |
583 """ | 583 """ |
584 client = self.host.getClient(profile) | 584 client = self.host.get_client(profile) |
585 try: | 585 try: |
586 to_jid = jid.JID(menu_data["jid"]) | 586 to_jid = jid.JID(menu_data["jid"]) |
587 if not to_jid.resource: | 587 if not to_jid.resource: |
588 to_jid.resource = self.host.memory.getMainResource( | 588 to_jid.resource = self.host.memory.main_resource_get( |
589 client, to_jid | 589 client, to_jid |
590 ) # FIXME: temporary and unsecure, must be changed when frontends | 590 ) # FIXME: temporary and unsecure, must be changed when frontends |
591 # are refactored | 591 # are refactored |
592 except KeyError: | 592 except KeyError: |
593 log.error(_("jid key is not present !")) | 593 log.error(_("jid key is not present !")) |
597 if ctxMng.account.privkey is None: | 597 if ctxMng.account.privkey is None: |
598 return { | 598 return { |
599 "xmlui": xml_tools.note(_("You don't have a private key yet !")).toXml() | 599 "xmlui": xml_tools.note(_("You don't have a private key yet !")).toXml() |
600 } | 600 } |
601 | 601 |
602 def dropKey(data, profile): | 602 def drop_key(data, profile): |
603 if C.bool(data["answer"]): | 603 if C.bool(data["answer"]): |
604 # we end all sessions | 604 # we end all sessions |
605 for context in list(ctxMng.contexts.values()): | 605 for context in list(ctxMng.contexts.values()): |
606 context.disconnect() | 606 context.disconnect() |
607 ctxMng.account.privkey = None | 607 ctxMng.account.privkey = None |
612 D_("Your private key has been dropped") | 612 D_("Your private key has been dropped") |
613 ).toXml() | 613 ).toXml() |
614 } | 614 } |
615 return {} | 615 return {} |
616 | 616 |
617 submit_id = self.host.registerCallback(dropKey, with_data=True, one_shot=True) | 617 submit_id = self.host.register_callback(drop_key, with_data=True, one_shot=True) |
618 | 618 |
619 confirm = xml_tools.XMLUI( | 619 confirm = xml_tools.XMLUI( |
620 C.XMLUI_DIALOG, | 620 C.XMLUI_DIALOG, |
621 title=_("Confirm private key drop"), | 621 title=_("Confirm private key drop"), |
622 dialog_opt={"type": C.XMLUI_DIALOG_CONFIRM, "message": _(DROP_TXT)}, | 622 dialog_opt={"type": C.XMLUI_DIALOG_CONFIRM, "message": _(DROP_TXT)}, |
623 submit_id=submit_id, | 623 submit_id=submit_id, |
624 ) | 624 ) |
625 return {"xmlui": confirm.toXml()} | 625 return {"xmlui": confirm.toXml()} |
626 | 626 |
627 def _receivedTreatment(self, data, client): | 627 def _received_treatment(self, data, client): |
628 from_jid = data["from"] | 628 from_jid = data["from"] |
629 log.debug("_receivedTreatment [from_jid = %s]" % from_jid) | 629 log.debug("_received_treatment [from_jid = %s]" % from_jid) |
630 otrctx = client._otr_context_manager.getContextForUser(from_jid) | 630 otrctx = client._otr_context_manager.get_context_for_user(from_jid) |
631 | 631 |
632 try: | 632 try: |
633 message = ( | 633 message = ( |
634 next(iter(data["message"].values())) | 634 next(iter(data["message"].values())) |
635 ) # FIXME: Q&D fix for message refactoring, message is now a dict | 635 ) # FIXME: Q&D fix for message refactoring, message is now a dict |
697 else: | 697 else: |
698 raise failure.Failure( | 698 raise failure.Failure( |
699 exceptions.CancelError("Cancelled by OTR") | 699 exceptions.CancelError("Cancelled by OTR") |
700 ) # no message at all (no history, no signal) | 700 ) # no message at all (no history, no signal) |
701 | 701 |
702 client.encryption.markAsEncrypted(data, namespace=NS_OTR) | 702 client.encryption.mark_as_encrypted(data, namespace=NS_OTR) |
703 trusted = otrctx.isTrusted() | 703 trusted = otrctx.is_trusted() |
704 | 704 |
705 if trusted: | 705 if trusted: |
706 client.encryption.markAsTrusted(data) | 706 client.encryption.mark_as_trusted(data) |
707 else: | 707 else: |
708 client.encryption.markAsUntrusted(data) | 708 client.encryption.mark_as_untrusted(data) |
709 | 709 |
710 return data | 710 return data |
711 | 711 |
712 def _receivedTreatmentForSkippedProfiles(self, data): | 712 def _received_treatment_for_skipped_profiles(self, data): |
713 """This profile must be skipped because the frontend manages OTR itself, | 713 """This profile must be skipped because the frontend manages OTR itself, |
714 | 714 |
715 but we still need to check if the message must be stored in history or not | 715 but we still need to check if the message must be stored in history or not |
716 """ | 716 """ |
717 # XXX: FIXME: this should not be done on a per-profile basis, but per-message | 717 # XXX: FIXME: this should not be done on a per-profile basis, but per-message |
729 # if they are used at the same time as Libervia. | 729 # if they are used at the same time as Libervia. |
730 # Hard to avoid with decryption on Libervia though. | 730 # Hard to avoid with decryption on Libervia though. |
731 data["history"] = C.HISTORY_SKIP | 731 data["history"] = C.HISTORY_SKIP |
732 return data | 732 return data |
733 | 733 |
734 def messageReceivedTrigger(self, client, message_elt, post_treat): | 734 def message_received_trigger(self, client, message_elt, post_treat): |
735 if client.is_component: | 735 if client.is_component: |
736 return True | 736 return True |
737 if message_elt.getAttribute("type") == C.MESS_TYPE_GROUPCHAT: | 737 if message_elt.getAttribute("type") == C.MESS_TYPE_GROUPCHAT: |
738 # OTR is not possible in group chats | 738 # OTR is not possible in group chats |
739 return True | 739 return True |
740 from_jid = jid.JID(message_elt['from']) | 740 from_jid = jid.JID(message_elt['from']) |
741 if not from_jid.resource or from_jid.userhostJID() == client.jid.userhostJID(): | 741 if not from_jid.resource or from_jid.userhostJID() == client.jid.userhostJID(): |
742 # OTR is only usable when resources are present | 742 # OTR is only usable when resources are present |
743 return True | 743 return True |
744 if client.profile in self.skipped_profiles: | 744 if client.profile in self.skipped_profiles: |
745 post_treat.addCallback(self._receivedTreatmentForSkippedProfiles) | 745 post_treat.addCallback(self._received_treatment_for_skipped_profiles) |
746 else: | 746 else: |
747 post_treat.addCallback(self._receivedTreatment, client) | 747 post_treat.addCallback(self._received_treatment, client) |
748 return True | 748 return True |
749 | 749 |
750 def _sendMessageDataTrigger(self, client, mess_data): | 750 def _send_message_data_trigger(self, client, mess_data): |
751 if client.is_component: | 751 if client.is_component: |
752 return True | 752 return True |
753 encryption = mess_data.get(C.MESS_KEY_ENCRYPTION) | 753 encryption = mess_data.get(C.MESS_KEY_ENCRYPTION) |
754 if encryption is None or encryption['plugin'].namespace != NS_OTR: | 754 if encryption is None or encryption['plugin'].namespace != NS_OTR: |
755 return | 755 return |
756 to_jid = mess_data['to'] | 756 to_jid = mess_data['to'] |
757 if not to_jid.resource: | 757 if not to_jid.resource: |
758 to_jid.resource = self.host.memory.getMainResource( | 758 to_jid.resource = self.host.memory.main_resource_get( |
759 client, to_jid | 759 client, to_jid |
760 ) # FIXME: temporary and unsecure, must be changed when frontends | 760 ) # FIXME: temporary and unsecure, must be changed when frontends |
761 otrctx = client._otr_context_manager.getContextForUser(to_jid) | 761 otrctx = client._otr_context_manager.get_context_for_user(to_jid) |
762 message_elt = mess_data["xml"] | 762 message_elt = mess_data["xml"] |
763 if otrctx.state == potr.context.STATE_ENCRYPTED: | 763 if otrctx.state == potr.context.STATE_ENCRYPTED: |
764 log.debug("encrypting message") | 764 log.debug("encrypting message") |
765 body = None | 765 body = None |
766 for child in list(message_elt.children): | 766 for child in list(message_elt.children): |
774 # we don't want any XHTML-IM element | 774 # we don't want any XHTML-IM element |
775 message_elt.children.remove(child) | 775 message_elt.children.remove(child) |
776 if body is None: | 776 if body is None: |
777 log.warning("No message found") | 777 log.warning("No message found") |
778 else: | 778 else: |
779 self._p_carbons.setPrivate(message_elt) | 779 self._p_carbons.set_private(message_elt) |
780 self._p_hints.addHintElements(message_elt, [ | 780 self._p_hints.add_hint_elements(message_elt, [ |
781 self._p_hints.HINT_NO_COPY, | 781 self._p_hints.HINT_NO_COPY, |
782 self._p_hints.HINT_NO_PERMANENT_STORE]) | 782 self._p_hints.HINT_NO_PERMANENT_STORE]) |
783 otrctx.sendMessage(0, str(body).encode("utf-8"), appdata=mess_data) | 783 otrctx.sendMessage(0, str(body).encode("utf-8"), appdata=mess_data) |
784 else: | 784 else: |
785 feedback = D_( | 785 feedback = D_( |
789 ) | 789 ) |
790 log.warning(_("Message discarded because closed encryption channel")) | 790 log.warning(_("Message discarded because closed encryption channel")) |
791 client.feedback(to_jid, feedback) | 791 client.feedback(to_jid, feedback) |
792 raise failure.Failure(exceptions.CancelError("Cancelled by OTR plugin")) | 792 raise failure.Failure(exceptions.CancelError("Cancelled by OTR plugin")) |
793 | 793 |
794 def sendMessageTrigger(self, client, mess_data, pre_xml_treatments, | 794 def send_message_trigger(self, client, mess_data, pre_xml_treatments, |
795 post_xml_treatments): | 795 post_xml_treatments): |
796 if client.is_component: | 796 if client.is_component: |
797 return True | 797 return True |
798 if mess_data["type"] == "groupchat": | 798 if mess_data["type"] == "groupchat": |
799 return True | 799 return True |
806 if client.encryption.getSession(to_jid.userhostJID()): | 806 if client.encryption.getSession(to_jid.userhostJID()): |
807 # there is already an encrypted session with this entity | 807 # there is already an encrypted session with this entity |
808 return True | 808 return True |
809 | 809 |
810 if not to_jid.resource: | 810 if not to_jid.resource: |
811 to_jid.resource = self.host.memory.getMainResource( | 811 to_jid.resource = self.host.memory.main_resource_get( |
812 client, to_jid | 812 client, to_jid |
813 ) # FIXME: full jid may not be known | 813 ) # FIXME: full jid may not be known |
814 | 814 |
815 otrctx = client._otr_context_manager.getContextForUser(to_jid) | 815 otrctx = client._otr_context_manager.get_context_for_user(to_jid) |
816 | 816 |
817 if otrctx.state != potr.context.STATE_PLAINTEXT: | 817 if otrctx.state != potr.context.STATE_PLAINTEXT: |
818 defer.ensureDeferred(client.encryption.start(to_jid, NS_OTR)) | 818 defer.ensureDeferred(client.encryption.start(to_jid, NS_OTR)) |
819 client.encryption.setEncryptionFlag(mess_data) | 819 client.encryption.set_encryption_flag(mess_data) |
820 if not mess_data["to"].resource: | 820 if not mess_data["to"].resource: |
821 # if not resource was given, we force it here | 821 # if not resource was given, we force it here |
822 mess_data["to"] = to_jid | 822 mess_data["to"] = to_jid |
823 return True | 823 return True |
824 | 824 |
825 def _presenceReceivedTrigger(self, client, entity, show, priority, statuses): | 825 def _presence_received_trigger(self, client, entity, show, priority, statuses): |
826 if show != C.PRESENCE_UNAVAILABLE: | 826 if show != C.PRESENCE_UNAVAILABLE: |
827 return True | 827 return True |
828 if not entity.resource: | 828 if not entity.resource: |
829 try: | 829 try: |
830 entity.resource = self.host.memory.getMainResource( | 830 entity.resource = self.host.memory.main_resource_get( |
831 client, entity | 831 client, entity |
832 ) # FIXME: temporary and unsecure, must be changed when frontends | 832 ) # FIXME: temporary and unsecure, must be changed when frontends |
833 # are refactored | 833 # are refactored |
834 except exceptions.UnknownEntityError: | 834 except exceptions.UnknownEntityError: |
835 return True # entity was not connected | 835 return True # entity was not connected |
836 if entity in client._otr_context_manager.contexts: | 836 if entity in client._otr_context_manager.contexts: |
837 otrctx = client._otr_context_manager.getContextForUser(entity) | 837 otrctx = client._otr_context_manager.get_context_for_user(entity) |
838 otrctx.disconnect() | 838 otrctx.disconnect() |
839 return True | 839 return True |