diff sat_frontends/quick_frontend/quick_chat.py @ 2664:e35a265ec174

quick frontend (app, chat): encryption handling: - new QuickApp.ENCRYPTION_HANDLERS class attribute, if True (default), encryption handlers are set - encryption plugins are retrieved on startup and cached in QuickApp.encryption_plugins list - QuickChat's encrypted boolean attribute indicate if a session is currently encrypted. This is updated automatically if ENCRYPTION_HANDLERS is set - if ENCRYPTION_HANDLERS is set, messageEncryptionStarted and messageEncryptionStopped are called when suitable.
author Goffi <goffi@goffi.org>
date Sat, 11 Aug 2018 18:24:55 +0200
parents 96911768b0f3
children b4c0a5bec729
line wrap: on
line diff
--- a/sat_frontends/quick_frontend/quick_chat.py	Sat Aug 11 18:24:55 2018 +0200
+++ b/sat_frontends/quick_frontend/quick_chat.py	Sat Aug 11 18:24:55 2018 +0200
@@ -19,14 +19,14 @@
 
 from sat.core.i18n import _
 from sat.core.log import getLogger
-
-log = getLogger(__name__)
+from sat.tools.common import data_format
 from sat.core import exceptions
 from sat_frontends.quick_frontend import quick_widgets
 from sat_frontends.quick_frontend.constants import Const as C
 from collections import OrderedDict
 from sat_frontends.tools import jid
 import time
+log = getLogger(__name__)
 
 try:
     from locale import getlocale
@@ -56,19 +56,8 @@
 class Message(object):
     """Message metadata"""
 
-    def __init__(
-        self,
-        parent,
-        uid,
-        timestamp,
-        from_jid,
-        to_jid,
-        msg,
-        subject,
-        type_,
-        extra,
-        profile,
-    ):
+    def __init__(self, parent, uid, timestamp, from_jid, to_jid, msg, subject, type_,
+                 extra, profile):
         self.parent = parent
         self.profile = profile
         self.uid = uid
@@ -269,18 +258,11 @@
 class QuickChat(quick_widgets.QuickWidget):
     visible_states = ["chat_state"]  # FIXME: to be removed, used only in quick_games
 
-    def __init__(
-        self,
-        host,
-        target,
-        type_=C.CHAT_ONE2ONE,
-        nick=None,
-        occupants=None,
-        subject=None,
-        profiles=None,
-    ):
+    def __init__(self, host, target, type_=C.CHAT_ONE2ONE, nick=None, occupants=None,
+                 subject=None, profiles=None):
         """
-        @param type_: can be C.CHAT_ONE2ONE for single conversation or C.CHAT_GROUP for chat à la IRC
+        @param type_: can be C.CHAT_ONE2ONE for single conversation or C.CHAT_GROUP for
+                      chat à la IRC
         """
         self.lang = ""  # default language to use for messages
         quick_widgets.QuickWidget.__init__(self, host, target, profiles=profiles)
@@ -290,6 +272,7 @@
         assert type_ in (C.CHAT_ONE2ONE, C.CHAT_GROUP)
         self.current_target = target
         self.type = type_
+        self.encrypted = False  # True if this session is currently encrypted
         if type_ == C.CHAT_GROUP:
             if target.resource:
                 raise exceptions.InternalError(
@@ -332,6 +315,8 @@
         self.historyPrint(profile=self.profile)
         if self.subject is not None:
             self.setSubject(self.subject)
+        if self.host.ENCRYPTION_HANDLERS:
+            self.getEncryptionState()
 
     def onDelete(self):
         if self.host.AVATARS_HANDLER:
@@ -565,9 +550,27 @@
             errback=_historyGetEb,
         )
 
-    def messageNew(
-        self, uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile
-    ):
+    def messageEncryptionGetCb(self, session_data):
+        if session_data:
+            session_data = data_format.deserialise(session_data)
+            self.messageEncryptionStarted(session_data)
+
+    def messageEncryptionGetEb(self, failure_):
+        log.error(_(u"Can't get encryption state: {reason}").format(reason=failure_))
+
+    def getEncryptionState(self):
+        """Retrieve encryption state with current target.
+
+        Once state is retrieved, default messageEncryptionStarted will be called if
+        suitable
+        """
+        self.host.bridge.messageEncryptionGet(self.target, self.profile,
+                                              callback=self.messageEncryptionGetCb,
+                                              errback=self.messageEncryptionGetEb)
+
+
+    def messageNew(self, uid, timestamp, from_jid, to_jid, msg, subject, type_, extra,
+                   profile):
         if self._locked:
             self._cache[uid] = (
                 uid,
@@ -583,7 +586,8 @@
             return
         if self.type == C.CHAT_GROUP:
             if to_jid.resource and type_ != C.MESS_TYPE_GROUPCHAT:
-                # we have a private message, we forward it to a private conversation widget
+                # we have a private message, we forward it to a private conversation
+                # widget
                 chat_widget = self.getOrCreatePrivateWidget(to_jid)
                 chat_widget.messageNew(
                     uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile
@@ -612,6 +616,16 @@
             log.warning(u"Delayed message received after history, this should not happen")
         self.createMessage(message)
 
+    def messageEncryptionStarted(self, session_data):
+        self.encrypted = True
+        log.debug(_(u"message encryption started with {target} using {encryption}").format(
+            target=self.target, encryption=session_data[u'name']))
+
+    def messageEncryptionStopped(self, session_data):
+        self.encrypted = False
+        log.debug(_(u"message encryption stopped with {target} (was using {encryption})")
+                 .format(target=self.target, encryption=session_data[u'name']))
+
     def createMessage(self, message, append=False):
         """Must be implemented by frontend to create and show a new message widget