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, 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::context("getting transport for conversation guard"))
48 .map_err(Into::into)
49 }
50
51 fn database(&self) -> Result<Arc<Database>> {
52 self.tx_context
53 .database()
54 .map_err(RecursiveError::context("getting database from context"))
55 .map_err(Into::into)
56 }
57
58 async fn crypto_provider(&self) -> Result<CryptoProvider> {
59 self.tx_context
60 .crypto_provider()
61 .await
62 .map_err(RecursiveError::context(
63 "acquiring crypto provider for conversation guard from tx context",
64 ))
65 .map_err(Into::into)
66 }
67
68 pub(crate) async fn credential(&self) -> Result<Arc<Credential>> {
69 self.find_current_credential()
70 .await
71 .map_err(|_| Error::IdentityInitializationError)
72 }
73
74 pub(super) async fn session(&self) -> Result<Session> {
76 self.tx_context
77 .session()
78 .await
79 .map_err(RecursiveError::context("getting session from transaction context"))
80 .map_err(Into::into)
81 }
82
83 fn group_info(group_info: Option<GroupInfo>) -> Result<GroupInfoBundle> {
84 let group_info = group_info.ok_or(Error::MissingGroupInfo)?;
85 GroupInfoBundle::try_new_full_plaintext(group_info)
86 }
87}
88
89#[cfg(test)]
90mod test_utils {
91 use super::ConversationMut;
92 use crate::mls::conversation::Conversation;
93
94 impl ConversationMut {
95 pub async fn drop_and_restore(&mut self) {
97 let session = self.tx_context.session().await.unwrap();
98 let id = self.id();
99
100 let conversation = Conversation::load(session, id).await.unwrap().unwrap();
101 self.tx_context.mls_groups().await.unwrap().insert(conversation);
102 }
103 }
104}