buffer: Store undecrytped events so we can try to decrypt them later.
This commit is contained in:
parent
bdb7f4509e
commit
a0199109be
2 changed files with 67 additions and 0 deletions
|
@ -20,6 +20,7 @@ from __future__ import unicode_literals
|
||||||
import time
|
import time
|
||||||
from builtins import super
|
from builtins import super
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
from collections import deque
|
||||||
from typing import Dict, List, NamedTuple, Optional, Set
|
from typing import Dict, List, NamedTuple, Optional, Set
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
|
@ -816,6 +817,7 @@ class RoomBuffer(object):
|
||||||
|
|
||||||
self.sent_messages_queue = dict() # type: Dict[UUID, OwnMessage]
|
self.sent_messages_queue = dict() # type: Dict[UUID, OwnMessage]
|
||||||
self.printed_before_ack_queue = list() # type: List[UUID]
|
self.printed_before_ack_queue = list() # type: List[UUID]
|
||||||
|
self.undecrypted_events = deque(maxlen=5000)
|
||||||
|
|
||||||
buffer_name = "{}.{}".format(server_name, room.room_id)
|
buffer_name = "{}.{}".format(server_name, room.room_id)
|
||||||
|
|
||||||
|
@ -1300,6 +1302,8 @@ class RoomBuffer(object):
|
||||||
self.get_event_tags(event) + [session_id_tag]
|
self.get_event_tags(event) + [session_id_tag]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.undecrypted_events.append(event)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
W.prnt(
|
W.prnt(
|
||||||
"", "Unhandled event of type {}.".format(type(event).__name__)
|
"", "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)
|
new_tags.append(SCRIPT_NAME + "_id_" + new_message.event_id)
|
||||||
line.tags = new_tags
|
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):
|
def old_redacted(self, event):
|
||||||
tags = [
|
tags = [
|
||||||
SCRIPT_NAME + "_message",
|
SCRIPT_NAME + "_message",
|
||||||
|
|
|
@ -957,6 +957,28 @@ class MatrixServer(object):
|
||||||
"matrix_load_users_cb", self.name)
|
"matrix_load_users_cb", self.name)
|
||||||
self.lazy_load_hook = hook
|
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):
|
def _handle_sync(self, response):
|
||||||
# we got the same batch again, nothing to do
|
# we got the same batch again, nothing to do
|
||||||
if self.next_batch == response.next_batch:
|
if self.next_batch == response.next_batch:
|
||||||
|
@ -979,6 +1001,10 @@ class MatrixServer(object):
|
||||||
}
|
}
|
||||||
W.hook_hsignal_send("matrix_room_key_received", message)
|
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.
|
# Full sync response handle everything.
|
||||||
if isinstance(response, SyncResponse):
|
if isinstance(response, SyncResponse):
|
||||||
if self.client.should_upload_keys:
|
if self.client.should_upload_keys:
|
||||||
|
|
Loading…
Add table
Reference in a new issue