Skip to main content

opentalk_roomserver_types_e2ee/
command.rs

1// SPDX-License-Identifier: EUPL-1.2
2// SPDX-FileCopyrightText: OpenTalk Team <mail@opentalk.eu>
3
4use opentalk_roomserver_signaling::signaling_module::CreateReplica;
5use opentalk_roomserver_types::connection_id::ConnectionId;
6use serde::{Deserialize, Serialize};
7
8use crate::{E2eeEvent, MlsMessages, WelcomeMessage};
9
10#[derive(Deserialize, Serialize, PartialEq, Debug)]
11#[serde(tag = "action", rename_all = "snake_case")]
12pub enum E2eeCommand {
13    Invite {
14        invitee: ConnectionId,
15        welcome_message: WelcomeMessage,
16        /// Proposal and commit sent to the existing members of the group
17        mls_messages: MlsMessages,
18    },
19    Message(MlsMessages),
20}
21
22impl CreateReplica<E2eeEvent> for E2eeCommand {
23    fn replicate(&self) -> Option<E2eeEvent> {
24        // Replication is handled by the module.
25        None
26    }
27}
28
29#[cfg(test)]
30mod tests {
31
32    use std::str::FromStr;
33
34    use bytes::Bytes;
35    use opentalk_roomserver_types::connection_id::ConnectionId;
36    use pretty_assertions::assert_eq;
37    use serde_json::json;
38
39    use super::*;
40    use crate::WelcomeMessage;
41
42    const SAMPLE_UUID: &str = "6650b3e2-5f1c-4073-951e-cc4bcd6ddfef";
43
44    fn sample_invite_command() -> E2eeCommand {
45        E2eeCommand::Invite {
46            invitee: ConnectionId::from_str(SAMPLE_UUID).expect("SAMPLE_UUID must be a valid UUID"),
47            welcome_message: WelcomeMessage {
48                welcome: Bytes::from_static(b"welcome-bytes"),
49                ratchet_tree: Bytes::from_static(b"ratchet-tree-bytes"),
50            },
51            mls_messages: MlsMessages {
52                payload: vec![Bytes::from_static(b"mls1"), Bytes::from_static(b"mls2")],
53            },
54        }
55    }
56
57    fn sample_mls_messages() -> MlsMessages {
58        MlsMessages {
59            payload: vec![Bytes::from_static(b"mls1"), Bytes::from_static(b"mls2")],
60        }
61    }
62
63    #[test]
64    fn serialize_invite_command() {
65        let cmd = sample_invite_command();
66        let serialized = serde_json::to_value(&cmd).unwrap();
67
68        let expected = json!({
69            "action": "invite",
70            "invitee": SAMPLE_UUID,
71            "welcome_message": {
72                "welcome": b"welcome-bytes",
73                "ratchet_tree": b"ratchet-tree-bytes",
74            },
75            "mls_messages": {
76                "payload": [
77                    b"mls1",
78                    b"mls2",
79                ]
80            }
81        });
82
83        assert_eq!(
84            serialized, expected,
85            "Invite serialization mismatch.\nExpected: {expected:?}\nGot: {serialized:?}"
86        );
87    }
88
89    #[test]
90    fn serialize_message_command() {
91        let mls_messages = sample_mls_messages();
92        let cmd = E2eeCommand::Message(mls_messages.clone());
93        let serialized = serde_json::to_value(&cmd).unwrap();
94
95        let expected = json!({
96            "action": "message",
97            "payload": [
98                b"mls1",
99                b"mls2",
100            ]
101        });
102
103        assert_eq!(
104            serialized, expected,
105            "Message serialization mismatch.\nExpected: {expected:?}\nGot: {serialized:?}"
106        );
107    }
108
109    #[test]
110    fn deserialize_invite_command() {
111        let expected = sample_invite_command();
112        let value = json!({
113            "action": "invite",
114            "invitee": SAMPLE_UUID,
115            "welcome_message": {
116                "welcome": b"welcome-bytes",
117                "ratchet_tree": b"ratchet-tree-bytes",
118            },
119            "mls_messages": {
120                "payload": [
121                    b"mls1",
122                    b"mls2",
123                ]
124            }
125        });
126
127        let cmd: E2eeCommand = serde_json::from_value(value).unwrap();
128        assert_eq!(cmd, expected);
129    }
130
131    #[test]
132    fn deserialize_message_command() {
133        let mls_messages = sample_mls_messages();
134        let value = json!({
135            "action": "message",
136            "payload": [
137                b"mls1",
138                b"mls2",
139            ]
140        });
141
142        let cmd: E2eeCommand = serde_json::from_value(value).unwrap();
143        assert_eq!(cmd, E2eeCommand::Message(mls_messages.clone()),);
144    }
145
146    #[test]
147    fn replicate_message() {
148        let mls_messages = sample_mls_messages();
149        let cmd = E2eeCommand::Message(mls_messages.clone());
150        let event = cmd.replicate();
151        assert_eq!(event, None);
152    }
153}