bitwarden_vault/cipher/attachment_client/
mod.rs1use std::{path::Path, sync::Arc};
2
3use bitwarden_core::{FromClient, client::ApiConfigurations, key_management::KeySlotIds};
4use bitwarden_crypto::{EncString, KeyStore};
5use bitwarden_error::bitwarden_error;
6use bitwarden_state::repository::Repository;
7use thiserror::Error;
8
9use crate::{
10 Attachment, AttachmentEncryptResult, AttachmentFile, AttachmentFileView, AttachmentView,
11 Cipher, DecryptError, EncryptError,
12};
13
14mod admin;
15mod create;
16mod delete;
17mod download_url;
18mod renew;
19mod upgrade;
20
21pub use admin::{
22 AttachmentAdminClient, CipherAdminGetAttachmentDownloadUrlError, CreateAttachmentAdminError,
23 DeleteAttachmentAdminError,
24};
25pub use create::{
26 AttachmentFileUploadType, CipherCreateAttachmentError, CreateAttachmentRequest,
27 CreatedAttachment,
28};
29pub use delete::CipherDeleteAttachmentError;
30pub use download_url::CipherGetAttachmentDownloadUrlError;
31pub use renew::CipherRenewFileUploadUrlError;
32pub use upgrade::CipherUpgradeAttachmentError;
33
34#[allow(missing_docs)]
36#[bitwarden_error(flat)]
37#[derive(Debug, Error)]
38pub enum EncryptFileError {
39 #[error(transparent)]
40 Encrypt(#[from] EncryptError),
41 #[error(transparent)]
42 Io(#[from] std::io::Error),
43}
44
45#[allow(missing_docs)]
47#[bitwarden_error(flat)]
48#[derive(Debug, Error)]
49pub enum DecryptFileError {
50 #[error(transparent)]
51 Decrypt(#[from] DecryptError),
52 #[error(transparent)]
53 Io(#[from] std::io::Error),
54}
55
56#[bitwarden_ffi::wasm_object]
58#[derive(FromClient)]
59pub struct AttachmentsClient {
60 pub(crate) key_store: KeyStore<KeySlotIds>,
61 pub(crate) api_configurations: Arc<ApiConfigurations>,
62 pub(crate) repository: Option<Arc<dyn Repository<Cipher>>>,
63 pub(crate) http_client: reqwest::Client,
64}
65
66#[bitwarden_ffi::wasm_export]
67impl AttachmentsClient {
68 pub fn admin(&self) -> AttachmentAdminClient {
71 AttachmentAdminClient {
72 api_configurations: self.api_configurations.clone(),
73 }
74 }
75
76 #[allow(missing_docs)]
77 pub fn decrypt_buffer(
78 &self,
79 cipher: Cipher,
80 attachment: AttachmentView,
81 encrypted_buffer: &[u8],
82 ) -> Result<Vec<u8>, DecryptError> {
83 Ok(self.key_store.decrypt(&AttachmentFile {
84 cipher,
85 attachment,
86 contents: EncString::from_buffer(encrypted_buffer)?,
87 })?)
88 }
89}
90
91impl AttachmentsClient {
92 #[allow(missing_docs)]
93 pub fn encrypt_buffer(
94 &self,
95 cipher: Cipher,
96 attachment: AttachmentView,
97 buffer: &[u8],
98 ) -> Result<AttachmentEncryptResult, EncryptError> {
99 Ok(self.key_store.encrypt(AttachmentFileView {
100 cipher,
101 attachment,
102 contents: buffer,
103 })?)
104 }
105
106 #[allow(missing_docs)]
107 pub fn encrypt_file(
108 &self,
109 cipher: Cipher,
110 attachment: AttachmentView,
111 decrypted_file_path: &Path,
112 encrypted_file_path: &Path,
113 ) -> Result<Attachment, EncryptFileError> {
114 let data = std::fs::read(decrypted_file_path)?;
115 let AttachmentEncryptResult {
116 attachment,
117 contents,
118 } = self.encrypt_buffer(cipher, attachment, &data)?;
119 std::fs::write(encrypted_file_path, contents)?;
120 Ok(attachment)
121 }
122
123 #[allow(missing_docs)]
124 pub fn decrypt_file(
125 &self,
126 cipher: Cipher,
127 attachment: AttachmentView,
128 encrypted_file_path: &Path,
129 decrypted_file_path: &Path,
130 ) -> Result<(), DecryptFileError> {
131 let data = std::fs::read(encrypted_file_path)?;
132 let decrypted = self.decrypt_buffer(cipher, attachment, &data)?;
133 std::fs::write(decrypted_file_path, decrypted)?;
134 Ok(())
135 }
136}