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,
This commit is contained in:
Goffi 2019-03-20 09:08:47 +01:00
commit 71144d4581

View file

@ -783,27 +783,28 @@ class OMEMO(object):
## triggers
@defer.inlineCallbacks
def handleProblems(self, client, entity, bundles, problems):
"""Try to solve problem found by EncryptMessage
def handleProblems(self, client, entity, bundles, expect_problems, problems):
"""Try to solve problems found by EncryptMessage
@param entity(jid.JID): bare jid of the destinee
@param bundles(dict): bundles data as used in EncryptMessage
already filled with known bundles, missing bundles
need to be added to it
This dict is updated
@param problems(list): exceptions raised by EncryptMessage
@return (dict): expect_problems arguments, used in EncryptMessage
this dict will list devices where problems can be ignored
@param expect_problems(dict): known problems to expect, used in encryptMessage
This dict will list devices where problems can be ignored
(those devices won't receive the encrypted data)
This dict is updated
"""
# FIXME: not all problems are handled yet
untrusted = {}
missing_bundles = {}
expect_problems = {}
cache = client._xep_0384_cache
for problem in problems:
if isinstance(problem, omemo_excpt.TrustException):
untrusted[unicode(hash(problem))] = problem
if isinstance(problem, omemo_excpt.MissingBundleException):
elif isinstance(problem, omemo_excpt.MissingBundleException):
pb_entity = jid.JID(problem.bare_jid)
entity_cache = cache.setdefault(pb_entity, {})
entity_bundles = bundles.setdefault(pb_entity, {})
@ -819,8 +820,8 @@ class OMEMO(object):
problem.device)
expect_problems.setdefault(problem.bare_jid, set()).add(
problem.device)
elif isinstance(problem, omemo_excpt.NoEligibleDevicesException):
pass
else:
raise problem
for peer_jid, devices in missing_bundles.iteritems():
devices_s = [unicode(d) for d in devices]
@ -859,33 +860,41 @@ class OMEMO(object):
profile=client.profile)
yield self.trustUICb(answer, trust_data, expect_problems, client.profile)
defer.returnValue(expect_problems)
@defer.inlineCallbacks
def encryptMessage(self, client, entity_bare_jid, message):
omemo_session = client._xep_0384_session
expect_problems = {}
bundles = {}
loop_idx = 0
try:
# first try may fail, in case of e.g. trust issue or missing bundle
encrypted = yield omemo_session.encryptMessage(
entity_bare_jid,
message)
except omemo_excpt.EncryptionProblemsException as e:
# we know the problem to solve, we can try to fix them
bundles = {}
expect_problems = yield self.handleProblems(client, entity_bare_jid, bundles,
e.problems)
# and try an encryption again.
try:
encrypted = yield omemo_session.encryptMessage(
entity_bare_jid,
message,
bundles,
expect_problems = expect_problems)
except omemo_excpt.EncryptionProblemsException as e:
log.warning(
_(u"Can't encrypt message for {entity}: {reason}".format(
entity=entity_bare_jid.full(), reason=e)))
raise e
while True:
if loop_idx > 10:
msg = _(u"Too many iterations in encryption loop")
log.error(msg)
raise exceptions.InternalError(msg)
# encryptMessage may fail, in case of e.g. trust issue or missing bundle
try:
encrypted = yield omemo_session.encryptMessage(
entity_bare_jid,
message,
bundles,
expect_problems = expect_problems)
except omemo_excpt.EncryptionProblemsException as e:
# we know the problem to solve, we can try to fix them
yield self.handleProblems(
client,
entity=entity_bare_jid,
bundles=bundles,
expect_problems=expect_problems,
problems=e.problems)
loop_idx += 1
else:
break
except Exception as e:
log.warning(
_(u"Can't encrypt message for {entity}: {reason}".format(
entity=entity_bare_jid.full(), reason=str(e).decode('utf-8', 'replace'))))
raise e
defer.returnValue(encrypted)