buffer: Store undecrytped events so we can try to decrypt them later.

This commit is contained in:
Damir Jelić 2018-11-22 13:52:09 +01:00
parent bdb7f4509e
commit a0199109be
2 changed files with 67 additions and 0 deletions

View file

@ -20,6 +20,7 @@ from __future__ import unicode_literals
import time
from builtins import super
from functools import partial
from collections import deque
from typing import Dict, List, NamedTuple, Optional, Set
from uuid import UUID
@ -816,6 +817,7 @@ class RoomBuffer(object):
self.sent_messages_queue = dict() # type: Dict[UUID, OwnMessage]
self.printed_before_ack_queue = list() # type: List[UUID]
self.undecrypted_events = deque(maxlen=5000)
buffer_name = "{}.{}".format(server_name, room.room_id)
@ -1300,6 +1302,8 @@ class RoomBuffer(object):
self.get_event_tags(event) + [session_id_tag]
)
self.undecrypted_events.append(event)
else:
W.prnt(
"", "Unhandled event of type {}.".format(type(event).__name__)
@ -1384,6 +1388,43 @@ class RoomBuffer(object):
new_tags.append(SCRIPT_NAME + "_id_" + new_message.event_id)
line.tags = new_tags
def replace_undecrypted_line(self, event):
"""Find a undecrypted message in the buffer and replace it with the now
decrypted event."""
# TODO different messages need different formatting
# To implement this, refactor out the different formatting code
# snippets to a Formatter class and reuse them here.
if not isinstance(event, RoomMessageText):
return
def predicate(event_id, line):
event_tag = SCRIPT_NAME + "_id_{}".format(event_id)
if event_tag in line.tags:
return True
return False
lines = self.weechat_buffer.find_lines(
partial(predicate, event.event_id)
)
if not lines:
return
formatted = None
if event.formatted_body:
formatted = Formatted.from_html(event.formatted_body)
data = formatted.to_weechat() if formatted else event.body
# TODO this isn't right if the data has multiple lines, that is
# everything is printed on a signle line and newlines are shown as a
# space.
# Weechat should support deleting lines and printing new ones at an
# arbitrary position.
# To implement this without weechat support either only handle single
# line messages or edit the first line in place, print new ones at the
# bottom and sort the buffer lines.
lines[0].message = data
def old_redacted(self, event):
tags = [
SCRIPT_NAME + "_message",

View file

@ -957,6 +957,28 @@ class MatrixServer(object):
"matrix_load_users_cb", self.name)
self.lazy_load_hook = hook
def decrypt_printed_messages(self, key_event):
"""Decrypt already printed messages and send them to the buffer"""
try:
room_buffer = self.find_room_from_id(key_event.room_id)
except KeyError:
return
decrypted_events = []
for undecrypted_event in room_buffer.undecrypted_events:
if undecrypted_event.session_id != key_event.session_id:
continue
event = self.client.decrypt_event(undecrypted_event)
if event:
decrypted_events.append((undecrypted_event, event))
for event_pair in decrypted_events:
undecrypted_event, event = event_pair
room_buffer.undecrypted_events.remove(undecrypted_event)
room_buffer.replace_undecrypted_line(event)
def _handle_sync(self, response):
# we got the same batch again, nothing to do
if self.next_batch == response.next_batch:
@ -979,6 +1001,10 @@ class MatrixServer(object):
}
W.hook_hsignal_send("matrix_room_key_received", message)
# TODO try to decrypt some cached undecrypted messages with the
# new key
# self.decrypt_printed_messages(event)
# Full sync response handle everything.
if isinstance(response, SyncResponse):
if self.client.should_upload_keys: