diff --git a/examples/echo_client.py b/examples/echo_client.py index 82ee6f5..f7d422b 100644 --- a/examples/echo_client.py +++ b/examples/echo_client.py @@ -58,7 +58,7 @@ class EchoBot(ClientXMPP): self.send_presence() self.get_roster() - def message(self, msg: Message) -> None: + def message(self, msg: Message, allow_untrusted: bool = False) -> None: """ Process incoming message stanzas. Be aware that this also includes MUC messages and error messages. It is usually @@ -77,58 +77,48 @@ class EchoBot(ClientXMPP): self.plain_reply(msg, 'This message was not encrypted.\n%(body)s' % msg) return None - allow_untrusted = False - while True: - try: - body = self['xep_0384'].decrypt_message( - msg, - allow_untrusted=allow_untrusted, - ) - self.encrypted_reply(msg, 'Thanks for sending\n%s' % body.decode("utf8")) - break - except (MissingOwnKey,): - # The message is missing our own key, it was not encrypted for - # us, and we can't decrypt it. - self.plain_reply( - msg, - 'I can\'t decrypt this message as it is not encrypted for me.', - ) - break - except (NoAvailableSession,) as exn: - # We received a message from that contained a session that we - # don't know about (deleted session storage, etc.). We can't - # decrypt the message, and it's going to be lost. - # Here, as we need to initiate a new encrypted session, it is - # best if we send an encrypted message directly. XXX: Is it - # where we talk about self-healing messages? - self.encrypted_reply( - msg, - 'I can\'t decrypt this message as it uses an encrypted ' - 'session I don\'t know about.', - ) - break - except (UndecidedException, UntrustedException) as exn: - # We received a message from an untrusted device. We can - # choose to decrypt the message nonetheless, with the - # `allow_untrusted` flag on the `decrypt_message` call, which - # we will do here. This is only possible for decryption, - # encryption will require us to decide if we trust the device - # or not. Clients _should_ indicate that the message was not - # trusted, or in undecided state, if they decide to decrypt it - # anyway. - allow_untrusted = True - - self.plain_reply( - msg, - "Your device '%(device)s' is not in my trusted devices." % exn, - ) - # Now we let the loop go on for decrypt_message to run again. - except (EncryptionPrepareException,): - # Slixmpp tried its best, but there were errors it couldn't - # resolve. At this point you should have seen other exceptions - # and given a chance to resolve them already. - self.plain_reply(msg, 'I was not able to decrypt the message.') - break + try: + body = self['xep_0384'].decrypt_message(msg, allow_untrusted) + self.encrypted_reply(msg, 'Thanks for sending\n%s' % body.decode("utf8")) + except (MissingOwnKey,): + # The message is missing our own key, it was not encrypted for + # us, and we can't decrypt it. + self.plain_reply( + msg, + 'I can\'t decrypt this message as it is not encrypted for me.', + ) + except (NoAvailableSession,) as exn: + # We received a message from that contained a session that we + # don't know about (deleted session storage, etc.). We can't + # decrypt the message, and it's going to be lost. + # Here, as we need to initiate a new encrypted session, it is + # best if we send an encrypted message directly. XXX: Is it + # where we talk about self-healing messages? + self.encrypted_reply( + msg, + 'I can\'t decrypt this message as it uses an encrypted ' + 'session I don\'t know about.', + ) + except (UndecidedException, UntrustedException) as exn: + # We received a message from an untrusted device. We can + # choose to decrypt the message nonetheless, with the + # `allow_untrusted` flag on the `decrypt_message` call, which + # we will do here. This is only possible for decryption, + # encryption will require us to decide if we trust the device + # or not. Clients _should_ indicate that the message was not + # trusted, or in undecided state, if they decide to decrypt it + # anyway. + self.plain_reply( + msg, + "Your device '%s' is not in my trusted devices." % exn.device, + ) + # We resend, setting the `allow_untrusted` parameter to True. + self.message(msg, allow_untrusted=True) + except (EncryptionPrepareException,): + # Slixmpp tried its best, but there were errors it couldn't + # resolve. At this point you should have seen other exceptions + # and given a chance to resolve them already. + self.plain_reply(msg, 'I was not able to decrypt the message.') return None @@ -143,8 +133,11 @@ class EchoBot(ClientXMPP): msg['body'] = body msg.send() - def encrypted_reply(self, msg, body) -> None: - pass + def encrypted_reply(self, original_msg, body) -> None: + """Helper to reply with encrypted messages""" + + # TODO: Send the message encrypted. + self.plain_reply(msg, body) if __name__ == '__main__':