diff --git a/rust/Cargo.lock b/rust/Cargo.lock index e16907f6d1..ae78586b97 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -29,10 +29,10 @@ dependencies = [ "curl", "fs_extra", "indicatif", + "inquire", "log", "nix 0.27.1", "reqwest 0.11.27", - "rpassword", "serde", "serde_json", "serde_yaml", @@ -945,6 +945,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 +1098,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 +1386,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 +1828,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 +2137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", + "log", "wasi", "windows-sys 0.48.0", ] @@ -2103,6 +2160,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 +2961,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 +3238,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..5896b79901 100644 --- a/rust/agama-cli/Cargo.toml +++ b/rust/agama-cli/Cargo.toml @@ -25,8 +25,8 @@ 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" +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..a64a754055 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::Password; use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE}; use std::io::{self, IsTerminal}; @@ -37,15 +38,25 @@ 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::StdinPassword)?; buffer }; Ok(password) } +/// Asks interactively for the password. (For authentication, not for changing it) +fn ask_password() -> Result { + Password::new("Please enter the root password:") + .without_confirmation() + .prompt() + .map_err(CliError::InteractivePassword) +} + /// 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..0fe383b741 100644 --- a/rust/agama-cli/src/error.rs +++ b/rust/agama-cli/src/error.rs @@ -1,11 +1,14 @@ +use inquire::InquireError; 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, - #[error("Could not read the password: {0}")] - MissingPassword(#[from] std::io::Error), + Installation, + #[error("Could not read the password")] + InteractivePassword(#[source] InquireError), + #[error("Could not read the password from the standard input")] + StdinPassword(#[source] std::io::Error), } 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)); 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