diff --git a/.github/workflows/rust_build.yml b/.github/workflows/rust_build.yml index 764e38877..91812dcc2 100644 --- a/.github/workflows/rust_build.yml +++ b/.github/workflows/rust_build.yml @@ -35,6 +35,32 @@ jobs: libssl-dev \ libsqlite3-dev - - run: cargo build --workspace - - run: cargo build --bin kanidm --features idv-tui - - run: cargo test \ No newline at end of file + - name: "Build the workspace" + run: cargo build --workspace + - name: "Build the idv-tui feature kanidm binary" + run: cargo build --bin kanidm --features idv-tui + - name: "Run cargo test" + run: cargo test + run_release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + - name: Setup sccache + uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.4.2" + + - name: Install dependencies + run: | + sudo apt-get update && \ + sudo apt-get install -y \ + libpam0g-dev \ + libudev-dev \ + libssl-dev \ + ripgrep + - name: "Run the release build test script" + env: + BUILD_MODE: release + run: ./scripts/test_run_release_server.sh diff --git a/Cargo.lock b/Cargo.lock index 4f7b506c6..28c82e8d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1425,6 +1425,12 @@ dependencies = [ "libc", ] +[[package]] +name = "exitcode" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193" + [[package]] name = "fake-simd" version = "0.1.2" @@ -2415,6 +2421,7 @@ dependencies = [ "compact_jwt", "cursive", "dialoguer", + "exitcode", "futures-concurrency", "kanidm_build_profiles", "kanidm_client", diff --git a/scripts/setup_dev_environment.sh b/scripts/setup_dev_environment.sh index 1a2fee6eb..f0b746ae6 100755 --- a/scripts/setup_dev_environment.sh +++ b/scripts/setup_dev_environment.sh @@ -9,12 +9,25 @@ set -e +if [ -n "${BUILD_MODE}" ]; then + BUILD_MODE="--${BUILD_MODE}" +else + BUILD_MODE="" +fi + # if they passed --help then output the help if [ "${1}" == "--help" ]; then echo "Usage: $0 [--remove-db]" echo " --remove-db: remove the existing DB before running" + echo " Env vars:" + echo " BUILD_MODE - default=debug, set to 'release' to build binaries in release mode" exit 0 fi +if [ ! -f run_insecure_dev_server.sh ]; then + echo "Please run from the server/daemon dir!" + exit 1 +fi + # if --remove-db is in the command line args then remove the DB if [ -z "${REMOVE_TEST_DB}" ]; then @@ -25,10 +38,6 @@ if [ -z "${REMOVE_TEST_DB}" ]; then fi fi -if [ ! -f run_insecure_dev_server.sh ]; then - echo "Please run from the server/daemon dir!" - exit 1 -fi # defaults KANIDM_CONFIG_FILE="../../examples/insecure_server.toml" @@ -62,22 +71,26 @@ OAUTH2_RP_ID="test_oauth2" OAUTH2_RP_DISPLAY="test_oauth2" # commands to run things -KANIDM="cargo run --manifest-path ../../Cargo.toml --bin kanidm -- " -KANIDMD="cargo run -p daemon --bin kanidmd -- " +KANIDM="cargo run ${BUILD_MODE} --manifest-path ../../Cargo.toml --bin kanidm -- " +KANIDMD="cargo run ${BUILD_MODE} -p daemon --bin kanidmd -- " if [ "${REMOVE_TEST_DB}" -eq 1 ]; then echo "Removing the existing DB!" rm /tmp/kanidm/kanidm.db || true fi -echo "Reset the admin user" -ADMIN_PASS=$(${KANIDMD} recover-account admin -o json 2>&1 | rg password | jq -r .password) +echo "Resetting the admin user..." +${KANIDMD} recover-account admin -o json 2>&1 +ADMIN_PASS_STR="$(${KANIDMD} recover-account admin -o json 2>&1)" +ADMIN_PASS=$(echo "${ADMIN_PASS_STR}" | rg password | jq -r .password) if [ -z "${ADMIN_PASS}" ] || [ "${ADMIN_PASS}" == "null " ]; then echo "Failed to reset admin password!" + echo "${ADMIN_PASS_STR}" exit 1 fi + echo "admin pass: '${ADMIN_PASS}'" -echo "Reset the idm_admin user" +echo "Resetting the idm_admin user..." IDM_ADMIN_PASS=$(${KANIDMD} recover-account idm_admin -o json 2>&1 | rg password | jq -r .password) if [ -z "${IDM_ADMIN_PASS}" ] || [ "${IDM_ADMIN_PASS}" == "null " ]; then echo "Failed to reset admin password!" diff --git a/scripts/test_run_release_server.sh b/scripts/test_run_release_server.sh new file mode 100755 index 000000000..2b556c2c5 --- /dev/null +++ b/scripts/test_run_release_server.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# this script runs the server in release mode and tries to set up a dev environment, which catches failures between the +# server and CLI, and ensures clap/etc rules actually work +# +# you really really really really don't want to run this when an environment you like exists, it'll mess it up + +set -e + +WAIT_TIMER=5 + +echo "Building release binaries..." +cargo build --release --bin kanidm --bin kanidmd + +if [ -d '.git' ]; then + echo "You're in the root dir, let's move you!" + CURRENT_DIR="$(pwd)" + cd server/daemon/ || exit 1 +fi + +if [ ! -f "run_insecure_dev_server.sh" ]; then + echo "I'm not sure where you are, please run this from the root of the repository or the server/daemon directory" + exit 1 +fi + +mkdir -p /tmp/kanidm/ + +echo "Generating certificates..." +cargo run --bin kanidmd --release cert-generate --config ../../examples/insecure_server.toml + +echo "Making sure it runs with the DB..." +cargo run --bin kanidmd --release recover-account idm_admin -o json + +echo "Running the server..." +cargo run --bin kanidmd --release server --config ../../examples/insecure_server.toml & +KANIDMD_PID=$! +echo "${KANIDMD_PID}" + +if [ "$(jobs -p | wc -l)" -eq 0 ]; then + echo "Kanidmd failed to start!" + exit 1 +fi + +ATTEMPT=0 + +KANIDM_CONFIG_FILE="../../examples/insecure_server.toml" +KANIDM_URL="$(rg origin "${KANIDM_CONFIG_FILE}" | awk '{print $NF}' | tr -d '"')" +KANIDM_CA_PATH="/tmp/kanidm/ca.pem" + +while true; do + echo "Waiting the server to start... testing ${KANIDM_URL}" + curl --cacert "${KANIDM_CA_PATH}" -fs "${KANIDM_URL}" >/dev/null && break + sleep 2 + ATTEMPT="$((ATTEMPT + 1))" + if [ "${ATTEMPT}" -gt 3 ]; then + echo "Kanidmd failed to start!" + exit 1 + fi +done + +../../scripts/setup_dev_environment.sh + + +echo "Waiting ${WAIT_TIMER} seconds and terminating Kanidmd" +sleep "${WAIT_TIMER}" +if [ "$(pgrep kanidmd | wc -l)" -gt 0 ]; then + kill $(pgrep kanidmd) +fi + +if [ -n "$CURRENT_DIR" ]; then + cd "$CURRENT_DIR" || exit 1 +fi diff --git a/server/lib/src/be/idl_arc_sqlite.rs b/server/lib/src/be/idl_arc_sqlite.rs index abea72a15..e3a5c3ddb 100644 --- a/server/lib/src/be/idl_arc_sqlite.rs +++ b/server/lib/src/be/idl_arc_sqlite.rs @@ -1106,7 +1106,7 @@ impl<'a> IdlArcSqliteWriteTransaction<'a> { /// specific situations. #[instrument(level = "trace", skip_all)] pub fn danger_purge_idxs(&mut self) -> Result<(), OperationError> { - error!("CLEARING CACHE"); + warn!("CLEARING CACHE"); self.db.danger_purge_idxs().map(|()| { self.idl_cache.clear(); self.name_cache.clear(); diff --git a/tools/cli/Cargo.toml b/tools/cli/Cargo.toml index 5b7c5a9e9..6b1e09287 100644 --- a/tools/cli/Cargo.toml +++ b/tools/cli/Cargo.toml @@ -53,6 +53,7 @@ uuid = { workspace=true } zxcvbn = { workspace=true } lazy_static.workspace = true regex.workspace = true +exitcode = "1.1.2" [dependencies.cursive] version = "0.20.0" diff --git a/tools/cli/src/cli/badlist.rs b/tools/cli/src/cli/badlist.rs index 22d9873ae..6d869bb81 100644 --- a/tools/cli/src/cli/badlist.rs +++ b/tools/cli/src/cli/badlist.rs @@ -1,6 +1,7 @@ use crate::common::OpType; -use crate::PwBadlistOpt; +use crate::{handle_client_error, PwBadlistOpt}; use futures_concurrency::prelude::*; + // use std::thread; use std::fs::File; use std::io::Read; @@ -29,7 +30,7 @@ impl PwBadlistOpt { eprintln!("--"); eprintln!("Success"); } - Err(e) => eprintln!("{:?}", e), + Err(e) => crate::handle_client_error(e, &copt.output_mode), } } PwBadlistOpt::Upload { @@ -125,7 +126,7 @@ impl PwBadlistOpt { let client = copt.to_client(OpType::Write).await; match client.system_password_badlist_append(filt_pwset).await { Ok(_) => println!("Success"), - Err(e) => eprintln!("{:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } } // End Upload @@ -164,7 +165,7 @@ impl PwBadlistOpt { match client.system_password_badlist_remove(pwset).await { Ok(_) => println!("Success"), - Err(e) => eprintln!("{:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } // End Remove } diff --git a/tools/cli/src/cli/domain.rs b/tools/cli/src/cli/domain.rs index 24a25f498..bf7f99971 100644 --- a/tools/cli/src/cli/domain.rs +++ b/tools/cli/src/cli/domain.rs @@ -1,5 +1,5 @@ use crate::common::OpType; -use crate::DomainOpt; +use crate::{handle_client_error, DomainOpt}; impl DomainOpt { pub fn debug(&self) -> bool { @@ -23,7 +23,7 @@ impl DomainOpt { .await { Ok(_) => println!("Success"), - Err(e) => eprintln!("{:?}", e), + Err(e) => handle_client_error(e, &opt.copt.output_mode), } } DomainOpt::SetLdapBasedn { copt, new_basedn } => { @@ -34,21 +34,21 @@ impl DomainOpt { let client = copt.to_client(OpType::Write).await; match client.idm_domain_set_ldap_basedn(new_basedn).await { Ok(_) => println!("Success"), - Err(e) => eprintln!("{:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } DomainOpt::Show(copt) => { let client = copt.to_client(OpType::Read).await; match client.idm_domain_get().await { Ok(e) => println!("{}", e), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } DomainOpt::ResetTokenKey(copt) => { let client = copt.to_client(OpType::Write).await; match client.idm_domain_reset_token_key().await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } } diff --git a/tools/cli/src/cli/group.rs b/tools/cli/src/cli/group.rs index 32e34f8c8..48f40508b 100644 --- a/tools/cli/src/cli/group.rs +++ b/tools/cli/src/cli/group.rs @@ -1,5 +1,5 @@ use crate::common::OpType; -use crate::{GroupOpt, GroupPosix, OutputMode}; +use crate::{handle_client_error, GroupOpt, GroupPosix, OutputMode}; impl GroupOpt { pub fn debug(&self) -> bool { @@ -35,7 +35,7 @@ impl GroupOpt { } OutputMode::Text => r.iter().for_each(|ent| println!("{}", ent)), }, - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } GroupOpt::Get(gcopt) => { @@ -52,7 +52,7 @@ impl GroupOpt { OutputMode::Text => println!("{}", e), }, Ok(None) => warn!("No matching group '{}'", gcopt.name.as_str()), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &gcopt.copt.output_mode), } } GroupOpt::Create(gcopt) => { @@ -67,14 +67,14 @@ impl GroupOpt { GroupOpt::Delete(gcopt) => { let client = gcopt.copt.to_client(OpType::Write).await; match client.idm_group_delete(gcopt.name.as_str()).await { - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &gcopt.copt.output_mode), Ok(_) => println!("Successfully deleted group {}", gcopt.name.as_str()), } } GroupOpt::PurgeMembers(gcopt) => { let client = gcopt.copt.to_client(OpType::Write).await; match client.idm_group_purge_members(gcopt.name.as_str()).await { - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &gcopt.copt.output_mode), Ok(_) => println!( "Successfully purged members of group {}", gcopt.name.as_str() @@ -86,7 +86,7 @@ impl GroupOpt { match client.idm_group_get_members(gcopt.name.as_str()).await { Ok(Some(groups)) => groups.iter().for_each(|m| println!("{:?}", m)), Ok(None) => warn!("No members in group {}", gcopt.name.as_str()), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &gcopt.copt.output_mode), } } GroupOpt::AddMembers(gcopt) => { @@ -97,7 +97,7 @@ impl GroupOpt { .idm_group_add_members(gcopt.name.as_str(), &new_members) .await { - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &gcopt.copt.output_mode), Ok(_) => println!( "Successfully added {:?} to group \"{}\"", &new_members, @@ -114,7 +114,10 @@ impl GroupOpt { .idm_group_remove_members(gcopt.name.as_str(), &remove_members) .await { - Err(e) => error!("Failed to remove members -> {:?}", e), + Err(e) => { + error!("Failed to remove members!"); + handle_client_error(e, &gcopt.copt.output_mode) + } Ok(_) => println!("Successfully removed members from {}", gcopt.name.as_str()), } } @@ -127,7 +130,7 @@ impl GroupOpt { .idm_group_set_members(gcopt.name.as_str(), &new_members) .await { - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &gcopt.copt.output_mode), Ok(_) => println!("Successfully set members for group {}", gcopt.name.as_str()), } } @@ -136,7 +139,7 @@ impl GroupOpt { let client = gcopt.copt.to_client(OpType::Read).await; match client.idm_group_unix_token_get(gcopt.name.as_str()).await { Ok(token) => println!("{}", token), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &gcopt.copt.output_mode), } } GroupPosix::Set(gcopt) => { @@ -145,7 +148,7 @@ impl GroupOpt { .idm_group_unix_extend(gcopt.name.as_str(), gcopt.gidnumber) .await { - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &gcopt.copt.output_mode), Ok(_) => println!( "Success adding POSIX configuration for group {}", gcopt.name.as_str() diff --git a/tools/cli/src/cli/lib.rs b/tools/cli/src/cli/lib.rs index 518542c76..40fcddbcd 100644 --- a/tools/cli/src/cli/lib.rs +++ b/tools/cli/src/cli/lib.rs @@ -21,6 +21,7 @@ use identify_user_no_tui::{run_identity_verification_no_tui, IdentifyUserState}; #[cfg(feature = "idv-tui")] use identify_user_tui::run_identity_verification_tui; +use kanidm_client::{ClientError, StatusCode}; use url::Url; use uuid::Uuid; @@ -42,6 +43,32 @@ pub mod session_expiry; pub mod synch; mod webauthn; +/// Throws an error and exits the program when we get an error +pub(crate) fn handle_client_error(response: ClientError, _output_mode: &OutputMode) { + match response { + ClientError::Http(status, error, message) => { + let error_msg = match error { + Some(msg) => format!(" {:?}", msg), + None => "".to_string(), + }; + if status == StatusCode::INTERNAL_SERVER_ERROR { + error!( + "Internal Server Error in response:{:?} {:?}", + error_msg, message + ); + std::process::exit(exitcode::SOFTWARE); + } else if status == StatusCode::NOT_FOUND { + error!("Item not found:{:?} {:?}", error_msg, message) + } else { + error!("HTTP Error: {}{} {:?}", status, error_msg, message); + } + } + _ => { + eprintln!("{:?}", response); + } + }; +} + impl SelfOpt { pub fn debug(&self) -> bool { match self { @@ -67,7 +94,7 @@ impl SelfOpt { } } } - Err(e) => println!("Error: {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } SelfOpt::IdentifyUser(copt) => { diff --git a/tools/cli/src/cli/oauth2.rs b/tools/cli/src/cli/oauth2.rs index 0be62b0f5..0b6f470b4 100644 --- a/tools/cli/src/cli/oauth2.rs +++ b/tools/cli/src/cli/oauth2.rs @@ -1,5 +1,7 @@ +use std::process::exit; + use crate::common::OpType; -use crate::{Oauth2Opt, OutputMode}; +use crate::{handle_client_error, Oauth2Opt, OutputMode}; impl Oauth2Opt { pub fn debug(&self) -> bool { @@ -44,7 +46,7 @@ impl Oauth2Opt { } OutputMode::Text => r.iter().for_each(|ent| println!("{}", ent)), }, - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } Oauth2Opt::Get(nopt) => { @@ -52,7 +54,7 @@ impl Oauth2Opt { match client.idm_oauth2_rs_get(nopt.name.as_str()).await { Ok(Some(e)) => println!("{}", e), Ok(None) => println!("No matching entries"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } Oauth2Opt::CreateBasic { @@ -71,7 +73,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } Oauth2Opt::CreatePublic { @@ -90,7 +92,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } Oauth2Opt::UpdateScopeMap(cbopt) => { @@ -104,7 +106,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &cbopt.nopt.copt.output_mode), } } Oauth2Opt::DeleteScopeMap(cbopt) => { @@ -114,7 +116,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &cbopt.nopt.copt.output_mode), } } Oauth2Opt::UpdateSupScopeMap(cbopt) => { @@ -128,7 +130,10 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => { + error!("Error -> {:?}", e); + exit(1) + } } } Oauth2Opt::DeleteSupScopeMap(cbopt) => { @@ -141,7 +146,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &cbopt.nopt.copt.output_mode), } } Oauth2Opt::ResetSecrets(cbopt) => { @@ -160,7 +165,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &cbopt.copt.output_mode), } } Oauth2Opt::ShowBasicSecret(nopt) => { @@ -179,14 +184,14 @@ impl Oauth2Opt { Ok(None) => { eprintln!("No secret configured"); } - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } Oauth2Opt::Delete(nopt) => { let client = nopt.copt.to_client(OpType::Write).await; match client.idm_oauth2_rs_delete(nopt.name.as_str()).await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } Oauth2Opt::SetDisplayname(cbopt) => { @@ -205,7 +210,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &cbopt.nopt.copt.output_mode), } } Oauth2Opt::SetName { nopt, name } => { @@ -224,7 +229,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } Oauth2Opt::SetLandingUrl { nopt, url } => { @@ -243,21 +248,21 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } Oauth2Opt::EnablePkce(nopt) => { let client = nopt.copt.to_client(OpType::Write).await; match client.idm_oauth2_rs_enable_pkce(nopt.name.as_str()).await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } Oauth2Opt::DisablePkce(nopt) => { let client = nopt.copt.to_client(OpType::Write).await; match client.idm_oauth2_rs_disable_pkce(nopt.name.as_str()).await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } Oauth2Opt::EnableLegacyCrypto(nopt) => { @@ -267,7 +272,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } Oauth2Opt::DisableLegacyCrypto(nopt) => { @@ -277,7 +282,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } Oauth2Opt::PreferShortUsername(nopt) => { @@ -287,7 +292,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } Oauth2Opt::PreferSPNUsername(nopt) => { @@ -297,7 +302,7 @@ impl Oauth2Opt { .await { Ok(_) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } } diff --git a/tools/cli/src/cli/person.rs b/tools/cli/src/cli/person.rs index fb45e3f6c..df5e9a63d 100644 --- a/tools/cli/src/cli/person.rs +++ b/tools/cli/src/cli/person.rs @@ -20,8 +20,8 @@ use uuid::Uuid; use crate::webauthn::get_authenticator; use crate::{ - password_prompt, AccountCredential, AccountRadius, AccountSsh, AccountUserAuthToken, - AccountValidity, OutputMode, PersonOpt, PersonPosix, + handle_client_error, password_prompt, AccountCredential, AccountRadius, AccountSsh, + AccountUserAuthToken, AccountValidity, OutputMode, PersonOpt, PersonPosix, }; impl PersonOpt { @@ -82,9 +82,7 @@ impl PersonOpt { "No RADIUS secret set for user {}", aopt.aopts.account_id.as_str(), ), - Err(e) => { - error!("Error -> {:?}", e); - } + Err(e) => handle_client_error(e, &aopt.copt.output_mode), } } AccountRadius::Generate(aopt) => { @@ -134,9 +132,7 @@ impl PersonOpt { .await { Ok(token) => println!("{}", token), - Err(e) => { - error!("Error -> {:?}", e); - } + Err(e) => handle_client_error(e, &aopt.copt.output_mode), } } PersonPosix::Set(aopt) => { @@ -149,7 +145,7 @@ impl PersonOpt { ) .await { - error!("Error -> {:?}", e); + handle_client_error(e, &aopt.copt.output_mode) } } PersonPosix::SetPassword(aopt) => { @@ -169,7 +165,7 @@ impl PersonOpt { ) .await { - error!("Error -> {:?}", e); + handle_client_error(e, &aopt.copt.output_mode) } } }, // end PersonOpt::Posix @@ -189,9 +185,7 @@ impl PersonOpt { } } } - Err(e) => { - error!("Error listing sessions -> {:?}", e); - } + Err(e) => handle_client_error(e, &apo.copt.output_mode), } } AccountUserAuthToken::Destroy { @@ -208,7 +202,8 @@ impl PersonOpt { println!("Success"); } Err(e) => { - error!("Error destroying account session -> {:?}", e); + error!("Error destroying account session"); + handle_client_error(e, &copt.output_mode); } } } @@ -222,9 +217,7 @@ impl PersonOpt { .await { Ok(pkeys) => pkeys.iter().for_each(|pkey| println!("{}", pkey)), - Err(e) => { - error!("Error -> {:?}", e); - } + Err(e) => handle_client_error(e, &aopt.copt.output_mode), } } AccountSsh::Add(aopt) => { @@ -237,7 +230,7 @@ impl PersonOpt { ) .await { - error!("Error -> {:?}", e); + handle_client_error(e, &aopt.copt.output_mode) } } AccountSsh::Delete(aopt) => { @@ -249,7 +242,7 @@ impl PersonOpt { ) .await { - error!("Error -> {:?}", e); + handle_client_error(e, &aopt.copt.output_mode) } } }, // end PersonOpt::Ssh @@ -266,7 +259,7 @@ impl PersonOpt { } OutputMode::Text => r.iter().for_each(|ent| println!("{}", ent)), }, - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } PersonOpt::Update(aopt) => { @@ -282,7 +275,7 @@ impl PersonOpt { .await { Ok(()) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &aopt.copt.output_mode), } } PersonOpt::Get(aopt) => { @@ -301,7 +294,7 @@ impl PersonOpt { OutputMode::Text => println!("{}", e), }, Ok(None) => println!("No matching entries"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &aopt.copt.output_mode), } } PersonOpt::Delete(aopt) => { @@ -326,6 +319,8 @@ impl PersonOpt { modmessage.result = format!("Error -> {:?}", e); modmessage.status = MessageStatus::Failure; eprintln!("{}", modmessage); + + // handle_client_error(e, &aopt.copt.output_mode), } Ok(result) => { debug!("{:?}", result); @@ -349,9 +344,7 @@ impl PersonOpt { acopt.aopts.account_id.as_str(), ) } - Err(err) => { - error!("Error -> {:?}", err); - } + Err(e) => handle_client_error(e, &acopt.copt.output_mode), } } PersonOpt::Validity { commands } => match commands { @@ -367,10 +360,7 @@ impl PersonOpt { .await { Ok(v) => v, - Err(e) => { - error!("Error -> {:?}", e); - return; - } + Err(e) => return handle_client_error(e, &ano.copt.output_mode), }; let vf = match client @@ -381,10 +371,7 @@ impl PersonOpt { .await { Ok(v) => v, - Err(e) => { - error!("Error -> {:?}", e); - return; - } + Err(e) => return handle_client_error(e, &ano.copt.output_mode), }; if let Some(t) = vf { @@ -432,7 +419,7 @@ impl PersonOpt { ) .await { - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &ano.copt.output_mode), _ => println!("Success"), } } else if matches!(ano.datetime.as_str(), "now") { @@ -491,7 +478,7 @@ impl PersonOpt { ) .await { - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &ano.copt.output_mode), _ => println!("Success"), } } diff --git a/tools/cli/src/cli/recycle.rs b/tools/cli/src/cli/recycle.rs index 109285b05..6553e3c1b 100644 --- a/tools/cli/src/cli/recycle.rs +++ b/tools/cli/src/cli/recycle.rs @@ -1,5 +1,5 @@ use crate::common::OpType; -use crate::RecycleOpt; +use crate::{handle_client_error, RecycleOpt}; impl RecycleOpt { pub fn debug(&self) -> bool { @@ -16,9 +16,7 @@ impl RecycleOpt { let client = copt.to_client(OpType::Read).await; match client.recycle_bin_list().await { Ok(r) => r.iter().for_each(|e| println!("{}", e)), - Err(e) => { - error!("Error -> {:?}", e); - } + Err(e) => handle_client_error(e, &copt.output_mode), } } RecycleOpt::Get(nopt) => { @@ -26,15 +24,13 @@ impl RecycleOpt { match client.recycle_bin_get(nopt.name.as_str()).await { Ok(Some(e)) => println!("{}", e), Ok(None) => println!("No matching entries"), - Err(e) => { - error!("Error -> {:?}", e); - } + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } RecycleOpt::Revive(nopt) => { let client = nopt.copt.to_client(OpType::Write).await; if let Err(e) = client.recycle_bin_revive(nopt.name.as_str()).await { - error!("Error -> {:?}", e); + handle_client_error(e, &nopt.copt.output_mode) } } } diff --git a/tools/cli/src/cli/serviceaccount.rs b/tools/cli/src/cli/serviceaccount.rs index 7150e1384..b810115cd 100644 --- a/tools/cli/src/cli/serviceaccount.rs +++ b/tools/cli/src/cli/serviceaccount.rs @@ -3,8 +3,8 @@ use kanidm_proto::messages::{AccountChangeMessage, ConsoleOutputMode, MessageSta use time::OffsetDateTime; use crate::{ - AccountSsh, AccountUserAuthToken, AccountValidity, OutputMode, ServiceAccountApiToken, - ServiceAccountCredential, ServiceAccountOpt, ServiceAccountPosix, + handle_client_error, AccountSsh, AccountUserAuthToken, AccountValidity, OutputMode, + ServiceAccountApiToken, ServiceAccountCredential, ServiceAccountOpt, ServiceAccountPosix, }; use time::format_description::well_known::Rfc3339; @@ -191,9 +191,7 @@ impl ServiceAccountOpt { .await { Ok(token) => println!("{}", token), - Err(e) => { - error!("Error -> {:?}", e); - } + Err(e) => handle_client_error(e, &aopt.copt.output_mode), } } ServiceAccountPosix::Set(aopt) => { @@ -206,7 +204,7 @@ impl ServiceAccountOpt { ) .await { - error!("Error -> {:?}", e); + handle_client_error(e, &aopt.copt.output_mode) } } }, // end ServiceAccountOpt::Posix @@ -259,9 +257,7 @@ impl ServiceAccountOpt { .await { Ok(pkeys) => pkeys.iter().for_each(|pkey| println!("{}", pkey)), - Err(e) => { - error!("Error -> {:?}", e); - } + Err(e) => handle_client_error(e, &aopt.copt.output_mode), } } AccountSsh::Add(aopt) => { @@ -274,7 +270,7 @@ impl ServiceAccountOpt { ) .await { - error!("Error -> {:?}", e); + handle_client_error(e, &aopt.copt.output_mode) } } AccountSsh::Delete(aopt) => { @@ -286,7 +282,7 @@ impl ServiceAccountOpt { ) .await { - error!("Error -> {:?}", e); + handle_client_error(e, &aopt.copt.output_mode) } } }, // end ServiceAccountOpt::Ssh @@ -294,7 +290,7 @@ impl ServiceAccountOpt { let client = copt.to_client(OpType::Read).await; match client.idm_service_account_list().await { Ok(r) => r.iter().for_each(|ent| println!("{}", ent)), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } ServiceAccountOpt::Update(aopt) => { @@ -309,7 +305,7 @@ impl ServiceAccountOpt { .await { Ok(()) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &aopt.copt.output_mode), } } ServiceAccountOpt::Get(aopt) => { @@ -320,7 +316,7 @@ impl ServiceAccountOpt { { Ok(Some(e)) => println!("{}", e), Ok(None) => println!("No matching entries"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &aopt.copt.output_mode), } } ServiceAccountOpt::Delete(aopt) => { @@ -361,7 +357,7 @@ impl ServiceAccountOpt { ) .await { - error!("Error -> {:?}", e) + handle_client_error(e, &acopt.copt.output_mode) } } ServiceAccountOpt::Validity { commands } => match commands { @@ -459,7 +455,7 @@ impl ServiceAccountOpt { ) .await { - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &ano.copt.output_mode), _ => println!("Success"), } } @@ -475,7 +471,7 @@ impl ServiceAccountOpt { ) .await { - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &ano.copt.output_mode), _ => println!("Success"), } } else { @@ -493,7 +489,7 @@ impl ServiceAccountOpt { ) .await { - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &ano.copt.output_mode), _ => println!("Success"), } } @@ -506,7 +502,7 @@ impl ServiceAccountOpt { .await { Ok(()) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &aopt.copt.output_mode), } } } diff --git a/tools/cli/src/cli/session_expiry.rs b/tools/cli/src/cli/session_expiry.rs index f68c360c6..2693f981a 100644 --- a/tools/cli/src/cli/session_expiry.rs +++ b/tools/cli/src/cli/session_expiry.rs @@ -1,6 +1,6 @@ use crate::common::OpType; -use crate::{AuthSessionExpiryOpt, PrivilegedSessionExpiryOpt}; +use crate::{handle_client_error, AuthSessionExpiryOpt, PrivilegedSessionExpiryOpt}; impl AuthSessionExpiryOpt { pub fn debug(&self) -> bool { @@ -20,7 +20,7 @@ impl AuthSessionExpiryOpt { "The current system auth session expiry time is: {exp_time} seconds." ); } - Err(e) => eprintln!("{:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } AuthSessionExpiryOpt::Set { copt, expiry } => { @@ -30,7 +30,7 @@ impl AuthSessionExpiryOpt { println!("The system auth session expiry has been successfully updated.") } - Err(e) => eprintln!("{:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } } @@ -55,7 +55,7 @@ impl PrivilegedSessionExpiryOpt { "The current system auth privilege expiry time is: {exp_time} seconds." ); } - Err(e) => eprintln!("{:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } PrivilegedSessionExpiryOpt::Set { copt, expiry } => { @@ -65,7 +65,7 @@ impl PrivilegedSessionExpiryOpt { println!("The system auth privilege expiry has been successfully updated.") } - Err(e) => eprintln!("{:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } } diff --git a/tools/cli/src/cli/synch.rs b/tools/cli/src/cli/synch.rs index 89535e393..733b00b2f 100644 --- a/tools/cli/src/cli/synch.rs +++ b/tools/cli/src/cli/synch.rs @@ -1,5 +1,5 @@ use crate::common::OpType; -use crate::SynchOpt; +use crate::{handle_client_error, SynchOpt}; use dialoguer::Confirm; impl SynchOpt { @@ -24,7 +24,8 @@ impl SynchOpt { let client = copt.to_client(OpType::Read).await; match client.idm_sync_account_list().await { Ok(r) => r.iter().for_each(|ent| println!("{}", ent)), - Err(e) => error!("Error -> {:?}", e), + + Err(e) => handle_client_error(e, &copt.output_mode), } } SynchOpt::Get(nopt) => { @@ -32,7 +33,7 @@ impl SynchOpt { match client.idm_sync_account_get(nopt.name.as_str()).await { Ok(Some(e)) => println!("{}", e), Ok(None) => println!("No matching entries"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &nopt.copt.output_mode), } } SynchOpt::SetCredentialPortal { @@ -46,7 +47,7 @@ impl SynchOpt { .await { Ok(()) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } SynchOpt::Create { @@ -60,7 +61,7 @@ impl SynchOpt { .await { Ok(()) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } SynchOpt::GenerateToken { @@ -74,14 +75,14 @@ impl SynchOpt { .await { Ok(token) => println!("token: {}", token), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } SynchOpt::DestroyToken { account_id, copt } => { let client = copt.to_client(OpType::Write).await; match client.idm_sync_account_destroy_token(account_id).await { Ok(()) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } SynchOpt::SetYieldAttributes { @@ -95,14 +96,14 @@ impl SynchOpt { .await { Ok(()) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } SynchOpt::ForceRefresh { account_id, copt } => { let client = copt.to_client(OpType::Write).await; match client.idm_sync_account_force_refresh(account_id).await { Ok(()) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } SynchOpt::Finalise { account_id, copt } => { @@ -119,7 +120,7 @@ impl SynchOpt { let client = copt.to_client(OpType::Write).await; match client.idm_sync_account_finalise(account_id).await { Ok(()) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } SynchOpt::Terminate { account_id, copt } => { @@ -136,7 +137,7 @@ impl SynchOpt { let client = copt.to_client(OpType::Write).await; match client.idm_sync_account_terminate(account_id).await { Ok(()) => println!("Success"), - Err(e) => error!("Error -> {:?}", e), + Err(e) => handle_client_error(e, &copt.output_mode), } } } diff --git a/tools/cli/src/ssh_authorizedkeys.rs b/tools/cli/src/ssh_authorizedkeys.rs index 29b209d87..028696db1 100644 --- a/tools/cli/src/ssh_authorizedkeys.rs +++ b/tools/cli/src/ssh_authorizedkeys.rs @@ -89,6 +89,8 @@ async fn main() { .await { Ok(pkeys) => pkeys.iter().for_each(|pkey| println!("{}", pkey)), - Err(e) => error!("Failed to retrieve pubkeys - {:?}", e), + Err(e) => { + error!("Failed to retrieve pubkeys - {:?}", e); + } } }