bitwarden_send/
send_client.rs1use std::{path::Path, sync::Arc};
2
3use bitwarden_core::Client;
4use bitwarden_crypto::{
5 Decryptable, EncString, IdentifyKey, OctetStreamBytes, PrimitiveEncryptable,
6};
7use bitwarden_error::bitwarden_error;
8use bitwarden_state::repository::{Repository, RepositoryError};
9use thiserror::Error;
10#[cfg(feature = "wasm")]
11use wasm_bindgen::prelude::*;
12
13use crate::{Send, SendListView, SendView};
14
15#[allow(missing_docs)]
17#[bitwarden_error(flat)]
18#[derive(Debug, Error)]
19pub enum SendEncryptError {
20 #[error(transparent)]
21 Crypto(#[from] bitwarden_crypto::CryptoError),
22}
23
24#[allow(missing_docs)]
26#[bitwarden_error(flat)]
27#[derive(Debug, Error)]
28pub enum SendDecryptError {
29 #[error(transparent)]
30 Crypto(#[from] bitwarden_crypto::CryptoError),
31}
32
33#[allow(missing_docs)]
35#[derive(Debug, Error)]
36#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
37pub enum SendEncryptFileError {
38 #[error(transparent)]
39 Encrypt(#[from] SendEncryptError),
40 #[error(transparent)]
41 Io(#[from] std::io::Error),
42}
43
44#[allow(missing_docs)]
46#[derive(Debug, Error)]
47#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
48pub enum SendDecryptFileError {
49 #[error(transparent)]
50 Decrypt(#[from] SendDecryptError),
51 #[error(transparent)]
52 Io(#[from] std::io::Error),
53}
54
55#[allow(missing_docs)]
56#[cfg_attr(feature = "wasm", wasm_bindgen)]
57pub struct SendClient {
58 pub(crate) client: Client,
59}
60
61#[allow(missing_docs)]
62#[cfg_attr(feature = "wasm", wasm_bindgen)]
63impl SendClient {
64 pub fn decrypt_send(&self, send: Send) -> Result<SendView, SendDecryptError> {
67 self.decrypt(send)
68 }
69}
70
71impl SendClient {
72 fn new(client: Client) -> Self {
73 Self { client }
74 }
75
76 #[allow(missing_docs)]
77 pub fn decrypt(&self, send: Send) -> Result<SendView, SendDecryptError> {
78 let key_store = self.client.internal.get_key_store();
79 let send_view = key_store.decrypt(&send)?;
80 Ok(send_view)
81 }
82
83 #[allow(missing_docs)]
84 pub fn decrypt_list(&self, sends: Vec<Send>) -> Result<Vec<SendListView>, SendDecryptError> {
85 let key_store = self.client.internal.get_key_store();
86 let send_views = key_store.decrypt_list(&sends)?;
87 Ok(send_views)
88 }
89
90 #[allow(missing_docs)]
91 pub fn decrypt_file(
92 &self,
93 send: Send,
94 encrypted_file_path: &Path,
95 decrypted_file_path: &Path,
96 ) -> Result<(), SendDecryptFileError> {
97 let data = std::fs::read(encrypted_file_path)?;
98 let decrypted = self.decrypt_buffer(send, &data)?;
99 std::fs::write(decrypted_file_path, decrypted)?;
100 Ok(())
101 }
102
103 #[allow(missing_docs)]
104 pub fn decrypt_buffer(
105 &self,
106 send: Send,
107 encrypted_buffer: &[u8],
108 ) -> Result<Vec<u8>, SendDecryptError> {
109 let key_store = self.client.internal.get_key_store();
110 let mut ctx = key_store.context();
111
112 let key = Send::get_key(&mut ctx, &send.key, send.key_identifier())?;
113
114 let buf = EncString::from_buffer(encrypted_buffer)?;
115 Ok(buf.decrypt(&mut ctx, key)?)
116 }
117
118 #[allow(missing_docs)]
119 pub fn encrypt(&self, send_view: SendView) -> Result<Send, SendEncryptError> {
120 let key_store = self.client.internal.get_key_store();
121
122 let send = key_store.encrypt(send_view)?;
123
124 Ok(send)
125 }
126
127 #[allow(missing_docs)]
128 pub fn encrypt_file(
129 &self,
130 send: Send,
131 decrypted_file_path: &Path,
132 encrypted_file_path: &Path,
133 ) -> Result<(), SendEncryptFileError> {
134 let data = std::fs::read(decrypted_file_path)?;
135 let encrypted = self.encrypt_buffer(send, &data)?;
136 std::fs::write(encrypted_file_path, encrypted)?;
137 Ok(())
138 }
139
140 #[allow(missing_docs)]
141 pub fn encrypt_buffer(&self, send: Send, buffer: &[u8]) -> Result<Vec<u8>, SendEncryptError> {
142 let key_store = self.client.internal.get_key_store();
143 let mut ctx = key_store.context();
144
145 let key = Send::get_key(&mut ctx, &send.key, send.key_identifier())?;
146
147 let encrypted = OctetStreamBytes::from(buffer).encrypt(&mut ctx, key)?;
148 Ok(encrypted.to_buffer()?)
149 }
150}
151
152impl SendClient {
153 pub(crate) fn get_repository(&self) -> Result<Arc<dyn Repository<Send>>, RepositoryError> {
154 Ok(self.client.platform().state().get::<Send>()?)
155 }
156}
157
158#[allow(missing_docs)]
159pub trait SendClientExt {
160 fn sends(&self) -> SendClient;
161}
162
163impl SendClientExt for Client {
164 fn sends(&self) -> SendClient {
165 SendClient::new(self.clone())
166 }
167}