mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-06 23:15:08 -04:00
refactor(timeline): store UTDs in decrypt_room_event
When `decrypt_room_event` fails to decrypt an event, return the UTD as a `TimelineEvent` instead of an Error.
This commit is contained in:
committed by
Richard van der Hoff
parent
543152d914
commit
b69575d5ff
@@ -708,6 +708,14 @@ pub enum UnableToDecryptReason {
|
||||
SenderIdentityNotTrusted(VerificationLevel),
|
||||
}
|
||||
|
||||
impl UnableToDecryptReason {
|
||||
/// Returns true if this UTD is due to a missing room key (and hence might
|
||||
/// resolve itself if we wait a bit.)
|
||||
pub fn is_missing_room_key(&self) -> bool {
|
||||
matches!(self, Self::MissingMegolmSession | Self::UnknownMegolmMessageIndex)
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserialization helper for [`SyncTimelineEvent`], for the modern format.
|
||||
///
|
||||
/// This has the exact same fields as [`SyncTimelineEvent`] itself, but has a
|
||||
|
||||
@@ -20,10 +20,7 @@ use std::{
|
||||
use futures_util::{pin_mut, StreamExt as _};
|
||||
use matrix_sdk::{room::Room, Client, ClientBuildError, SlidingSyncList, SlidingSyncMode};
|
||||
use matrix_sdk_base::{
|
||||
crypto::{vodozemac, MegolmError},
|
||||
deserialized_responses::TimelineEvent,
|
||||
sliding_sync::http,
|
||||
RoomState, StoreError,
|
||||
deserialized_responses::TimelineEvent, sliding_sync::http, RoomState, StoreError,
|
||||
};
|
||||
use ruma::{
|
||||
assign,
|
||||
@@ -216,24 +213,24 @@ impl NotificationClient {
|
||||
|
||||
tokio::time::sleep(Duration::from_millis(wait)).await;
|
||||
|
||||
match room.decrypt_event(raw_event.cast_ref()).await {
|
||||
Ok(new_event) => {
|
||||
let new_event = room.decrypt_event(raw_event.cast_ref()).await?;
|
||||
|
||||
match new_event.kind {
|
||||
matrix_sdk::deserialized_responses::TimelineEventKind::UnableToDecrypt {
|
||||
utd_info, ..} => {
|
||||
if utd_info.reason.is_missing_room_key() {
|
||||
// Decryption error that could be caused by a missing room
|
||||
// key; retry in a few.
|
||||
wait *= 2;
|
||||
} else {
|
||||
debug!("Event could not be decrypted, but waiting longer is unlikely to help: {:?}", utd_info.reason);
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
trace!("Waiting succeeded and event could be decrypted!");
|
||||
return Ok(Some(new_event));
|
||||
}
|
||||
Err(matrix_sdk::Error::MegolmError(
|
||||
MegolmError::MissingRoomKey(_)
|
||||
| MegolmError::Decryption(
|
||||
vodozemac::megolm::DecryptionError::UnknownMessageIndex(_, _),
|
||||
),
|
||||
)) => {
|
||||
// Decryption error that could be caused by a missing room key;
|
||||
// retry in a few.
|
||||
wait *= 2;
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(err.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,10 +256,21 @@ impl NotificationClient {
|
||||
match encryption_sync {
|
||||
Ok(sync) => match sync.run_fixed_iterations(2, sync_permit_guard).await {
|
||||
Ok(()) => match room.decrypt_event(raw_event.cast_ref()).await {
|
||||
Ok(new_event) => {
|
||||
trace!("Encryption sync managed to decrypt the event.");
|
||||
Ok(Some(new_event))
|
||||
}
|
||||
Ok(new_event) => match new_event.kind {
|
||||
matrix_sdk::deserialized_responses::TimelineEventKind::UnableToDecrypt {
|
||||
utd_info, ..
|
||||
} => {
|
||||
trace!(
|
||||
"Encryption sync failed to decrypt the event: {:?}",
|
||||
utd_info.reason
|
||||
);
|
||||
Ok(None)
|
||||
}
|
||||
_ => {
|
||||
trace!("Encryption sync managed to decrypt the event.");
|
||||
Ok(Some(new_event))
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
trace!("Encryption sync failed to decrypt the event: {err}");
|
||||
Ok(None)
|
||||
|
||||
@@ -19,7 +19,7 @@ use futures_util::{
|
||||
#[cfg(all(feature = "e2e-encryption", not(target_arch = "wasm32")))]
|
||||
pub use identity_status_changes::IdentityStatusChanges;
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
use matrix_sdk_base::crypto::DecryptionSettings;
|
||||
use matrix_sdk_base::crypto::{DecryptionSettings, RoomEventDecryptionResult};
|
||||
#[cfg(all(feature = "e2e-encryption", not(target_arch = "wasm32")))]
|
||||
use matrix_sdk_base::crypto::{IdentityStatusChange, RoomIdentityProvider, UserIdentity};
|
||||
use matrix_sdk_base::{
|
||||
@@ -1215,7 +1215,8 @@ impl Room {
|
||||
/// # Arguments
|
||||
/// * `event` - The room event to be decrypted.
|
||||
///
|
||||
/// Returns the decrypted event.
|
||||
/// Returns the decrypted event. In the case of a decryption error, returns
|
||||
/// a `TimelineEvent` representing the decryption error.
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
pub async fn decrypt_event(
|
||||
&self,
|
||||
@@ -1227,24 +1228,21 @@ impl Room {
|
||||
let decryption_settings = DecryptionSettings {
|
||||
sender_device_trust_requirement: self.client.base_client().decryption_trust_requirement,
|
||||
};
|
||||
let decrypted = match machine
|
||||
.decrypt_room_event(event.cast_ref(), self.inner.room_id(), &decryption_settings)
|
||||
.await
|
||||
let mut event: TimelineEvent = match machine
|
||||
.try_decrypt_room_event(event.cast_ref(), self.inner.room_id(), &decryption_settings)
|
||||
.await?
|
||||
{
|
||||
Ok(event) => event,
|
||||
Err(e) => {
|
||||
RoomEventDecryptionResult::Decrypted(decrypted) => decrypted.into(),
|
||||
RoomEventDecryptionResult::UnableToDecrypt(utd_info) => {
|
||||
self.client
|
||||
.encryption()
|
||||
.backups()
|
||||
.maybe_download_room_key(self.room_id().to_owned(), event.clone());
|
||||
|
||||
return Err(e.into());
|
||||
TimelineEvent::new_utd_event(event.clone().cast(), utd_info)
|
||||
}
|
||||
};
|
||||
|
||||
let mut event: TimelineEvent = decrypted.into();
|
||||
event.push_actions = self.event_push_actions(event.raw()).await?;
|
||||
|
||||
Ok(event)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user