core_crypto/mls/conversation/mutable/
mod.rs1mod commit;
2pub(crate) mod decrypt;
3mod encrypt;
4mod group_mutation;
5mod history_sharing;
6mod merge;
7mod own_commit;
8mod proposal;
9mod tnt;
10mod wipe;
11
12use std::sync::Arc;
13
14use core_crypto_keystore::Database;
15use openmls::prelude::group_info::GroupInfo;
16
17pub use self::tnt::TargetedMessagePolicy;
18pub(crate) use self::tnt::TntMessageCounter;
19use super::{Error, Result};
20use crate::{
21 CryptoProvider, GroupInfoBundle, LeafError, MlsTransport, RecursiveError, Session,
22 mls::{conversation::Conversation, credential::Credential},
23 transaction_context::TransactionContext,
24};
25
26#[derive(Debug, derive_more::Constructor, derive_more::Deref)]
36pub struct ConversationMut {
37 #[deref(forward)]
38 inner: Arc<Conversation>,
39 tx_context: TransactionContext,
40}
41
42impl ConversationMut {
43 async fn transport(&self) -> Result<Arc<dyn MlsTransport>> {
44 self.tx_context
45 .mls_transport()
46 .await
47 .map_err(RecursiveError::transaction("getting transport for conversation guard"))
48 .map_err(Into::into)
49 }
50
51 async fn database(&self) -> Result<Arc<Database>> {
52 self.tx_context
53 .database()
54 .await
55 .map_err(RecursiveError::transaction("getting database from context"))
56 .map_err(Into::into)
57 }
58
59 async fn crypto_provider(&self) -> Result<CryptoProvider> {
60 self.tx_context
61 .crypto_provider()
62 .await
63 .map_err(RecursiveError::transaction(
64 "acquiring crypto provider for conversation guard from tx context",
65 ))
66 .map_err(Into::into)
67 }
68
69 pub(crate) async fn credential(&self) -> Result<Arc<Credential>> {
70 self.find_current_credential()
71 .await
72 .map_err(|_| Error::IdentityInitializationError)
73 }
74
75 pub(super) async fn session(&self) -> Result<Session> {
77 self.tx_context
78 .session()
79 .await
80 .map_err(RecursiveError::transaction("getting session from transaction context"))
81 .map_err(Into::into)
82 }
83
84 fn group_info(group_info: Option<GroupInfo>) -> Result<GroupInfoBundle> {
85 let group_info = group_info.ok_or(LeafError::MissingGroupInfo)?;
86 GroupInfoBundle::try_new_full_plaintext(group_info)
87 }
88}
89
90#[cfg(test)]
91mod test_utils {
92 use super::ConversationMut;
93 use crate::mls::conversation::Conversation;
94
95 impl ConversationMut {
96 pub async fn drop_and_restore(&mut self) {
98 let session = self.tx_context.session().await.unwrap();
99 let id = self.id();
100
101 let conversation = Conversation::load(session, id).await.unwrap().unwrap();
102 self.tx_context.mls_groups().await.unwrap().insert(conversation);
103 }
104 }
105}