Skip to content

Commit 3146be3

Browse files
committed
fix(crypto): Fix the serialization of DecryptedOlmV1Event
1 parent a6ec092 commit 3146be3

File tree

1 file changed

+73
-2
lines changed
  • crates/matrix-sdk-crypto/src/types/events

1 file changed

+73
-2
lines changed

crates/matrix-sdk-crypto/src/types/events/olm_v1.rs

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ impl AnyDecryptedOlmEvent {
162162
}
163163

164164
/// An `m.olm.v1.curve25519-aes-sha2` decrypted to-device event.
165-
#[derive(Clone, Debug, Deserialize, Serialize)]
165+
///
166+
/// **Note**: This event will reserialize events lossy, unknown fields will be
167+
/// lost during deserialization.
168+
#[derive(Clone, Debug, Deserialize)]
166169
pub struct DecryptedOlmV1Event<C>
167170
where
168171
C: EventType + Debug + Sized + Serialize,
@@ -182,6 +185,59 @@ where
182185
pub content: C,
183186
}
184187

188+
impl<C: EventType + Debug + Sized + Serialize> Serialize for DecryptedOlmV1Event<C> {
189+
/// A customized [`Serialize`] implementation that ensures that the
190+
/// `event_type` field is present in the serialized JSON.
191+
///
192+
/// The `event_type` in the [`DecryptedOlmV1Event`] is omitted because the
193+
/// event type is expressed in the generic type `C`. To properly serialize
194+
/// the [`DecryptedOlmV1Event`] we'll must extract the event type from `C`
195+
/// and reintroduce it into the JSON field.
196+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
197+
where
198+
S: serde::Serializer,
199+
{
200+
#[derive(Serialize)]
201+
struct DecryptedEventSerializationHelper<'a, C: EventType + Debug + Sized + Serialize> {
202+
sender: &'a UserId,
203+
recipient: &'a UserId,
204+
keys: &'a OlmV1Keys,
205+
recipient_keys: &'a OlmV1Keys,
206+
#[serde(
207+
rename = "org.matrix.msc4147.device_keys",
208+
skip_serializing_if = "Option::is_none"
209+
)]
210+
sender_device_keys: Option<&'a DeviceKeys>,
211+
content: &'a C,
212+
#[serde(rename = "type")]
213+
event_type: &'a str,
214+
}
215+
216+
let event_type = self.content.event_type();
217+
218+
let DecryptedOlmV1Event {
219+
sender,
220+
recipient,
221+
keys,
222+
recipient_keys,
223+
sender_device_keys,
224+
content,
225+
} = &self;
226+
227+
let event = DecryptedEventSerializationHelper {
228+
sender,
229+
recipient,
230+
keys,
231+
recipient_keys,
232+
sender_device_keys: sender_device_keys.as_ref(),
233+
content,
234+
event_type,
235+
};
236+
237+
event.serialize(serializer)
238+
}
239+
}
240+
185241
impl<C: EventType + Debug + Sized + Serialize> DecryptedOlmV1Event<C> {
186242
#[cfg(test)]
187243
/// Test helper to create a new [`DecryptedOlmV1Event`] with the given
@@ -269,6 +325,7 @@ mod tests {
269325
use assert_matches::assert_matches;
270326
use ruma::{device_id, owned_user_id, KeyId};
271327
use serde_json::{json, Value};
328+
use similar_asserts::assert_eq;
272329
use vodozemac::{Curve25519PublicKey, Ed25519PublicKey, Ed25519Signature};
273330

274331
use super::AnyDecryptedOlmEvent;
@@ -298,7 +355,6 @@ mod tests {
298355
fn room_key_event() -> Value {
299356
json!({
300357
"sender": "@alice:example.org",
301-
"sender_device": "DEVICEID",
302358
"keys": {
303359
"ed25519": ED25519_KEY,
304360
},
@@ -513,4 +569,19 @@ mod tests {
513569
// Then it contains the sender_device_keys
514570
assert_eq!(event.sender_device_keys, Some(sender_device_keys));
515571
}
572+
573+
#[test]
574+
fn test_serialization_cycle() {
575+
let event_json = room_key_event();
576+
let event: DecryptedRoomKeyEvent = serde_json::from_value(event_json.clone())
577+
.expect("JSON should deserialize to the right event type");
578+
579+
let reserialized =
580+
serde_json::to_value(event).expect("We should be able to serialize the event");
581+
582+
assert_eq!(
583+
event_json, reserialized,
584+
"The reserialized JSON should match the original value"
585+
);
586+
}
516587
}

0 commit comments

Comments
 (0)