// Libraries use bincode; use rand::Rng; use serde::{Serialize, Deserialize}; use crate::{interface, resource, secure}; // Structs #[derive(Serialize, Deserialize)] pub struct Password { pub name: String, pub user: String, pub phrase: String, } #[derive(Serialize, Deserialize)] pub struct Manager{ passwords: Vec, key: String } // Implementations impl Manager { // Constructors pub fn init(key: String) -> Self { let mut manager: Manager = Manager { passwords: vec![], key: key }; if resource::ResourceFileBin::exists("res/manager.dat") { manager.load(); } return manager; } // Functions fn save(&self) { // Going through each password and encrypting them let mut enc_manager: Manager = Manager { passwords: vec![], key: String::new() }; for pla_password in &self.passwords { enc_manager.passwords.push(Password { name: secure::Secure::encrypt(pla_password.name.clone(), self.key.clone()), user: secure::Secure::encrypt(pla_password.user.clone(), self.key.clone()), phrase: secure::Secure::encrypt(pla_password.phrase.clone(), self.key.clone()) }); } // Turning the manager into binary data let manager_binary: Vec = bincode::serialize(&enc_manager).expect("Failed to serialize manager"); // Saving via Binary Reader resource::ResourceFileBin::write("res/manager.dat", manager_binary); // Message: println!("{}[Saved]{}", interface::COLOR_GREEN, interface::COLOR_RESET); } fn load(&mut self) { // Saving via Binary Reader let content: resource::ResourceFileBin = resource::ResourceFileBin::read("res/manager.dat"); // Turning the manager into binary data let manager: Manager = bincode::deserialize(&content.content).expect("Failed to serialize manager"); // Decrypt all passwords for enc_password in manager.passwords { self.passwords.push(Password { name: secure::Secure::decrypt(enc_password.name.clone(), self.key.clone()), user: secure::Secure::decrypt(enc_password.user.clone(), self.key.clone()), phrase: secure::Secure::decrypt(enc_password.phrase.clone(), self.key.clone()) }); } // Message: println!("{}[Loaded]{}", interface::COLOR_GREEN, interface::COLOR_RESET); } pub fn password_generate(length: u32, numbers: bool, special: bool) -> String { // Variables let mut result: String = String::new(); let mut possible_characters: String = String::new(); // Making lists of possibilities let ascii_letters: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; let ascii_numbers: &str = "1234567890"; let ascii_special: &str = "!\"#$%&'()*+,-./:;<=>?@[]^_`{|}~"; // Putting everything together! possible_characters += ascii_letters; if numbers {possible_characters += ascii_numbers;} if special {possible_characters += ascii_special;} // Creating the password! for _ in 0..length { let rand_index: usize = rand::thread_rng().gen_range(0..=possible_characters.len()-1); let rand_character: char = possible_characters.chars().nth(rand_index).unwrap(); result += &rand_character.to_string(); } // Giving back the result return result; } pub fn password_create(&mut self, name: String, user: String, pass: String) { // Create the password object let new_password: Password = Password{name: name, user: user, phrase: pass}; // Adding it to our list self.passwords.push(new_password); // Saving the password manager self.save(); } pub fn password_view(&mut self, name: String) -> (bool, Password) { // Variables let mut success: bool = false; let mut selected_password: Password = Password { name: String::new(), user: String::new(), phrase: String::new() }; // Getting the right password for c_pass in &self.passwords { success = name.to_lowercase() == c_pass.name.to_lowercase(); if success { selected_password.name = c_pass.name.clone(); selected_password.user = c_pass.user.clone(); selected_password.phrase = c_pass.phrase.clone(); break; } } // Returning the password return (success, selected_password); } }