core_crypto/transaction_context/credential/
mod.rs1mod check;
2
3use std::sync::Arc;
4
5use super::{Error, Result};
6use crate::{
7 Credential, CredentialRef, RecursiveError, mls::conversation::Conversation, transaction_context::TransactionContext,
8};
9
10impl TransactionContext {
11 pub(crate) async fn add_credential_without_clientid_check(
18 &self,
19 mut credential: Credential,
20 ) -> Result<Arc<Credential>> {
21 let inner = self.inner().await?;
22 let _credential_ref = credential
23 .save(&inner.transaction)
24 .await
25 .map_err(RecursiveError::mls_credential("saving credential"))?;
26
27 Ok(Arc::new(credential))
28 }
29 pub async fn add_credential(&self, credential: Credential) -> Result<CredentialRef> {
31 let credential = self.add_credential_producing_arc(credential).await?;
32 Ok(CredentialRef::from_credential(&credential))
33 }
34
35 pub(crate) async fn add_credential_producing_arc(&self, credential: Credential) -> Result<Arc<Credential>> {
41 if *credential.client_id() != self.session().await?.id() {
42 return Err(Error::WrongCredential);
43 }
44
45 self.add_credential_without_clientid_check(credential).await
46 }
47
48 pub async fn remove_credential(&self, credential_ref: &CredentialRef) -> Result<()> {
53 if *credential_ref.client_id() != self.session().await?.id() {
55 return Err(Error::WrongCredential);
56 }
57
58 let inner = self.inner().await?;
59
60 let credential = credential_ref
61 .load(&inner.transaction)
62 .await
63 .map_err(RecursiveError::mls_credential_ref(
64 "loading all credentials from ref to remove from session identities",
65 ))?;
66
67 let session = self.session().await?;
73 for (conversation_id, conversation) in
74 Conversation::load_all(session)
75 .await
76 .map_err(RecursiveError::mls_conversation(
77 "loading all conversations to check if the credential to be removed is present",
78 ))?
79 {
80 let converation_credential = conversation
81 .own_mls_credential()
82 .await
83 .map_err(RecursiveError::mls_conversation("geting conversation credential"))?;
84 if credential.mls_credential() == &converation_credential {
85 return Err(Error::CredentialStillInUse(conversation_id));
86 }
87 }
88
89 self.remove_key_packages_for(credential_ref).await?;
91
92 credential
94 .delete(&inner.transaction)
95 .await
96 .map_err(RecursiveError::mls_credential("deleting credential from keystore"))
97 .map_err(Into::into)
98 }
99}