Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retry the decryption of events in the timeline if backups were enabled #3964

Merged
merged 7 commits into from
Sep 9, 2024
40 changes: 40 additions & 0 deletions crates/matrix-sdk-ui/src/timeline/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::{collections::BTreeSet, sync::Arc};

use futures_util::{pin_mut, StreamExt};
use matrix_sdk::{
encryption::backups::BackupState,
event_cache::{EventsOrigin, RoomEventCacheUpdate},
executor::spawn,
Room,
Expand Down Expand Up @@ -370,6 +371,44 @@ impl TimelineBuilder {
})
};

let room_key_backup_enabled_join_handle = {
let inner = controller.clone();
let stream = client.encryption().backups().state_stream();

spawn(async move {
pin_mut!(stream);

while let Some(update) = stream.next().await {
match update {
// If the backup got enabled, or we lagged and thus missed that the backup
// might be enabled, retry to decrypt all the events. Please note, depending
// on the backup download strategy, this might do two things under the
// assumption that the backup contains the relevant room keys:
//
// 1. It will decrypt the events, if `BackupDownloadStrategy` has been set
// to `OneShot`.
// 2. It will fail to decrypt the event, but try to download the room key to
// decrypt it if the `BackupDownloadStrategy` has been set to
// `AfterDecryptionFailure`.
Ok(BackupState::Enabled) | Err(_) => {
let room = inner.room();
inner.retry_event_decryption(room, None).await;
}
// The other states aren't interesting since they are either still enabling
// the backup or have the backup in the disabled state.
Ok(
BackupState::Unknown
| BackupState::Creating
| BackupState::Resuming
| BackupState::Disabling
| BackupState::Downloading
| BackupState::Enabling,
) => (),
}
}
})
};

let timeline = Timeline {
controller,
event_cache: room_event_cache,
Expand All @@ -379,6 +418,7 @@ impl TimelineBuilder {
room_update_join_handle,
pinned_events_join_handle,
room_key_from_backups_join_handle,
room_key_backup_enabled_join_handle,
local_echo_listener_handle,
_event_cache_drop_handle: event_cache_drop,
}),
Expand Down
4 changes: 4 additions & 0 deletions crates/matrix-sdk-ui/src/timeline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ struct TimelineDropHandle {
room_update_join_handle: JoinHandle<()>,
pinned_events_join_handle: Option<JoinHandle<()>>,
room_key_from_backups_join_handle: JoinHandle<()>,
room_key_backup_enabled_join_handle: JoinHandle<()>,
local_echo_listener_handle: JoinHandle<()>,
_event_cache_drop_handle: Arc<EventCacheDropHandles>,
}
Expand All @@ -860,12 +861,15 @@ impl Drop for TimelineDropHandle {
for handle in self.event_handler_handles.drain(..) {
self.client.remove_event_handler(handle);
}

if let Some(handle) = self.pinned_events_join_handle.take() {
handle.abort()
};

self.local_echo_listener_handle.abort();
self.room_update_join_handle.abort();
self.room_key_from_backups_join_handle.abort();
self.room_key_backup_enabled_join_handle.abort();
}
}

Expand Down
8 changes: 8 additions & 0 deletions crates/matrix-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ Additions:
- WidgetDriver: Support the `"delay"` field in the `send_event` widget actions.
This allows to send delayed events, as defined in [MSC4157](https://github.com/matrix-org/matrix-spec-proposals/pull/4157)

Bug fixes:

- Fix a bug where room keys were considered to be downloaded before backups were
enabled. This bug only affects the
`BackupDownloadStrategy::AfterDecryptionFailure`, where no attempt would be
made to download a room key, if a decryption failure with a given room key
would have been encountered before the backups were enabled.

# 0.7.0

Breaking changes:
Expand Down
19 changes: 16 additions & 3 deletions crates/matrix-sdk/src/encryption/backups/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,16 @@ impl Backups {
}

/// Download a single room key from the server-side key backup.
pub async fn download_room_key(&self, room_id: &RoomId, session_id: &str) -> Result<(), Error> {
///
/// Returns `true` if we managed to download a room key, `false` or an error
/// if we failed to download it. `false` indicates that there was no
/// error, we just don't have backups enabled so we can't download a
/// room key.
pub async fn download_room_key(
&self,
room_id: &RoomId,
session_id: &str,
) -> Result<bool, Error> {
let olm_machine = self.client.olm_machine().await;
let olm_machine = olm_machine.as_ref().ok_or(Error::NoOlmMachine)?;

Expand All @@ -471,10 +480,14 @@ impl Backups {

self.handle_downloaded_room_keys(response, decryption_key, &version, olm_machine)
.await?;

Ok(true)
} else {
Ok(false)
}
} else {
Ok(false)
}

Ok(())
}

/// Set the state of the backup.
Expand Down
Loading
Loading