diff sat_frontends/jp/cmd_message.py @ 2740:8fd8ce5a5855

jp (message/send, encryption): encryption handling: - encryption algorithm can now be requested when sending a message (using --encrypt option) - new encryption commands to (de)activate encryption session, check available algorithms, or manage trust.
author Goffi <goffi@goffi.org>
date Wed, 02 Jan 2019 18:50:57 +0100
parents 45189c8bd165
children 92af49cde255
line wrap: on
line diff
--- a/sat_frontends/jp/cmd_message.py	Wed Jan 02 18:50:47 2019 +0100
+++ b/sat_frontends/jp/cmd_message.py	Wed Jan 02 18:50:57 2019 +0100
@@ -33,6 +33,7 @@
 class Send(base.CommandBase):
     def __init__(self, host):
         super(Send, self).__init__(host, "send", help=_("send a message to a contact"))
+        self.need_loop=True
 
     def add_parser_options(self):
         self.parser.add_argument(
@@ -71,6 +72,12 @@
             default=C.MESS_TYPE_AUTO,
             help=_("type of the message"),
         )
+        self.parser.add_argument("-e", "--encrypt", metavar="ALGORITHM",
+                                 help=_(u"encrypt message using given algorithm"))
+        self.parser.add_argument(
+            "--encrypt-noreplace",
+            action="store_true",
+            help=_(u"don't replace encryption algorithm if an other one is already used"))
         syntax = self.parser.add_mutually_exclusive_group()
         syntax.add_argument("-x", "--xhtml", action="store_true", help=_(u"XHTML body"))
         syntax.add_argument("-r", "--rich", action="store_true", help=_(u"rich body"))
@@ -78,17 +85,16 @@
             "jid", type=base.unicode_decoder, help=_(u"the destination jid")
         )
 
-    def start(self):
-        if self.args.xhtml and self.args.separate:
-            self.disp(
-                u"argument -s/--separate is not compatible yet with argument -x/--xhtml",
-                error=True,
-            )
-            self.host.quit(2)
+    def multi_send_cb(self):
+        self.sent += 1
+        if self.sent == self.to_send:
+            self.host.quit(self.errcode)
 
-        jids = self.host.check_jids([self.args.jid])
-        jid = jids[0]
-        self.sendStdin(jid)
+    def multi_send_eb(self, failure_, msg):
+        self.disp(_(u"Can't send message [{msg}]: {reason}").format(
+            msg=msg, reason=failure_))
+        self.errcode = C.EXIT_BRIDGE_ERRBACK
+        self.multi_send_cb()
 
     def sendStdin(self, dest_jid):
         """Send incomming data on stdin to jabber contact
@@ -113,7 +119,12 @@
             stdin_lines = []
 
         if self.args.separate:  # we send stdin in several messages
+            self.to_send = 0
+            self.sent = 0
+            self.errcode = 0
+
             if header:
+                self.to_send += 1
                 self.host.bridge.messageSend(
                     dest_jid,
                     {self.args.lang: header},
@@ -124,6 +135,7 @@
                     errback=lambda ignore: ignore,
                 )
 
+            self.to_send += len(stdin_lines)
             for line in stdin_lines:
                 self.host.bridge.messageSend(
                     dest_jid,
@@ -132,8 +144,8 @@
                     self.args.type,
                     extra,
                     profile_key=self.host.profile,
-                    callback=lambda: None,
-                    errback=lambda ignore: ignore,
+                    callback=self.multi_send_cb,
+                    errback=partial(self.multi_send_eb, msg=line),
                 )
 
         else:
@@ -149,9 +161,44 @@
                 self.args.type,
                 extra,
                 profile_key=self.host.profile,
-                callback=lambda: None,
-                errback=lambda ignore: ignore,
+                callback=self.host.quit,
+                errback=partial(self.errback,
+                                msg=_(u"Can't send message: {}")))
+
+    def encryptionNamespaceGetCb(self, namespace, jid_):
+        self.host.bridge.messageEncryptionStart(
+            jid_, namespace, not self.args.encrypt_noreplace,
+            self.profile,
+            callback=lambda: self.sendStdin(jid_),
+            errback=partial(self.errback,
+                            msg=_(u"Can't start encryption session: {}"),
+                            exit_code=C.EXIT_BRIDGE_ERRBACK,
+                            ))
+
+
+    def start(self):
+        if self.args.xhtml and self.args.separate:
+            self.disp(
+                u"argument -s/--separate is not compatible yet with argument -x/--xhtml",
+                error=True,
             )
+            self.host.quit(2)
+
+        jids = self.host.check_jids([self.args.jid])
+        jid_ = jids[0]
+
+        if self.args.encrypt_noreplace and self.args.encrypt is None:
+            self.parser.error("You need to use --encrypt if you use --encrypt-noreplace")
+
+        if self.args.encrypt is not None:
+            self.host.bridge.encryptionNamespaceGet(self.args.encrypt,
+                callback=partial(self.encryptionNamespaceGetCb, jid_=jid_),
+                errback=partial(self.errback,
+                                msg=_(u"Can't get encryption namespace: {}"),
+                                exit_code=C.EXIT_BRIDGE_ERRBACK,
+                                ))
+        else:
+            self.sendStdin(jid_)
 
 
 class MAM(base.CommandBase):
@@ -216,56 +263,8 @@
             callback=self._MAMGetCb, errback=self.errback)
 
 
-class EncryptionAlgorithms(base.CommandBase):
-
-    def __init__(self, host):
-        extra_outputs = {"default": self.default_output}
-        super(EncryptionAlgorithms, self).__init__(
-            host, "algorithms",
-            use_output=C.OUTPUT_LIST_DICT,
-            extra_outputs=extra_outputs,
-            use_profile=False,
-            help=_("show available encryption algorithms"))
-        self.need_loop = True
-
-    def add_parser_options(self):
-        pass
-
-    def encryptionPluginsGetCb(self, plugins):
-        self.output(plugins)
-        self.host.quit()
-
-    def default_output(self, plugins):
-        if not plugins:
-            self.disp(_(u"No encryption plugin registered!"))
-            self.host.quit(C.EXIT_NOT_FOUND)
-        else:
-            self.disp(_(u"Following encryption algorithms are available: {algos}").format(
-                algos=', '.join([p['name'] for p in plugins])))
-            self.host.quit()
-
-    def start(self):
-        self.host.bridge.encryptionPluginsGet(
-            callback=self.encryptionPluginsGetCb,
-            errback=partial(
-                self.errback,
-                msg=_(u"can't retrieve plugins: {}"),
-                exit_code=C.EXIT_BRIDGE_ERRBACK,
-            ),
-        )
-
-
-class Encryption(base.CommandBase):
-    subcommands = (EncryptionAlgorithms,)
-
-    def __init__(self, host):
-        super(Encryption, self).__init__(
-            host, "encryption", use_profile=False, help=_("encryption sessions handling")
-        )
-
-
 class Message(base.CommandBase):
-    subcommands = (Send, MAM, Encryption)
+    subcommands = (Send, MAM)
 
     def __init__(self, host):
         super(Message, self).__init__(