feat(sdk): Retry event decryption on forwarded room keys

This commit is contained in:
Jonas Platte
2022-12-21 21:52:16 +01:00
committed by Jonas Platte
parent 3a715ea822
commit 9bad6faedd
2 changed files with 72 additions and 30 deletions

View File

@@ -54,7 +54,10 @@ pub use self::{
},
virtual_item::VirtualTimelineItem,
};
use self::{inner::TimelineInner, to_device::handle_room_key_event};
use self::{
inner::TimelineInner,
to_device::{handle_forwarded_room_key_event, handle_room_key_event},
};
/// A high-level view into a regular¹ room's contents.
///
@@ -71,6 +74,7 @@ pub struct Timeline {
_fully_read_handler_guard: Option<EventHandlerDropGuard>,
#[cfg(feature = "e2e-encryption")]
_room_key_handler_guard: EventHandlerDropGuard,
_forwarded_room_key_handler_guard: EventHandlerDropGuard,
}
/// Non-signalling parts of `TimelineInner`.
@@ -118,6 +122,14 @@ impl Timeline {
#[cfg(feature = "e2e-encryption")]
let _room_key_handler_guard = room.client.event_handler_drop_guard(room_key_handle);
#[cfg(feature = "e2e-encryption")]
let forwarded_room_key_handle = room.client.add_event_handler(
handle_forwarded_room_key_event(inner.clone(), room.room_id().to_owned()),
);
#[cfg(feature = "e2e-encryption")]
let _forwarded_room_key_handler_guard =
room.client.event_handler_drop_guard(forwarded_room_key_handle);
Timeline {
inner,
room: room.clone(),
@@ -127,6 +139,8 @@ impl Timeline {
_fully_read_handler_guard: None,
#[cfg(feature = "e2e-encryption")]
_room_key_handler_guard,
#[cfg(feature = "e2e-encryption")]
_forwarded_room_key_handler_guard,
}
}

View File

@@ -1,6 +1,9 @@
use std::{iter, sync::Arc};
use ruma::{events::room_key::ToDeviceRoomKeyEvent, OwnedRoomId};
use ruma::{
events::{forwarded_room_key::ToDeviceForwardedRoomKeyEvent, room_key::ToDeviceRoomKeyEvent},
OwnedRoomId,
};
use tracing::{debug_span, error, trace, Instrument};
use super::inner::TimelineInner;
@@ -14,36 +17,61 @@ pub(super) fn handle_room_key_event(
let inner = inner.clone();
let room_id = room_id.clone();
async move {
if event.content.room_id != room_id {
let event_room_id = &event.content.room_id;
let session_id = &event.content.session_id;
trace!(
%event_room_id, timeline_room_id = %room_id, %session_id,
"Received to-device room key event for a different room, ignoring"
);
return;
}
let Some(olm_machine) = client.olm_machine() else {
error!("The olm machine isn't yet available");
return;
};
let event_room_id = event.content.room_id;
let session_id = event.content.session_id;
let Some(own_user_id) = client.user_id() else {
error!("The user's own ID isn't available");
return;
};
inner
.retry_event_decryption(
&room_id,
olm_machine,
iter::once(session_id.as_str()).collect(),
own_user_id,
)
.await;
retry_decryption(client, inner, room_id, event_room_id, session_id).await;
}
.instrument(debug_span!("handle_room_key_event"))
}
}
pub(super) fn handle_forwarded_room_key_event(
inner: Arc<TimelineInner>,
room_id: OwnedRoomId,
) -> impl EventHandler<ToDeviceForwardedRoomKeyEvent, (Client,)> {
move |event: ToDeviceForwardedRoomKeyEvent, client: Client| {
let inner = inner.clone();
let room_id = room_id.clone();
async move {
let event_room_id = event.content.room_id;
let session_id = event.content.session_id;
retry_decryption(client, inner, room_id, event_room_id, session_id).await;
}
.instrument(debug_span!("handle_forwarded_room_key_event"))
}
}
async fn retry_decryption(
client: Client,
inner: Arc<TimelineInner>,
room_id: OwnedRoomId,
event_room_id: OwnedRoomId,
session_id: String,
) {
if event_room_id != room_id {
trace!(
%event_room_id, timeline_room_id = %room_id, %session_id,
"Received to-device room key event for a different room, ignoring"
);
return;
}
let Some(olm_machine) = client.olm_machine() else {
error!("The olm machine isn't yet available");
return;
};
let Some(own_user_id) = client.user_id() else {
error!("The user's own ID isn't available");
return;
};
inner
.retry_event_decryption(
&room_id,
olm_machine,
iter::once(session_id.as_str()).collect(),
own_user_id,
)
.await;
}