bitwarden_send/
send_client.rs

1use std::path::Path;
2
3use bitwarden_core::Client;
4use bitwarden_crypto::{Decryptable, EncString, Encryptable, IdentifyKey};
5use thiserror::Error;
6
7use crate::{Send, SendListView, SendView};
8
9/// Generic error type for send encryption errors.
10#[allow(missing_docs)]
11#[derive(Debug, Error)]
12pub enum SendEncryptError {
13    #[error(transparent)]
14    Crypto(#[from] bitwarden_crypto::CryptoError),
15    #[error(transparent)]
16    VaultLocked(#[from] bitwarden_core::VaultLockedError),
17}
18
19/// Generic error type for send decryption errors
20#[allow(missing_docs)]
21#[derive(Debug, Error)]
22pub enum SendDecryptError {
23    #[error(transparent)]
24    Crypto(#[from] bitwarden_crypto::CryptoError),
25    #[error(transparent)]
26    VaultLocked(#[from] bitwarden_core::VaultLockedError),
27}
28
29/// Generic error type for send encryption errors.
30#[allow(missing_docs)]
31#[derive(Debug, Error)]
32pub enum SendEncryptFileError {
33    #[error(transparent)]
34    Encrypt(#[from] SendEncryptError),
35    #[error(transparent)]
36    Io(#[from] std::io::Error),
37}
38
39/// Generic error type for send decryption errors
40#[allow(missing_docs)]
41#[derive(Debug, Error)]
42pub enum SendDecryptFileError {
43    #[error(transparent)]
44    Decrypt(#[from] SendDecryptError),
45    #[error(transparent)]
46    Io(#[from] std::io::Error),
47}
48
49#[allow(missing_docs)]
50pub struct SendClient {
51    client: Client,
52}
53
54impl SendClient {
55    fn new(client: Client) -> Self {
56        Self { client }
57    }
58
59    #[allow(missing_docs)]
60    pub fn decrypt(&self, send: Send) -> Result<SendView, SendDecryptError> {
61        let key_store = self.client.internal.get_key_store();
62        let send_view = key_store.decrypt(&send)?;
63        Ok(send_view)
64    }
65
66    #[allow(missing_docs)]
67    pub fn decrypt_list(&self, sends: Vec<Send>) -> Result<Vec<SendListView>, SendDecryptError> {
68        let key_store = self.client.internal.get_key_store();
69        let send_views = key_store.decrypt_list(&sends)?;
70        Ok(send_views)
71    }
72
73    #[allow(missing_docs)]
74    pub fn decrypt_file(
75        &self,
76        send: Send,
77        encrypted_file_path: &Path,
78        decrypted_file_path: &Path,
79    ) -> Result<(), SendDecryptFileError> {
80        let data = std::fs::read(encrypted_file_path)?;
81        let decrypted = self.decrypt_buffer(send, &data)?;
82        std::fs::write(decrypted_file_path, decrypted)?;
83        Ok(())
84    }
85
86    #[allow(missing_docs)]
87    pub fn decrypt_buffer(
88        &self,
89        send: Send,
90        encrypted_buffer: &[u8],
91    ) -> Result<Vec<u8>, SendDecryptError> {
92        let key_store = self.client.internal.get_key_store();
93        let mut ctx = key_store.context();
94
95        let key = Send::get_key(&mut ctx, &send.key, send.key_identifier())?;
96
97        let buf = EncString::from_buffer(encrypted_buffer)?;
98        Ok(buf.decrypt(&mut ctx, key)?)
99    }
100
101    #[allow(missing_docs)]
102    pub fn encrypt(&self, send_view: SendView) -> Result<Send, SendEncryptError> {
103        let key_store = self.client.internal.get_key_store();
104
105        let send = key_store.encrypt(send_view)?;
106
107        Ok(send)
108    }
109
110    #[allow(missing_docs)]
111    pub fn encrypt_file(
112        &self,
113        send: Send,
114        decrypted_file_path: &Path,
115        encrypted_file_path: &Path,
116    ) -> Result<(), SendEncryptFileError> {
117        let data = std::fs::read(decrypted_file_path)?;
118        let encrypted = self.encrypt_buffer(send, &data)?;
119        std::fs::write(encrypted_file_path, encrypted)?;
120        Ok(())
121    }
122
123    #[allow(missing_docs)]
124    pub fn encrypt_buffer(&self, send: Send, buffer: &[u8]) -> Result<Vec<u8>, SendEncryptError> {
125        let key_store = self.client.internal.get_key_store();
126        let mut ctx = key_store.context();
127
128        let key = Send::get_key(&mut ctx, &send.key, send.key_identifier())?;
129
130        let encrypted = buffer.encrypt(&mut ctx, key)?;
131        Ok(encrypted.to_buffer()?)
132    }
133}
134
135#[allow(missing_docs)]
136pub trait SendClientExt {
137    fn sends(&self) -> SendClient;
138}
139
140impl SendClientExt for Client {
141    fn sends(&self) -> SendClient {
142        SendClient::new(self.clone())
143    }
144}