use crate::{
encryptor::{
Encryptor,
SecretType,
},
re_export::std_anyhow::*,
common::traits::JsonSerializable
};
#[derive(Debug, Clone, Serialize, Deserialize, Builder, Zeroize, ZeroizeOnDrop)]
pub struct UniVault<T: Encryptor + Serialize> {
#[zeroize(skip)]
pub encryptor: T,
#[zeroize(skip)]
#[builder(setter(into))]
#[builder(default = "SecretType::Text")]
pub data_type: SecretType,
#[zeroize(skip)]
#[builder(setter(into))]
#[builder(default = "false")]
pub encrypted: bool,
#[builder(setter(into))]
#[builder(default = "Vec::new()")]
pub data: Vec<u8>,
}
impl<T: Encryptor + Serialize + for<'de> Deserialize<'de>> JsonSerializable for UniVault<T> {}
impl<T: Encryptor + Serialize + for<'de> Deserialize<'de>> UniVault<T> {
pub fn encrypt(&mut self) -> anyhow::Result<()> {
if self.encrypted {
return Err(Error::msg("Do not encrypt already encrypted Bytes again"));
}
let encrypted_bytes = self.encryptor.encrypt(&self.data)?;
self.data.zeroize();
self.data = encrypted_bytes;
self.encrypted = true;
Ok(())
}
pub fn decrypt(&mut self) -> anyhow::Result<()> {
if !self.encrypted {
return Err(Error::msg("Operation only supported on encrypted bytes"));
}
self.data = self.encryptor.decrypt(&self.data)?;
self.encrypted = false;
Ok(())
}
pub fn decrypt_and_decode_json_string(
json_str: &str,
) -> anyhow::Result<Self> {
let mut uni_vault = UniVault::from_json(json_str)?;
uni_vault.decrypt()?;
Ok(uni_vault)
}
pub fn data_to_string(&mut self) -> anyhow::Result<String> {
if self.encrypted {
self.decrypt()?;
}
let data_str = String::from_utf8(self.data.clone())
.map_err(Error::msg)?;
Ok(data_str)
}
}