2020-09-18 05:19:57 +02:00
|
|
|
use crate::login::read_tokens;
|
2020-03-24 23:21:49 +01:00
|
|
|
use kanidm_client::{KanidmClient, KanidmClientBuilder};
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use structopt::StructOpt;
|
|
|
|
|
|
|
|
#[derive(Debug, StructOpt)]
|
|
|
|
pub struct Named {
|
|
|
|
#[structopt()]
|
|
|
|
pub name: String,
|
|
|
|
#[structopt(flatten)]
|
|
|
|
pub copt: CommonOpt,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, StructOpt)]
|
|
|
|
pub struct CommonOpt {
|
|
|
|
#[structopt(short = "d", long = "debug")]
|
|
|
|
pub debug: bool,
|
|
|
|
#[structopt(short = "H", long = "url")]
|
|
|
|
pub addr: Option<String>,
|
|
|
|
#[structopt(short = "D", long = "name")]
|
2020-09-18 05:19:57 +02:00
|
|
|
pub username: Option<String>,
|
2020-03-24 23:21:49 +01:00
|
|
|
#[structopt(parse(from_os_str), short = "C", long = "ca")]
|
|
|
|
pub ca_path: Option<PathBuf>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CommonOpt {
|
2020-09-18 05:19:57 +02:00
|
|
|
pub fn to_unauth_client(&self) -> KanidmClient {
|
2020-03-24 23:21:49 +01:00
|
|
|
let config_path: String = shellexpand::tilde("~/.config/kanidm").into_owned();
|
|
|
|
|
|
|
|
debug!("Attempting to use config {}", "/etc/kanidm/config");
|
2020-08-01 12:31:05 +02:00
|
|
|
let client_builder = match KanidmClientBuilder::new()
|
2020-03-24 23:21:49 +01:00
|
|
|
.read_options_from_optional_config("/etc/kanidm/config")
|
|
|
|
.and_then(|cb| {
|
|
|
|
debug!("Attempting to use config {}", config_path);
|
|
|
|
cb.read_options_from_optional_config(config_path)
|
2020-08-01 12:31:05 +02:00
|
|
|
}) {
|
|
|
|
Ok(c) => c,
|
|
|
|
Err(e) => {
|
|
|
|
error!("Failed to parse config (if present) -- {:?}", e);
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
};
|
2020-03-24 23:21:49 +01:00
|
|
|
|
|
|
|
let client_builder = match &self.addr {
|
|
|
|
Some(a) => client_builder.address(a.to_string()),
|
|
|
|
None => client_builder,
|
|
|
|
};
|
|
|
|
|
2020-08-01 12:31:05 +02:00
|
|
|
let ca_path: Option<&str> = self.ca_path.as_ref().map(|p| p.to_str()).flatten();
|
2020-03-24 23:21:49 +01:00
|
|
|
let client_builder = match ca_path {
|
2020-08-01 12:31:05 +02:00
|
|
|
Some(p) => match client_builder.add_root_certificate_filepath(p) {
|
|
|
|
Ok(cb) => cb,
|
|
|
|
Err(e) => {
|
|
|
|
error!("Failed to add ca certificate -- {:?}", e);
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
},
|
2020-03-24 23:21:49 +01:00
|
|
|
None => client_builder,
|
|
|
|
};
|
|
|
|
|
2020-08-01 12:31:05 +02:00
|
|
|
let client = match client_builder.build() {
|
|
|
|
Ok(c) => c,
|
|
|
|
Err(e) => {
|
|
|
|
error!("Failed to build client instance -- {:?}", e);
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
};
|
2020-09-18 05:19:57 +02:00
|
|
|
client
|
|
|
|
}
|
2020-03-24 23:21:49 +01:00
|
|
|
|
2020-09-18 05:19:57 +02:00
|
|
|
pub fn to_client(&self) -> KanidmClient {
|
|
|
|
let mut client = self.to_unauth_client();
|
|
|
|
// Read the token file.
|
|
|
|
let tokens = match read_tokens() {
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(_e) => {
|
|
|
|
error!("Error retrieving authentication token store");
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
2020-03-24 23:21:49 +01:00
|
|
|
};
|
|
|
|
|
2020-09-18 05:19:57 +02:00
|
|
|
if tokens.len() == 0 {
|
|
|
|
error!(
|
|
|
|
"No valid authentication tokens found. Please login with the 'login' subcommand."
|
|
|
|
);
|
2020-03-24 23:21:49 +01:00
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
|
2020-09-18 05:19:57 +02:00
|
|
|
// If we have a username, use that to select tokens
|
|
|
|
let token = match &self.username {
|
|
|
|
Some(username) => {
|
|
|
|
// Is it in the store?
|
|
|
|
match tokens.get(username) {
|
|
|
|
Some(t) => t.clone(),
|
|
|
|
None => {
|
|
|
|
error!("No valid authentication tokens found for {}.", username);
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
if tokens.len() == 1 {
|
|
|
|
let (f_uname, f_token) = tokens.iter().next().expect("Memory Corruption");
|
|
|
|
// else pick the first token
|
|
|
|
info!("Authenticated as {}", f_uname);
|
|
|
|
f_token.clone()
|
|
|
|
} else {
|
|
|
|
// Unable to select
|
|
|
|
error!("Multiple authentication tokens exist. Please select one with --name.");
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Set it into the client
|
|
|
|
client.set_token(token);
|
|
|
|
|
2020-03-24 23:21:49 +01:00
|
|
|
client
|
|
|
|
}
|
|
|
|
}
|