use ruma_common::room_version_rules::RedactionRules;
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};
use crate::{
PossiblyRedactedStateEventContent, RedactContent, StateEventType, StaticEventContent,
room::encrypted::EncryptedEventScheme,
};
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
#[ruma_event(type = "m.room.encrypted", kind = State, state_key_type = String, custom_possibly_redacted)]
pub struct StateRoomEncryptedEventContent {
#[serde(flatten)]
pub scheme: EncryptedEventScheme,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
pub struct PossiblyRedactedStateRoomEncryptedEventContent {
#[serde(flatten, skip_serializing_if = "Option::is_none")]
pub scheme: Option<EncryptedEventScheme>,
}
impl StaticEventContent for PossiblyRedactedStateRoomEncryptedEventContent {
const TYPE: &'static str = StateRoomEncryptedEventContent::TYPE;
type IsPrefix = <StateRoomEncryptedEventContent as StaticEventContent>::IsPrefix;
}
impl PossiblyRedactedStateEventContent for PossiblyRedactedStateRoomEncryptedEventContent {
type StateKey = String;
fn event_type(&self) -> StateEventType {
StateEventType::RoomEncrypted
}
}
impl RedactContent for PossiblyRedactedStateRoomEncryptedEventContent {
type Redacted = Self;
fn redact(self, _rules: &RedactionRules) -> Self::Redacted {
Self { scheme: None }
}
}
impl From<StateRoomEncryptedEventContent> for PossiblyRedactedStateRoomEncryptedEventContent {
fn from(value: StateRoomEncryptedEventContent) -> Self {
let StateRoomEncryptedEventContent { scheme } = value;
Self { scheme: Some(scheme) }
}
}
impl From<RedactedStateRoomEncryptedEventContent>
for PossiblyRedactedStateRoomEncryptedEventContent
{
fn from(_value: RedactedStateRoomEncryptedEventContent) -> Self {
Self { scheme: None }
}
}
#[cfg(test)]
mod tests {
use assert_matches2::assert_matches;
use js_int::uint;
use ruma_common::{
MilliSecondsSinceUnixEpoch, canonical_json::assert_to_canonical_json_eq, room_id, user_id,
};
use serde_json::{from_value as from_json_value, json};
use crate::{
AnyStateEvent, StateEvent,
room::encrypted::{
EncryptedEventScheme, MegolmV1AesSha2ContentInit,
unstable_state::StateRoomEncryptedEventContent,
},
};
#[test]
fn serialize_content() {
let key_verification_start_content = StateRoomEncryptedEventContent {
scheme: EncryptedEventScheme::MegolmV1AesSha2(
MegolmV1AesSha2ContentInit {
ciphertext: "ciphertext".into(),
sender_key: "sender_key".into(),
device_id: "device_id".into(),
session_id: "session_id".into(),
}
.into(),
),
};
assert_to_canonical_json_eq!(
key_verification_start_content,
json!({
"algorithm": "m.megolm.v1.aes-sha2",
"ciphertext": "ciphertext",
"sender_key": "sender_key",
"device_id": "device_id",
"session_id": "session_id",
}),
);
}
#[test]
#[allow(deprecated)]
fn deserialize_content() {
let json_data = json!({
"algorithm": "m.megolm.v1.aes-sha2",
"ciphertext": "ciphertext",
"session_id": "session_id",
});
let content: StateRoomEncryptedEventContent = from_json_value(json_data).unwrap();
assert_matches!(content.scheme, EncryptedEventScheme::MegolmV1AesSha2(scheme));
assert_eq!(scheme.ciphertext, "ciphertext");
assert_eq!(scheme.sender_key, None);
assert_eq!(scheme.device_id, None);
assert_eq!(scheme.session_id, "session_id");
}
#[test]
#[allow(deprecated)]
fn deserialize_event() {
let json_data = json!({
"type": "m.room.encrypted",
"event_id": "$event_id:example.com",
"room_id": "!roomid:example.com",
"sender": "@example:example.com",
"origin_server_ts": 1_234_567_890,
"state_key": "",
"content": {
"algorithm": "m.megolm.v1.aes-sha2",
"ciphertext": "ciphertext",
"session_id": "session_id",
}
});
let event = from_json_value::<AnyStateEvent>(json_data).unwrap();
assert_matches!(event, AnyStateEvent::RoomEncrypted(StateEvent::Original(ev)));
assert_matches!(ev.content.scheme, EncryptedEventScheme::MegolmV1AesSha2(scheme));
assert_eq!(scheme.ciphertext, "ciphertext");
assert_eq!(scheme.sender_key, None);
assert_eq!(scheme.device_id, None);
assert_eq!(scheme.session_id, "session_id");
assert_eq!(ev.sender, user_id!("@example:example.com"));
assert_eq!(ev.room_id, room_id!("!roomid:example.com"));
assert_eq!(ev.origin_server_ts, MilliSecondsSinceUnixEpoch(uint!(1_234_567_890)));
assert_eq!(ev.state_key, "");
}
}