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#[cfg(feature = "wasm")]
7use wasm_bindgen::prelude::wasm_bindgen;
8
9use super::CiphersClient;
10use crate::{
11 Cipher, CipherView, ItemNotFoundError,
12 cipher::cipher::{DecryptCipherListResult, DecryptCipherResult, StrictDecrypt},
13};
14
15#[allow(missing_docs)]
16#[bitwarden_error(flat)]
17#[derive(Debug, Error)]
18pub enum GetCipherError {
19 #[error(transparent)]
20 ItemNotFound(#[from] ItemNotFoundError),
21 #[error(transparent)]
22 Crypto(#[from] CryptoError),
23 #[error(transparent)]
24 Repository(#[from] RepositoryError),
25}
26
27async fn get_cipher(
28 store: &KeyStore<KeySlotIds>,
29 repository: &dyn Repository<Cipher>,
30 id: &str,
31 use_strict_decryption: bool,
32) -> Result<CipherView, GetCipherError> {
33 let id = id.parse().map_err(|_| ItemNotFoundError)?;
34 let cipher = repository.get(id).await?.ok_or(ItemNotFoundError)?;
35
36 if use_strict_decryption {
37 Ok(store.decrypt(&StrictDecrypt(cipher))?)
38 } else {
39 Ok(store.decrypt(&cipher)?)
40 }
41}
42
43async fn list_ciphers(
44 store: &KeyStore<KeySlotIds>,
45 repository: &dyn Repository<Cipher>,
46) -> Result<DecryptCipherListResult, GetCipherError> {
47 let ciphers = repository.list().await?;
48 let (successes, failures) = store.decrypt_list_with_failures(&ciphers);
49 Ok(DecryptCipherListResult {
50 successes,
51 failures: failures.into_iter().cloned().collect(),
52 })
53}
54
55async fn get_all_ciphers(
56 store: &KeyStore<KeySlotIds>,
57 repository: &dyn Repository<Cipher>,
58) -> Result<DecryptCipherResult, GetCipherError> {
59 let ciphers = repository.list().await?;
60 let (successes, failures) = store.decrypt_list_with_failures(&ciphers);
61 Ok(DecryptCipherResult {
62 successes,
63 failures: failures.into_iter().cloned().collect(),
64 })
65}
66
67#[cfg_attr(feature = "wasm", wasm_bindgen)]
68impl CiphersClient {
69 pub async fn list(&self) -> Result<DecryptCipherListResult, GetCipherError> {
73 let key_store = self.client.internal.get_key_store();
74 let repository = self.get_repository()?;
75
76 list_ciphers(key_store, repository.as_ref()).await
77 }
78
79 pub async fn get_all(&self) -> Result<DecryptCipherResult, GetCipherError> {
83 let key_store = self.client.internal.get_key_store();
84 let repository = self.get_repository()?;
85
86 get_all_ciphers(key_store, repository.as_ref()).await
87 }
88
89 pub async fn get(&self, cipher_id: &str) -> Result<CipherView, GetCipherError> {
91 let key_store = self.client.internal.get_key_store();
92 let repository = self.get_repository()?;
93
94 get_cipher(
95 key_store,
96 repository.as_ref(),
97 cipher_id,
98 self.is_strict_decrypt().await,
99 )
100 .await
101 }
102}