diff --git a/Cargo.lock b/Cargo.lock index b41b8bb7f..db6c13174 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -638,6 +638,18 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "clicolors-control" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e" +dependencies = [ + "atty", + "lazy_static", + "libc", + "winapi", +] + [[package]] name = "concread" version = "0.2.16" @@ -664,6 +676,23 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "console" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586208b33573b7f76ccfbe5adb076394c88deaf81b84d7213969805b0a952a7" +dependencies = [ + "clicolors-control", + "encode_unicode", + "lazy_static", + "libc", + "regex", + "terminal_size", + "termios", + "unicode-width", + "winapi", +] + [[package]] name = "console_error_panic_hook" version = "0.1.6" @@ -1001,6 +1030,17 @@ dependencies = [ "nom 6.1.2", ] +[[package]] +name = "dialoguer" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b5eb0fce3c4f955b8d8d864b131fb8863959138da962026c106ba7a2e3bf7a" +dependencies = [ + "console", + "lazy_static", + "tempfile", +] + [[package]] name = "digest" version = "0.8.1" @@ -1052,6 +1092,12 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "encoding_rs" version = "0.8.28" @@ -1846,6 +1892,7 @@ name = "kanidm_tools" version = "1.1.0-alpha.5" dependencies = [ "bundy", + "dialoguer", "env_logger", "kanidm_client", "kanidm_proto", @@ -3323,6 +3370,25 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "termios" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b" +dependencies = [ + "libc", +] + [[package]] name = "textwrap" version = "0.11.0" diff --git a/kanidm_tools/Cargo.toml b/kanidm_tools/Cargo.toml index 33f15efff..50e3b5b43 100644 --- a/kanidm_tools/Cargo.toml +++ b/kanidm_tools/Cargo.toml @@ -44,6 +44,8 @@ bundy = "0.1" zxcvbn = "2.0" +dialoguer = "0.5.1" + webauthn-authenticator-rs = "^0.3.0-alpha.9" # webauthn-authenticator-rs = { path = "../../webauthn-authenticator-rs/" } diff --git a/kanidm_tools/src/cli/common.rs b/kanidm_tools/src/cli/common.rs index 7c551985f..295980011 100644 --- a/kanidm_tools/src/cli/common.rs +++ b/kanidm_tools/src/cli/common.rs @@ -3,6 +3,8 @@ use crate::CommonOpt; use kanidm_client::{KanidmClient, KanidmClientBuilder}; use kanidm_proto::v1::UserAuthToken; +use dialoguer::{theme::ColorfulTheme, Select}; + impl CommonOpt { pub fn to_unauth_client(&self) -> KanidmClient { let config_path: String = shellexpand::tilde("~/.config/kanidm").into_owned(); @@ -76,9 +78,24 @@ impl CommonOpt { info!("Using cached token for name {}", f_uname); f_token.clone() } else { - // Unable to select - error!("Multiple authentication tokens exist. Please select one with --name."); - std::process::exit(1); + // Unable to automatically select the user because multiple tokens exist + // so we'll prompt the user to select one + let mut options = Vec::new(); + for option in tokens.iter() { + options.push(String::from(option.0)); + } + let selection = Select::with_theme(&ColorfulTheme::default()) + .with_prompt("Multiple authentication tokens exist. Please select one") + .default(0) + .items(&options) + .interact() + .unwrap(); + debug!("Index of the chosen menu item: {:?}", selection); + + let (f_uname, f_token) = + tokens.iter().nth(selection).expect("Memory Corruption"); + info!("Using cached token for name {}", f_uname); + f_token.clone() } } };