mirror of
https://github.com/kanidm/kanidm.git
synced 2025-05-28 11:53:55 +02:00
306 command complete (#354)
Fixes #306 adding command line autocompletion. These are generated to: CARGO_TARGET_DIR/item-hash/out/. These will need to be packaged for distros later, it's unclear how we could use cargo install with these as cargo doesn't support arbitrary artefacts like this (yet?).
This commit is contained in:
parent
c416bc19df
commit
6c79914395
|
@ -45,3 +45,6 @@ zxcvbn = "2.0"
|
|||
|
||||
webauthn-authenticator-rs = "^0.3.0-alpha.6"
|
||||
# webauthn-authenticator-rs = { path = "../../webauthn-authenticator-rs" }
|
||||
|
||||
[build-dependencies]
|
||||
structopt = { version = "0.3", default-features = false }
|
||||
|
|
37
kanidm_tools/build.rs
Normal file
37
kanidm_tools/build.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use structopt::clap::Shell;
|
||||
use structopt::StructOpt;
|
||||
|
||||
include!("src/opt/ssh_authorizedkeys.rs");
|
||||
include!("src/opt/badlist_preprocess.rs");
|
||||
include!("src/opt/kanidm.rs");
|
||||
|
||||
fn main() {
|
||||
let outdir = match env::var_os("OUT_DIR") {
|
||||
None => return,
|
||||
Some(outdir) => outdir,
|
||||
};
|
||||
|
||||
SshAuthorizedOpt::clap().gen_completions(
|
||||
"kanidm_ssh_authorizedkeys_direct",
|
||||
Shell::Bash,
|
||||
outdir.clone(),
|
||||
);
|
||||
SshAuthorizedOpt::clap().gen_completions(
|
||||
"kanidm_ssh_authorizedkeys_direct",
|
||||
Shell::Zsh,
|
||||
outdir.clone(),
|
||||
);
|
||||
|
||||
BadlistProcOpt::clap().gen_completions(
|
||||
"kanidm_badlist_preprocess",
|
||||
Shell::Bash,
|
||||
outdir.clone(),
|
||||
);
|
||||
BadlistProcOpt::clap().gen_completions("kanidm_badlist_preprocess", Shell::Zsh, outdir.clone());
|
||||
|
||||
KanidmClientOpt::clap().gen_completions("kanidm", Shell::Bash, outdir.clone());
|
||||
KanidmClientOpt::clap().gen_completions("kanidm", Shell::Zsh, outdir);
|
||||
}
|
|
@ -20,20 +20,10 @@ use log::{debug, error, info};
|
|||
use rayon::prelude::*;
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct ClientOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
#[structopt(short = "m", long = "modlist")]
|
||||
modlist: bool,
|
||||
#[structopt(short = "o", long = "output")]
|
||||
outfile: PathBuf,
|
||||
#[structopt(parse(from_os_str))]
|
||||
password_list: Vec<PathBuf>,
|
||||
}
|
||||
include!("opt/badlist_preprocess.rs");
|
||||
|
||||
fn main() {
|
||||
let opt = ClientOpt::from_args();
|
||||
let opt = BadlistProcOpt::from_args();
|
||||
if opt.debug {
|
||||
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
|
||||
} else {
|
||||
|
|
|
@ -1,182 +1,14 @@
|
|||
use crate::common::CommonOpt;
|
||||
use crate::password_prompt;
|
||||
use crate::{
|
||||
AccountCredential, AccountOpt, AccountPosix, AccountRadius, AccountSsh, AccountValidity,
|
||||
};
|
||||
use qrcode::render::unicode;
|
||||
use qrcode::QrCode;
|
||||
use std::io;
|
||||
use structopt::StructOpt;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use webauthn_authenticator_rs::{u2fhid::U2FHid, WebauthnAuthenticator};
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountCommonOpt {
|
||||
#[structopt()]
|
||||
account_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountCredentialSet {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountNamedOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountNamedExpireDateTimeOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
#[structopt(name = "datetime")]
|
||||
/// An rfc3339 time of the format "YYYY-MM-DDTHH:MM:SS+TZ", "2020-09-25T11:22:02+10:00"
|
||||
/// or the word "never", "clear" to remove account expiry.
|
||||
datetime: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountNamedValidDateTimeOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
#[structopt(name = "datetime")]
|
||||
/// An rfc3339 time of the format "YYYY-MM-DDTHH:MM:SS+TZ", "2020-09-25T11:22:02+10:00"
|
||||
/// or the word "any", "clear" to remove valid from enforcement.
|
||||
datetime: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountNamedTagOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
#[structopt(name = "tag")]
|
||||
tag: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountNamedTagPKOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
#[structopt(name = "tag")]
|
||||
tag: String,
|
||||
#[structopt(name = "pubkey")]
|
||||
pubkey: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountCreateOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(name = "display_name")]
|
||||
display_name: String,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountCredential {
|
||||
#[structopt(name = "set_password")]
|
||||
SetPassword(AccountCredentialSet),
|
||||
#[structopt(name = "generate_password")]
|
||||
GeneratePassword(AccountCredentialSet),
|
||||
#[structopt(name = "register_webauthn")]
|
||||
RegisterWebauthn(AccountNamedTagOpt),
|
||||
/// Set the TOTP credential of the account. If a TOTP already exists, on a successful
|
||||
/// registration, this will replace it.
|
||||
#[structopt(name = "set_totp")]
|
||||
RegisterTOTP(AccountNamedTagOpt),
|
||||
/// Remove TOTP from the account. If no TOTP exists, no action is taken.
|
||||
#[structopt(name = "remove_totp")]
|
||||
RemoveTOTP(AccountNamedOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountRadius {
|
||||
#[structopt(name = "show_secret")]
|
||||
Show(AccountNamedOpt),
|
||||
#[structopt(name = "generate_secret")]
|
||||
Generate(AccountNamedOpt),
|
||||
#[structopt(name = "delete_secret")]
|
||||
Delete(AccountNamedOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountPosixOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(long = "gidnumber")]
|
||||
gidnumber: Option<u32>,
|
||||
#[structopt(long = "shell")]
|
||||
shell: Option<String>,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountPosix {
|
||||
#[structopt(name = "show")]
|
||||
Show(AccountNamedOpt),
|
||||
#[structopt(name = "set")]
|
||||
Set(AccountPosixOpt),
|
||||
#[structopt(name = "set_password")]
|
||||
SetPassword(AccountNamedOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountSsh {
|
||||
#[structopt(name = "list_publickeys")]
|
||||
List(AccountNamedOpt),
|
||||
#[structopt(name = "add_publickey")]
|
||||
Add(AccountNamedTagPKOpt),
|
||||
#[structopt(name = "delete_publickey")]
|
||||
Delete(AccountNamedTagOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountValidity {
|
||||
#[structopt(name = "show")]
|
||||
Show(AccountNamedOpt),
|
||||
#[structopt(name = "expire_at")]
|
||||
ExpireAt(AccountNamedExpireDateTimeOpt),
|
||||
#[structopt(name = "begin_from")]
|
||||
BeginFrom(AccountNamedValidDateTimeOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountOpt {
|
||||
#[structopt(name = "credential")]
|
||||
Credential(AccountCredential),
|
||||
#[structopt(name = "radius")]
|
||||
Radius(AccountRadius),
|
||||
#[structopt(name = "posix")]
|
||||
Posix(AccountPosix),
|
||||
#[structopt(name = "ssh")]
|
||||
Ssh(AccountSsh),
|
||||
#[structopt(name = "list")]
|
||||
List(CommonOpt),
|
||||
#[structopt(name = "get")]
|
||||
Get(AccountNamedOpt),
|
||||
#[structopt(name = "create")]
|
||||
Create(AccountCreateOpt),
|
||||
#[structopt(name = "delete")]
|
||||
Delete(AccountNamedOpt),
|
||||
#[structopt(name = "validity")]
|
||||
Validity(AccountValidity),
|
||||
}
|
||||
|
||||
impl AccountOpt {
|
||||
pub fn debug(&self) -> bool {
|
||||
match self {
|
||||
|
|
|
@ -1,27 +1,6 @@
|
|||
use crate::login::read_tokens;
|
||||
use crate::CommonOpt;
|
||||
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")]
|
||||
pub username: Option<String>,
|
||||
#[structopt(parse(from_os_str), short = "C", long = "ca")]
|
||||
pub ca_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl CommonOpt {
|
||||
pub fn to_unauth_client(&self) -> KanidmClient {
|
||||
|
|
|
@ -1,55 +1,4 @@
|
|||
use crate::common::{CommonOpt, Named};
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct GroupNamedMembers {
|
||||
#[structopt()]
|
||||
name: String,
|
||||
#[structopt()]
|
||||
members: Vec<String>,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct GroupPosixOpt {
|
||||
#[structopt()]
|
||||
name: String,
|
||||
#[structopt(long = "gidnumber")]
|
||||
gidnumber: Option<u32>,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum GroupPosix {
|
||||
#[structopt(name = "show")]
|
||||
Show(Named),
|
||||
#[structopt(name = "set")]
|
||||
Set(GroupPosixOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum GroupOpt {
|
||||
#[structopt(name = "list")]
|
||||
List(CommonOpt),
|
||||
#[structopt(name = "get")]
|
||||
Get(Named),
|
||||
#[structopt(name = "create")]
|
||||
Create(Named),
|
||||
#[structopt(name = "delete")]
|
||||
Delete(Named),
|
||||
#[structopt(name = "list_members")]
|
||||
ListMembers(Named),
|
||||
#[structopt(name = "set_members")]
|
||||
SetMembers(GroupNamedMembers),
|
||||
#[structopt(name = "purge_members")]
|
||||
PurgeMembers(Named),
|
||||
#[structopt(name = "add_members")]
|
||||
AddMembers(GroupNamedMembers),
|
||||
#[structopt(name = "posix")]
|
||||
Posix(GroupPosix),
|
||||
}
|
||||
use crate::{GroupOpt, GroupPosix};
|
||||
|
||||
impl GroupOpt {
|
||||
pub fn debug(&self) -> bool {
|
||||
|
|
|
@ -10,8 +10,11 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
use std::path::PathBuf;
|
||||
use structopt::StructOpt;
|
||||
|
||||
include!("../opt/kanidm.rs");
|
||||
|
||||
pub mod account;
|
||||
pub mod common;
|
||||
pub mod group;
|
||||
|
@ -19,23 +22,6 @@ pub mod login;
|
|||
pub mod raw;
|
||||
pub mod recycle;
|
||||
|
||||
use crate::account::AccountOpt;
|
||||
use crate::common::CommonOpt;
|
||||
use crate::group::GroupOpt;
|
||||
use crate::login::LoginOpt;
|
||||
use crate::raw::RawOpt;
|
||||
use crate::recycle::RecycleOpt;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum SelfOpt {
|
||||
#[structopt(name = "whoami")]
|
||||
/// Show the current authenticated user's identity
|
||||
Whoami(CommonOpt),
|
||||
#[structopt(name = "set_password")]
|
||||
/// Set the current user's password
|
||||
SetPassword(CommonOpt),
|
||||
}
|
||||
|
||||
impl SelfOpt {
|
||||
pub fn debug(&self) -> bool {
|
||||
match self {
|
||||
|
@ -80,49 +66,26 @@ impl SelfOpt {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(about = "Kanidm Client Utility")]
|
||||
pub enum ClientOpt {
|
||||
#[structopt(name = "login")]
|
||||
/// Login to an account to use with future cli operations
|
||||
Login(LoginOpt),
|
||||
#[structopt(name = "self")]
|
||||
/// Actions for the current authenticated account
|
||||
CSelf(SelfOpt),
|
||||
#[structopt(name = "account")]
|
||||
/// Account operations
|
||||
Account(AccountOpt),
|
||||
#[structopt(name = "group")]
|
||||
/// Group operations
|
||||
Group(GroupOpt),
|
||||
#[structopt(name = "recycle_bin")]
|
||||
/// Recycle Bin operations
|
||||
Recycle(RecycleOpt),
|
||||
#[structopt(name = "raw")]
|
||||
/// Unsafe - low level, raw database operations.
|
||||
Raw(RawOpt),
|
||||
}
|
||||
|
||||
impl ClientOpt {
|
||||
impl KanidmClientOpt {
|
||||
pub fn debug(&self) -> bool {
|
||||
match self {
|
||||
ClientOpt::Raw(ropt) => ropt.debug(),
|
||||
ClientOpt::Login(lopt) => lopt.debug(),
|
||||
ClientOpt::CSelf(csopt) => csopt.debug(),
|
||||
ClientOpt::Account(aopt) => aopt.debug(),
|
||||
ClientOpt::Group(gopt) => gopt.debug(),
|
||||
ClientOpt::Recycle(ropt) => ropt.debug(),
|
||||
KanidmClientOpt::Raw(ropt) => ropt.debug(),
|
||||
KanidmClientOpt::Login(lopt) => lopt.debug(),
|
||||
KanidmClientOpt::CSelf(csopt) => csopt.debug(),
|
||||
KanidmClientOpt::Account(aopt) => aopt.debug(),
|
||||
KanidmClientOpt::Group(gopt) => gopt.debug(),
|
||||
KanidmClientOpt::Recycle(ropt) => ropt.debug(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exec(&self) {
|
||||
match self {
|
||||
ClientOpt::Raw(ropt) => ropt.exec(),
|
||||
ClientOpt::Login(lopt) => lopt.exec(),
|
||||
ClientOpt::CSelf(csopt) => csopt.exec(),
|
||||
ClientOpt::Account(aopt) => aopt.exec(),
|
||||
ClientOpt::Group(gopt) => gopt.exec(),
|
||||
ClientOpt::Recycle(ropt) => ropt.exec(),
|
||||
KanidmClientOpt::Raw(ropt) => ropt.exec(),
|
||||
KanidmClientOpt::Login(lopt) => lopt.exec(),
|
||||
KanidmClientOpt::CSelf(csopt) => csopt.exec(),
|
||||
KanidmClientOpt::Account(aopt) => aopt.exec(),
|
||||
KanidmClientOpt::Group(gopt) => gopt.exec(),
|
||||
KanidmClientOpt::Recycle(ropt) => ropt.exec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::common::CommonOpt;
|
||||
use crate::LoginOpt;
|
||||
use kanidm_client::{ClientError, KanidmClient};
|
||||
use kanidm_proto::v1::{AuthAllowed, AuthResponse, AuthState};
|
||||
use libc::umask;
|
||||
|
@ -6,7 +6,6 @@ use std::collections::BTreeMap;
|
|||
use std::fs::{create_dir, File};
|
||||
use std::io::{self, BufReader, BufWriter};
|
||||
use std::path::PathBuf;
|
||||
use structopt::StructOpt;
|
||||
use webauthn_authenticator_rs::{u2fhid::U2FHid, RequestChallengeResponse, WebauthnAuthenticator};
|
||||
|
||||
static TOKEN_DIR: &str = "~/.cache";
|
||||
|
@ -102,14 +101,6 @@ fn get_index_choice(len: usize) -> Result<u8, ClientError> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct LoginOpt {
|
||||
#[structopt(flatten)]
|
||||
pub copt: CommonOpt,
|
||||
#[structopt(short = "w", long = "webauthn")]
|
||||
pub webauthn: bool,
|
||||
}
|
||||
|
||||
impl LoginOpt {
|
||||
pub fn debug(&self) -> bool {
|
||||
self.copt.debug
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
#![deny(clippy::needless_pass_by_value)]
|
||||
#![deny(clippy::trivially_copy_pass_by_ref)]
|
||||
|
||||
use kanidm_cli::ClientOpt;
|
||||
use kanidm_cli::KanidmClientOpt;
|
||||
use structopt::StructOpt;
|
||||
|
||||
fn main() {
|
||||
let opt = ClientOpt::from_args();
|
||||
let opt = KanidmClientOpt::from_args();
|
||||
|
||||
if opt.debug() {
|
||||
::std::env::set_var(
|
||||
|
|
|
@ -1,54 +1,14 @@
|
|||
use crate::common::CommonOpt;
|
||||
use crate::RawOpt;
|
||||
use kanidm_proto::v1::{Entry, Filter, Modify, ModifyList};
|
||||
use std::collections::BTreeMap;
|
||||
use structopt::StructOpt;
|
||||
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct FilterOpt {
|
||||
#[structopt()]
|
||||
filter: String,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct CreateOpt {
|
||||
#[structopt(parse(from_os_str))]
|
||||
file: PathBuf,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct ModifyOpt {
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
#[structopt()]
|
||||
filter: String,
|
||||
#[structopt(parse(from_os_str))]
|
||||
file: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum RawOpt {
|
||||
#[structopt(name = "search")]
|
||||
Search(FilterOpt),
|
||||
#[structopt(name = "create")]
|
||||
Create(CreateOpt),
|
||||
#[structopt(name = "modify")]
|
||||
Modify(ModifyOpt),
|
||||
#[structopt(name = "delete")]
|
||||
Delete(FilterOpt),
|
||||
}
|
||||
|
||||
fn read_file<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> Result<T, Box<dyn Error>> {
|
||||
let f = File::open(path)?;
|
||||
let r = BufReader::new(f);
|
||||
|
|
|
@ -1,18 +1,4 @@
|
|||
use crate::common::{CommonOpt, Named};
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum RecycleOpt {
|
||||
#[structopt(name = "list")]
|
||||
/// List objects that are in the recycle bin
|
||||
List(CommonOpt),
|
||||
#[structopt(name = "get")]
|
||||
/// Display an object from the recycle bin
|
||||
Get(Named),
|
||||
#[structopt(name = "revive")]
|
||||
/// Revive a recycled object into a live (accessible) state - this is the opposite of "delete"
|
||||
Revive(Named),
|
||||
}
|
||||
use crate::RecycleOpt;
|
||||
|
||||
impl RecycleOpt {
|
||||
pub fn debug(&self) -> bool {
|
||||
|
|
12
kanidm_tools/src/opt/badlist_preprocess.rs
Normal file
12
kanidm_tools/src/opt/badlist_preprocess.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct BadlistProcOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
#[structopt(short = "m", long = "modlist")]
|
||||
modlist: bool,
|
||||
#[structopt(short = "o", long = "output")]
|
||||
outfile: PathBuf,
|
||||
#[structopt(parse(from_os_str))]
|
||||
password_list: Vec<PathBuf>,
|
||||
}
|
333
kanidm_tools/src/opt/kanidm.rs
Normal file
333
kanidm_tools/src/opt/kanidm.rs
Normal file
|
@ -0,0 +1,333 @@
|
|||
#[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")]
|
||||
pub username: Option<String>,
|
||||
#[structopt(parse(from_os_str), short = "C", long = "ca")]
|
||||
pub ca_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct GroupNamedMembers {
|
||||
#[structopt()]
|
||||
name: String,
|
||||
#[structopt()]
|
||||
members: Vec<String>,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct GroupPosixOpt {
|
||||
#[structopt()]
|
||||
name: String,
|
||||
#[structopt(long = "gidnumber")]
|
||||
gidnumber: Option<u32>,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum GroupPosix {
|
||||
#[structopt(name = "show")]
|
||||
Show(Named),
|
||||
#[structopt(name = "set")]
|
||||
Set(GroupPosixOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum GroupOpt {
|
||||
#[structopt(name = "list")]
|
||||
List(CommonOpt),
|
||||
#[structopt(name = "get")]
|
||||
Get(Named),
|
||||
#[structopt(name = "create")]
|
||||
Create(Named),
|
||||
#[structopt(name = "delete")]
|
||||
Delete(Named),
|
||||
#[structopt(name = "list_members")]
|
||||
ListMembers(Named),
|
||||
#[structopt(name = "set_members")]
|
||||
SetMembers(GroupNamedMembers),
|
||||
#[structopt(name = "purge_members")]
|
||||
PurgeMembers(Named),
|
||||
#[structopt(name = "add_members")]
|
||||
AddMembers(GroupNamedMembers),
|
||||
#[structopt(name = "posix")]
|
||||
Posix(GroupPosix),
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountCommonOpt {
|
||||
#[structopt()]
|
||||
account_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountCredentialSet {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountNamedOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountNamedExpireDateTimeOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
#[structopt(name = "datetime")]
|
||||
/// An rfc3339 time of the format "YYYY-MM-DDTHH:MM:SS+TZ", "2020-09-25T11:22:02+10:00"
|
||||
/// or the word "never", "clear" to remove account expiry.
|
||||
datetime: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountNamedValidDateTimeOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
#[structopt(name = "datetime")]
|
||||
/// An rfc3339 time of the format "YYYY-MM-DDTHH:MM:SS+TZ", "2020-09-25T11:22:02+10:00"
|
||||
/// or the word "any", "clear" to remove valid from enforcement.
|
||||
datetime: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountNamedTagOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
#[structopt(name = "tag")]
|
||||
tag: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountNamedTagPKOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
#[structopt(name = "tag")]
|
||||
tag: String,
|
||||
#[structopt(name = "pubkey")]
|
||||
pubkey: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountCreateOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(name = "display_name")]
|
||||
display_name: String,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountCredential {
|
||||
#[structopt(name = "set_password")]
|
||||
SetPassword(AccountCredentialSet),
|
||||
#[structopt(name = "generate_password")]
|
||||
GeneratePassword(AccountCredentialSet),
|
||||
#[structopt(name = "register_webauthn")]
|
||||
RegisterWebauthn(AccountNamedTagOpt),
|
||||
/// Set the TOTP credential of the account. If a TOTP already exists, on a successful
|
||||
/// registration, this will replace it.
|
||||
#[structopt(name = "set_totp")]
|
||||
RegisterTOTP(AccountNamedTagOpt),
|
||||
/// Remove TOTP from the account. If no TOTP exists, no action is taken.
|
||||
#[structopt(name = "remove_totp")]
|
||||
RemoveTOTP(AccountNamedOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountRadius {
|
||||
#[structopt(name = "show_secret")]
|
||||
Show(AccountNamedOpt),
|
||||
#[structopt(name = "generate_secret")]
|
||||
Generate(AccountNamedOpt),
|
||||
#[structopt(name = "delete_secret")]
|
||||
Delete(AccountNamedOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct AccountPosixOpt {
|
||||
#[structopt(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[structopt(long = "gidnumber")]
|
||||
gidnumber: Option<u32>,
|
||||
#[structopt(long = "shell")]
|
||||
shell: Option<String>,
|
||||
#[structopt(flatten)]
|
||||
copt: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountPosix {
|
||||
#[structopt(name = "show")]
|
||||
Show(AccountNamedOpt),
|
||||
#[structopt(name = "set")]
|
||||
Set(AccountPosixOpt),
|
||||
#[structopt(name = "set_password")]
|
||||
SetPassword(AccountNamedOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountSsh {
|
||||
#[structopt(name = "list_publickeys")]
|
||||
List(AccountNamedOpt),
|
||||
#[structopt(name = "add_publickey")]
|
||||
Add(AccountNamedTagPKOpt),
|
||||
#[structopt(name = "delete_publickey")]
|
||||
Delete(AccountNamedTagOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountValidity {
|
||||
#[structopt(name = "show")]
|
||||
Show(AccountNamedOpt),
|
||||
#[structopt(name = "expire_at")]
|
||||
ExpireAt(AccountNamedExpireDateTimeOpt),
|
||||
#[structopt(name = "begin_from")]
|
||||
BeginFrom(AccountNamedValidDateTimeOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum AccountOpt {
|
||||
#[structopt(name = "credential")]
|
||||
Credential(AccountCredential),
|
||||
#[structopt(name = "radius")]
|
||||
Radius(AccountRadius),
|
||||
#[structopt(name = "posix")]
|
||||
Posix(AccountPosix),
|
||||
#[structopt(name = "ssh")]
|
||||
Ssh(AccountSsh),
|
||||
#[structopt(name = "list")]
|
||||
List(CommonOpt),
|
||||
#[structopt(name = "get")]
|
||||
Get(AccountNamedOpt),
|
||||
#[structopt(name = "create")]
|
||||
Create(AccountCreateOpt),
|
||||
#[structopt(name = "delete")]
|
||||
Delete(AccountNamedOpt),
|
||||
#[structopt(name = "validity")]
|
||||
Validity(AccountValidity),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum RecycleOpt {
|
||||
#[structopt(name = "list")]
|
||||
/// List objects that are in the recycle bin
|
||||
List(CommonOpt),
|
||||
#[structopt(name = "get")]
|
||||
/// Display an object from the recycle bin
|
||||
Get(Named),
|
||||
#[structopt(name = "revive")]
|
||||
/// Revive a recycled object into a live (accessible) state - this is the opposite of "delete"
|
||||
Revive(Named),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct LoginOpt {
|
||||
#[structopt(flatten)]
|
||||
pub copt: CommonOpt,
|
||||
#[structopt(short = "w", long = "webauthn")]
|
||||
pub webauthn: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct FilterOpt {
|
||||
#[structopt()]
|
||||
filter: String,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct CreateOpt {
|
||||
#[structopt(parse(from_os_str))]
|
||||
file: PathBuf,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct ModifyOpt {
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
#[structopt()]
|
||||
filter: String,
|
||||
#[structopt(parse(from_os_str))]
|
||||
file: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum RawOpt {
|
||||
#[structopt(name = "search")]
|
||||
Search(FilterOpt),
|
||||
#[structopt(name = "create")]
|
||||
Create(CreateOpt),
|
||||
#[structopt(name = "modify")]
|
||||
Modify(ModifyOpt),
|
||||
#[structopt(name = "delete")]
|
||||
Delete(FilterOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum SelfOpt {
|
||||
#[structopt(name = "whoami")]
|
||||
/// Show the current authenticated user's identity
|
||||
Whoami(CommonOpt),
|
||||
#[structopt(name = "set_password")]
|
||||
/// Set the current user's password
|
||||
SetPassword(CommonOpt),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(about = "Kanidm Client Utility")]
|
||||
pub enum KanidmClientOpt {
|
||||
#[structopt(name = "login")]
|
||||
/// Login to an account to use with future cli operations
|
||||
Login(LoginOpt),
|
||||
#[structopt(name = "self")]
|
||||
/// Actions for the current authenticated account
|
||||
CSelf(SelfOpt),
|
||||
#[structopt(name = "account")]
|
||||
/// Account operations
|
||||
Account(AccountOpt),
|
||||
#[structopt(name = "group")]
|
||||
/// Group operations
|
||||
Group(GroupOpt),
|
||||
#[structopt(name = "recycle_bin")]
|
||||
/// Recycle Bin operations
|
||||
Recycle(RecycleOpt),
|
||||
#[structopt(name = "raw")]
|
||||
/// Unsafe - low level, raw database operations.
|
||||
Raw(RawOpt),
|
||||
}
|
||||
|
14
kanidm_tools/src/opt/ssh_authorizedkeys.rs
Normal file
14
kanidm_tools/src/opt/ssh_authorizedkeys.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct SshAuthorizedOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
#[structopt(short = "H", long = "url")]
|
||||
addr: Option<String>,
|
||||
#[structopt(short = "D", long = "name")]
|
||||
username: String,
|
||||
#[structopt(parse(from_os_str), short = "C", long = "ca")]
|
||||
ca_path: Option<PathBuf>,
|
||||
#[structopt()]
|
||||
account_id: String,
|
||||
}
|
|
@ -8,33 +8,20 @@
|
|||
#![deny(clippy::needless_pass_by_value)]
|
||||
#![deny(clippy::trivially_copy_pass_by_ref)]
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use kanidm_client::KanidmClientBuilder;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use log::{debug, error};
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct ClientOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
#[structopt(short = "H", long = "url")]
|
||||
addr: Option<String>,
|
||||
#[structopt(short = "D", long = "name")]
|
||||
username: String,
|
||||
#[structopt(parse(from_os_str), short = "C", long = "ca")]
|
||||
ca_path: Option<PathBuf>,
|
||||
#[structopt()]
|
||||
account_id: String,
|
||||
}
|
||||
include!("opt/ssh_authorizedkeys.rs");
|
||||
|
||||
// For now we lift a few things from the main.rs to use.
|
||||
//
|
||||
// usage: AuthorizedKeysCommand /usr/sbin/kanidm_ssh_authorizedkeys %u -H URL -D anonymous -C /etc/kanidm/ca.pem
|
||||
//
|
||||
fn main() {
|
||||
let opt = ClientOpt::from_args();
|
||||
let opt = SshAuthorizedOpt::from_args();
|
||||
if opt.debug {
|
||||
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
|
||||
} else {
|
||||
|
|
|
@ -75,3 +75,7 @@ lru = "0.6"
|
|||
|
||||
[dev-dependencies]
|
||||
kanidm = { path = "../kanidmd" }
|
||||
|
||||
[build-dependencies]
|
||||
structopt = { version = "0.3", default-features = false }
|
||||
|
||||
|
|
44
kanidm_unix_int/build.rs
Normal file
44
kanidm_unix_int/build.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
use std::env;
|
||||
|
||||
use structopt::clap::Shell;
|
||||
use structopt::StructOpt;
|
||||
|
||||
include!("src/opt/ssh_authorizedkeys.rs");
|
||||
include!("src/opt/cache_invalidate.rs");
|
||||
include!("src/opt/cache_clear.rs");
|
||||
include!("src/opt/unixd_status.rs");
|
||||
|
||||
fn main() {
|
||||
let outdir = match env::var_os("OUT_DIR") {
|
||||
None => return,
|
||||
Some(outdir) => outdir,
|
||||
};
|
||||
|
||||
SshAuthorizedOpt::clap().gen_completions(
|
||||
"kanidm_ssh_authorizedkeys",
|
||||
Shell::Bash,
|
||||
outdir.clone(),
|
||||
);
|
||||
SshAuthorizedOpt::clap().gen_completions(
|
||||
"kanidm_ssh_authorizedkeys",
|
||||
Shell::Zsh,
|
||||
outdir.clone(),
|
||||
);
|
||||
|
||||
CacheInvalidateOpt::clap().gen_completions(
|
||||
"kanidm_cache_invalidate",
|
||||
Shell::Bash,
|
||||
outdir.clone(),
|
||||
);
|
||||
CacheInvalidateOpt::clap().gen_completions(
|
||||
"kanidm_cache_invalidate",
|
||||
Shell::Zsh,
|
||||
outdir.clone(),
|
||||
);
|
||||
|
||||
CacheClearOpt::clap().gen_completions("kanidm_cache_clear", Shell::Bash, outdir.clone());
|
||||
CacheClearOpt::clap().gen_completions("kanidm_cache_clear", Shell::Zsh, outdir.clone());
|
||||
|
||||
UnixdStatusOpt::clap().gen_completions("kanidm_unixd_status", Shell::Bash, outdir.clone());
|
||||
UnixdStatusOpt::clap().gen_completions("kanidm_unixd_status", Shell::Zsh, outdir);
|
||||
}
|
|
@ -20,17 +20,11 @@ use kanidm_unix_common::client::call_daemon;
|
|||
use kanidm_unix_common::unix_config::KanidmUnixdConfig;
|
||||
use kanidm_unix_common::unix_proto::{ClientRequest, ClientResponse};
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct ClientOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
#[structopt(long = "really")]
|
||||
really: bool,
|
||||
}
|
||||
include!("./opt/cache_clear.rs");
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let opt = ClientOpt::from_args();
|
||||
let opt = CacheClearOpt::from_args();
|
||||
if opt.debug {
|
||||
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
|
||||
} else {
|
||||
|
|
|
@ -20,15 +20,11 @@ use kanidm_unix_common::client::call_daemon;
|
|||
use kanidm_unix_common::unix_config::KanidmUnixdConfig;
|
||||
use kanidm_unix_common::unix_proto::{ClientRequest, ClientResponse};
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct ClientOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
}
|
||||
include!("./opt/cache_invalidate.rs");
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let opt = ClientOpt::from_args();
|
||||
let opt = CacheInvalidateOpt::from_args();
|
||||
if opt.debug {
|
||||
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
|
||||
} else {
|
||||
|
|
|
@ -20,15 +20,11 @@ use kanidm_unix_common::client::call_daemon;
|
|||
use kanidm_unix_common::unix_config::KanidmUnixdConfig;
|
||||
use kanidm_unix_common::unix_proto::{ClientRequest, ClientResponse};
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct ClientOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
}
|
||||
include!("./opt/unixd_status.rs");
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let opt = ClientOpt::from_args();
|
||||
let opt = UnixdStatusOpt::from_args();
|
||||
if opt.debug {
|
||||
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
|
||||
} else {
|
||||
|
|
9
kanidm_unix_int/src/opt/cache_clear.rs
Normal file
9
kanidm_unix_int/src/opt/cache_clear.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
#[derive(Debug, StructOpt)]
|
||||
struct CacheClearOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
#[structopt(long = "really")]
|
||||
really: bool,
|
||||
}
|
||||
|
||||
|
7
kanidm_unix_int/src/opt/cache_invalidate.rs
Normal file
7
kanidm_unix_int/src/opt/cache_invalidate.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct CacheInvalidateOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
}
|
||||
|
8
kanidm_unix_int/src/opt/ssh_authorizedkeys.rs
Normal file
8
kanidm_unix_int/src/opt/ssh_authorizedkeys.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct SshAuthorizedOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
#[structopt()]
|
||||
account_id: String,
|
||||
}
|
6
kanidm_unix_int/src/opt/unixd_status.rs
Normal file
6
kanidm_unix_int/src/opt/unixd_status.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
#[derive(Debug, StructOpt)]
|
||||
struct UnixdStatusOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
}
|
||||
|
|
@ -20,17 +20,11 @@ use kanidm_unix_common::client::call_daemon;
|
|||
use kanidm_unix_common::unix_config::KanidmUnixdConfig;
|
||||
use kanidm_unix_common::unix_proto::{ClientRequest, ClientResponse};
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct ClientOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
debug: bool,
|
||||
#[structopt()]
|
||||
account_id: String,
|
||||
}
|
||||
include!("./opt/ssh_authorizedkeys.rs");
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let opt = ClientOpt::from_args();
|
||||
let opt = SshAuthorizedOpt::from_args();
|
||||
if opt.debug {
|
||||
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
|
||||
} else {
|
||||
|
|
|
@ -111,3 +111,9 @@ webauthn-authenticator-rs = "0.3.0-alpha.5"
|
|||
version = "1"
|
||||
default-features = false # Disable features which are enabled by default
|
||||
features = ["precommit-hook", "run-cargo-fmt"]
|
||||
|
||||
[build-dependencies]
|
||||
structopt = { version = "0.3", default-features = false }
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
|
||||
|
|
21
kanidmd/build.rs
Normal file
21
kanidmd/build.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
use std::env;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use structopt::clap::Shell;
|
||||
use structopt::StructOpt;
|
||||
|
||||
include!("src/lib/audit_loglevel.rs");
|
||||
include!("src/server/opt.rs");
|
||||
|
||||
fn main() {
|
||||
let outdir = match env::var_os("OUT_DIR") {
|
||||
None => return,
|
||||
Some(outdir) => outdir,
|
||||
};
|
||||
|
||||
KanidmdOpt::clap().gen_completions("kanidmd", Shell::Bash, outdir.clone());
|
||||
KanidmdOpt::clap().gen_completions("kanidmd", Shell::Zsh, outdir);
|
||||
}
|
|
@ -8,7 +8,7 @@ use chrono::offset::Utc;
|
|||
use chrono::DateTime;
|
||||
use uuid::Uuid;
|
||||
|
||||
use std::str::FromStr;
|
||||
include!("./audit_loglevel.rs");
|
||||
|
||||
pub const AUDIT_LINE_SIZE: usize = 512;
|
||||
|
||||
|
@ -38,41 +38,6 @@ pub enum LogTag {
|
|||
Trace = 0x8000_0000,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum LogLevel {
|
||||
// Errors only
|
||||
Quiet = 0x0000_1111,
|
||||
// All Error, All Security, Request and Admin Warning,
|
||||
Default = 0x0000_1111 | 0x0000_0f00 | 0x0000_0022 | 0x1000_0000,
|
||||
// Default + Filter Plans
|
||||
Filter = 0x0000_1111 | 0x0000_0f00 | 0x0000_0022 | 0x0000_4000 | 0x1000_0000,
|
||||
// All Error, All Warning, All Info, Filter and Request Tracing
|
||||
Verbose = 0x0000_ffff | 0x1000_0000,
|
||||
// Default + PerfCoarse
|
||||
PerfBasic = 0x0000_1111 | 0x0000_0f00 | 0x0000_0022 | 0x3000_0000,
|
||||
// Default + PerfCoarse ? PerfTrace
|
||||
PerfFull = 0x0000_1111 | 0x0000_0f00 | 0x0000_0022 | 0x7000_0000,
|
||||
// Yolo
|
||||
FullTrace = 0xffff_ffff,
|
||||
}
|
||||
|
||||
impl FromStr for LogLevel {
|
||||
type Err = &'static str;
|
||||
fn from_str(l: &str) -> Result<Self, Self::Err> {
|
||||
match l.to_lowercase().as_str() {
|
||||
"quiet" => Ok(LogLevel::Quiet),
|
||||
"default" => Ok(LogLevel::Default),
|
||||
"filter" => Ok(LogLevel::Filter),
|
||||
"verbose" => Ok(LogLevel::Verbose),
|
||||
"perfbasic" => Ok(LogLevel::PerfBasic),
|
||||
"perffull" => Ok(LogLevel::PerfFull),
|
||||
"fulltrace" => Ok(LogLevel::FullTrace),
|
||||
_ => Err("Could not parse loglevel"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for LogTag {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
|
|
35
kanidmd/src/lib/audit_loglevel.rs
Normal file
35
kanidmd/src/lib/audit_loglevel.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use std::str::FromStr;
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum LogLevel {
|
||||
// Errors only
|
||||
Quiet = 0x0000_1111,
|
||||
// All Error, All Security, Request and Admin Warning,
|
||||
Default = 0x0000_1111 | 0x0000_0f00 | 0x0000_0022 | 0x1000_0000,
|
||||
// Default + Filter Plans
|
||||
Filter = 0x0000_1111 | 0x0000_0f00 | 0x0000_0022 | 0x0000_4000 | 0x1000_0000,
|
||||
// All Error, All Warning, All Info, Filter and Request Tracing
|
||||
Verbose = 0x0000_ffff | 0x1000_0000,
|
||||
// Default + PerfCoarse
|
||||
PerfBasic = 0x0000_1111 | 0x0000_0f00 | 0x0000_0022 | 0x3000_0000,
|
||||
// Default + PerfCoarse ? PerfTrace
|
||||
PerfFull = 0x0000_1111 | 0x0000_0f00 | 0x0000_0022 | 0x7000_0000,
|
||||
// Yolo
|
||||
FullTrace = 0xffff_ffff,
|
||||
}
|
||||
|
||||
impl FromStr for LogLevel {
|
||||
type Err = &'static str;
|
||||
fn from_str(l: &str) -> Result<Self, Self::Err> {
|
||||
match l.to_lowercase().as_str() {
|
||||
"quiet" => Ok(LogLevel::Quiet),
|
||||
"default" => Ok(LogLevel::Default),
|
||||
"filter" => Ok(LogLevel::Filter),
|
||||
"verbose" => Ok(LogLevel::Verbose),
|
||||
"perfbasic" => Ok(LogLevel::PerfBasic),
|
||||
"perffull" => Ok(LogLevel::PerfFull),
|
||||
"fulltrace" => Ok(LogLevel::FullTrace),
|
||||
_ => Err("Could not parse loglevel"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,6 +27,8 @@ use kanidm::core::{
|
|||
|
||||
use structopt::StructOpt;
|
||||
|
||||
include!("./opt.rs");
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ServerConfig {
|
||||
pub bindaddress: Option<String>,
|
||||
|
@ -55,87 +57,16 @@ impl ServerConfig {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct CommonOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
/// Logging level. quiet, default, filter, verbose, perffull
|
||||
debug: Option<LogLevel>,
|
||||
#[structopt(parse(from_os_str), short = "c", long = "config")]
|
||||
/// Path to the server's configuration file. If it does not exist, it will be created.
|
||||
config_path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct BackupOpt {
|
||||
#[structopt(parse(from_os_str))]
|
||||
/// Output path for the backup content.
|
||||
path: PathBuf,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct RestoreOpt {
|
||||
#[structopt(parse(from_os_str))]
|
||||
/// Restore from this path. Should be created with "backupu".
|
||||
path: PathBuf,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct RecoverAccountOpt {
|
||||
#[structopt(short)]
|
||||
/// The account name to recover credentials for.
|
||||
name: String,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct DomainOpt {
|
||||
#[structopt(short)]
|
||||
/// The new domain name.
|
||||
new_domain_name: String,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
enum Opt {
|
||||
#[structopt(name = "server")]
|
||||
/// Start the IDM Server
|
||||
Server(CommonOpt),
|
||||
#[structopt(name = "backup")]
|
||||
/// Backup the database content (offline)
|
||||
Backup(BackupOpt),
|
||||
#[structopt(name = "restore")]
|
||||
/// Restore the database content (offline)
|
||||
Restore(RestoreOpt),
|
||||
#[structopt(name = "verify")]
|
||||
/// Verify database and entity consistency.
|
||||
Verify(CommonOpt),
|
||||
#[structopt(name = "recover_account")]
|
||||
/// Recover an account's password
|
||||
RecoverAccount(RecoverAccountOpt),
|
||||
// #[structopt(name = "reset_server_id")]
|
||||
// ResetServerId(CommonOpt),
|
||||
#[structopt(name = "reindex")]
|
||||
/// Reindex the database (offline)
|
||||
Reindex(CommonOpt),
|
||||
#[structopt(name = "domain_name_change")]
|
||||
/// Change the IDM domain name
|
||||
DomainChange(DomainOpt),
|
||||
}
|
||||
|
||||
impl Opt {
|
||||
impl KanidmdOpt {
|
||||
fn commonopt(&self) -> &CommonOpt {
|
||||
match self {
|
||||
Opt::Server(sopt) | Opt::Verify(sopt) | Opt::Reindex(sopt) => &sopt,
|
||||
Opt::Backup(bopt) => &bopt.commonopts,
|
||||
Opt::Restore(ropt) => &ropt.commonopts,
|
||||
Opt::RecoverAccount(ropt) => &ropt.commonopts,
|
||||
Opt::DomainChange(dopt) => &dopt.commonopts,
|
||||
KanidmdOpt::Server(sopt) | KanidmdOpt::Verify(sopt) | KanidmdOpt::Reindex(sopt) => {
|
||||
&sopt
|
||||
}
|
||||
KanidmdOpt::Backup(bopt) => &bopt.commonopts,
|
||||
KanidmdOpt::Restore(ropt) => &ropt.commonopts,
|
||||
KanidmdOpt::RecoverAccount(ropt) => &ropt.commonopts,
|
||||
KanidmdOpt::DomainChange(dopt) => &dopt.commonopts,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +106,7 @@ async fn main() {
|
|||
}
|
||||
|
||||
// Read cli args, determine if we should backup/restore
|
||||
let opt = Opt::from_args();
|
||||
let opt = KanidmdOpt::from_args();
|
||||
|
||||
let mut config = Configuration::new();
|
||||
// Check the permissions are sane.
|
||||
|
@ -295,7 +226,7 @@ async fn main() {
|
|||
.init();
|
||||
|
||||
match opt {
|
||||
Opt::Server(_sopt) => {
|
||||
KanidmdOpt::Server(_sopt) => {
|
||||
eprintln!("Running in server mode ...");
|
||||
|
||||
/*
|
||||
|
@ -323,7 +254,7 @@ async fn main() {
|
|||
}
|
||||
}
|
||||
}
|
||||
Opt::Backup(bopt) => {
|
||||
KanidmdOpt::Backup(bopt) => {
|
||||
eprintln!("Running in backup mode ...");
|
||||
|
||||
// config.update_db_path(&bopt.commonopts.db_path);
|
||||
|
@ -337,7 +268,7 @@ async fn main() {
|
|||
};
|
||||
backup_server_core(&config, p);
|
||||
}
|
||||
Opt::Restore(ropt) => {
|
||||
KanidmdOpt::Restore(ropt) => {
|
||||
eprintln!("Running in restore mode ...");
|
||||
|
||||
// config.update_db_path(&ropt.commonopts.db_path);
|
||||
|
@ -351,13 +282,13 @@ async fn main() {
|
|||
};
|
||||
restore_server_core(&config, p);
|
||||
}
|
||||
Opt::Verify(_vopt) => {
|
||||
KanidmdOpt::Verify(_vopt) => {
|
||||
eprintln!("Running in db verification mode ...");
|
||||
|
||||
// config.update_db_path(&vopt.db_path);
|
||||
verify_server_core(&config);
|
||||
}
|
||||
Opt::RecoverAccount(raopt) => {
|
||||
KanidmdOpt::RecoverAccount(raopt) => {
|
||||
eprintln!("Running account recovery ...");
|
||||
|
||||
let password = match rpassword::prompt_password_stderr("new password: ") {
|
||||
|
@ -372,20 +303,20 @@ async fn main() {
|
|||
recover_account_core(&config, &raopt.name, &password);
|
||||
}
|
||||
/*
|
||||
Opt::ResetServerId(vopt) => {
|
||||
KanidmdOpt::ResetServerId(vopt) => {
|
||||
eprintln!("Resetting server id. THIS WILL BREAK REPLICATION");
|
||||
|
||||
config.update_db_path(&vopt.db_path);
|
||||
reset_sid_core(config);
|
||||
}
|
||||
*/
|
||||
Opt::Reindex(_copt) => {
|
||||
KanidmdOpt::Reindex(_copt) => {
|
||||
eprintln!("Running in reindex mode ...");
|
||||
|
||||
// config.update_db_path(&copt.db_path);
|
||||
reindex_server_core(&config);
|
||||
}
|
||||
Opt::DomainChange(dopt) => {
|
||||
KanidmdOpt::DomainChange(dopt) => {
|
||||
eprintln!("Running in domain name change mode ... this may take a long time ...");
|
||||
|
||||
// config.update_db_path(&dopt.commonopts.db_path);
|
||||
|
|
73
kanidmd/src/server/opt.rs
Normal file
73
kanidmd/src/server/opt.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
#[derive(Debug, StructOpt)]
|
||||
struct CommonOpt {
|
||||
#[structopt(short = "d", long = "debug")]
|
||||
/// Logging level. quiet, default, filter, verbose, perffull
|
||||
debug: Option<LogLevel>,
|
||||
#[structopt(parse(from_os_str), short = "c", long = "config")]
|
||||
/// Path to the server's configuration file. If it does not exist, it will be created.
|
||||
config_path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct BackupOpt {
|
||||
#[structopt(parse(from_os_str))]
|
||||
/// Output path for the backup content.
|
||||
path: PathBuf,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct RestoreOpt {
|
||||
#[structopt(parse(from_os_str))]
|
||||
/// Restore from this path. Should be created with "backupu".
|
||||
path: PathBuf,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct RecoverAccountOpt {
|
||||
#[structopt(short)]
|
||||
/// The account name to recover credentials for.
|
||||
name: String,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct DomainOpt {
|
||||
#[structopt(short)]
|
||||
/// The new domain name.
|
||||
new_domain_name: String,
|
||||
#[structopt(flatten)]
|
||||
commonopts: CommonOpt,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
enum KanidmdOpt {
|
||||
#[structopt(name = "server")]
|
||||
/// Start the IDM Server
|
||||
Server(CommonOpt),
|
||||
#[structopt(name = "backup")]
|
||||
/// Backup the database content (offline)
|
||||
Backup(BackupOpt),
|
||||
#[structopt(name = "restore")]
|
||||
/// Restore the database content (offline)
|
||||
Restore(RestoreOpt),
|
||||
#[structopt(name = "verify")]
|
||||
/// Verify database and entity consistency.
|
||||
Verify(CommonOpt),
|
||||
#[structopt(name = "recover_account")]
|
||||
/// Recover an account's password
|
||||
RecoverAccount(RecoverAccountOpt),
|
||||
// #[structopt(name = "reset_server_id")]
|
||||
// ResetServerId(CommonOpt),
|
||||
#[structopt(name = "reindex")]
|
||||
/// Reindex the database (offline)
|
||||
Reindex(CommonOpt),
|
||||
#[structopt(name = "domain_name_change")]
|
||||
/// Change the IDM domain name
|
||||
DomainChange(DomainOpt),
|
||||
}
|
||||
|
Loading…
Reference in a new issue