From 75bf74d51209b519ed6ba68d7b85ba653e993fa5 Mon Sep 17 00:00:00 2001 From: Awiteb Date: Thu, 25 Apr 2024 08:31:33 +0300 Subject: [PATCH] feat: Validate args before ask for the master password Fixes: https://git.4rs.nl/awiteb/lprs/issues/13 --- src/cli/add_command.rs | 19 ++++++++------ src/cli/edit_command.rs | 25 ++++++++++-------- src/cli/export_command.rs | 22 +++++++++------- src/cli/gen_command.rs | 37 ++++++++++++++------------ src/cli/import_command.rs | 55 ++++++++++++++++++++------------------- 5 files changed, 85 insertions(+), 73 deletions(-) diff --git a/src/cli/add_command.rs b/src/cli/add_command.rs index 1d6d86f..dc7f5ef 100644 --- a/src/cli/add_command.rs +++ b/src/cli/add_command.rs @@ -33,14 +33,6 @@ pub struct Add { impl LprsCommand for Add { fn run(mut self, mut vault_manager: Vaults) -> LprsResult<()> { - if self.vault_info.username.is_none() - && self.password.is_none() - && self.vault_info.service.is_none() - && self.vault_info.note.is_none() - { - return Err(LprsError::Other("You can't add empty vault".to_owned())); - } - match self.password { Some(Some(password)) => self.vault_info.password = Some(password), Some(None) => { @@ -58,4 +50,15 @@ impl LprsCommand for Add { vault_manager.add_vault(self.vault_info); vault_manager.try_export() } + + fn validate_args(&self) -> LprsResult<()> { + if self.vault_info.username.is_none() + && self.password.is_none() + && self.vault_info.service.is_none() + && self.vault_info.note.is_none() + { + return Err(LprsError::Other("You can't add empty vault".to_owned())); + } + Ok(()) + } } diff --git a/src/cli/edit_command.rs b/src/cli/edit_command.rs index 8e1052f..9fe9b17 100644 --- a/src/cli/edit_command.rs +++ b/src/cli/edit_command.rs @@ -58,17 +58,6 @@ impl LprsCommand for Edit { ))); }; - if self.name.is_none() - && self.username.is_none() - && self.password.is_none() - && self.service.is_none() - && self.note.is_none() - { - return Err(LprsError::Other( - "You must edit one option at least".to_owned(), - )); - } - // Get the password from stdin or from its value if provided let password = match self.password { Some(Some(password)) => Some(password), @@ -91,4 +80,18 @@ impl LprsCommand for Edit { ); vault_manager.try_export() } + + fn validate_args(&self) -> LprsResult<()> { + if self.name.is_none() + && self.username.is_none() + && self.password.is_none() + && self.service.is_none() + && self.note.is_none() + { + return Err(LprsError::Other( + "You must edit one option at least".to_owned(), + )); + } + Ok(()) + } } diff --git a/src/cli/export_command.rs b/src/cli/export_command.rs index fd46e81..56f18f5 100644 --- a/src/cli/export_command.rs +++ b/src/cli/export_command.rs @@ -35,22 +35,24 @@ pub struct Export { impl LprsCommand for Export { fn run(self, vault_manager: Vaults) -> LprsResult<()> { + let exported_data = match self.format { + Format::Lprs => { + serde_json::to_string::>>(&vault_manager.encrypt_vaults()?) + } + Format::BitWarden => serde_json::to_string(&BitWardenPasswords::from(vault_manager)), + }?; + + fs::write(&self.path, exported_data).map_err(LprsError::from) + } + + fn validate_args(&self) -> LprsResult<()> { if self .path .extension() .is_some_and(|e| e.to_string_lossy().eq_ignore_ascii_case("json")) { if !self.path.exists() { - let exported_data = match self.format { - Format::Lprs => serde_json::to_string::>>( - &vault_manager.encrypt_vaults()?, - ), - Format::BitWarden => { - serde_json::to_string(&BitWardenPasswords::from(vault_manager)) - } - }?; - - fs::write(&self.path, exported_data).map_err(LprsError::from) + Ok(()) } else { Err(LprsError::Io(IoError::new( IoErrorKind::AlreadyExists, diff --git a/src/cli/gen_command.rs b/src/cli/gen_command.rs index 382d94a..92dfae3 100644 --- a/src/cli/gen_command.rs +++ b/src/cli/gen_command.rs @@ -46,24 +46,27 @@ pub struct Gen { impl LprsCommand for Gen { fn run(self, _vault_manager: Vaults) -> LprsResult<()> { - if self.uppercase || self.lowercase || self.numbers || self.symbols { - println!( - "{}", - passwords::PasswordGenerator::new() - .length(self.length.get() as usize) - .uppercase_letters(self.uppercase) - .lowercase_letters(self.lowercase) - .numbers(self.numbers) - .symbols(self.symbols) - .strict(true) - .generate_one() - .expect("The length cannot be zero") - ); - Ok(()) - } else { - Err(LprsError::Other( + println!( + "{}", + passwords::PasswordGenerator::new() + .length(self.length.get() as usize) + .uppercase_letters(self.uppercase) + .lowercase_letters(self.lowercase) + .numbers(self.numbers) + .symbols(self.symbols) + .strict(true) + .generate_one() + .expect("The length cannot be zero") + ); + Ok(()) + } + + fn validate_args(&self) -> LprsResult<()> { + if !(self.uppercase || self.lowercase || self.numbers || self.symbols) { + return Err(LprsError::Other( "You need to enable at least one kind of characters".to_owned(), - )) + )); } + Ok(()) } } diff --git a/src/cli/import_command.rs b/src/cli/import_command.rs index 4bdb5f7..6c46762 100644 --- a/src/cli/import_command.rs +++ b/src/cli/import_command.rs @@ -36,39 +36,40 @@ pub struct Import { impl LprsCommand for Import { fn run(self, mut vault_manager: Vaults) -> LprsResult<()> { + let imported_passwords_len = match self.format { + Format::Lprs => { + let vaults = Vaults::try_reload(self.path, vault_manager.master_password.to_vec())?; + let vaults_len = vaults.vaults.len(); + + vault_manager.vaults.extend(vaults.vaults); + vault_manager.try_export()?; + vaults_len + } + Format::BitWarden => { + let vaults: BitWardenPasswords = serde_json::from_reader(File::open(&self.path)?)?; + let vaults_len = vaults.items.len(); + + vault_manager + .vaults + .extend(vaults.items.into_iter().map(Vault::from)); + vault_manager.try_export()?; + vaults_len + } + }; + println!( + "{imported_passwords_len} vault{s} were imported successfully", + s = if imported_passwords_len >= 2 { "s" } else { "" } + ); + Ok(()) + } + + fn validate_args(&self) -> LprsResult<()> { if self.path.exists() { if self .path .extension() .is_some_and(|e| e.to_string_lossy().eq_ignore_ascii_case("json")) { - let imported_passwords_len = match self.format { - Format::Lprs => { - let vaults = - Vaults::try_reload(self.path, vault_manager.master_password.to_vec())?; - let vaults_len = vaults.vaults.len(); - - vault_manager.vaults.extend(vaults.vaults); - vault_manager.try_export()?; - vaults_len - } - Format::BitWarden => { - let vaults: BitWardenPasswords = - serde_json::from_reader(File::open(&self.path)?)?; - let vaults_len = vaults.items.len(); - - vault_manager - .vaults - .extend(vaults.items.into_iter().map(Vault::from)); - vault_manager.try_export()?; - vaults_len - } - }; - println!( - "{imported_passwords_len} vault{s} were imported successfully", - s = if imported_passwords_len >= 2 { "s" } else { "" } - ); - Ok(()) } else { Err(LprsError::Io(IoError::new(