1pub(crate) mod cipher_suite;
2pub mod conversation;
3pub(crate) mod conversation_cache;
4pub mod credential;
5mod error;
6mod external_sender;
7pub mod key_package;
8pub(crate) mod session;
9
10pub use error::{Error, Result};
11pub use external_sender::ExternalSender;
12pub use session::{EpochObserver, HistoryObserver};
13
14#[cfg(test)]
15mod tests {
16 use crate::{CoreCrypto, test_utils::*, transaction_context::Error as TransactionError};
17
18 mod conversation_epoch {
19 use super::*;
20
21 #[apply(all_cred_cipher)]
22 async fn can_get_newly_created_conversation_epoch(case: TestContext) {
23 let [session] = case.sessions().await;
24 let conversation = case.create_conversation([&session]).await;
25 let epoch = conversation.guard().await.epoch().await;
26 assert_eq!(epoch, 0);
27 }
28
29 #[apply(all_cred_cipher)]
30 async fn can_get_conversation_epoch(case: TestContext) {
31 let [alice, bob] = case.sessions().await;
32 Box::pin(async move {
33 let conversation = case.create_conversation([&alice, &bob]).await;
34 let epoch = conversation.guard().await.epoch().await;
35 assert_eq!(epoch, 1);
36 })
37 .await;
38 }
39
40 #[apply(all_cred_cipher)]
41 async fn conversation_not_found(case: TestContext) {
42 use crate::LeafError;
43 let [session] = case.sessions().await;
44 let id = conversation_id();
45 let err = session.transaction.conversation(&id).await.unwrap_err();
46 assert!(matches!(
47 err,
48 TransactionError::Leaf(LeafError::ConversationNotFound(i)) if i == id
49 ));
50 }
51 }
52
53 #[apply(all_cred_cipher)]
54 async fn create_conversation_should_fail_when_already_exists(case: TestContext) {
55 use crate::LeafError;
56
57 let [alice] = case.sessions().await;
58 Box::pin(async move {
59 let conversation = case.create_conversation([&alice]).await;
60 let id = conversation.id().clone();
61 let credentials = alice.find_credentials(Default::default()).await.expect("finding credentials");
62 let credential = credentials.first().expect("first credential");
63
64 let repeat_create = alice
66 .transaction
67 .new_conversation(&id, credential, case.cfg.clone())
68 .await;
69 assert!(matches!(repeat_create.unwrap_err(), TransactionError::Leaf(LeafError::ConversationAlreadyExists(i)) if i == id));
70 })
71 .await;
72 }
73
74 #[apply(all_cred_cipher)]
75 async fn can_2_phase_init_central(mut case: TestContext) {
76 let db = case.create_persistent_db().await;
77 Box::pin(async move {
78 use std::sync::Arc;
79
80 use wire_e2e_identity::pki_env::PkiEnvironment;
81
82 use crate::test_utils::DummyPkiEnvironmentHooks;
83
84 let x509_test_chain = case.set_test_chain(&[], &[], None).await;
85
86 let cc = CoreCrypto::new(db.clone());
88 let context = cc.new_transaction().await.unwrap();
89
90 let hooks = Arc::new(DummyPkiEnvironmentHooks);
91 let pki_env = PkiEnvironment::new(hooks, db).await.expect("creating pki environment");
92 cc.set_pki_environment(Some(Arc::new(pki_env))).await;
93
94 x509_test_chain.register_with_central(&context).await;
95
96 let credential = case.generate_credential().await;
98 let session_id = credential.client_id().to_owned();
99 context
100 .mls_init(
101 session_id.clone(),
102 Arc::new(CoreCryptoTransportSuccessProvider::default()),
103 )
104 .await
105 .unwrap();
106
107 let credential_ref = context.add_credential(credential).await.unwrap();
108
109 assert!(context.generate_key_package(&credential_ref, None).await.is_ok());
111 })
112 .await
113 }
114}