Mercurial > libervia-backend
comparison sat/plugins/plugin_xep_0384.py @ 2858:31a5038cdf79
plugin XEP-0384: small refactoring to encrypt messages + bugfix:
encryptMessage is now called in a loop, because problems may happen by steps (e.g. trust issue after getting missing bundles).
Fixed a mix between "if" and "elif" in problems handling,
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 20 Mar 2019 09:08:47 +0100 |
parents | 88f10630d5ea |
children | 4e875d9eea48 |
comparison
equal
deleted
inserted
replaced
2857:88f10630d5ea | 2858:31a5038cdf79 |
---|---|
781 yield self.setDevices(client, devices) | 781 yield self.setDevices(client, devices) |
782 | 782 |
783 ## triggers | 783 ## triggers |
784 | 784 |
785 @defer.inlineCallbacks | 785 @defer.inlineCallbacks |
786 def handleProblems(self, client, entity, bundles, problems): | 786 def handleProblems(self, client, entity, bundles, expect_problems, problems): |
787 """Try to solve problem found by EncryptMessage | 787 """Try to solve problems found by EncryptMessage |
788 | 788 |
789 @param entity(jid.JID): bare jid of the destinee | 789 @param entity(jid.JID): bare jid of the destinee |
790 @param bundles(dict): bundles data as used in EncryptMessage | 790 @param bundles(dict): bundles data as used in EncryptMessage |
791 already filled with known bundles, missing bundles | 791 already filled with known bundles, missing bundles |
792 need to be added to it | 792 need to be added to it |
793 This dict is updated | |
793 @param problems(list): exceptions raised by EncryptMessage | 794 @param problems(list): exceptions raised by EncryptMessage |
794 @return (dict): expect_problems arguments, used in EncryptMessage | 795 @param expect_problems(dict): known problems to expect, used in encryptMessage |
795 this dict will list devices where problems can be ignored | 796 This dict will list devices where problems can be ignored |
796 (those devices won't receive the encrypted data) | 797 (those devices won't receive the encrypted data) |
798 This dict is updated | |
797 """ | 799 """ |
798 # FIXME: not all problems are handled yet | 800 # FIXME: not all problems are handled yet |
799 untrusted = {} | 801 untrusted = {} |
800 missing_bundles = {} | 802 missing_bundles = {} |
801 expect_problems = {} | |
802 cache = client._xep_0384_cache | 803 cache = client._xep_0384_cache |
803 for problem in problems: | 804 for problem in problems: |
804 if isinstance(problem, omemo_excpt.TrustException): | 805 if isinstance(problem, omemo_excpt.TrustException): |
805 untrusted[unicode(hash(problem))] = problem | 806 untrusted[unicode(hash(problem))] = problem |
806 if isinstance(problem, omemo_excpt.MissingBundleException): | 807 elif isinstance(problem, omemo_excpt.MissingBundleException): |
807 pb_entity = jid.JID(problem.bare_jid) | 808 pb_entity = jid.JID(problem.bare_jid) |
808 entity_cache = cache.setdefault(pb_entity, {}) | 809 entity_cache = cache.setdefault(pb_entity, {}) |
809 entity_bundles = bundles.setdefault(pb_entity, {}) | 810 entity_bundles = bundles.setdefault(pb_entity, {}) |
810 if problem.device in entity_cache: | 811 if problem.device in entity_cache: |
811 entity_bundles[problem.device] = entity_cache[problem.device] | 812 entity_bundles[problem.device] = entity_cache[problem.device] |
817 if problem.device in missing: | 818 if problem.device in missing: |
818 missing_bundles.setdefault(pb_entity, set()).add( | 819 missing_bundles.setdefault(pb_entity, set()).add( |
819 problem.device) | 820 problem.device) |
820 expect_problems.setdefault(problem.bare_jid, set()).add( | 821 expect_problems.setdefault(problem.bare_jid, set()).add( |
821 problem.device) | 822 problem.device) |
822 elif isinstance(problem, omemo_excpt.NoEligibleDevicesException): | 823 else: |
823 pass | 824 raise problem |
824 | 825 |
825 for peer_jid, devices in missing_bundles.iteritems(): | 826 for peer_jid, devices in missing_bundles.iteritems(): |
826 devices_s = [unicode(d) for d in devices] | 827 devices_s = [unicode(d) for d in devices] |
827 log.warning( | 828 log.warning( |
828 _(u"Can't retrieve bundle for device(s) {devices} of entity {peer}, " | 829 _(u"Can't retrieve bundle for device(s) {devices} of entity {peer}, " |
857 u"meta_encryption_trust": NS_OMEMO, | 858 u"meta_encryption_trust": NS_OMEMO, |
858 }, | 859 }, |
859 profile=client.profile) | 860 profile=client.profile) |
860 yield self.trustUICb(answer, trust_data, expect_problems, client.profile) | 861 yield self.trustUICb(answer, trust_data, expect_problems, client.profile) |
861 | 862 |
862 defer.returnValue(expect_problems) | |
863 | |
864 @defer.inlineCallbacks | 863 @defer.inlineCallbacks |
865 def encryptMessage(self, client, entity_bare_jid, message): | 864 def encryptMessage(self, client, entity_bare_jid, message): |
866 omemo_session = client._xep_0384_session | 865 omemo_session = client._xep_0384_session |
866 expect_problems = {} | |
867 bundles = {} | |
868 loop_idx = 0 | |
867 try: | 869 try: |
868 # first try may fail, in case of e.g. trust issue or missing bundle | 870 while True: |
869 encrypted = yield omemo_session.encryptMessage( | 871 if loop_idx > 10: |
870 entity_bare_jid, | 872 msg = _(u"Too many iterations in encryption loop") |
871 message) | 873 log.error(msg) |
872 except omemo_excpt.EncryptionProblemsException as e: | 874 raise exceptions.InternalError(msg) |
873 # we know the problem to solve, we can try to fix them | 875 # encryptMessage may fail, in case of e.g. trust issue or missing bundle |
874 bundles = {} | 876 try: |
875 expect_problems = yield self.handleProblems(client, entity_bare_jid, bundles, | 877 encrypted = yield omemo_session.encryptMessage( |
876 e.problems) | 878 entity_bare_jid, |
877 # and try an encryption again. | 879 message, |
878 try: | 880 bundles, |
879 encrypted = yield omemo_session.encryptMessage( | 881 expect_problems = expect_problems) |
880 entity_bare_jid, | 882 except omemo_excpt.EncryptionProblemsException as e: |
881 message, | 883 # we know the problem to solve, we can try to fix them |
882 bundles, | 884 yield self.handleProblems( |
883 expect_problems = expect_problems) | 885 client, |
884 except omemo_excpt.EncryptionProblemsException as e: | 886 entity=entity_bare_jid, |
885 log.warning( | 887 bundles=bundles, |
886 _(u"Can't encrypt message for {entity}: {reason}".format( | 888 expect_problems=expect_problems, |
887 entity=entity_bare_jid.full(), reason=e))) | 889 problems=e.problems) |
888 raise e | 890 loop_idx += 1 |
891 else: | |
892 break | |
893 except Exception as e: | |
894 log.warning( | |
895 _(u"Can't encrypt message for {entity}: {reason}".format( | |
896 entity=entity_bare_jid.full(), reason=str(e).decode('utf-8', 'replace')))) | |
897 raise e | |
889 | 898 |
890 defer.returnValue(encrypted) | 899 defer.returnValue(encrypted) |
891 | 900 |
892 @defer.inlineCallbacks | 901 @defer.inlineCallbacks |
893 def _messageReceivedTrigger(self, client, message_elt, post_treat): | 902 def _messageReceivedTrigger(self, client, message_elt, post_treat): |