core_crypto/mls/conversation/
external_sender.rs

1use crate::context::CentralContext;
2use crate::prelude::{ConversationId, CryptoError, CryptoResult, MlsCentral, MlsConversation};
3
4impl MlsCentral {
5    /// Returns the raw public key of the single external sender present in this group.
6    /// This should be used to initialize a subconversation
7    pub async fn get_external_sender(&self, id: &ConversationId) -> CryptoResult<Vec<u8>> {
8        self.get_conversation(id)
9            .await?
10            .ok_or_else(|| CryptoError::ConversationNotFound(id.clone()))?
11            .get_external_sender()
12            .await
13    }
14}
15
16impl CentralContext {
17    /// See [MlsCentral::get_external_sender]
18    pub async fn get_external_sender(&self, id: &ConversationId) -> CryptoResult<Vec<u8>> {
19        self.get_conversation(id)
20            .await?
21            .read()
22            .await
23            .get_external_sender()
24            .await
25    }
26}
27
28impl MlsConversation {
29    async fn get_external_sender(&self) -> CryptoResult<Vec<u8>> {
30        let ext_senders = self
31            .group
32            .group_context_extensions()
33            .external_senders()
34            .ok_or(CryptoError::MissingExternalSenderExtension)?;
35        let ext_sender = ext_senders.first().ok_or(CryptoError::MissingExternalSenderExtension)?;
36        let ext_sender_public_key = ext_sender.signature_key().as_slice().to_vec();
37        Ok(ext_sender_public_key)
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use wasm_bindgen_test::*;
44
45    use crate::test_utils::*;
46
47    wasm_bindgen_test_configure!(run_in_browser);
48
49    #[apply(all_cred_cipher)]
50    #[wasm_bindgen_test]
51    pub async fn should_fetch_ext_sender(case: TestCase) {
52        run_test_with_client_ids(case.clone(), ["alice"], move |[alice_central]| {
53            Box::pin(async move {
54                let id = conversation_id();
55
56                // by default in test no external sender is set. Let's add one
57                let mut cfg = case.cfg.clone();
58                let external_sender = alice_central.rand_external_sender(&case).await;
59                cfg.external_senders = vec![external_sender.clone()];
60
61                alice_central
62                    .context
63                    .new_conversation(&id, case.credential_type, cfg)
64                    .await
65                    .unwrap();
66
67                let alice_ext_sender = alice_central.context.get_external_sender(&id).await.unwrap();
68                assert!(!alice_ext_sender.is_empty());
69                assert_eq!(alice_ext_sender, external_sender.signature_key().as_slice().to_vec());
70            })
71        })
72        .await
73    }
74}