From bbc2a7a9447804d31d949c1d8d1143336c5dad79 Mon Sep 17 00:00:00 2001 From: Awiteb Date: Sat, 17 Aug 2024 14:47:57 +0000 Subject: [PATCH 1/4] feat: Support key without value in custom fields parser Signed-off-by: Awiteb --- src/clap_parsers.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/clap_parsers.rs b/src/clap_parsers.rs index 05a423e..7666505 100644 --- a/src/clap_parsers.rs +++ b/src/clap_parsers.rs @@ -19,12 +19,14 @@ use crate::{LprsError, LprsResult}; /// Parse the key & value arguments. /// ## Errors /// - If the argument value syntax not `key=value` -pub fn kv_parser(value: &str) -> LprsResult<(String, String)> { +pub fn kv_parser(value: &str) -> LprsResult<(String, Option)> { if let Some((key, value)) = value.split_once('=') { - Ok((key.trim().to_owned(), value.trim().to_owned())) - } else { + Ok((key.trim().to_owned(), Some(value.trim().to_owned()))) + } else if value.trim().is_empty() { Err(LprsError::ArgParse( - "There is no value, the syntax is `KEY=VALUE`".to_owned(), + "Invalid key, the syntax is `KEY(=VALUE)?`".to_owned(), )) + } else { + Ok((value.trim().to_owned(), None)) } } -- 2.45.2 From 2f0531fbc997f38f910dc0cd5b6273d3d96ce52e Mon Sep 17 00:00:00 2001 From: Awiteb Date: Sat, 17 Aug 2024 14:50:38 +0000 Subject: [PATCH 2/4] chore: Util to ask the user for the value of a key without value Signed-off-by: Awiteb --- src/utils.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/utils.rs b/src/utils.rs index eb5ed46..74eccba 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -181,7 +181,7 @@ pub fn lprs_version() -> LprsResult> { } /// Returns the duplicated field from the custom field (unprocessed fields) -pub fn get_duplicated_field(fields: &[(String, String)]) -> Option<&str> { +pub fn get_duplicated_field(fields: &[(String, Option)]) -> Option<&str> { fields.iter().find_map(|(key, _)| { if fields.iter().filter(|(k, _)| key == k).count() > 1 { return Some(key.as_str()); @@ -210,6 +210,27 @@ pub fn apply_custom_fields( } } +/// Make sure all custom field values are there, if not, ask the user for it +/// +/// ## Errors +/// - If can't read the user input +pub fn prompt_custom( + custom_fields: Vec<(String, Option)>, +) -> LprsResult> { + let mut new_fields = Vec::new(); + + for (key, value) in custom_fields { + if let Some(value) = value { + new_fields.push((key, value)); + } else { + let value = inquire::Text::new(&format!("Value of `{key}`:")).prompt()?; + new_fields.push((key, value)); + } + } + + Ok(new_fields) +} + /// Returns the vault with its index by its index or name /// /// ## Errors -- 2.45.2 From 4028607cb5ba0baaf6671d65fa46d433aba554a7 Mon Sep 17 00:00:00 2001 From: Awiteb Date: Sat, 17 Aug 2024 14:52:14 +0000 Subject: [PATCH 3/4] feat: Support entering custom keys value via STDIN This for adding new key, and editing keys (Change the key value) Fixes: https://git.4rs.nl/awiteb/lprs/issues/56 Signed-off-by: Awiteb --- src/cli/add_command.rs | 20 ++++++++++++-------- src/cli/edit_command.rs | 24 ++++++++++++++++-------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/cli/add_command.rs b/src/cli/add_command.rs index 1b02d0e..1fdaa8f 100644 --- a/src/cli/add_command.rs +++ b/src/cli/add_command.rs @@ -39,9 +39,11 @@ pub struct Add { #[allow(clippy::option_option)] totp_secret: Option>, /// Add a custom field to the vault - #[arg(name = "KEY=VALUE", short = 'c', long = "custom")] + /// + /// If there is no value, you will enter it through a prompt + #[arg(name = "KEY(=VALUE)?", short = 'c', long = "custom")] #[arg(value_parser = clap_parsers::kv_parser)] - custom_fields: Vec<(String, String)>, + custom_fields: Vec<(String, Option)>, /// Force add, will not return error if there is a problem with the args. /// /// For example, duplication in the custom fields and try to adding empty @@ -73,7 +75,9 @@ impl LprsCommand for Add { self.vault_info.name = self.vault_info.name.trim().to_string(); self.vault_info.password = utils::user_secret(self.password, "Vault password:", false)?; - self.vault_info.custom_fields = self.custom_fields.into_iter().collect(); + self.vault_info.custom_fields = utils::prompt_custom(self.custom_fields)? + .into_iter() + .collect(); vault_manager.add_vault(self.vault_info); vault_manager.try_export()?; } @@ -95,23 +99,23 @@ impl LprsCommand for Add { if self .password .as_ref() - .is_some_and(|p| p.as_ref().is_some_and(|p| p.is_empty())) + .is_some_and(|p| p.as_ref().is_some_and(String::is_empty)) || self.vault_info.name.is_empty() || self .vault_info .username .as_ref() - .is_some_and(|u| u.is_empty()) + .is_some_and(String::is_empty) || self .vault_info .service .as_ref() - .is_some_and(|s| s.is_empty()) - || self.vault_info.note.as_ref().is_some_and(|n| n.is_empty()) + .is_some_and(String::is_empty) + || self.vault_info.note.as_ref().is_some_and(String::is_empty) || self .custom_fields .iter() - .any(|(k, v)| k.is_empty() || v.is_empty()) + .any(|(k, v)| k.is_empty() || v.as_ref().is_some_and(String::is_empty)) { return Err(LprsError::EmptyValue); } diff --git a/src/cli/edit_command.rs b/src/cli/edit_command.rs index 6fd2ee2..23ad011 100644 --- a/src/cli/edit_command.rs +++ b/src/cli/edit_command.rs @@ -36,28 +36,33 @@ pub struct Edit { /// The new vault name name: Option, #[arg(short, long)] - /// The new vault username + /// The new vault username, make it empty string to delete it username: Option, #[arg(short, long)] - /// The new password, if there is no value for it you will prompt it + /// The new password, make it empty string to delete it + /// + /// If there is no value for it you will prompt it #[allow(clippy::option_option)] password: Option>, #[arg(short, long)] - /// The new vault service + /// The new vault service, make it empty string to delete it service: Option, #[arg(short = 'o', long)] /// The new vault note note: Option, - /// The TOTP secret, if there is no value you will prompt it + /// The TOTP secret, make it empty string to delete it + /// + /// If there is no value you will prompt it #[arg(short, long)] #[allow(clippy::option_option)] totp_secret: Option>, - /// The custom field, make its value empty to delete it + /// The custom field, make it empty string to delete it /// - /// If the custom field not exist will created it, if it's will update it + /// If the custom field not exist will created it, if it's will update it, + /// if there is no value, you will enter it through a prompt (e.g `-c key`) #[arg(name = "KEY=VALUE", short = 'c', long = "custom")] #[arg(value_parser = clap_parsers::kv_parser)] - custom_fields: Vec<(String, String)>, + custom_fields: Vec<(String, Option)>, /// Force edit, will not return error if there is a problem with the args. /// /// For example, duplication in the custom fields and try to editing nothing @@ -120,7 +125,10 @@ impl LprsCommand for Edit { vault.note = Some(new_note); } } - utils::apply_custom_fields(&mut vault.custom_fields, self.custom_fields); + utils::apply_custom_fields( + &mut vault.custom_fields, + utils::prompt_custom(self.custom_fields)?, + ); vault_manager.try_export() } -- 2.45.2 From 4133b0fe1e02d4b4c202d4e430c1407d005e5900 Mon Sep 17 00:00:00 2001 From: Awiteb Date: Sat, 17 Aug 2024 15:14:53 +0000 Subject: [PATCH 4/4] docs: Update the docs - Remove the version option - Update it with the changes of this commit 4028607cb5ba0baaf6671d65fa46d433aba554a7 (current patch) Signed-off-by: Awiteb --- docs/commands/add.md | 7 +++---- docs/commands/clean.md | 4 ---- docs/commands/edit.md | 19 ++++++++++--------- docs/commands/gen.md | 1 - docs/commands/get.md | 3 --- docs/commands/import-export.md | 3 --- docs/commands/list.md | 2 +- docs/commands/remove.md | 1 - 8 files changed, 14 insertions(+), 26 deletions(-) diff --git a/docs/commands/add.md b/docs/commands/add.md index c9617de..bbaa508 100644 --- a/docs/commands/add.md +++ b/docs/commands/add.md @@ -35,8 +35,10 @@ Options: -t, --totp-secret [] The TOTP secret, if there is no value you will prompt it - -c, --custom + -c, --custom Add a custom field to the vault + + If there is no value, you will enter it through a prompt -f, --force Force add, will not return error if there is a problem with the args. @@ -45,9 +47,6 @@ Options: -h, --help Print help (see a summary with '-h') - - -V, --version - Print version ``` So, to add a vault you need to provide a name for the vault, and you can provide diff --git a/docs/commands/clean.md b/docs/commands/clean.md index 75a29c0..255a8d0 100644 --- a/docs/commands/clean.md +++ b/docs/commands/clean.md @@ -4,10 +4,6 @@ ``` Usage: lprs clean - -Options: - -h, --help Print help - -V, --version Print version ``` Is simple, just run `lprs clean` and the vaults file will be cleaned, removing diff --git a/docs/commands/edit.md b/docs/commands/edit.md index 5e11789..d3acbff 100644 --- a/docs/commands/edit.md +++ b/docs/commands/edit.md @@ -14,24 +14,28 @@ Options: The new vault name -u, --username - The new vault username + The new vault username, make it empty string to delete it -p, --password [] - The new password, if there is no value for it you will prompt it + The new password, make it empty string to delete it + + If there is no value for it you will prompt it -s, --service - The new vault service + The new vault service, make it empty string to delete it -o, --note The new vault note -t, --totp-secret [] - The TOTP secret, if there is no value you will prompt it + The TOTP secret, make it empty string to delete it + + If there is no value you will prompt it -c, --custom - The custom field, make its value empty to delete it + The custom field, make it empty string to delete it - If the custom field not exist will created it, if it's will update it + If the custom field not exist will created it, if it's will update it, if there is no value, you will enter it through a prompt (e.g `-c key`) -f, --force Force edit, will not return error if there is a problem with the args. @@ -40,9 +44,6 @@ Options: -h, --help Print help (see a summary with '-h') - - -V, --version - Print version ``` To edit a vault you need to provide the index or the name of the vault. If you diff --git a/docs/commands/gen.md b/docs/commands/gen.md index 6fad352..9296cca 100644 --- a/docs/commands/gen.md +++ b/docs/commands/gen.md @@ -14,7 +14,6 @@ Options: -n, --numbers With numbers (0-9) -s, --symbols With symbols (!,# ...) -h, --help Print help - -V, --version Print version ``` Generate a password with the specified length, by default the length is `18`, diff --git a/docs/commands/get.md b/docs/commands/get.md index e4f901e..69832f6 100644 --- a/docs/commands/get.md +++ b/docs/commands/get.md @@ -19,9 +19,6 @@ Arguments: Options: -h, --help Print help (see a summary with '-h') - - -V, --version - Print version ``` Get a single field from a vault, if the field is not provided, the whole vault diff --git a/docs/commands/import-export.md b/docs/commands/import-export.md index 42eb78b..c44e05a 100644 --- a/docs/commands/import-export.md +++ b/docs/commands/import-export.md @@ -24,9 +24,6 @@ Options: -h, --help Print help (see a summary with '-h') - - -V, --version - Print version ``` ## Export usage diff --git a/docs/commands/list.md b/docs/commands/list.md index 367c1bf..a3dfca7 100644 --- a/docs/commands/list.md +++ b/docs/commands/list.md @@ -10,7 +10,6 @@ Options: -r, --regex Enable regex when use `--filter` option --json Returns the output as `json` list of vaults -h, --help Print help - -V, --version Print version ``` Lprs `list` command is used to list all vaults in the vaults file, you can also @@ -21,4 +20,5 @@ work with it with `jq`). ### Examples + diff --git a/docs/commands/remove.md b/docs/commands/remove.md index ce4bdfd..7647221 100644 --- a/docs/commands/remove.md +++ b/docs/commands/remove.md @@ -11,7 +11,6 @@ Arguments: Options: -f, --force Force remove, will not return error if there is no vault with the given index or name -h, --help Print help - -V, --version Print version ``` To remove a vault you need to provide the index or the name of the vault. If you -- 2.45.2