diff --git a/matrix_sdk_crypto/Cargo.toml b/matrix_sdk_crypto/Cargo.toml index 7b42b582..80d168e4 100644 --- a/matrix_sdk_crypto/Cargo.toml +++ b/matrix_sdk_crypto/Cargo.toml @@ -48,6 +48,7 @@ byteorder = "1.4.3" [dev-dependencies] tokio = { version = "1.7.1", default-features = false, features = ["rt-multi-thread", "macros"] } proptest = "1.0.0" +matches = "0.1.8" serde_json = "1.0.64" tempfile = "3.2.0" http = "0.2.4" diff --git a/matrix_sdk_crypto/src/olm/mod.rs b/matrix_sdk_crypto/src/olm/mod.rs index 02767025..9abe2620 100644 --- a/matrix_sdk_crypto/src/olm/mod.rs +++ b/matrix_sdk_crypto/src/olm/mod.rs @@ -61,11 +61,19 @@ where pub(crate) mod test { use std::{collections::BTreeMap, convert::TryInto}; + use matches::assert_matches; use olm_rs::session::OlmMessage; use ruma::{ - encryption::SignedKey, events::forwarded_room_key::ForwardedRoomKeyToDeviceEventContent, + encryption::SignedKey, + event_id, + events::{ + forwarded_room_key::ForwardedRoomKeyToDeviceEventContent, + room::message::{MessageEventContent, Relation, Replacement}, + AnyMessageEventContent, AnySyncMessageEvent, AnySyncRoomEvent, + }, room_id, user_id, DeviceId, UserId, }; + use serde_json::json; use crate::olm::{InboundGroupSession, ReadOnlyAccount, Session}; @@ -214,6 +222,71 @@ pub(crate) mod test { assert_eq!(plaintext, inbound.decrypt_helper(ciphertext).await.unwrap().0); } + #[tokio::test] + async fn edit_decryption() { + let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id()); + let room_id = room_id!("!test:localhost"); + let event_id = event_id!("$1234adfad:asdf"); + + let (outbound, _) = alice.create_group_session_pair_with_defaults(&room_id).await.unwrap(); + + assert_eq!(0, outbound.message_index().await); + assert!(!outbound.shared()); + outbound.mark_as_shared(); + assert!(outbound.shared()); + + let mut content = MessageEventContent::text_plain("Hello"); + content.relates_to = Some(Relation::Replacement(Replacement::new( + event_id.clone(), + MessageEventContent::text_plain("Hello edit").into(), + ))); + + let inbound = InboundGroupSession::new( + "test_key", + "test_key", + &room_id, + outbound.session_key().await, + None, + ) + .unwrap(); + + assert_eq!(0, inbound.first_known_index()); + + assert_eq!(outbound.session_id(), inbound.session_id()); + + let encrypted_content = + outbound.encrypt(AnyMessageEventContent::RoomMessage(content)).await; + + let event = json!({ + "sender": alice.user_id(), + "event_id": event_id, + "origin_server_ts": 0, + "room_id": room_id, + "type": "m.room.encrypted", + "content": encrypted_content, + }) + .to_string(); + + let event: AnySyncRoomEvent = serde_json::from_str(&event).expect("WHAAAT?!?!?"); + + let event = + if let AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomEncrypted(event)) = event { + event + } else { + panic!("Invalid event type") + }; + + let decrypted = inbound.decrypt(&event).await.unwrap().0; + + if let AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomMessage(e)) = + decrypted.deserialize().unwrap() + { + assert_matches!(e.content.relates_to, Some(Relation::Replacement(_))); + } else { + panic!("Invalid event type") + } + } + #[tokio::test] async fn group_session_export() { let alice = ReadOnlyAccount::new(&alice_id(), &alice_device_id());