Mercurial > libervia-backend
comparison 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 |
comparison
equal
deleted
inserted
replaced
2739:e8dc00f612fb | 2740:8fd8ce5a5855 |
---|---|
31 | 31 |
32 | 32 |
33 class Send(base.CommandBase): | 33 class Send(base.CommandBase): |
34 def __init__(self, host): | 34 def __init__(self, host): |
35 super(Send, self).__init__(host, "send", help=_("send a message to a contact")) | 35 super(Send, self).__init__(host, "send", help=_("send a message to a contact")) |
36 self.need_loop=True | |
36 | 37 |
37 def add_parser_options(self): | 38 def add_parser_options(self): |
38 self.parser.add_argument( | 39 self.parser.add_argument( |
39 "-l", "--lang", type=str, default="", help=_(u"language of the message") | 40 "-l", "--lang", type=str, default="", help=_(u"language of the message") |
40 ) | 41 ) |
69 "--type", | 70 "--type", |
70 choices=C.MESS_TYPE_STANDARD + (C.MESS_TYPE_AUTO,), | 71 choices=C.MESS_TYPE_STANDARD + (C.MESS_TYPE_AUTO,), |
71 default=C.MESS_TYPE_AUTO, | 72 default=C.MESS_TYPE_AUTO, |
72 help=_("type of the message"), | 73 help=_("type of the message"), |
73 ) | 74 ) |
75 self.parser.add_argument("-e", "--encrypt", metavar="ALGORITHM", | |
76 help=_(u"encrypt message using given algorithm")) | |
77 self.parser.add_argument( | |
78 "--encrypt-noreplace", | |
79 action="store_true", | |
80 help=_(u"don't replace encryption algorithm if an other one is already used")) | |
74 syntax = self.parser.add_mutually_exclusive_group() | 81 syntax = self.parser.add_mutually_exclusive_group() |
75 syntax.add_argument("-x", "--xhtml", action="store_true", help=_(u"XHTML body")) | 82 syntax.add_argument("-x", "--xhtml", action="store_true", help=_(u"XHTML body")) |
76 syntax.add_argument("-r", "--rich", action="store_true", help=_(u"rich body")) | 83 syntax.add_argument("-r", "--rich", action="store_true", help=_(u"rich body")) |
77 self.parser.add_argument( | 84 self.parser.add_argument( |
78 "jid", type=base.unicode_decoder, help=_(u"the destination jid") | 85 "jid", type=base.unicode_decoder, help=_(u"the destination jid") |
79 ) | 86 ) |
80 | 87 |
81 def start(self): | 88 def multi_send_cb(self): |
82 if self.args.xhtml and self.args.separate: | 89 self.sent += 1 |
83 self.disp( | 90 if self.sent == self.to_send: |
84 u"argument -s/--separate is not compatible yet with argument -x/--xhtml", | 91 self.host.quit(self.errcode) |
85 error=True, | 92 |
86 ) | 93 def multi_send_eb(self, failure_, msg): |
87 self.host.quit(2) | 94 self.disp(_(u"Can't send message [{msg}]: {reason}").format( |
88 | 95 msg=msg, reason=failure_)) |
89 jids = self.host.check_jids([self.args.jid]) | 96 self.errcode = C.EXIT_BRIDGE_ERRBACK |
90 jid = jids[0] | 97 self.multi_send_cb() |
91 self.sendStdin(jid) | |
92 | 98 |
93 def sendStdin(self, dest_jid): | 99 def sendStdin(self, dest_jid): |
94 """Send incomming data on stdin to jabber contact | 100 """Send incomming data on stdin to jabber contact |
95 | 101 |
96 @param dest_jid: destination jid | 102 @param dest_jid: destination jid |
111 key = u"{}_{}".format(key, self.args.lang) | 117 key = u"{}_{}".format(key, self.args.lang) |
112 extra[key] = clean_ustr(u"".join(stdin_lines)) | 118 extra[key] = clean_ustr(u"".join(stdin_lines)) |
113 stdin_lines = [] | 119 stdin_lines = [] |
114 | 120 |
115 if self.args.separate: # we send stdin in several messages | 121 if self.args.separate: # we send stdin in several messages |
122 self.to_send = 0 | |
123 self.sent = 0 | |
124 self.errcode = 0 | |
125 | |
116 if header: | 126 if header: |
127 self.to_send += 1 | |
117 self.host.bridge.messageSend( | 128 self.host.bridge.messageSend( |
118 dest_jid, | 129 dest_jid, |
119 {self.args.lang: header}, | 130 {self.args.lang: header}, |
120 subject, | 131 subject, |
121 self.args.type, | 132 self.args.type, |
122 profile_key=self.profile, | 133 profile_key=self.profile, |
123 callback=lambda: None, | 134 callback=lambda: None, |
124 errback=lambda ignore: ignore, | 135 errback=lambda ignore: ignore, |
125 ) | 136 ) |
126 | 137 |
138 self.to_send += len(stdin_lines) | |
127 for line in stdin_lines: | 139 for line in stdin_lines: |
128 self.host.bridge.messageSend( | 140 self.host.bridge.messageSend( |
129 dest_jid, | 141 dest_jid, |
130 {self.args.lang: line.replace("\n", "")}, | 142 {self.args.lang: line.replace("\n", "")}, |
131 subject, | 143 subject, |
132 self.args.type, | 144 self.args.type, |
133 extra, | 145 extra, |
134 profile_key=self.host.profile, | 146 profile_key=self.host.profile, |
135 callback=lambda: None, | 147 callback=self.multi_send_cb, |
136 errback=lambda ignore: ignore, | 148 errback=partial(self.multi_send_eb, msg=line), |
137 ) | 149 ) |
138 | 150 |
139 else: | 151 else: |
140 msg = ( | 152 msg = ( |
141 {self.args.lang: header + clean_ustr(u"".join(stdin_lines))} | 153 {self.args.lang: header + clean_ustr(u"".join(stdin_lines))} |
147 msg, | 159 msg, |
148 subject, | 160 subject, |
149 self.args.type, | 161 self.args.type, |
150 extra, | 162 extra, |
151 profile_key=self.host.profile, | 163 profile_key=self.host.profile, |
152 callback=lambda: None, | 164 callback=self.host.quit, |
153 errback=lambda ignore: ignore, | 165 errback=partial(self.errback, |
166 msg=_(u"Can't send message: {}"))) | |
167 | |
168 def encryptionNamespaceGetCb(self, namespace, jid_): | |
169 self.host.bridge.messageEncryptionStart( | |
170 jid_, namespace, not self.args.encrypt_noreplace, | |
171 self.profile, | |
172 callback=lambda: self.sendStdin(jid_), | |
173 errback=partial(self.errback, | |
174 msg=_(u"Can't start encryption session: {}"), | |
175 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
176 )) | |
177 | |
178 | |
179 def start(self): | |
180 if self.args.xhtml and self.args.separate: | |
181 self.disp( | |
182 u"argument -s/--separate is not compatible yet with argument -x/--xhtml", | |
183 error=True, | |
154 ) | 184 ) |
185 self.host.quit(2) | |
186 | |
187 jids = self.host.check_jids([self.args.jid]) | |
188 jid_ = jids[0] | |
189 | |
190 if self.args.encrypt_noreplace and self.args.encrypt is None: | |
191 self.parser.error("You need to use --encrypt if you use --encrypt-noreplace") | |
192 | |
193 if self.args.encrypt is not None: | |
194 self.host.bridge.encryptionNamespaceGet(self.args.encrypt, | |
195 callback=partial(self.encryptionNamespaceGetCb, jid_=jid_), | |
196 errback=partial(self.errback, | |
197 msg=_(u"Can't get encryption namespace: {}"), | |
198 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
199 )) | |
200 else: | |
201 self.sendStdin(jid_) | |
155 | 202 |
156 | 203 |
157 class MAM(base.CommandBase): | 204 class MAM(base.CommandBase): |
158 | 205 |
159 def __init__(self, host): | 206 def __init__(self, host): |
214 self.host.bridge.MAMGet( | 261 self.host.bridge.MAMGet( |
215 self.args.service, data_format.serialise(extra), self.profile, | 262 self.args.service, data_format.serialise(extra), self.profile, |
216 callback=self._MAMGetCb, errback=self.errback) | 263 callback=self._MAMGetCb, errback=self.errback) |
217 | 264 |
218 | 265 |
219 class EncryptionAlgorithms(base.CommandBase): | |
220 | |
221 def __init__(self, host): | |
222 extra_outputs = {"default": self.default_output} | |
223 super(EncryptionAlgorithms, self).__init__( | |
224 host, "algorithms", | |
225 use_output=C.OUTPUT_LIST_DICT, | |
226 extra_outputs=extra_outputs, | |
227 use_profile=False, | |
228 help=_("show available encryption algorithms")) | |
229 self.need_loop = True | |
230 | |
231 def add_parser_options(self): | |
232 pass | |
233 | |
234 def encryptionPluginsGetCb(self, plugins): | |
235 self.output(plugins) | |
236 self.host.quit() | |
237 | |
238 def default_output(self, plugins): | |
239 if not plugins: | |
240 self.disp(_(u"No encryption plugin registered!")) | |
241 self.host.quit(C.EXIT_NOT_FOUND) | |
242 else: | |
243 self.disp(_(u"Following encryption algorithms are available: {algos}").format( | |
244 algos=', '.join([p['name'] for p in plugins]))) | |
245 self.host.quit() | |
246 | |
247 def start(self): | |
248 self.host.bridge.encryptionPluginsGet( | |
249 callback=self.encryptionPluginsGetCb, | |
250 errback=partial( | |
251 self.errback, | |
252 msg=_(u"can't retrieve plugins: {}"), | |
253 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
254 ), | |
255 ) | |
256 | |
257 | |
258 class Encryption(base.CommandBase): | |
259 subcommands = (EncryptionAlgorithms,) | |
260 | |
261 def __init__(self, host): | |
262 super(Encryption, self).__init__( | |
263 host, "encryption", use_profile=False, help=_("encryption sessions handling") | |
264 ) | |
265 | |
266 | |
267 class Message(base.CommandBase): | 266 class Message(base.CommandBase): |
268 subcommands = (Send, MAM, Encryption) | 267 subcommands = (Send, MAM) |
269 | 268 |
270 def __init__(self, host): | 269 def __init__(self, host): |
271 super(Message, self).__init__( | 270 super(Message, self).__init__( |
272 host, "message", use_profile=False, help=_("messages handling") | 271 host, "message", use_profile=False, help=_("messages handling") |
273 ) | 272 ) |