1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
use crate::feed_api::error::{FeedApiError, FeedApiErrorKind}; use failure::ResultExt; use log::error; use magic_crypt::{new_magic_crypt, MagicCryptTrait}; use rust_embed::RustEmbed; use serde_derive::{Deserialize, Serialize}; use serde_json; use std::str; #[derive(RustEmbed)] #[folder = "$OUT_DIR"] struct KeyFile; #[derive(Debug, Serialize, Deserialize)] pub struct PasswordEncryption { password_crypt_key: String, } impl PasswordEncryption { pub fn encrypt(password: &str) -> Result<String, FeedApiError> { let key = Self::read_key()?; let crypt = new_magic_crypt!(key, 256); Ok(crypt.encrypt_str_to_base64(password)) } pub fn decrypt(password: &str) -> Result<String, FeedApiError> { let key = Self::read_key()?; let crypt = new_magic_crypt!(key, 256); let password = crypt.decrypt_base64_to_string(password).map_err(|_| { error!("Failed to decrypt password: {}", password); FeedApiErrorKind::Encryption })?; Ok(password) } fn read_key() -> Result<String, FeedApiError> { let key_data = KeyFile::get("password_crypt_key.json").ok_or(FeedApiErrorKind::IO)?; let key_string = str::from_utf8(key_data.as_ref()).context(FeedApiErrorKind::IO)?; let key_struct: PasswordEncryption = serde_json::from_str(key_string).context(FeedApiErrorKind::Json)?; Ok(key_struct.password_crypt_key) } }