From afdebef7e76da1ec541aa23c58defc0ede042a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imobach=20Gonz=C3=A1lez=20Sosa?= Date: Tue, 28 May 2024 11:41:03 +0100 Subject: [PATCH 1/7] refactor(rust): replace rpassword with inquire --- rust/Cargo.lock | 111 +++++++++++++++++++++++++++++------- rust/agama-cli/Cargo.toml | 3 +- rust/agama-cli/src/auth.rs | 25 +++++++- rust/agama-cli/src/error.rs | 4 +- 4 files changed, 116 insertions(+), 27 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index e16907f6d1..2d9923e5a5 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -28,11 +28,12 @@ dependencies = [ "console", "curl", "fs_extra", + "home", "indicatif", + "inquire", "log", "nix 0.27.1", "reqwest 0.11.27", - "rpassword", "serde", "serde_json", "serde_yaml", @@ -945,6 +946,31 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "crossterm" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +dependencies = [ + "bitflags 1.3.2", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -1073,6 +1099,12 @@ dependencies = [ "const-random", ] +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + [[package]] name = "either" version = "1.10.0" @@ -1355,6 +1387,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1788,6 +1829,22 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "inquire" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" +dependencies = [ + "bitflags 2.5.0", + "crossterm", + "dyn-clone", + "fxhash", + "newline-converter", + "once_cell", + "unicode-segmentation", + "unicode-width", +] + [[package]] name = "instant" version = "0.1.12" @@ -2081,6 +2138,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", + "log", "wasi", "windows-sys 0.48.0", ] @@ -2103,6 +2161,15 @@ dependencies = [ "tempfile", ] +[[package]] +name = "newline-converter" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "nix" version = "0.26.4" @@ -2895,27 +2962,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "rpassword" -version = "7.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" -dependencies = [ - "libc", - "rtoolbox", - "windows-sys 0.48.0", -] - -[[package]] -name = "rtoolbox" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "rust-ini" version = "0.19.0" @@ -3193,6 +3239,27 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" diff --git a/rust/agama-cli/Cargo.toml b/rust/agama-cli/Cargo.toml index 71d3629795..f891d1f6cc 100644 --- a/rust/agama-cli/Cargo.toml +++ b/rust/agama-cli/Cargo.toml @@ -25,8 +25,9 @@ zbus = { version = "3", default-features = false, features = ["tokio"] } tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread"] } async-trait = "0.1.77" reqwest = { version = "0.11", features = ["json"] } -rpassword = "7.3.1" url = "2.5.0" +home = "0.5.9" +inquire = { version = "0.7.5", default-features = false, features = ["crossterm", "one-liners"] } [[bin]] name = "agama" diff --git a/rust/agama-cli/src/auth.rs b/rust/agama-cli/src/auth.rs index 7ce7d35f13..a0d5f8d3b4 100644 --- a/rust/agama-cli/src/auth.rs +++ b/rust/agama-cli/src/auth.rs @@ -2,6 +2,7 @@ use agama_lib::auth::AuthToken; use clap::Subcommand; use crate::error::CliError; +use inquire::{validator::Validation, Password}; use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE}; use std::io::{self, IsTerminal}; @@ -37,15 +38,35 @@ pub async fn run(subcommand: AuthCommands) -> anyhow::Result<()> { fn read_password() -> Result { let stdin = io::stdin(); let password = if stdin.is_terminal() { - rpassword::prompt_password("Please, introduce the root password: ")? + ask_password()? } else { let mut buffer = String::new(); - stdin.read_line(&mut buffer)?; + stdin + .read_line(&mut buffer) + .map_err(|_| CliError::MissingPassword)?; buffer }; Ok(password) } +/// Asks interactively for the password. +fn ask_password() -> Result { + let validator = |input: &str| { + if input.is_empty() { + Ok(Validation::Invalid("The password cannot be blank.".into())) + } else { + Ok(Validation::Valid) + } + }; + + Password::new("Please, introduce the root password:") + .with_validator(validator) + .without_confirmation() + .with_help_message("Press to exit.") + .prompt() + .map_err(|_| CliError::MissingPassword) +} + /// Necessary http request header for authenticate fn authenticate_headers() -> HeaderMap { let mut headers = HeaderMap::new(); diff --git a/rust/agama-cli/src/error.rs b/rust/agama-cli/src/error.rs index 2aa5985981..228692513f 100644 --- a/rust/agama-cli/src/error.rs +++ b/rust/agama-cli/src/error.rs @@ -6,6 +6,6 @@ pub enum CliError { ValidationError, #[error("Could not start the installation")] InstallationError, - #[error("Could not read the password: {0}")] - MissingPassword(#[from] std::io::Error), + #[error("No password was provided")] + MissingPassword, } From 8593a435929df7cc36303791cdb2720c88136724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imobach=20Gonz=C3=A1lez=20Sosa?= Date: Tue, 28 May 2024 12:36:37 +0100 Subject: [PATCH 2/7] chore(rust): update the changes file --- rust/package/agama.changes | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rust/package/agama.changes b/rust/package/agama.changes index fed08d18ff..83ea4bc679 100644 --- a/rust/package/agama.changes +++ b/rust/package/agama.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Jun 27 07:02:29 UTC 2024 - Imobach Gonzalez Sosa + +- Improve the prompt to introduce the password in the "auth login" + command (gh#openSUSE/agama#1271). + ------------------------------------------------------------------- Wed Jun 26 12:56:31 UTC 2024 - Knut Anderssen From e81e7437258ae26b5309f0910d0632927a9e3b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imobach=20Gonz=C3=A1lez=20Sosa?= Date: Thu, 27 Jun 2024 10:28:30 +0100 Subject: [PATCH 3/7] Apply suggestions from code review Co-authored-by: Martin Vidner --- rust/agama-cli/src/auth.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/agama-cli/src/auth.rs b/rust/agama-cli/src/auth.rs index a0d5f8d3b4..317b9dca48 100644 --- a/rust/agama-cli/src/auth.rs +++ b/rust/agama-cli/src/auth.rs @@ -49,7 +49,7 @@ fn read_password() -> Result { Ok(password) } -/// Asks interactively for the password. +/// Asks interactively for the password. (For authentication, not for changing it) fn ask_password() -> Result { let validator = |input: &str| { if input.is_empty() { @@ -59,7 +59,7 @@ fn ask_password() -> Result { } }; - Password::new("Please, introduce the root password:") + Password::new("Please enter the root password:") .with_validator(validator) .without_confirmation() .with_help_message("Press to exit.") From c20364f578612067724b246e238931acce62888d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imobach=20Gonz=C3=A1lez=20Sosa?= Date: Thu, 27 Jun 2024 12:50:03 +0100 Subject: [PATCH 4/7] fix(cli): allow empty passwords in "auth login" --- rust/agama-cli/src/auth.rs | 15 +++------------ rust/agama-cli/src/error.rs | 7 +++++-- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/rust/agama-cli/src/auth.rs b/rust/agama-cli/src/auth.rs index 317b9dca48..435b2924b5 100644 --- a/rust/agama-cli/src/auth.rs +++ b/rust/agama-cli/src/auth.rs @@ -2,7 +2,7 @@ use agama_lib::auth::AuthToken; use clap::Subcommand; use crate::error::CliError; -use inquire::{validator::Validation, Password}; +use inquire::Password; use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE}; use std::io::{self, IsTerminal}; @@ -43,7 +43,7 @@ fn read_password() -> Result { let mut buffer = String::new(); stdin .read_line(&mut buffer) - .map_err(|_| CliError::MissingPassword)?; + .map_err(CliError::StdinPassword)?; buffer }; Ok(password) @@ -51,20 +51,11 @@ fn read_password() -> Result { /// Asks interactively for the password. (For authentication, not for changing it) fn ask_password() -> Result { - let validator = |input: &str| { - if input.is_empty() { - Ok(Validation::Invalid("The password cannot be blank.".into())) - } else { - Ok(Validation::Valid) - } - }; - Password::new("Please enter the root password:") - .with_validator(validator) .without_confirmation() .with_help_message("Press to exit.") .prompt() - .map_err(|_| CliError::MissingPassword) + .map_err(CliError::InteractivePassword) } /// Necessary http request header for authenticate diff --git a/rust/agama-cli/src/error.rs b/rust/agama-cli/src/error.rs index 228692513f..5ae196612e 100644 --- a/rust/agama-cli/src/error.rs +++ b/rust/agama-cli/src/error.rs @@ -1,3 +1,4 @@ +use inquire::InquireError; use thiserror::Error; #[derive(Error, Debug)] @@ -6,6 +7,8 @@ pub enum CliError { ValidationError, #[error("Could not start the installation")] InstallationError, - #[error("No password was provided")] - MissingPassword, + #[error("Could not read the password")] + InteractivePassword(#[source] InquireError), + #[error("Could not read the password from the standard input")] + StdinPassword(#[source] std::io::Error), } From 6d58288bbb9f3512525646b846647de32626580c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imobach=20Gonz=C3=A1lez=20Sosa?= Date: Thu, 27 Jun 2024 12:50:36 +0100 Subject: [PATCH 5/7] refactor(cli): rename CliError variants --- rust/agama-cli/src/error.rs | 4 ++-- rust/agama-cli/src/main.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rust/agama-cli/src/error.rs b/rust/agama-cli/src/error.rs index 5ae196612e..0fe383b741 100644 --- a/rust/agama-cli/src/error.rs +++ b/rust/agama-cli/src/error.rs @@ -4,9 +4,9 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum CliError { #[error("Cannot perform the installation as the settings are not valid")] - ValidationError, + Validation, #[error("Could not start the installation")] - InstallationError, + Installation, #[error("Could not read the password")] InteractivePassword(#[source] InquireError), #[error("Could not read the password from the standard input")] diff --git a/rust/agama-cli/src/main.rs b/rust/agama-cli/src/main.rs index e3bde3f913..1c0642eddc 100644 --- a/rust/agama-cli/src/main.rs +++ b/rust/agama-cli/src/main.rs @@ -63,7 +63,7 @@ async fn install(manager: &ManagerClient<'_>, max_attempts: u8) -> anyhow::Resul manager.wait().await?; if !manager.can_install().await? { - return Err(CliError::ValidationError)?; + return Err(CliError::Validation)?; } let progress = tokio::spawn(async { show_progress().await }); @@ -81,7 +81,7 @@ async fn install(manager: &ManagerClient<'_>, max_attempts: u8) -> anyhow::Resul } if attempts == max_attempts { eprintln!("Giving up."); - return Err(CliError::InstallationError)?; + return Err(CliError::Installation)?; } attempts += 1; sleep(Duration::from_secs(1)); From 677c4f6c97ac52bbd1d68e0e17d46e7f1840b5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imobach=20Gonz=C3=A1lez=20Sosa?= Date: Thu, 27 Jun 2024 13:22:49 +0100 Subject: [PATCH 6/7] fix(cli): remove useless help text --- rust/agama-cli/src/auth.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/agama-cli/src/auth.rs b/rust/agama-cli/src/auth.rs index 435b2924b5..a64a754055 100644 --- a/rust/agama-cli/src/auth.rs +++ b/rust/agama-cli/src/auth.rs @@ -53,7 +53,6 @@ fn read_password() -> Result { fn ask_password() -> Result { Password::new("Please enter the root password:") .without_confirmation() - .with_help_message("Press to exit.") .prompt() .map_err(CliError::InteractivePassword) } From c608ed2fc5942e7d2fe5d03abae3e062be18476d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imobach=20Gonz=C3=A1lez=20Sosa?= Date: Thu, 27 Jun 2024 13:24:13 +0100 Subject: [PATCH 7/7] fix(cli): drop unused dependency --- rust/Cargo.lock | 1 - rust/agama-cli/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 2d9923e5a5..ae78586b97 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -28,7 +28,6 @@ dependencies = [ "console", "curl", "fs_extra", - "home", "indicatif", "inquire", "log", diff --git a/rust/agama-cli/Cargo.toml b/rust/agama-cli/Cargo.toml index f891d1f6cc..5896b79901 100644 --- a/rust/agama-cli/Cargo.toml +++ b/rust/agama-cli/Cargo.toml @@ -26,7 +26,6 @@ tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread"] } async-trait = "0.1.77" reqwest = { version = "0.11", features = ["json"] } url = "2.5.0" -home = "0.5.9" inquire = { version = "0.7.5", default-features = false, features = ["crossterm", "one-liners"] } [[bin]]