ruma_events/room/encrypted/
unstable_state.rs1use ruma_common::room_version_rules::RedactionRules;
5use ruma_macros::EventContent;
6use serde::{Deserialize, Serialize};
7
8use crate::{
9 PossiblyRedactedStateEventContent, RedactContent, StateEventType, StaticEventContent,
10 room::encrypted::EncryptedEventScheme,
11};
12
13#[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
15#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
16#[ruma_event(type = "m.room.encrypted", kind = State, state_key_type = String, custom_possibly_redacted)]
17pub struct StateRoomEncryptedEventContent {
18 #[serde(flatten)]
20 pub scheme: EncryptedEventScheme,
21}
22
23#[derive(Clone, Debug, Default, Serialize, Deserialize)]
25#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
26pub struct PossiblyRedactedStateRoomEncryptedEventContent {
27 #[serde(flatten, skip_serializing_if = "Option::is_none")]
29 pub scheme: Option<EncryptedEventScheme>,
30}
31
32impl StaticEventContent for PossiblyRedactedStateRoomEncryptedEventContent {
33 const TYPE: &'static str = StateRoomEncryptedEventContent::TYPE;
34 type IsPrefix = <StateRoomEncryptedEventContent as StaticEventContent>::IsPrefix;
35}
36
37impl PossiblyRedactedStateEventContent for PossiblyRedactedStateRoomEncryptedEventContent {
38 type StateKey = String;
39
40 fn event_type(&self) -> StateEventType {
41 StateEventType::RoomEncrypted
42 }
43}
44
45impl RedactContent for PossiblyRedactedStateRoomEncryptedEventContent {
46 type Redacted = Self;
47
48 fn redact(self, _rules: &RedactionRules) -> Self::Redacted {
49 Self { scheme: None }
50 }
51}
52
53impl From<StateRoomEncryptedEventContent> for PossiblyRedactedStateRoomEncryptedEventContent {
54 fn from(value: StateRoomEncryptedEventContent) -> Self {
55 let StateRoomEncryptedEventContent { scheme } = value;
56 Self { scheme: Some(scheme) }
57 }
58}
59
60impl From<RedactedStateRoomEncryptedEventContent>
61 for PossiblyRedactedStateRoomEncryptedEventContent
62{
63 fn from(_value: RedactedStateRoomEncryptedEventContent) -> Self {
64 Self { scheme: None }
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use js_int::uint;
71 use ruma_common::canonical_json::assert_to_canonical_json_eq;
72 use serde_json::{from_value as from_json_value, json};
73 use strass::assert_let;
74
75 use crate::{
76 AnyStateEvent, StateEvent,
77 room::encrypted::{
78 EncryptedEventScheme, MegolmV1AesSha2ContentInit,
79 unstable_state::StateRoomEncryptedEventContent,
80 },
81 };
82
83 #[test]
84 fn serialize_content() {
85 let key_verification_start_content = StateRoomEncryptedEventContent {
86 scheme: EncryptedEventScheme::MegolmV1AesSha2(
87 MegolmV1AesSha2ContentInit {
88 ciphertext: "ciphertext".into(),
89 sender_key: "sender_key".into(),
90 device_id: "device_id".into(),
91 session_id: "session_id".into(),
92 }
93 .into(),
94 ),
95 };
96
97 assert_to_canonical_json_eq!(
98 key_verification_start_content,
99 json!({
100 "algorithm": "m.megolm.v1.aes-sha2",
101 "ciphertext": "ciphertext",
102 "sender_key": "sender_key",
103 "device_id": "device_id",
104 "session_id": "session_id",
105 }),
106 );
107 }
108
109 #[test]
110 #[allow(deprecated)]
111 fn deserialize_content() {
112 let json_data = json!({
113 "algorithm": "m.megolm.v1.aes-sha2",
114 "ciphertext": "ciphertext",
115 "session_id": "session_id",
116 });
117
118 let content: StateRoomEncryptedEventContent = from_json_value(json_data).unwrap();
119
120 assert_let!(EncryptedEventScheme::MegolmV1AesSha2(scheme) = content.scheme);
121 assert_eq!(scheme.ciphertext, "ciphertext");
122 assert_eq!(scheme.sender_key, None);
123 assert_eq!(scheme.device_id, None);
124 assert_eq!(scheme.session_id, "session_id");
125 }
126
127 #[test]
128 #[allow(deprecated)]
129 fn deserialize_event() {
130 let json_data = json!({
131 "type": "m.room.encrypted",
132 "event_id": "$event_id:example.com",
133 "room_id": "!roomid:example.com",
134 "sender": "@example:example.com",
135 "origin_server_ts": 1_234_567_890,
136 "state_key": "",
137 "content": {
138 "algorithm": "m.megolm.v1.aes-sha2",
139 "ciphertext": "ciphertext",
140 "session_id": "session_id",
141 }
142 });
143 let event = from_json_value::<AnyStateEvent>(json_data).unwrap();
144
145 assert_let!(AnyStateEvent::RoomEncrypted(StateEvent::Original(ev)) = event);
146
147 assert_let!(EncryptedEventScheme::MegolmV1AesSha2(scheme) = ev.content.scheme);
148 assert_eq!(scheme.ciphertext, "ciphertext");
149 assert_eq!(scheme.sender_key, None);
150 assert_eq!(scheme.device_id, None);
151 assert_eq!(scheme.session_id, "session_id");
152
153 assert_eq!(ev.sender, "@example:example.com");
154 assert_eq!(ev.room_id, "!roomid:example.com");
155 assert_eq!(ev.origin_server_ts.0, uint!(1_234_567_890));
156 assert_eq!(ev.state_key, "");
157 }
158}