bitwarden_vault/cipher/cipher_client/
get.rs1use bitwarden_core::key_management::KeySlotIds;
2use bitwarden_crypto::{CryptoError, KeyStore};
3use bitwarden_error::bitwarden_error;
4use bitwarden_state::repository::{Repository, RepositoryError};
5use thiserror::Error;
6
7use super::CiphersClient;
8use crate::{
9 Cipher, CipherId, CipherView, ItemNotFoundError,
10 cipher::cipher::{DecryptCipherListResult, DecryptCipherResult, StrictDecrypt},
11};
12
13#[allow(missing_docs)]
14#[bitwarden_error(flat)]
15#[derive(Debug, Error)]
16pub enum GetCipherError {
17 #[error(transparent)]
18 ItemNotFound(#[from] ItemNotFoundError),
19 #[error(transparent)]
20 Crypto(#[from] CryptoError),
21 #[error(transparent)]
22 Repository(#[from] RepositoryError),
23}
24
25async fn get_cipher(
26 store: &KeyStore<KeySlotIds>,
27 repository: &dyn Repository<Cipher>,
28 id: CipherId,
29 use_strict_decryption: bool,
30) -> Result<CipherView, GetCipherError> {
31 let cipher = repository.get(id).await?.ok_or(ItemNotFoundError)?;
32
33 Ok(if use_strict_decryption {
34 store.decrypt(&StrictDecrypt(cipher))?
35 } else {
36 store.decrypt(&cipher)?
37 })
38}
39
40async fn list_ciphers(
41 store: &KeyStore<KeySlotIds>,
42 repository: &dyn Repository<Cipher>,
43 use_strict_decryption: bool,
44) -> Result<DecryptCipherListResult, GetCipherError> {
45 let ciphers = repository.list().await?;
46 Ok(if use_strict_decryption {
47 let wrapped: Vec<StrictDecrypt<Cipher>> = ciphers.into_iter().map(StrictDecrypt).collect();
48 let (successes, failures) = store.decrypt_list_with_failures(&wrapped);
49 DecryptCipherListResult {
50 successes,
51 failures: failures.into_iter().map(|f| f.0.clone()).collect(),
52 }
53 } else {
54 let (successes, failures) = store.decrypt_list_with_failures(&ciphers);
55 DecryptCipherListResult {
56 successes,
57 failures: failures.into_iter().cloned().collect(),
58 }
59 })
60}
61
62async fn get_all_ciphers(
63 store: &KeyStore<KeySlotIds>,
64 repository: &dyn Repository<Cipher>,
65 use_strict_decryption: bool,
66) -> Result<DecryptCipherResult, GetCipherError> {
67 let ciphers = repository.list().await?;
68 Ok(if use_strict_decryption {
69 let wrapped: Vec<StrictDecrypt<Cipher>> = ciphers.into_iter().map(StrictDecrypt).collect();
70 let (successes, failures) = store.decrypt_list_with_failures(&wrapped);
71 DecryptCipherResult {
72 successes,
73 failures: failures.into_iter().map(|f| f.0.clone()).collect(),
74 }
75 } else {
76 let (successes, failures) = store.decrypt_list_with_failures(&ciphers);
77 DecryptCipherResult {
78 successes,
79 failures: failures.into_iter().cloned().collect(),
80 }
81 })
82}
83
84#[allow(deprecated)]
85#[bitwarden_ffi::wasm_export]
86impl CiphersClient {
87 pub async fn list(&self) -> Result<DecryptCipherListResult, GetCipherError> {
91 let key_store = self.client.internal.get_key_store();
92 let repository = self.get_repository()?;
93
94 list_ciphers(
95 key_store,
96 repository.as_ref(),
97 self.is_strict_decrypt().await,
98 )
99 .await
100 }
101
102 pub async fn get_all(&self) -> Result<DecryptCipherResult, GetCipherError> {
106 let key_store = self.client.internal.get_key_store();
107 let repository = self.get_repository()?;
108
109 get_all_ciphers(
110 key_store,
111 repository.as_ref(),
112 self.is_strict_decrypt().await,
113 )
114 .await
115 }
116
117 pub async fn get(&self, cipher_id: CipherId) -> Result<CipherView, GetCipherError> {
119 let key_store = self.client.internal.get_key_store();
120 let repository = self.get_repository()?;
121
122 get_cipher(
123 key_store,
124 repository.as_ref(),
125 cipher_id,
126 self.is_strict_decrypt().await,
127 )
128 .await
129 }
130}