diff --git a/README.md b/README.md index 2ad2bc4..59ca08a 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Commands: add Add new password list List your password and search clean Clean the password file + edit Edit the password content help Print this message or the help of the given subcommand(s) Options: @@ -57,4 +58,4 @@ Contributions to Passrs are welcome! If you would like to contribute, please fol ## License -Passrs is licensed under the GPL-3.0 License. This means that you are free to use, modify, and distribute the software under the terms of this license. Please refer to the [LICENSE](LICENSE) file for more details. \ No newline at end of file +Passrs is licensed under the GPL-3.0 License. This means that you are free to use, modify, and distribute the software under the terms of this license. Please refer to the [LICENSE](LICENSE) file for more details. diff --git a/src/cli/edit_command.rs b/src/cli/edit_command.rs new file mode 100644 index 0000000..83de8af --- /dev/null +++ b/src/cli/edit_command.rs @@ -0,0 +1,89 @@ +// Local CLI password manager +// Copyright (C) 2024 Awiteb +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use std::num::NonZeroU64; + +use clap::Args; + +use crate::{ + password::{Password, Passwords}, + PassrsError, PassrsResult, RunCommand, +}; + +#[derive(Debug, Args)] +#[command(author, version, about, long_about = None)] +pub struct Edit { + /// The password index. Check it from list command + index: NonZeroU64, + + #[arg(short, long)] + /// The new password name + name: Option, + #[arg(short, long)] + /// The new password username + username: Option, + #[arg(short, long)] + /// The new password + password: Option, + #[arg(short, long)] + /// The new password service + service: Option, + #[arg(short = 'o', long)] + /// The new password note + note: Option, +} + +impl RunCommand for Edit { + fn run(&self, mut password_manager: Passwords) -> PassrsResult<()> { + let index = self.index.get() as usize; + + if let Some(password) = password_manager.passwords.get_mut(index - 1) { + if self.name.is_none() + && self.username.is_none() + && self.password.is_none() + && self.service.is_none() + && self.note.is_none() + { + Err(PassrsError::Other( + "You must edit one option at least".to_owned(), + )) + } else { + *password = Password { + name: self.name.as_ref().unwrap_or(&password.name).to_string(), + username: self + .username + .as_ref() + .unwrap_or(&password.username) + .to_string(), + password: self + .password + .as_ref() + .unwrap_or(&password.password) + .to_string(), + service: self.service.as_ref().or(password.service.as_ref()).cloned(), + note: self.note.as_ref().or(password.note.as_ref()).cloned(), + }; + password_manager.try_export() + } + } else { + Err(PassrsError::InvalidPasswordIndex(format!( + "The index `{}` is greater than the passwords count {}", + self.index, + password_manager.passwords.len() + ))) + } + } +} diff --git a/src/cli/list_command.rs b/src/cli/list_command.rs index 578ea61..1035ac6 100644 --- a/src/cli/list_command.rs +++ b/src/cli/list_command.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use std::num::NonZeroU64; + use clap::Args; use comfy_table::Table; use regex::Regex; @@ -35,7 +37,7 @@ pub struct List { /// Return the password with spesifc index #[arg(short, long, value_name = "INDEX")] - get: Option, + get: Option, /// Search and display only matching passwords. /// /// The name and username will be searched. And service and note if included @@ -79,7 +81,7 @@ impl RunCommand for List { .enumerate() .filter(|(idx, pass)| { if let Some(index) = self.get { - return (idx + 1) == index; + return (idx + 1) == index.get() as usize; } if let Some(ref pattern) = self.search { if self.regex { diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 3ba8a0b..292af26 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -25,6 +25,7 @@ use crate::{ pub mod add_command; pub mod clean_command; +pub mod edit_command; pub mod list_command; crate::create_commands!( @@ -32,8 +33,8 @@ crate::create_commands!( "Add new password", Add => add_command::Add "List your password and search", List => list_command::List "Clean the password file", Clean => clean_command::Clean - // TODO: Edit command - // TODO: Delete command + "Edit the password content", Edit => edit_command::Edit + // TODO: Remove command // TODO: Export command // TODO: Import command ); diff --git a/src/errors.rs b/src/errors.rs index eddf2e4..05d6265 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -34,6 +34,10 @@ pub enum Error { WeakPassword(String), #[error("Args Conflict Error: {0}")] ArgsConflict(String), + #[error("Invalid Password Index Error: {0}")] + InvalidPasswordIndex(String), + #[error("{0}")] + Other(String), #[error("Invalid Regex: {0}")] InvalidRegex(#[from] regex::Error),