From 87632e7ead7f0a54aa8a1eafdf580a25442bda63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 12 Apr 2022 12:37:56 +0200 Subject: [PATCH 1/5] chore(crypto): Update vodozemac --- crates/matrix-qrcode/Cargo.toml | 2 +- crates/matrix-sdk-crypto/Cargo.toml | 4 +- crates/matrix-sdk-crypto/src/error.rs | 2 +- .../src/file_encryption/key_export.rs | 2 +- crates/matrix-sdk-crypto/src/machine.rs | 23 ++++----- crates/matrix-sdk-crypto/src/olm/account.rs | 3 +- .../src/olm/group_sessions/inbound.rs | 47 ++++++++----------- .../src/olm/group_sessions/mod.rs | 21 ++++++--- .../src/olm/group_sessions/outbound.rs | 2 +- crates/matrix-sdk-crypto/src/olm/mod.rs | 11 ++--- crates/matrix-sdk-crypto/src/store/caches.rs | 3 +- .../src/store/integration_tests.rs | 2 +- .../src/store/memorystore.rs | 3 +- crates/matrix-sdk-crypto/src/store/mod.rs | 2 +- 14 files changed, 63 insertions(+), 64 deletions(-) diff --git a/crates/matrix-qrcode/Cargo.toml b/crates/matrix-qrcode/Cargo.toml index f8042a882..394681d5d 100644 --- a/crates/matrix-qrcode/Cargo.toml +++ b/crates/matrix-qrcode/Cargo.toml @@ -30,4 +30,4 @@ thiserror = "1.0.25" [dependencies.vodozemac] git = "https://github.com/matrix-org/vodozemac" -rev = "443b6530510004a60a9e5937ff4021f7b06f63c8" +rev = "e09c93f2c8df9770793abeec57ed984d5e1f3834" diff --git a/crates/matrix-sdk-crypto/Cargo.toml b/crates/matrix-sdk-crypto/Cargo.toml index f9d94f45c..f8367c33b 100644 --- a/crates/matrix-sdk-crypto/Cargo.toml +++ b/crates/matrix-sdk-crypto/Cargo.toml @@ -52,11 +52,11 @@ http = { version = "0.2.4", optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies.vodozemac] git = "https://github.com/matrix-org/vodozemac" -rev = "443b6530510004a60a9e5937ff4021f7b06f63c8" +rev = "e09c93f2c8df9770793abeec57ed984d5e1f3834" [target.'cfg(target_arch = "wasm32")'.dependencies.vodozemac] git = "https://github.com/matrix-org/vodozemac" -rev = "443b6530510004a60a9e5937ff4021f7b06f63c8" +rev = "e09c93f2c8df9770793abeec57ed984d5e1f3834" features = ["js"] [dependencies.ruma] diff --git a/crates/matrix-sdk-crypto/src/error.rs b/crates/matrix-sdk-crypto/src/error.rs index 8b91dece5..b45d20a0a 100644 --- a/crates/matrix-sdk-crypto/src/error.rs +++ b/crates/matrix-sdk-crypto/src/error.rs @@ -39,7 +39,7 @@ pub enum OlmError { /// The received room key couldn't be converted into a valid Megolm session. #[error(transparent)] - SessionCreation(#[from] vodozemac::megolm::SessionCreationError), + SessionCreation(#[from] vodozemac::megolm::SessionKeyDecodeError), /// The storage layer returned an error. #[error("failed to read or write to the crypto store {0}")] diff --git a/crates/matrix-sdk-crypto/src/file_encryption/key_export.rs b/crates/matrix-sdk-crypto/src/file_encryption/key_export.rs index aac59e9dd..c3bbb3e06 100644 --- a/crates/matrix-sdk-crypto/src/file_encryption/key_export.rs +++ b/crates/matrix-sdk-crypto/src/file_encryption/key_export.rs @@ -336,7 +336,7 @@ mod tests { let decrypted = decrypt_key_export(Cursor::new(encrypted), "1234").unwrap(); for (exported, decrypted) in export.iter().zip(decrypted.iter()) { - assert_eq!(exported.session_key.as_str(), decrypted.session_key.as_str()); + assert_eq!(exported.session_key.to_base64(), decrypted.session_key.to_base64()); } assert_eq!( diff --git a/crates/matrix-sdk-crypto/src/machine.rs b/crates/matrix-sdk-crypto/src/machine.rs index 2d0c62191..a1d3e43b9 100644 --- a/crates/matrix-sdk-crypto/src/machine.rs +++ b/crates/matrix-sdk-crypto/src/machine.rs @@ -14,7 +14,6 @@ use std::{ collections::{BTreeMap, BTreeSet, HashSet}, - mem, sync::Arc, }; @@ -48,6 +47,7 @@ use ruma::{ }; use serde_json::Value; use tracing::{debug, error, info, trace, warn}; +use zeroize::Zeroize; #[cfg(feature = "backups_v1")] use crate::backups::BackupMachine; @@ -556,16 +556,17 @@ impl OlmMachine { ) -> OlmResult<(Option, Option)> { match event.content.algorithm { EventEncryptionAlgorithm::MegolmV1AesSha2 => { - let session_key = SessionKey(mem::take(&mut event.content.session_key)); + match SessionKey::from_base64(&event.content.session_key) { + Ok(session_key) => { + event.content.session_key.zeroize(); + let session = InboundGroupSession::new( + sender_key, + signing_key, + &event.content.room_id, + session_key, + None, + ); - match InboundGroupSession::new( - sender_key, - signing_key, - &event.content.room_id, - session_key, - None, - ) { - Ok(session) => { info!( sender = event.sender.as_str(), sender_key = sender_key, @@ -1312,7 +1313,7 @@ impl OlmMachine { let mut keys = BTreeMap::new(); for (i, key) in exported_keys.into_iter().enumerate() { - let session = InboundGroupSession::from_export(key)?; + let session = InboundGroupSession::from_export(key); // Only import the session if we didn't have this session or if it's // a better version of the same session, that is the first known diff --git a/crates/matrix-sdk-crypto/src/olm/account.rs b/crates/matrix-sdk-crypto/src/olm/account.rs index 1a932bfcc..839d11c40 100644 --- a/crates/matrix-sdk-crypto/src/olm/account.rs +++ b/crates/matrix-sdk-crypto/src/olm/account.rs @@ -1077,8 +1077,7 @@ impl ReadOnlyAccount { room_id, outbound.session_key().await, Some(visibility), - ) - .expect("Can't create inbound group session from a newly created outbound group session"); + ); Ok((outbound, inbound)) } diff --git a/crates/matrix-sdk-crypto/src/olm/group_sessions/inbound.rs b/crates/matrix-sdk-crypto/src/olm/group_sessions/inbound.rs index 2d2921be7..53a1d2b5d 100644 --- a/crates/matrix-sdk-crypto/src/olm/group_sessions/inbound.rs +++ b/crates/matrix-sdk-crypto/src/olm/group_sessions/inbound.rs @@ -16,8 +16,7 @@ use std::{ collections::BTreeMap, - convert::TryFrom, - fmt, mem, + fmt, sync::{ atomic::{AtomicBool, Ordering::SeqCst}, Arc, @@ -42,10 +41,11 @@ use serde_json::Value; use vodozemac::{ megolm::{ DecryptedMessage, DecryptionError, ExportedSessionKey, InboundGroupSession as InnerSession, - InboundGroupSessionPickle, MegolmMessage, SessionCreationError, + InboundGroupSessionPickle, MegolmMessage, SessionKeyDecodeError, }, PickleError, }; +use zeroize::Zeroize; use super::{BackedUpRoomKey, ExportedRoomKey, SessionKey}; use crate::error::{EventError, MegolmResult}; @@ -99,15 +99,15 @@ impl InboundGroupSession { room_id: &RoomId, session_key: SessionKey, history_visibility: Option, - ) -> Result { - let session = InnerSession::new(&session_key)?; + ) -> Self { + let session = InnerSession::new(&session_key); let session_id = session.session_id(); let first_known_index = session.first_known_index(); let mut keys: BTreeMap = BTreeMap::new(); keys.insert(DeviceKeyAlgorithm::Ed25519, signing_key.to_owned()); - Ok(InboundGroupSession { + InboundGroupSession { inner: Arc::new(Mutex::new(session)), session_id: session_id.into(), history_visibility: history_visibility.into(), @@ -118,7 +118,7 @@ impl InboundGroupSession { forwarding_chains: Vec::new().into(), imported: false, backed_up: AtomicBool::new(false).into(), - }) + } } /// Create a InboundGroupSession from an exported version of the group @@ -127,20 +127,14 @@ impl InboundGroupSession { /// Most notably this can be called with an `ExportedRoomKey` from a /// previous [`export()`] call. /// - /// /// [`export()`]: #method.export - pub fn from_export( - exported_session: impl Into, - ) -> Result { - Self::try_from(exported_session.into()) + pub fn from_export(exported_session: ExportedRoomKey) -> Self { + Self::from(exported_session) } #[allow(dead_code)] - fn from_backup( - room_id: &RoomId, - backup: BackedUpRoomKey, - ) -> Result { - let session = InnerSession::import(&backup.session_key)?; + fn from_backup(room_id: &RoomId, backup: BackedUpRoomKey) -> Self { + let session = InnerSession::import(&backup.session_key); let session_id = session.session_id(); Self::from_export(ExportedRoomKey { @@ -166,10 +160,11 @@ impl InboundGroupSession { pub fn from_forwarded_key( sender_key: &str, content: &mut ToDeviceForwardedRoomKeyEventContent, - ) -> Result { - let key = ExportedSessionKey(mem::take(&mut content.session_key)); + ) -> Result { + let key = ExportedSessionKey::from_base64(&content.session_key)?; + content.session_key.zeroize(); - let session = InnerSession::import(&key)?; + let session = InnerSession::import(&key); let first_known_index = session.first_known_index(); let mut forwarding_chains = content.forwarding_curve25519_key_chain.clone(); forwarding_chains.push(sender_key.to_owned()); @@ -440,14 +435,12 @@ pub struct PickledInboundGroupSession { pub history_visibility: Option, } -impl TryFrom for InboundGroupSession { - type Error = SessionCreationError; - - fn try_from(key: ExportedRoomKey) -> Result { - let session = InnerSession::import(&key.session_key)?; +impl From for InboundGroupSession { + fn from(key: ExportedRoomKey) -> Self { + let session = InnerSession::import(&key.session_key); let first_known_index = session.first_known_index(); - Ok(InboundGroupSession { + InboundGroupSession { inner: Mutex::new(session).into(), session_id: key.session_id.into(), sender_key: key.sender_key.into(), @@ -458,6 +451,6 @@ impl TryFrom for InboundGroupSession { forwarding_chains: key.forwarding_curve25519_key_chain.into(), imported: true, backed_up: AtomicBool::from(false).into(), - }) + } } } diff --git a/crates/matrix-sdk-crypto/src/olm/group_sessions/mod.rs b/crates/matrix-sdk-crypto/src/olm/group_sessions/mod.rs index d3d738f9a..88f240927 100644 --- a/crates/matrix-sdk-crypto/src/olm/group_sessions/mod.rs +++ b/crates/matrix-sdk-crypto/src/olm/group_sessions/mod.rs @@ -30,7 +30,9 @@ pub(crate) use outbound::ShareState; pub use outbound::{ EncryptionSettings, GroupSession, OutboundGroupSession, PickledOutboundGroupSession, ShareInfo, }; +use vodozemac::megolm::SessionKeyDecodeError; pub use vodozemac::megolm::{ExportedSessionKey, SessionKey}; +use zeroize::Zeroize; /// An exported version of an `InboundGroupSession` /// @@ -110,7 +112,7 @@ impl TryInto for ExportedRoomKey { room_id: self.room_id, sender_key: self.sender_key, session_id: self.session_id, - session_key: self.session_key.0.clone(), + session_key: self.session_key.to_base64(), sender_claimed_ed25519_key: claimed_key.to_owned(), forwarding_curve25519_key_chain: self.forwarding_curve25519_key_chain, } @@ -131,22 +133,29 @@ impl From for BackedUpRoomKey { } } -impl From for ExportedRoomKey { +impl TryFrom for ExportedRoomKey { + type Error = SessionKeyDecodeError; + /// Convert the content of a forwarded room key into a exported room key. - fn from(forwarded_key: ToDeviceForwardedRoomKeyEventContent) -> Self { + fn try_from( + mut forwarded_key: ToDeviceForwardedRoomKeyEventContent, + ) -> Result { let mut sender_claimed_keys: BTreeMap = BTreeMap::new(); sender_claimed_keys .insert(DeviceKeyAlgorithm::Ed25519, forwarded_key.sender_claimed_ed25519_key); - Self { + let session_key = ExportedSessionKey::from_base64(&forwarded_key.session_key)?; + forwarded_key.session_key.zeroize(); + + Ok(Self { algorithm: forwarded_key.algorithm, room_id: forwarded_key.room_id, session_id: forwarded_key.session_id, forwarding_curve25519_key_chain: forwarded_key.forwarding_curve25519_key_chain, sender_claimed_keys, sender_key: forwarded_key.sender_key, - session_key: ExportedSessionKey(forwarded_key.session_key), - } + session_key, + }) } } diff --git a/crates/matrix-sdk-crypto/src/olm/group_sessions/outbound.rs b/crates/matrix-sdk-crypto/src/olm/group_sessions/outbound.rs index 45d31c872..fb0e5f3ce 100644 --- a/crates/matrix-sdk-crypto/src/olm/group_sessions/outbound.rs +++ b/crates/matrix-sdk-crypto/src/olm/group_sessions/outbound.rs @@ -372,7 +372,7 @@ impl OutboundGroupSession { EventEncryptionAlgorithm::MegolmV1AesSha2, self.room_id().to_owned(), self.session_id().to_owned(), - session_key.0.clone(), + session_key.to_base64(), )) } diff --git a/crates/matrix-sdk-crypto/src/olm/mod.rs b/crates/matrix-sdk-crypto/src/olm/mod.rs index 3b45c6367..d784ae111 100644 --- a/crates/matrix-sdk-crypto/src/olm/mod.rs +++ b/crates/matrix-sdk-crypto/src/olm/mod.rs @@ -73,7 +73,7 @@ pub(crate) mod tests { use serde_json::json; use vodozemac::olm::OlmMessage; - use crate::olm::{InboundGroupSession, ReadOnlyAccount, Session}; + use crate::olm::{ExportedRoomKey, InboundGroupSession, ReadOnlyAccount, Session}; fn alice_id() -> &'static UserId { user_id!("@alice:example.org") @@ -185,8 +185,7 @@ pub(crate) mod tests { room_id, outbound.session_key().await, None, - ) - .unwrap(); + ); assert_eq!(0, inbound.first_known_index()); @@ -223,8 +222,7 @@ pub(crate) mod tests { room_id, outbound.session_key().await, None, - ) - .unwrap(); + ); assert_eq!(0, inbound.first_known_index()); @@ -274,8 +272,9 @@ pub(crate) mod tests { let export = inbound.export().await; let export: ToDeviceForwardedRoomKeyEventContent = export.try_into().unwrap(); + let export = ExportedRoomKey::try_from(export).unwrap(); - let imported = InboundGroupSession::from_export(export).unwrap(); + let imported = InboundGroupSession::from_export(export); assert_eq!(inbound.session_id(), imported.session_id()); } diff --git a/crates/matrix-sdk-crypto/src/store/caches.rs b/crates/matrix-sdk-crypto/src/store/caches.rs index 6d1881702..f8813a1f4 100644 --- a/crates/matrix-sdk-crypto/src/store/caches.rs +++ b/crates/matrix-sdk-crypto/src/store/caches.rs @@ -246,8 +246,7 @@ mod tests { room_id, outbound.session_key().await, None, - ) - .unwrap(); + ); let store = GroupSessionStore::new(); store.add(inbound.clone()); diff --git a/crates/matrix-sdk-crypto/src/store/integration_tests.rs b/crates/matrix-sdk-crypto/src/store/integration_tests.rs index 56532ac1f..66aef6552 100644 --- a/crates/matrix-sdk-crypto/src/store/integration_tests.rs +++ b/crates/matrix-sdk-crypto/src/store/integration_tests.rs @@ -275,7 +275,7 @@ macro_rules! cryptostore_integration_tests { export.forwarding_curve25519_key_chain = vec!["some_chain".to_owned()]; - let session = InboundGroupSession::from_export(export).unwrap(); + let session = InboundGroupSession::from_export(export); let changes = Changes { inbound_group_sessions: vec![session.clone()], ..Default::default() }; diff --git a/crates/matrix-sdk-crypto/src/store/memorystore.rs b/crates/matrix-sdk-crypto/src/store/memorystore.rs index 18d935b12..d58513185 100644 --- a/crates/matrix-sdk-crypto/src/store/memorystore.rs +++ b/crates/matrix-sdk-crypto/src/store/memorystore.rs @@ -347,8 +347,7 @@ mod tests { room_id, outbound.session_key().await, None, - ) - .unwrap(); + ); let store = MemoryStore::new(); let _ = store.save_inbound_group_sessions(vec![inbound.clone()]).await; diff --git a/crates/matrix-sdk-crypto/src/store/mod.rs b/crates/matrix-sdk-crypto/src/store/mod.rs index 9a0d700d9..ca5351a94 100644 --- a/crates/matrix-sdk-crypto/src/store/mod.rs +++ b/crates/matrix-sdk-crypto/src/store/mod.rs @@ -590,7 +590,7 @@ pub enum CryptoStoreError { /// The received room key couldn't be converted into a valid Megolm session. #[error(transparent)] - SessionCreation(#[from] vodozemac::megolm::SessionCreationError), + SessionCreation(#[from] vodozemac::megolm::SessionKeyDecodeError), /// A Matrix identifier failed to be validated. #[error(transparent)] From 7bd0f2c50c11b36eae2ad03521b40f1d4d9f75fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 12 Apr 2022 13:06:17 +0200 Subject: [PATCH 2/5] chore(sled): Fix a clippy warning --- crates/matrix-sdk-sled/src/state_store.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/crates/matrix-sdk-sled/src/state_store.rs b/crates/matrix-sdk-sled/src/state_store.rs index ef8f8328c..564316b10 100644 --- a/crates/matrix-sdk-sled/src/state_store.rs +++ b/crates/matrix-sdk-sled/src/state_store.rs @@ -674,9 +674,7 @@ impl SledStore { pub async fn get_room_infos(&self) -> Result>> { let db = self.clone(); spawn_blocking(move || { - stream::iter( - db.room_info.iter().map(move |r| db.deserialize_event(&r?.1).map_err(|e| e)), - ) + stream::iter(db.room_info.iter().map(move |r| db.deserialize_event(&r?.1))) }) .await .map_err(Into::into) @@ -685,11 +683,7 @@ impl SledStore { pub async fn get_stripped_room_infos(&self) -> Result>> { let db = self.clone(); spawn_blocking(move || { - stream::iter( - db.stripped_room_infos - .iter() - .map(move |r| db.deserialize_event(&r?.1).map_err(|e| e)), - ) + stream::iter(db.stripped_room_infos.iter().map(move |r| db.deserialize_event(&r?.1))) }) .await .map_err(Into::into) From 073d9db29f282d6d03778c050061aea52b6c4da0 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 6 Apr 2022 11:10:47 +0200 Subject: [PATCH 3/5] chore(crypto): Remove redundant match arms --- .../src/verification/event_enums.rs | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/verification/event_enums.rs b/crates/matrix-sdk-crypto/src/verification/event_enums.rs index 660386120..6fde3a16e 100644 --- a/crates/matrix-sdk-crypto/src/verification/event_enums.rs +++ b/crates/matrix-sdk-crypto/src/verification/event_enums.rs @@ -79,15 +79,6 @@ impl AnyEvent<'_> { pub fn verification_content(&self) -> Option> { match self { AnyEvent::Room(e) => match e { - AnyMessageLikeEvent::CallAnswer(_) - | AnyMessageLikeEvent::CallInvite(_) - | AnyMessageLikeEvent::CallHangup(_) - | AnyMessageLikeEvent::CallCandidates(_) - | AnyMessageLikeEvent::Reaction(_) - | AnyMessageLikeEvent::RoomEncrypted(_) - | AnyMessageLikeEvent::RoomMessageFeedback(_) - | AnyMessageLikeEvent::RoomRedaction(_) - | AnyMessageLikeEvent::Sticker(_) => None, AnyMessageLikeEvent::RoomMessage(m) => { if let MessageType::VerificationRequest(v) = &m.content.msgtype { Some(RequestContent::from(v).into()) @@ -119,11 +110,6 @@ impl AnyEvent<'_> { _ => None, }, AnyEvent::ToDevice(e) => match e { - AnyToDeviceEvent::Dummy(_) - | AnyToDeviceEvent::RoomKey(_) - | AnyToDeviceEvent::RoomKeyRequest(_) - | AnyToDeviceEvent::ForwardedRoomKey(_) - | AnyToDeviceEvent::RoomEncrypted(_) => None, AnyToDeviceEvent::KeyVerificationRequest(e) => { Some(RequestContent::from(&e.content).into()) } @@ -182,15 +168,6 @@ impl TryFrom<&AnyMessageLikeEvent> for FlowId { fn try_from(value: &AnyMessageLikeEvent) -> Result { match value { - AnyMessageLikeEvent::CallAnswer(_) - | AnyMessageLikeEvent::CallInvite(_) - | AnyMessageLikeEvent::CallHangup(_) - | AnyMessageLikeEvent::CallCandidates(_) - | AnyMessageLikeEvent::Reaction(_) - | AnyMessageLikeEvent::RoomEncrypted(_) - | AnyMessageLikeEvent::RoomMessageFeedback(_) - | AnyMessageLikeEvent::RoomRedaction(_) - | AnyMessageLikeEvent::Sticker(_) => Err(()), AnyMessageLikeEvent::KeyVerificationReady(e) => { Ok(FlowId::from((&*e.room_id, &*e.content.relates_to.event_id))) } @@ -223,11 +200,6 @@ impl TryFrom<&AnyToDeviceEvent> for FlowId { fn try_from(value: &AnyToDeviceEvent) -> Result { match value { - AnyToDeviceEvent::Dummy(_) - | AnyToDeviceEvent::RoomKey(_) - | AnyToDeviceEvent::RoomKeyRequest(_) - | AnyToDeviceEvent::ForwardedRoomKey(_) - | AnyToDeviceEvent::RoomEncrypted(_) => Err(()), AnyToDeviceEvent::KeyVerificationRequest(e) => { Ok(FlowId::from(e.content.transaction_id.to_owned())) } From ad538f3f28cfb6477fb15006a67032d85fdf3327 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 11 Apr 2022 17:22:23 +0200 Subject: [PATCH 4/5] Upgrade Ruma --- benchmarks/Cargo.toml | 2 +- crates/matrix-crypto-ffi/Cargo.toml | 2 +- crates/matrix-crypto-ffi/src/machine.rs | 6 +- crates/matrix-qrcode/Cargo.toml | 2 +- crates/matrix-sdk-appservice/Cargo.toml | 2 +- .../examples/appservice_autojoin.rs | 8 +- crates/matrix-sdk-appservice/tests/tests.rs | 4 +- crates/matrix-sdk-base/Cargo.toml | 2 +- crates/matrix-sdk-base/src/client.rs | 23 +-- crates/matrix-sdk-base/src/rooms/members.rs | 6 +- crates/matrix-sdk-base/src/rooms/mod.rs | 115 ++++++++++--- crates/matrix-sdk-base/src/rooms/normal.rs | 15 +- .../src/store/integration_tests.rs | 6 +- .../matrix-sdk-base/src/store/memory_store.rs | 9 +- crates/matrix-sdk-common/Cargo.toml | 2 +- .../src/deserialized_responses.rs | 27 +-- crates/matrix-sdk-crypto/Cargo.toml | 2 +- crates/matrix-sdk-crypto/src/machine.rs | 28 ++-- .../src/olm/group_sessions/inbound.rs | 4 +- crates/matrix-sdk-crypto/src/olm/mod.rs | 22 +-- .../src/verification/event_enums.rs | 35 ++-- .../matrix-sdk-indexeddb/src/state_store.rs | 9 +- crates/matrix-sdk-sled/src/state_store.rs | 5 +- crates/matrix-sdk-test/Cargo.toml | 2 +- crates/matrix-sdk/Cargo.toml | 2 +- crates/matrix-sdk/examples/command_bot.rs | 4 +- .../matrix-sdk/examples/emoji_verification.rs | 13 +- crates/matrix-sdk/examples/image_bot.rs | 6 +- crates/matrix-sdk/examples/login.rs | 6 +- crates/matrix-sdk/examples/timeline.rs | 14 +- .../examples/wasm_command_bot/src/lib.rs | 13 +- crates/matrix-sdk/src/client/mod.rs | 8 +- crates/matrix-sdk/src/encryption/mod.rs | 13 +- crates/matrix-sdk/src/event_handler.rs | 157 ++++++++++++------ crates/matrix-sdk/src/room/common.rs | 13 +- crates/matrix-sdk/src/room/joined.rs | 8 +- 36 files changed, 382 insertions(+), 213 deletions(-) diff --git a/benchmarks/Cargo.toml b/benchmarks/Cargo.toml index 299b58e14..d7de37382 100644 --- a/benchmarks/Cargo.toml +++ b/benchmarks/Cargo.toml @@ -12,7 +12,7 @@ criterion = { version = "0.3.4", features = ["async", "async_tokio", "html_repor matrix-sdk-crypto = { path = "../crates/matrix-sdk-crypto" } matrix-sdk-sled = { path = "../crates/matrix-sdk-sled", default-features = false, features = ["crypto-store"] } matrix-sdk-test = { path = "../crates/matrix-sdk-test" } -ruma = { git = "https://github.com/ruma/ruma", rev = "deea762b8" } +ruma = { git = "https://github.com/ruma/ruma", rev = "548232ef5" } serde_json = "1.0.79" tempfile = "3.2.0" tokio = { version = "1.7.1", default-features = false, features = ["rt-multi-thread"] } diff --git a/crates/matrix-crypto-ffi/Cargo.toml b/crates/matrix-crypto-ffi/Cargo.toml index 9f1c4c154..dabe70d45 100644 --- a/crates/matrix-crypto-ffi/Cargo.toml +++ b/crates/matrix-crypto-ffi/Cargo.toml @@ -47,7 +47,7 @@ features = ["rt-multi-thread"] [dependencies.ruma] git = "https://github.com/ruma/ruma" -rev = "deea762b8" +rev = "548232ef5" features = ["client-api-c"] [build-dependencies] diff --git a/crates/matrix-crypto-ffi/src/machine.rs b/crates/matrix-crypto-ffi/src/machine.rs index 227637c08..68e4d2201 100644 --- a/crates/matrix-crypto-ffi/src/machine.rs +++ b/crates/matrix-crypto-ffi/src/machine.rs @@ -31,7 +31,7 @@ use ruma::{ IncomingResponse, }, events::{ - key::verification::VerificationMethod, room::encrypted::SyncRoomEncryptedEvent, + key::verification::VerificationMethod, room::encrypted::OriginalSyncRoomEncryptedEvent, AnyMessageLikeEventContent, EventContent, }, DeviceKeyAlgorithm, EventId, RoomId, TransactionId, UserId, @@ -535,7 +535,7 @@ impl OlmMachine { content: &'a RawValue, } - let event: SyncRoomEncryptedEvent = serde_json::from_str(event)?; + let event: OriginalSyncRoomEncryptedEvent = serde_json::from_str(event)?; let room_id = RoomId::parse(room_id)?; let decrypted = self.runtime.block_on(self.inner.decrypt_room_event(&event, &room_id))?; @@ -573,7 +573,7 @@ impl OlmMachine { event: &str, room_id: &str, ) -> Result { - let event: SyncRoomEncryptedEvent = serde_json::from_str(event)?; + let event: OriginalSyncRoomEncryptedEvent = serde_json::from_str(event)?; let room_id = RoomId::parse(room_id)?; let (cancel, request) = diff --git a/crates/matrix-qrcode/Cargo.toml b/crates/matrix-qrcode/Cargo.toml index 394681d5d..817c41987 100644 --- a/crates/matrix-qrcode/Cargo.toml +++ b/crates/matrix-qrcode/Cargo.toml @@ -24,7 +24,7 @@ base64 = "0.13.0" byteorder = "1.4.3" image = { version = "0.23.14", optional = true } qrcode = { version = "0.12.0", default-features = false } -ruma-common = { git = "https://github.com/ruma/ruma", rev = "deea762b8" } +ruma-common = { git = "https://github.com/ruma/ruma", rev = "548232ef5" } rqrr = { version = "0.4.0", optional = true } thiserror = "1.0.25" diff --git a/crates/matrix-sdk-appservice/Cargo.toml b/crates/matrix-sdk-appservice/Cargo.toml index 20b23d145..37d04ae6a 100644 --- a/crates/matrix-sdk-appservice/Cargo.toml +++ b/crates/matrix-sdk-appservice/Cargo.toml @@ -29,7 +29,7 @@ http = "0.2" matrix-sdk = { version = "0.4", path = "../matrix-sdk", default-features = false, features = ["appservice"] } percent-encoding = "2.1.0" regex = "1" -ruma = { git = "https://github.com/ruma/ruma", rev = "deea762b8", features = ["client-api-c", "appservice-api-s"] } +ruma = { git = "https://github.com/ruma/ruma", rev = "548232ef5", features = ["client-api-c", "appservice-api-s"] } serde = "1" serde_json = "1" serde_yaml = "0.8" diff --git a/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs b/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs index 110652cc6..1f7b1b71a 100644 --- a/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs +++ b/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs @@ -5,7 +5,7 @@ use matrix_sdk_appservice::{ event_handler::Ctx, room::Room, ruma::{ - events::room::member::{MembershipState, SyncRoomMemberEvent}, + events::room::member::{MembershipState, OriginalSyncRoomMemberEvent}, UserId, }, }, @@ -16,7 +16,7 @@ use tracing::trace; pub async fn handle_room_member( appservice: AppService, room: Room, - event: SyncRoomMemberEvent, + event: OriginalSyncRoomMemberEvent, ) -> Result<()> { if !appservice.user_id_is_in_namespace(&event.state_key)? { trace!("not an appservice user: {}", event.state_key); @@ -44,7 +44,9 @@ pub async fn main() -> Result<(), Box> { appservice .register_event_handler_context(appservice.clone())? .register_event_handler( - move |event: SyncRoomMemberEvent, room: Room, Ctx(appservice): Ctx| { + move |event: OriginalSyncRoomMemberEvent, + room: Room, + Ctx(appservice): Ctx| { handle_room_member(appservice, room, event) }, ) diff --git a/crates/matrix-sdk-appservice/tests/tests.rs b/crates/matrix-sdk-appservice/tests/tests.rs index 1ca585fdf..88886e5ef 100644 --- a/crates/matrix-sdk-appservice/tests/tests.rs +++ b/crates/matrix-sdk-appservice/tests/tests.rs @@ -5,7 +5,7 @@ use std::{ use matrix_sdk::{ config::RequestConfig, - ruma::{api::appservice::Registration, events::room::member::SyncRoomMemberEvent}, + ruma::{api::appservice::Registration, events::room::member::OriginalSyncRoomMemberEvent}, Client, }; use matrix_sdk_appservice::*; @@ -204,7 +204,7 @@ async fn test_event_handler() -> Result<()> { appservice .register_event_handler({ let on_state_member = on_state_member.clone(); - move |_ev: SyncRoomMemberEvent| { + move |_ev: OriginalSyncRoomMemberEvent| { *on_state_member.lock().unwrap() = true; future::ready(()) } diff --git a/crates/matrix-sdk-base/Cargo.toml b/crates/matrix-sdk-base/Cargo.toml index d786c5550..e2f2a7f86 100644 --- a/crates/matrix-sdk-base/Cargo.toml +++ b/crates/matrix-sdk-base/Cargo.toml @@ -44,7 +44,7 @@ matrix-sdk-common = { version = "0.4.0", path = "../matrix-sdk-common" } matrix-sdk-crypto = { version = "0.4.0", path = "../matrix-sdk-crypto", optional = true } pbkdf2 = { version = "0.10.0", default-features = false, optional = true } rand = { version = "0.8.4", optional = true } -ruma = { git = "https://github.com/ruma/ruma", rev = "deea762b8", features = ["client-api-c", "signatures"] } +ruma = { git = "https://github.com/ruma/ruma", rev = "548232ef5", features = ["client-api-c", "signatures"] } serde = { version = "1.0.126", features = ["rc"] } serde_json = "1.0.64" sha2 = { version = "0.10.1", optional = true } diff --git a/crates/matrix-sdk-base/src/client.rs b/crates/matrix-sdk-base/src/client.rs index 66a81aa89..96d4865b6 100644 --- a/crates/matrix-sdk-base/src/client.rs +++ b/crates/matrix-sdk-base/src/client.rs @@ -45,7 +45,7 @@ use ruma::{ api::client::keys::claim_keys::v3::Request as KeysClaimRequest, events::{ room::{encrypted::RoomEncryptedEventContent, history_visibility::HistoryVisibility}, - AnySyncMessageLikeEvent, EventContent, MessageLikeEventType, + AnySyncMessageLikeEvent, MessageLikeEventContent, SyncMessageLikeEvent, }, DeviceId, TransactionId, }; @@ -55,6 +55,7 @@ use ruma::{ push_rules::PushRulesEvent, room::member::MembershipState, AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent, AnySyncRoomEvent, AnySyncStateEvent, GlobalAccountDataEventType, StateEventType, + SyncStateEvent, }, push::{Action, PushConditionRoomCtx, Ruleset}, serde::Raw, @@ -260,7 +261,7 @@ impl BaseClient { #[allow(clippy::single_match)] match &e { AnySyncRoomEvent::State(s) => match s { - AnySyncStateEvent::RoomMember(member) => { + AnySyncStateEvent::RoomMember(SyncStateEvent::Original(member)) => { if let Ok(member) = MemberEvent::try_from(member.clone()) { ambiguity_cache.handle_event(changes, room_id, &member).await?; @@ -293,7 +294,7 @@ impl BaseClient { } } _ => { - room_info.handle_state_event(&s.content()); + room_info.handle_state_event(s); let raw_event: Raw = event.event.clone().cast(); changes.add_state_event(room_id, s.clone(), raw_event); } @@ -301,7 +302,7 @@ impl BaseClient { #[cfg(feature = "encryption")] AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted( - encrypted, + SyncMessageLikeEvent::Original(encrypted), )) => { if let Some(olm) = self.olm_machine().await { if let Ok(decrypted) = @@ -385,7 +386,7 @@ impl BaseClient { } } Ok(e) => { - room_info.handle_state_event(&e.content()); + room_info.handle_stripped_state_event(&e); state_events .entry(e.event_type()) .or_insert_with(BTreeMap::new) @@ -429,9 +430,9 @@ impl BaseClient { } }; - room_info.handle_state_event(&event.content()); + room_info.handle_state_event(&event); - if let AnySyncStateEvent::RoomMember(member) = event { + if let AnySyncStateEvent::RoomMember(SyncStateEvent::Original(member)) = event { match MemberEvent::try_from(member) { Ok(m) => { ambiguity_cache.handle_event(changes, &room_id, &m).await?; @@ -1020,7 +1021,7 @@ impl BaseClient { pub async fn encrypt( &self, room_id: &RoomId, - content: impl EventContent, + content: impl MessageLikeEventContent, ) -> Result { match self.olm_machine().await { Some(o) => Ok(o.encrypt(room_id, content).await?), @@ -1210,14 +1211,14 @@ impl BaseClient { .and_then(|events| events.get("")) .and_then(|e| e.deserialize().ok()) { - event.content + event.power_levels() } else if let Some(AnySyncStateEvent::RoomPowerLevels(event)) = self .store .get_state_event(room_id, StateEventType::RoomPowerLevels, "") .await? .and_then(|e| e.deserialize().ok()) { - event.content + event.power_levels() } else { return Ok(None); }; @@ -1260,7 +1261,7 @@ impl BaseClient { .and_then(|events| events.get("")) .and_then(|e| e.deserialize().ok()) { - let room_power_levels = event.content; + let room_power_levels = event.power_levels(); push_rules.users_power_levels = room_power_levels.users; push_rules.default_power_level = room_power_levels.users_default; diff --git a/crates/matrix-sdk-base/src/rooms/members.rs b/crates/matrix-sdk-base/src/rooms/members.rs index dd055c5f9..158f1b81a 100644 --- a/crates/matrix-sdk-base/src/rooms/members.rs +++ b/crates/matrix-sdk-base/src/rooms/members.rs @@ -92,11 +92,11 @@ impl RoomMember { (*self.power_levels) .as_ref() .map(|e| { - e.content - .users + let pls = e.power_levels(); + pls.users .get(self.user_id()) .map(|p| (*p).into()) - .unwrap_or_else(|| e.content.users_default.into()) + .unwrap_or_else(|| pls.users_default.into()) }) .unwrap_or_else(|| if self.is_room_creator { 100 } else { 0 }) } diff --git a/crates/matrix-sdk-base/src/rooms/mod.rs b/crates/matrix-sdk-base/src/rooms/mod.rs index 23f271cd7..03382dca0 100644 --- a/crates/matrix-sdk-base/src/rooms/mod.rs +++ b/crates/matrix-sdk-base/src/rooms/mod.rs @@ -12,7 +12,7 @@ use ruma::{ guest_access::GuestAccess, history_visibility::HistoryVisibility, join_rules::JoinRule, tombstone::RoomTombstoneEventContent, }, - AnyStateEventContent, + AnyStrippedStateEvent, AnySyncStateEvent, SyncStateEvent, }, MxcUri, RoomAliasId, UserId, }; @@ -72,42 +72,103 @@ impl BaseRoomInfo { /// Handle a state event for this room and update our info accordingly. /// /// Returns true if the event modified the info, false otherwise. - pub fn handle_state_event(&mut self, content: &AnyStateEventContent) -> bool { - match content { - AnyStateEventContent::RoomEncryption(encryption) => { - self.encryption = Some(encryption.clone()); + pub fn handle_state_event(&mut self, ev: &AnySyncStateEvent) -> bool { + match ev { + // No redacted branch - enabling encryption cannot be undone. + AnySyncStateEvent::RoomEncryption(SyncStateEvent::Original(encryption)) => { + self.encryption = Some(encryption.content.clone()); } - AnyStateEventContent::RoomAvatar(a) => { - self.avatar_url = a.url.clone(); + AnySyncStateEvent::RoomAvatar(a) => { + self.avatar_url = a.as_original().and_then(|a| a.content.url.clone()); } - AnyStateEventContent::RoomName(n) => { - self.name = n.name.as_ref().map(|n| n.to_string()); + AnySyncStateEvent::RoomName(n) => { + self.name = + n.as_original().and_then(|n| n.content.name.as_ref().map(|n| n.to_string())); } - AnyStateEventContent::RoomCreate(c) if self.create.is_none() => { - self.create = Some(c.clone()); + AnySyncStateEvent::RoomCreate(SyncStateEvent::Original(c)) if self.create.is_none() => { + self.create = Some(c.content.clone()); } - AnyStateEventContent::RoomHistoryVisibility(h) => { - self.history_visibility = h.history_visibility.clone(); + AnySyncStateEvent::RoomHistoryVisibility(h) => { + self.history_visibility = match h { + SyncStateEvent::Original(h) => h.content.history_visibility.clone(), + SyncStateEvent::Redacted(h) => h.content.history_visibility.clone(), + }; } - AnyStateEventContent::RoomGuestAccess(g) => { - self.guest_access = g.guest_access.clone(); + AnySyncStateEvent::RoomGuestAccess(g) => { + self.guest_access = g + .as_original() + .map_or(GuestAccess::Forbidden, |g| g.content.guest_access.clone()); } - AnyStateEventContent::RoomJoinRules(c) => { - self.join_rule = c.join_rule.clone(); + AnySyncStateEvent::RoomJoinRules(c) => { + self.join_rule = match c { + SyncStateEvent::Original(c) => c.content.join_rule.clone(), + SyncStateEvent::Redacted(c) => c.content.join_rule.clone(), + }; } - AnyStateEventContent::RoomCanonicalAlias(a) => { - self.canonical_alias = a.alias.clone(); + AnySyncStateEvent::RoomCanonicalAlias(a) => { + self.canonical_alias = a.as_original().and_then(|a| a.content.alias.clone()); } - AnyStateEventContent::RoomTopic(t) => { - self.topic = Some(t.topic.clone()); + AnySyncStateEvent::RoomTopic(t) => { + self.topic = t.as_original().map(|t| t.content.topic.clone()); } - AnyStateEventContent::RoomTombstone(t) => { - self.tombstone = Some(t.clone()); + AnySyncStateEvent::RoomTombstone(t) => { + self.tombstone = t.as_original().map(|t| t.content.clone()); } - AnyStateEventContent::RoomPowerLevels(p) => { - let max_power_level = - p.users.values().fold(self.max_power_level, |acc, &p| max(acc, p.into())); - self.max_power_level = max_power_level; + AnySyncStateEvent::RoomPowerLevels(p) => { + self.max_power_level = p + .power_levels() + .users + .values() + .fold(self.max_power_level, |acc, &p| max(acc, p.into())); + } + _ => return false, + } + + true + } + + /// Handle a stripped state event for this room and update our info + /// accordingly. + /// + /// Returns true if the event modified the info, false otherwise. + pub fn handle_stripped_state_event(&mut self, ev: &AnyStrippedStateEvent) -> bool { + match ev { + AnyStrippedStateEvent::RoomEncryption(encryption) => { + self.encryption = Some(encryption.content.clone()); + } + AnyStrippedStateEvent::RoomAvatar(a) => { + self.avatar_url = a.content.url.clone(); + } + AnyStrippedStateEvent::RoomName(n) => { + self.name = n.content.name.as_ref().map(|n| n.to_string()); + } + AnyStrippedStateEvent::RoomCreate(c) if self.create.is_none() => { + self.create = Some(c.content.clone()); + } + AnyStrippedStateEvent::RoomHistoryVisibility(h) => { + self.history_visibility = h.content.history_visibility.clone(); + } + AnyStrippedStateEvent::RoomGuestAccess(g) => { + self.guest_access = g.content.guest_access.clone(); + } + AnyStrippedStateEvent::RoomJoinRules(c) => { + self.join_rule = c.content.join_rule.clone(); + } + AnyStrippedStateEvent::RoomCanonicalAlias(a) => { + self.canonical_alias = a.content.alias.clone(); + } + AnyStrippedStateEvent::RoomTopic(t) => { + self.topic = Some(t.content.topic.clone()); + } + AnyStrippedStateEvent::RoomTombstone(t) => { + self.tombstone = Some(t.content.clone()); + } + AnyStrippedStateEvent::RoomPowerLevels(p) => { + self.max_power_level = p + .content + .users + .values() + .fold(self.max_power_level, |acc, &p| max(acc, p.into())); } _ => return false, } diff --git a/crates/matrix-sdk-base/src/rooms/normal.rs b/crates/matrix-sdk-base/src/rooms/normal.rs index d1ae2aec2..04b4bd391 100644 --- a/crates/matrix-sdk-base/src/rooms/normal.rs +++ b/crates/matrix-sdk-base/src/rooms/normal.rs @@ -29,8 +29,8 @@ use ruma::{ tombstone::RoomTombstoneEventContent, }, tag::Tags, - AnyRoomAccountDataEvent, AnyStateEventContent, AnySyncStateEvent, RoomAccountDataEventType, - StateEventType, + AnyRoomAccountDataEvent, AnyStrippedStateEvent, AnySyncStateEvent, + RoomAccountDataEventType, StateEventType, }, receipt::ReceiptType, room::RoomType as CreateRoomType, @@ -654,13 +654,20 @@ impl RoomInfo { self.base_info.encryption.is_some() } - /// handle the given State event. + /// Handle the given state event. /// /// Returns true if the event modified the info, false otherwise. - pub fn handle_state_event(&mut self, event: &AnyStateEventContent) -> bool { + pub fn handle_state_event(&mut self, event: &AnySyncStateEvent) -> bool { self.base_info.handle_state_event(event) } + /// Handle the given stripped tate event. + /// + /// Returns true if the event modified the info, false otherwise. + pub fn handle_stripped_state_event(&mut self, event: &AnyStrippedStateEvent) -> bool { + self.base_info.handle_stripped_state_event(event) + } + /// Update the notifications count pub fn update_notification_count(&mut self, notification_counts: UnreadNotificationsCount) { self.notification_counts = notification_counts; diff --git a/crates/matrix-sdk-base/src/store/integration_tests.rs b/crates/matrix-sdk-base/src/store/integration_tests.rs index 784adef54..dca117cae 100644 --- a/crates/matrix-sdk-base/src/store/integration_tests.rs +++ b/crates/matrix-sdk-base/src/store/integration_tests.rs @@ -147,14 +147,14 @@ macro_rules! statestore_integration_tests { let name_json: &JsonValue = &test_json::NAME; let name_raw = serde_json::from_value::>(name_json.clone()).unwrap(); let name_event = name_raw.deserialize().unwrap(); - room.handle_state_event(&name_event.content()); + room.handle_state_event(&name_event); changes.add_state_event(room_id, name_event, name_raw); let topic_json: &JsonValue = &test_json::TOPIC; let topic_raw = serde_json::from_value::>(topic_json.clone()).unwrap(); let topic_event = topic_raw.deserialize().unwrap(); - room.handle_state_event(&topic_event.content()); + room.handle_state_event(&topic_event); changes.add_state_event(room_id, topic_event, topic_raw); let mut room_ambiguity_map = BTreeMap::new(); @@ -213,7 +213,7 @@ macro_rules! statestore_integration_tests { serde_json::from_value::>(stripped_name_json.clone()) .unwrap(); let stripped_name_event = stripped_name_raw.deserialize().unwrap(); - stripped_room.handle_state_event(&stripped_name_event.content()); + stripped_room.handle_stripped_state_event(&stripped_name_event); changes.stripped_state.insert( stripped_room_id.to_owned(), BTreeMap::from([( diff --git a/crates/matrix-sdk-base/src/store/memory_store.rs b/crates/matrix-sdk-base/src/store/memory_store.rs index 1374c75b7..2df59435e 100644 --- a/crates/matrix-sdk-base/src/store/memory_store.rs +++ b/crates/matrix-sdk-base/src/store/memory_store.rs @@ -26,7 +26,10 @@ use ruma::{ events::{ presence::PresenceEvent, receipt::Receipt, - room::member::{MembershipState, RoomMemberEventContent}, + room::{ + member::{MembershipState, RoomMemberEventContent}, + redaction::SyncRoomRedactionEvent, + }, AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, AnyStrippedStateEvent, AnySyncMessageLikeEvent, AnySyncRoomEvent, AnySyncStateEvent, GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType, @@ -361,7 +364,9 @@ impl MemoryStore { for event in &timeline.events { // Redact events already in store only on sync response if let Ok(AnySyncRoomEvent::MessageLike( - AnySyncMessageLikeEvent::RoomRedaction(redaction), + AnySyncMessageLikeEvent::RoomRedaction(SyncRoomRedactionEvent::Original( + redaction, + )), )) = event.event.deserialize() { let pos = data.event_id_to_position.get(&redaction.redacts).copied(); diff --git a/crates/matrix-sdk-common/Cargo.toml b/crates/matrix-sdk-common/Cargo.toml index 246622959..72f4bc102 100644 --- a/crates/matrix-sdk-common/Cargo.toml +++ b/crates/matrix-sdk-common/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"] [dependencies] async-trait = "0.1.50" -ruma = { git = "https://github.com/ruma/ruma", rev = "deea762b8", features = ["client-api-c"] } +ruma = { git = "https://github.com/ruma/ruma", rev = "548232ef5", features = ["client-api-c"] } serde = "1.0.126" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/crates/matrix-sdk-common/src/deserialized_responses.rs b/crates/matrix-sdk-common/src/deserialized_responses.rs index 5a909ee19..1703f68b1 100644 --- a/crates/matrix-sdk-common/src/deserialized_responses.rs +++ b/crates/matrix-sdk-common/src/deserialized_responses.rs @@ -10,7 +10,8 @@ use ruma::{ }, events::{ room::member::{ - RoomMemberEvent, RoomMemberEventContent, StrippedRoomMemberEvent, SyncRoomMemberEvent, + OriginalRoomMemberEvent, OriginalSyncRoomMemberEvent, RoomMemberEventContent, + StrippedRoomMemberEvent, }, AnyRoomEvent, AnySyncRoomEvent, StateUnsigned, }, @@ -296,7 +297,7 @@ impl TimelineSlice { } #[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(try_from = "SyncRoomMemberEvent", into = "SyncRoomMemberEvent")] +#[serde(try_from = "OriginalSyncRoomMemberEvent", into = "OriginalSyncRoomMemberEvent")] pub struct MemberEvent { pub content: RoomMemberEventContent, pub event_id: Box, @@ -306,10 +307,10 @@ pub struct MemberEvent { pub unsigned: StateUnsigned, } -impl TryFrom for MemberEvent { +impl TryFrom for MemberEvent { type Error = ruma::IdParseError; - fn try_from(event: SyncRoomMemberEvent) -> Result { + fn try_from(event: OriginalSyncRoomMemberEvent) -> Result { Ok(MemberEvent { content: event.content, event_id: event.event_id, @@ -321,10 +322,10 @@ impl TryFrom for MemberEvent { } } -impl TryFrom for MemberEvent { +impl TryFrom for MemberEvent { type Error = ruma::IdParseError; - fn try_from(event: RoomMemberEvent) -> Result { + fn try_from(event: OriginalRoomMemberEvent) -> Result { Ok(MemberEvent { content: event.content, event_id: event.event_id, @@ -336,7 +337,7 @@ impl TryFrom for MemberEvent { } } -impl From for SyncRoomMemberEvent { +impl From for OriginalSyncRoomMemberEvent { fn from(other: MemberEvent) -> Self { Self { content: other.content, @@ -395,8 +396,8 @@ mod tests { use ruma::{ event_id, events::{ - room::message::RoomMessageEventContent, AnyMessageLikeEvent, AnySyncMessageLikeEvent, - AnySyncRoomEvent, MessageLikeEvent, MessageLikeUnsigned, + room::message::RoomMessageEventContent, AnySyncMessageLikeEvent, AnySyncRoomEvent, + MessageLikeUnsigned, OriginalMessageLikeEvent, SyncMessageLikeEvent, }, room_id, serde::Raw, @@ -409,7 +410,7 @@ mod tests { fn room_event_to_sync_room_event() { let content = RoomMessageEventContent::text_plain("foobar"); - let event = MessageLikeEvent { + let event = OriginalMessageLikeEvent { content, event_id: event_id!("$xxxxx:example.org").to_owned(), room_id: room_id!("!someroom:example.com").to_owned(), @@ -425,9 +426,9 @@ mod tests { let converted_event: AnySyncRoomEvent = converted_room_event.event.deserialize().unwrap(); - let event: AnyMessageLikeEvent = event.into(); - let sync_event: AnySyncMessageLikeEvent = event.into(); - let sync_event: AnySyncRoomEvent = sync_event.into(); + let sync_event = AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomMessage( + SyncMessageLikeEvent::Original(event.into()), + )); // There is no PartialEq implementation for AnySyncRoomEvent, so we // just compare a couple of fields here. The important thing is that diff --git a/crates/matrix-sdk-crypto/Cargo.toml b/crates/matrix-sdk-crypto/Cargo.toml index f8367c33b..d262d6c22 100644 --- a/crates/matrix-sdk-crypto/Cargo.toml +++ b/crates/matrix-sdk-crypto/Cargo.toml @@ -61,7 +61,7 @@ features = ["js"] [dependencies.ruma] git = "https://github.com/ruma/ruma" -rev = "deea762b8" +rev = "548232ef5" features = ["client-api-c", "rand", "unstable-msc2676", "unstable-msc2677"] [dev-dependencies] diff --git a/crates/matrix-sdk-crypto/src/machine.rs b/crates/matrix-sdk-crypto/src/machine.rs index a1d3e43b9..62f9ad4c7 100644 --- a/crates/matrix-sdk-crypto/src/machine.rs +++ b/crates/matrix-sdk-crypto/src/machine.rs @@ -35,12 +35,12 @@ use ruma::{ assign, events::{ room::encrypted::{ - EncryptedEventScheme, MegolmV1AesSha2Content, RoomEncryptedEventContent, - SyncRoomEncryptedEvent, ToDeviceRoomEncryptedEvent, + EncryptedEventScheme, MegolmV1AesSha2Content, OriginalSyncRoomEncryptedEvent, + RoomEncryptedEventContent, ToDeviceRoomEncryptedEvent, }, room_key::ToDeviceRoomKeyEvent, secret::request::SecretName, - AnyRoomEvent, AnyToDeviceEvent, EventContent, MessageLikeEventType, + AnyRoomEvent, AnyToDeviceEvent, MessageLikeEventContent, }, DeviceId, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, RoomId, TransactionId, UInt, UserId, @@ -659,7 +659,7 @@ impl OlmMachine { pub async fn encrypt( &self, room_id: &RoomId, - content: impl EventContent, + content: impl MessageLikeEventContent, ) -> MegolmResult { let event_type = content.event_type().to_string(); let content = serde_json::to_value(&content)?; @@ -986,7 +986,7 @@ impl OlmMachine { /// * `session_id` - The id that uniquely identifies the session. pub async fn request_room_key( &self, - event: &SyncRoomEncryptedEvent, + event: &OriginalSyncRoomEncryptedEvent, room_id: &RoomId, ) -> MegolmResult<(Option, OutgoingRequest)> { let content = match &event.content.scheme { @@ -1039,7 +1039,7 @@ impl OlmMachine { async fn decrypt_megolm_v1_event( &self, room_id: &RoomId, - event: &SyncRoomEncryptedEvent, + event: &OriginalSyncRoomEncryptedEvent, content: &MegolmV1AesSha2Content, ) -> MegolmResult { if let Some(session) = self @@ -1100,7 +1100,7 @@ impl OlmMachine { /// * `room_id` - The ID of the room where the event was sent to. pub async fn decrypt_room_event( &self, - event: &SyncRoomEncryptedEvent, + event: &OriginalSyncRoomEncryptedEvent, room_id: &RoomId, ) -> MegolmResult { match &event.content.scheme { @@ -1536,8 +1536,8 @@ pub(crate) mod tests { message::{MessageType, RoomMessageEventContent}, }, AnyMessageLikeEvent, AnyMessageLikeEventContent, AnyRoomEvent, AnyToDeviceEvent, - AnyToDeviceEventContent, MessageLikeEvent, MessageLikeUnsigned, SyncMessageLikeEvent, - ToDeviceEvent, + AnyToDeviceEventContent, MessageLikeEvent, MessageLikeUnsigned, + OriginalMessageLikeEvent, OriginalSyncMessageLikeEvent, ToDeviceEvent, }, room_id, serde::Raw, @@ -1957,7 +1957,7 @@ pub(crate) mod tests { .await .unwrap(); - let event = SyncMessageLikeEvent { + let event = OriginalSyncMessageLikeEvent { event_id: event_id!("$xxxxx:example.org").to_owned(), origin_server_ts: milli_seconds_since_unix_epoch(), sender: alice.user_id().to_owned(), @@ -1968,11 +1968,9 @@ pub(crate) mod tests { let decrypted_event = bob.decrypt_room_event(&event, room_id).await.unwrap().event.deserialize().unwrap(); - if let AnyRoomEvent::MessageLike(AnyMessageLikeEvent::RoomMessage(MessageLikeEvent { - sender, - content, - .. - })) = decrypted_event + if let AnyRoomEvent::MessageLike(AnyMessageLikeEvent::RoomMessage( + MessageLikeEvent::Original(OriginalMessageLikeEvent { sender, content, .. }), + )) = decrypted_event { assert_eq!(&sender, alice.user_id()); if let MessageType::Text(c) = &content.msgtype { diff --git a/crates/matrix-sdk-crypto/src/olm/group_sessions/inbound.rs b/crates/matrix-sdk-crypto/src/olm/group_sessions/inbound.rs index 53a1d2b5d..b4b538ba8 100644 --- a/crates/matrix-sdk-crypto/src/olm/group_sessions/inbound.rs +++ b/crates/matrix-sdk-crypto/src/olm/group_sessions/inbound.rs @@ -28,7 +28,7 @@ use ruma::{ events::{ forwarded_room_key::ToDeviceForwardedRoomKeyEventContent, room::{ - encrypted::{EncryptedEventScheme, SyncRoomEncryptedEvent}, + encrypted::{EncryptedEventScheme, OriginalSyncRoomEncryptedEvent}, history_visibility::HistoryVisibility, }, AnyRoomEvent, @@ -343,7 +343,7 @@ impl InboundGroupSession { /// * `event` - The event that should be decrypted. pub async fn decrypt( &self, - event: &SyncRoomEncryptedEvent, + event: &OriginalSyncRoomEncryptedEvent, ) -> MegolmResult<(Raw, u32)> { let content = match &event.content.scheme { EncryptedEventScheme::MegolmV1AesSha2(c) => c, diff --git a/crates/matrix-sdk-crypto/src/olm/mod.rs b/crates/matrix-sdk-crypto/src/olm/mod.rs index d784ae111..4e7ae7687 100644 --- a/crates/matrix-sdk-crypto/src/olm/mod.rs +++ b/crates/matrix-sdk-crypto/src/olm/mod.rs @@ -67,6 +67,7 @@ pub(crate) mod tests { forwarded_room_key::ToDeviceForwardedRoomKeyEventContent, room::message::{Relation, Replacement, RoomMessageEventContent}, AnyMessageLikeEvent, AnyRoomEvent, AnySyncMessageLikeEvent, AnySyncRoomEvent, + MessageLikeEvent, SyncMessageLikeEvent, }, room_id, user_id, DeviceId, UserId, }; @@ -243,19 +244,20 @@ pub(crate) mod tests { let event: AnySyncRoomEvent = serde_json::from_str(&event).unwrap(); - let event = - if let AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted(event)) = - event - { - event - } else { - panic!("Invalid event type") - }; + let event = if let AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted( + SyncMessageLikeEvent::Original(event), + )) = event + { + event + } else { + panic!("Invalid event type") + }; let decrypted = inbound.decrypt(&event).await.unwrap().0; - if let AnyRoomEvent::MessageLike(AnyMessageLikeEvent::RoomMessage(e)) = - decrypted.deserialize().unwrap() + if let AnyRoomEvent::MessageLike(AnyMessageLikeEvent::RoomMessage( + MessageLikeEvent::Original(e), + )) = decrypted.deserialize().unwrap() { assert_matches!(e.content.relates_to, Some(Relation::Replacement(_))); } else { diff --git a/crates/matrix-sdk-crypto/src/verification/event_enums.rs b/crates/matrix-sdk-crypto/src/verification/event_enums.rs index 6fde3a16e..0a35ce566 100644 --- a/crates/matrix-sdk-crypto/src/verification/event_enums.rs +++ b/crates/matrix-sdk-crypto/src/verification/event_enums.rs @@ -41,6 +41,7 @@ use ruma::{ }, room::message::{KeyVerificationRequestEventContent, MessageType}, AnyMessageLikeEvent, AnyMessageLikeEventContent, AnyToDeviceEvent, AnyToDeviceEventContent, + MessageLikeEvent, }, serde::{Base64, CanonicalJsonValue}, DeviceId, MilliSecondsSinceUnixEpoch, RoomId, UserId, @@ -79,32 +80,32 @@ impl AnyEvent<'_> { pub fn verification_content(&self) -> Option> { match self { AnyEvent::Room(e) => match e { - AnyMessageLikeEvent::RoomMessage(m) => { + AnyMessageLikeEvent::RoomMessage(MessageLikeEvent::Original(m)) => { if let MessageType::VerificationRequest(v) = &m.content.msgtype { Some(RequestContent::from(v).into()) } else { None } } - AnyMessageLikeEvent::KeyVerificationReady(e) => { + AnyMessageLikeEvent::KeyVerificationReady(MessageLikeEvent::Original(e)) => { Some(ReadyContent::from(&e.content).into()) } - AnyMessageLikeEvent::KeyVerificationStart(e) => { + AnyMessageLikeEvent::KeyVerificationStart(MessageLikeEvent::Original(e)) => { Some(StartContent::from(&e.content).into()) } - AnyMessageLikeEvent::KeyVerificationCancel(e) => { + AnyMessageLikeEvent::KeyVerificationCancel(MessageLikeEvent::Original(e)) => { Some(CancelContent::from(&e.content).into()) } - AnyMessageLikeEvent::KeyVerificationAccept(e) => { + AnyMessageLikeEvent::KeyVerificationAccept(MessageLikeEvent::Original(e)) => { Some(AcceptContent::from(&e.content).into()) } - AnyMessageLikeEvent::KeyVerificationKey(e) => { + AnyMessageLikeEvent::KeyVerificationKey(MessageLikeEvent::Original(e)) => { Some(KeyContent::from(&e.content).into()) } - AnyMessageLikeEvent::KeyVerificationMac(e) => { + AnyMessageLikeEvent::KeyVerificationMac(MessageLikeEvent::Original(e)) => { Some(MacContent::from(&e.content).into()) } - AnyMessageLikeEvent::KeyVerificationDone(e) => { + AnyMessageLikeEvent::KeyVerificationDone(MessageLikeEvent::Original(e)) => { Some(DoneContent::from(&e.content).into()) } _ => None, @@ -168,26 +169,28 @@ impl TryFrom<&AnyMessageLikeEvent> for FlowId { fn try_from(value: &AnyMessageLikeEvent) -> Result { match value { - AnyMessageLikeEvent::KeyVerificationReady(e) => { + AnyMessageLikeEvent::KeyVerificationReady(MessageLikeEvent::Original(e)) => { Ok(FlowId::from((&*e.room_id, &*e.content.relates_to.event_id))) } - AnyMessageLikeEvent::RoomMessage(e) => Ok(FlowId::from((&*e.room_id, &*e.event_id))), - AnyMessageLikeEvent::KeyVerificationStart(e) => { + AnyMessageLikeEvent::RoomMessage(MessageLikeEvent::Original(e)) => { + Ok(FlowId::from((&*e.room_id, &*e.event_id))) + } + AnyMessageLikeEvent::KeyVerificationStart(MessageLikeEvent::Original(e)) => { Ok(FlowId::from((&*e.room_id, &*e.content.relates_to.event_id))) } - AnyMessageLikeEvent::KeyVerificationCancel(e) => { + AnyMessageLikeEvent::KeyVerificationCancel(MessageLikeEvent::Original(e)) => { Ok(FlowId::from((&*e.room_id, &*e.content.relates_to.event_id))) } - AnyMessageLikeEvent::KeyVerificationAccept(e) => { + AnyMessageLikeEvent::KeyVerificationAccept(MessageLikeEvent::Original(e)) => { Ok(FlowId::from((&*e.room_id, &*e.content.relates_to.event_id))) } - AnyMessageLikeEvent::KeyVerificationKey(e) => { + AnyMessageLikeEvent::KeyVerificationKey(MessageLikeEvent::Original(e)) => { Ok(FlowId::from((&*e.room_id, &*e.content.relates_to.event_id))) } - AnyMessageLikeEvent::KeyVerificationMac(e) => { + AnyMessageLikeEvent::KeyVerificationMac(MessageLikeEvent::Original(e)) => { Ok(FlowId::from((&*e.room_id, &*e.content.relates_to.event_id))) } - AnyMessageLikeEvent::KeyVerificationDone(e) => { + AnyMessageLikeEvent::KeyVerificationDone(MessageLikeEvent::Original(e)) => { Ok(FlowId::from((&*e.room_id, &*e.content.relates_to.event_id))) } _ => Err(()), diff --git a/crates/matrix-sdk-indexeddb/src/state_store.rs b/crates/matrix-sdk-indexeddb/src/state_store.rs index ad40aff8d..9c8dd3553 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store.rs @@ -32,7 +32,10 @@ use matrix_sdk_common::{ events::{ presence::PresenceEvent, receipt::Receipt, - room::member::{MembershipState, RoomMemberEventContent}, + room::{ + member::{MembershipState, RoomMemberEventContent}, + redaction::SyncRoomRedactionEvent, + }, AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, AnySyncMessageLikeEvent, AnySyncRoomEvent, AnySyncStateEvent, GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType, @@ -638,7 +641,9 @@ impl IndexeddbStore { for event in &timeline.events { // Redact events already in store only on sync response if let Ok(AnySyncRoomEvent::MessageLike( - AnySyncMessageLikeEvent::RoomRedaction(redaction), + AnySyncMessageLikeEvent::RoomRedaction( + SyncRoomRedactionEvent::Original(redaction), + ), )) = event.event.deserialize() { let redacts_key = (room_id, &redaction.redacts).encode(); diff --git a/crates/matrix-sdk-sled/src/state_store.rs b/crates/matrix-sdk-sled/src/state_store.rs index 564316b10..70f4c369d 100644 --- a/crates/matrix-sdk-sled/src/state_store.rs +++ b/crates/matrix-sdk-sled/src/state_store.rs @@ -27,6 +27,7 @@ use futures_util::stream::{self, TryStreamExt}; use matrix_sdk_base::{ deserialized_responses::{MemberEvent, SyncRoomEvent}, media::{MediaRequest, UniqueKey}, + ruma::events::room::redaction::SyncRoomRedactionEvent, store::{ store_key::{self, EncryptedEvent, StoreKey}, BoxStream, Result as StoreResult, StateChanges, StateStore, StoreError, @@ -1094,7 +1095,9 @@ impl SledStore { for event in &timeline.events { // Redact events already in store only on sync response if let Ok(AnySyncRoomEvent::MessageLike( - AnySyncMessageLikeEvent::RoomRedaction(redaction), + AnySyncMessageLikeEvent::RoomRedaction(SyncRoomRedactionEvent::Original( + redaction, + )), )) = event.event.deserialize() { let redacts_key = (room_id, redaction.redacts).encode(); diff --git a/crates/matrix-sdk-test/Cargo.toml b/crates/matrix-sdk-test/Cargo.toml index e6d688d0b..5af714bef 100644 --- a/crates/matrix-sdk-test/Cargo.toml +++ b/crates/matrix-sdk-test/Cargo.toml @@ -18,6 +18,6 @@ appservice = [] http = "0.2.4" lazy_static = "1.4.0" matrix-sdk-test-macros = { version = "0.1.0", path = "../matrix-sdk-test-macros" } -ruma = { git = "https://github.com/ruma/ruma", rev = "deea762b8", features = ["client-api-c"] } +ruma = { git = "https://github.com/ruma/ruma", rev = "548232ef5", features = ["client-api-c"] } serde = "1.0.126" serde_json = "1.0.64" diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index 9aaee56bd..0af2456b9 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -103,7 +103,7 @@ default_features = false [dependencies.ruma] git = "https://github.com/ruma/ruma" -rev = "deea762b8" +rev = "548232ef5" features = ["client-api-c", "compat", "rand", "unstable-msc2448"] [dependencies.tokio-stream] diff --git a/crates/matrix-sdk/examples/command_bot.rs b/crates/matrix-sdk/examples/command_bot.rs index 3eba062a2..e9b4dfe6b 100644 --- a/crates/matrix-sdk/examples/command_bot.rs +++ b/crates/matrix-sdk/examples/command_bot.rs @@ -4,12 +4,12 @@ use matrix_sdk::{ config::SyncSettings, room::Room, ruma::events::room::message::{ - MessageType, RoomMessageEventContent, SyncRoomMessageEvent, TextMessageEventContent, + MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent, TextMessageEventContent, }, Client, }; -async fn on_room_message(event: SyncRoomMessageEvent, room: Room) { +async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) { if let Room::Joined(room) = room { let msg_body = match event.content.msgtype { MessageType::Text(TextMessageEventContent { body, .. }) => body, diff --git a/crates/matrix-sdk/examples/emoji_verification.rs b/crates/matrix-sdk/examples/emoji_verification.rs index d4e77e132..4e9112157 100644 --- a/crates/matrix-sdk/examples/emoji_verification.rs +++ b/crates/matrix-sdk/examples/emoji_verification.rs @@ -19,6 +19,7 @@ use matrix_sdk::{ }, Client, LoopCtrl, }; +use ruma::events::SyncMessageLikeEvent; use url::Url; async fn wait_for_confirmation(client: Client, sas: SasVerification) { @@ -135,7 +136,9 @@ async fn login( { if let AnySyncRoomEvent::MessageLike(event) = event { match event { - AnySyncMessageLikeEvent::RoomMessage(m) => { + AnySyncMessageLikeEvent::RoomMessage( + SyncMessageLikeEvent::Original(m), + ) => { if let MessageType::VerificationRequest(_) = &m.content.msgtype { let request = client @@ -150,7 +153,9 @@ async fn login( .expect("Can't accept verification request"); } } - AnySyncMessageLikeEvent::KeyVerificationKey(e) => { + AnySyncMessageLikeEvent::KeyVerificationKey( + SyncMessageLikeEvent::Original(e), + ) => { if let Some(Verification::SasV1(sas)) = client .encryption() .get_verification( @@ -162,7 +167,9 @@ async fn login( tokio::spawn(wait_for_confirmation((*client).clone(), sas)); } } - AnySyncMessageLikeEvent::KeyVerificationMac(e) => { + AnySyncMessageLikeEvent::KeyVerificationMac( + SyncMessageLikeEvent::Original(e), + ) => { if let Some(Verification::SasV1(sas)) = client .encryption() .get_verification( diff --git a/crates/matrix-sdk/examples/image_bot.rs b/crates/matrix-sdk/examples/image_bot.rs index abf7281e7..6f6724f1b 100644 --- a/crates/matrix-sdk/examples/image_bot.rs +++ b/crates/matrix-sdk/examples/image_bot.rs @@ -13,16 +13,16 @@ use matrix_sdk::{ config::SyncSettings, room::Room, ruma::events::room::message::{ - MessageType, RoomMessageEventContent, SyncRoomMessageEvent, TextMessageEventContent, + MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent, TextMessageEventContent, }, Client, }; use tokio::sync::Mutex; use url::Url; -async fn on_room_message(event: SyncRoomMessageEvent, room: Room, image: Arc>) { +async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room, image: Arc>) { if let Room::Joined(room) = room { - let msg_body = if let SyncRoomMessageEvent { + let msg_body = if let OriginalSyncRoomMessageEvent { content: RoomMessageEventContent { msgtype: MessageType::Text(TextMessageEventContent { body: msg_body, .. }), diff --git a/crates/matrix-sdk/examples/login.rs b/crates/matrix-sdk/examples/login.rs index 2e47a7995..1d68f5e64 100644 --- a/crates/matrix-sdk/examples/login.rs +++ b/crates/matrix-sdk/examples/login.rs @@ -5,15 +5,15 @@ use matrix_sdk::{ config::SyncSettings, room::Room, ruma::events::room::message::{ - MessageType, RoomMessageEventContent, SyncRoomMessageEvent, TextMessageEventContent, + MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent, TextMessageEventContent, }, Client, }; use url::Url; -async fn on_room_message(event: SyncRoomMessageEvent, room: Room) { +async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) { if let Room::Joined(room) = room { - if let SyncRoomMessageEvent { + if let OriginalSyncRoomMessageEvent { content: RoomMessageEventContent { msgtype: MessageType::Text(TextMessageEventContent { body: msg_body, .. }), diff --git a/crates/matrix-sdk/examples/timeline.rs b/crates/matrix-sdk/examples/timeline.rs index 663b01b2d..34334e584 100644 --- a/crates/matrix-sdk/examples/timeline.rs +++ b/crates/matrix-sdk/examples/timeline.rs @@ -8,7 +8,7 @@ use matrix_sdk::{ ruma::{ api::client::filter::{FilterDefinition, LazyLoadOptions, RoomEventFilter, RoomFilter}, assign, - events::{AnyMessageLikeEventContent, AnySyncRoomEvent}, + events::{AnySyncMessageLikeEvent, AnySyncRoomEvent, SyncMessageLikeEvent}, }, store::make_store_config, Client, LoopCtrl, @@ -32,12 +32,14 @@ async fn login(homeserver_url: String, username: &str, password: &str) -> Client } fn event_content(event: AnySyncRoomEvent) -> Option { - if let AnySyncRoomEvent::MessageLike(event) = event { - if let AnyMessageLikeEventContent::RoomMessage(content) = event.content() { - return Some(content.msgtype.body().to_owned()); - } + if let AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomMessage( + SyncMessageLikeEvent::Original(event), + )) = event + { + Some(event.content.msgtype.body().to_owned()) + } else { + None } - None } async fn print_timeline(room: Room) { let backward_stream = room.timeline_backward().await.unwrap(); diff --git a/crates/matrix-sdk/examples/wasm_command_bot/src/lib.rs b/crates/matrix-sdk/examples/wasm_command_bot/src/lib.rs index 4f5e5b285..ed291ad35 100644 --- a/crates/matrix-sdk/examples/wasm_command_bot/src/lib.rs +++ b/crates/matrix-sdk/examples/wasm_command_bot/src/lib.rs @@ -4,9 +4,11 @@ use matrix_sdk::{ ruma::{ events::{ room::message::{ - MessageType, RoomMessageEventContent, SyncRoomMessageEvent, TextMessageEventContent, + MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent, + TextMessageEventContent, }, AnyMessageLikeEventContent, AnySyncMessageLikeEvent, AnySyncRoomEvent, + SyncMessageLikeEvent, }, RoomId, }, @@ -19,8 +21,8 @@ use web_sys::console; struct WasmBot(Client); impl WasmBot { - async fn on_room_message(&self, room_id: &RoomId, event: &SyncRoomMessageEvent) { - let msg_body = if let SyncRoomMessageEvent { + async fn on_room_message(&self, room_id: &RoomId, event: &OriginalSyncRoomMessageEvent) { + let msg_body = if let OriginalSyncRoomMessageEvent { content: RoomMessageEventContent { msgtype: MessageType::Text(TextMessageEventContent { body: msg_body, .. }), @@ -59,8 +61,9 @@ impl WasmBot { for (room_id, room) in response.rooms.join { for event in room.timeline.events { - if let Ok(AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomMessage(ev))) = - event.event.deserialize() + if let Ok(AnySyncRoomEvent::MessageLike(AnySyncMessageLikeEvent::RoomMessage( + SyncMessageLikeEvent::Original(ev), + ))) = event.event.deserialize() { self.on_room_message(&room_id, &ev).await } diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index 31a895c5f..12ee145a3 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -1660,7 +1660,7 @@ impl Client { /// # let password = ""; /// use matrix_sdk::{ /// Client, config::SyncSettings, - /// ruma::events::room::message::SyncRoomMessageEvent, + /// ruma::events::room::message::OriginalSyncRoomMessageEvent, /// }; /// /// let client = Client::new(homeserver).await?; @@ -1671,7 +1671,7 @@ impl Client { /// /// // Register our handler so we start responding once we receive a new /// // event. - /// client.register_event_handler(|ev: SyncRoomMessageEvent| async move { + /// client.register_event_handler(|ev: OriginalSyncRoomMessageEvent| async move { /// println!("Received event {}: {:?}", ev.sender, ev.content); /// }).await; /// @@ -1765,7 +1765,7 @@ impl Client { /// # let password = ""; /// use matrix_sdk::{ /// Client, config::SyncSettings, - /// ruma::events::room::message::SyncRoomMessageEvent, + /// ruma::events::room::message::OriginalSyncRoomMessageEvent, /// }; /// /// let client = Client::new(homeserver).await?; @@ -1773,7 +1773,7 @@ impl Client { /// /// // Register our handler so we start responding once we receive a new /// // event. - /// client.register_event_handler(|ev: SyncRoomMessageEvent| async move { + /// client.register_event_handler(|ev: OriginalSyncRoomMessageEvent| async move { /// println!("Received event {}: {:?}", ev.sender, ev.content); /// }).await; /// diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index f5e5a89cd..681791ea1 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -56,7 +56,10 @@ use ruma::{ }; use tracing::{debug, instrument, trace, warn}; #[cfg(feature = "encryption")] -use {ruma::api::client::config::set_global_account_data, ruma::events::EventContent}; +use { + ruma::api::client::config::set_global_account_data, + ruma::events::{GlobalAccountDataEventContent, SyncMessageLikeEvent}, +}; use crate::{ attachment::{AttachmentInfo, Thumbnail}, @@ -80,7 +83,10 @@ impl Client { // Turn the AnyMessageLikeEvent into a AnySyncMessageLikeEvent let event = event.clone().into(); - if let AnySyncMessageLikeEvent::RoomEncrypted(e) = event { + if let AnySyncMessageLikeEvent::RoomEncrypted(SyncMessageLikeEvent::Original( + e, + )) = event + { if let Ok(decrypted) = machine.decrypt_room_event(&e, room_id).await { return decrypted; } @@ -90,6 +96,7 @@ impl Client { } // Fallback to still-encrypted room event + RoomEvent { event, encryption_info: None } } @@ -237,7 +244,7 @@ impl Client { content: T, ) -> Result where - T: EventContent, + T: GlobalAccountDataEventContent, { let own_user = self.user_id().await.ok_or_else(|| Error::from(HttpError::AuthenticationRequired))?; diff --git a/crates/matrix-sdk/src/event_handler.rs b/crates/matrix-sdk/src/event_handler.rs index 84c13275d..9567d6f04 100644 --- a/crates/matrix-sdk/src/event_handler.rs +++ b/crates/matrix-sdk/src/event_handler.rs @@ -47,14 +47,36 @@ pub enum EventKind { GlobalAccountData, RoomAccountData, EphemeralRoomData, - Message { redacted: bool }, - State { redacted: bool }, + MessageLike, + OriginalMessageLike, + RedactedMessageLike, + State, + OriginalState, + RedactedState, StrippedState, InitialState, ToDevice, Presence, } +impl EventKind { + fn message_like_redacted(redacted: bool) -> Self { + if redacted { + Self::RedactedMessageLike + } else { + Self::OriginalMessageLike + } + } + + fn state_redacted(redacted: bool) -> Self { + if redacted { + Self::RedactedState + } else { + Self::OriginalState + } + } +} + /// A statically-known event kind/type that can be retrieved from an event sync. pub trait SyncEvent { #[doc(hidden)] @@ -269,6 +291,10 @@ impl Client { unsigned: Option, } + // Event handlers for possibly-redacted state events + self.handle_sync_events(EventKind::State, room, state_events).await?; + + // Event handlers specifically for redacted OR unredacted state events self.handle_sync_events_wrapped_with( room, state_events, @@ -276,10 +302,12 @@ impl Client { |raw| { let StateEventDetails { event_type, unsigned } = raw.deserialize_as()?; let redacted = unsigned.and_then(|u| u.redacted_because).is_some(); - Ok((EventKind::State { redacted }, event_type)) + Ok((EventKind::state_redacted(redacted), event_type)) }, ) - .await + .await?; + + Ok(()) } pub(crate) async fn handle_sync_timeline_events( @@ -295,6 +323,25 @@ impl Client { unsigned: Option, } + // Event handlers for possibly-redacted timeline events + self.handle_sync_events_wrapped_with( + room, + timeline_events, + |e| (&e.event, e.encryption_info.as_ref()), + |raw| { + let TimelineEventDetails { event_type, state_key, .. } = raw.deserialize_as()?; + + let kind = match state_key { + Some(_) => EventKind::State, + None => EventKind::MessageLike, + }; + + Ok((kind, event_type)) + }, + ) + .await?; + + // Event handlers specifically for redacted OR unredacted timeline events self.handle_sync_events_wrapped_with( room, timeline_events, @@ -305,14 +352,16 @@ impl Client { let redacted = unsigned.and_then(|u| u.redacted_because).is_some(); let kind = match state_key { - Some(_) => EventKind::State { redacted }, - None => EventKind::Message { redacted }, + Some(_) => EventKind::state_redacted(redacted), + None => EventKind::message_like_redacted(redacted), }; Ok((kind, event_type)) }, ) - .await + .await?; + + Ok(()) } async fn handle_sync_events_wrapped_with<'a, T: 'a, U: 'a>( @@ -390,72 +439,107 @@ mod static_events { use ruma::events::{ self, presence::{PresenceEvent, PresenceEventContent}, - EphemeralRoomEventType, EventContent, GlobalAccountDataEventType, MessageLikeEventType, - RedactedEventContent, RoomAccountDataEventType, StateEventType, StaticEventContent, - ToDeviceEventType, + EphemeralRoomEventContent, GlobalAccountDataEventContent, MessageLikeEventContent, + RedactContent, RedactedEventContent, RoomAccountDataEventContent, StateEventContent, + StaticEventContent, ToDeviceEventContent, }; use super::{EventKind, SyncEvent}; impl SyncEvent for events::GlobalAccountDataEvent where - C: StaticEventContent + EventContent, + C: StaticEventContent + GlobalAccountDataEventContent, { const ID: (EventKind, &'static str) = (EventKind::GlobalAccountData, C::TYPE); } impl SyncEvent for events::RoomAccountDataEvent where - C: StaticEventContent + EventContent, + C: StaticEventContent + RoomAccountDataEventContent, { const ID: (EventKind, &'static str) = (EventKind::RoomAccountData, C::TYPE); } impl SyncEvent for events::SyncEphemeralRoomEvent where - C: StaticEventContent + EventContent, + C: StaticEventContent + EphemeralRoomEventContent, { const ID: (EventKind, &'static str) = (EventKind::EphemeralRoomData, C::TYPE); } impl SyncEvent for events::SyncMessageLikeEvent where - C: StaticEventContent + EventContent, + C: StaticEventContent + MessageLikeEventContent + RedactContent, + C::Redacted: MessageLikeEventContent + RedactedEventContent, { - const ID: (EventKind, &'static str) = (EventKind::Message { redacted: false }, C::TYPE); + const ID: (EventKind, &'static str) = (EventKind::MessageLike, C::TYPE); + } + + impl SyncEvent for events::OriginalSyncMessageLikeEvent + where + C: StaticEventContent + MessageLikeEventContent, + { + const ID: (EventKind, &'static str) = (EventKind::OriginalMessageLike, C::TYPE); + } + + impl SyncEvent for events::RedactedSyncMessageLikeEvent + where + C: StaticEventContent + MessageLikeEventContent + RedactedEventContent, + { + const ID: (EventKind, &'static str) = (EventKind::RedactedMessageLike, C::TYPE); } impl SyncEvent for events::room::redaction::SyncRoomRedactionEvent { + const ID: (EventKind, &'static str) = + (EventKind::MessageLike, events::room::redaction::RoomRedactionEventContent::TYPE); + } + + impl SyncEvent for events::room::redaction::RedactedSyncRoomRedactionEvent { const ID: (EventKind, &'static str) = ( - EventKind::Message { redacted: false }, + EventKind::OriginalMessageLike, events::room::redaction::RoomRedactionEventContent::TYPE, ); } impl SyncEvent for events::SyncStateEvent where - C: StaticEventContent + EventContent, + C: StaticEventContent + StateEventContent + RedactContent, + C::Redacted: StateEventContent + RedactedEventContent, { - const ID: (EventKind, &'static str) = (EventKind::State { redacted: false }, C::TYPE); + const ID: (EventKind, &'static str) = (EventKind::State, C::TYPE); + } + + impl SyncEvent for events::OriginalSyncStateEvent + where + C: StaticEventContent + StateEventContent, + { + const ID: (EventKind, &'static str) = (EventKind::OriginalState, C::TYPE); + } + + impl SyncEvent for events::RedactedSyncStateEvent + where + C: StaticEventContent + StateEventContent + RedactedEventContent, + { + const ID: (EventKind, &'static str) = (EventKind::RedactedState, C::TYPE); } impl SyncEvent for events::StrippedStateEvent where - C: StaticEventContent + EventContent, + C: StaticEventContent + StateEventContent, { const ID: (EventKind, &'static str) = (EventKind::StrippedState, C::TYPE); } impl SyncEvent for events::InitialStateEvent where - C: StaticEventContent + EventContent, + C: StaticEventContent + StateEventContent, { const ID: (EventKind, &'static str) = (EventKind::InitialState, C::TYPE); } impl SyncEvent for events::ToDeviceEvent where - C: StaticEventContent + EventContent, + C: StaticEventContent + ToDeviceEventContent, { const ID: (EventKind, &'static str) = (EventKind::ToDevice, C::TYPE); } @@ -463,29 +547,6 @@ mod static_events { impl SyncEvent for PresenceEvent { const ID: (EventKind, &'static str) = (EventKind::Presence, PresenceEventContent::TYPE); } - - impl SyncEvent for events::RedactedSyncMessageLikeEvent - where - C: StaticEventContent - + EventContent - + RedactedEventContent, - { - const ID: (EventKind, &'static str) = (EventKind::Message { redacted: true }, C::TYPE); - } - - impl SyncEvent for events::room::redaction::RedactedSyncRoomRedactionEvent { - const ID: (EventKind, &'static str) = ( - EventKind::Message { redacted: true }, - events::room::redaction::RoomRedactionEventContent::TYPE, - ); - } - - impl SyncEvent for events::RedactedSyncStateEvent - where - C: StaticEventContent + EventContent + RedactedEventContent, - { - const ID: (EventKind, &'static str) = (EventKind::State { redacted: true }, C::TYPE); - } } #[cfg(all(test, not(target_arch = "wasm32")))] @@ -497,7 +558,7 @@ mod tests { use matrix_sdk_test::{EventBuilder, EventsJson}; use ruma::{ - events::room::member::{StrippedRoomMemberEvent, SyncRoomMemberEvent}, + events::room::member::{OriginalSyncRoomMemberEvent, StrippedRoomMemberEvent}, room_id, }; use serde_json::json; @@ -518,7 +579,7 @@ mod tests { client .register_event_handler({ let member_count = member_count.clone(); - move |_ev: SyncRoomMemberEvent, _room: room::Room| { + move |_ev: OriginalSyncRoomMemberEvent, _room: room::Room| { member_count.fetch_add(1, SeqCst); future::ready(()) } @@ -526,7 +587,7 @@ mod tests { .await .register_event_handler({ let typing_count = typing_count.clone(); - move |_ev: SyncRoomMemberEvent| { + move |_ev: OriginalSyncRoomMemberEvent| { typing_count.fetch_add(1, SeqCst); future::ready(()) } @@ -534,7 +595,7 @@ mod tests { .await .register_event_handler({ let power_levels_count = power_levels_count.clone(); - move |_ev: SyncRoomMemberEvent, _client: Client, _room: room::Room| { + move |_ev: OriginalSyncRoomMemberEvent, _client: Client, _room: room::Room| { power_levels_count.fetch_add(1, SeqCst); future::ready(()) } diff --git a/crates/matrix-sdk/src/room/common.rs b/crates/matrix-sdk/src/room/common.rs index 65b54aa39..b79c0d3e3 100644 --- a/crates/matrix-sdk/src/room/common.rs +++ b/crates/matrix-sdk/src/room/common.rs @@ -18,8 +18,9 @@ use ruma::{ events::{ room::{history_visibility::HistoryVisibility, MediaSource}, tag::{TagInfo, TagName}, - AnyRoomAccountDataEvent, AnyStateEvent, AnySyncStateEvent, EventContent, - RoomAccountDataEvent, RoomAccountDataEventType, StateEventType, StaticEventContent, + AnyRoomAccountDataEvent, AnyStateEvent, AnySyncStateEvent, RedactContent, + RedactedEventContent, RoomAccountDataEvent, RoomAccountDataEventContent, + RoomAccountDataEventType, StateEventContent, StateEventType, StaticEventContent, SyncStateEvent, }, serde::Raw, @@ -662,7 +663,8 @@ impl Common { /// ``` pub async fn get_state_events_static(&self) -> Result>>> where - C: StaticEventContent + EventContent, + C: StaticEventContent + StateEventContent + RedactContent, + C::Redacted: StateEventContent + RedactedEventContent, { // FIXME: Could be more efficient, if we had streaming store accessor functions Ok(self.get_state_events(C::TYPE.into()).await?.into_iter().map(Raw::cast).collect()) @@ -702,7 +704,8 @@ impl Common { state_key: &str, ) -> Result>>> where - C: StaticEventContent + EventContent, + C: StaticEventContent + StateEventContent + RedactContent, + C::Redacted: StateEventContent + RedactedEventContent, { Ok(self.get_state_event(C::TYPE.into(), state_key).await?.map(Raw::cast)) } @@ -737,7 +740,7 @@ impl Common { /// ``` pub async fn account_data_static(&self) -> Result>>> where - C: StaticEventContent + EventContent, + C: StaticEventContent + RoomAccountDataEventContent, { Ok(self.account_data(C::TYPE.into()).await?.map(Raw::cast)) } diff --git a/crates/matrix-sdk/src/room/joined.rs b/crates/matrix-sdk/src/room/joined.rs index 3573903c0..f7bf778df 100644 --- a/crates/matrix-sdk/src/room/joined.rs +++ b/crates/matrix-sdk/src/room/joined.rs @@ -26,9 +26,7 @@ use ruma::{ typing::create_typing_event::v3::{Request as TypingRequest, Typing}, }, assign, - events::{ - room::message::RoomMessageEventContent, EventContent, MessageLikeEventType, StateEventType, - }, + events::{room::message::RoomMessageEventContent, MessageLikeEventContent, StateEventContent}, receipt::ReceiptType, serde::Raw, EventId, TransactionId, UserId, @@ -468,7 +466,7 @@ impl Joined { /// [`transaction_id`]: ruma::events::MessageLikeUnsigned#structfield.transaction_id pub async fn send( &self, - content: impl EventContent, + content: impl MessageLikeEventContent, txn_id: Option<&TransactionId>, ) -> Result { let event_type = content.event_type().to_string(); @@ -808,7 +806,7 @@ impl Joined { /// ``` pub async fn send_state_event( &self, - content: impl EventContent, + content: impl StateEventContent, state_key: &str, ) -> Result { let request = From 35f598a09582d69a7c73de806c63318ca10b7d39 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 11 Apr 2022 18:23:50 +0200 Subject: [PATCH 5/5] fix(sdk): Change the default guest_access state to Forbidden --- crates/matrix-sdk-base/src/rooms/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/matrix-sdk-base/src/rooms/mod.rs b/crates/matrix-sdk-base/src/rooms/mod.rs index 03382dca0..f1924096e 100644 --- a/crates/matrix-sdk-base/src/rooms/mod.rs +++ b/crates/matrix-sdk-base/src/rooms/mod.rs @@ -185,7 +185,7 @@ impl Default for BaseRoomInfo { create: None, dm_target: None, encryption: None, - guest_access: GuestAccess::CanJoin, + guest_access: GuestAccess::Forbidden, history_visibility: HistoryVisibility::WorldReadable, join_rule: JoinRule::Public, max_power_level: 100,