use clap::{Arg, Command};
use color_eyre::Result;
use std::path::Path;
use crate::userdb::user_exists;
use crate::userdb;
#[derive(Debug, Clone, Default)]
pub struct UserDelOptions {
pub force: bool,
pub remove_home: bool,
pub root: Option<String>,
pub prefix: Option<String>,
pub selinux_user: bool,
pub username: String,
}
pub fn parse_options(matches: &clap::ArgMatches) -> Result<UserDelOptions> {
let force = matches.get_flag("force");
let remove_home = matches.get_flag("remove_home");
let root = matches.get_one::<String>("root").cloned();
let prefix = matches.get_one::<String>("prefix").cloned();
let selinux_user = matches.get_flag("selinux_user");
let username = matches
.get_one::<String>("username")
.expect("username is required")
.clone();
Ok(UserDelOptions {
force,
remove_home,
root,
prefix,
selinux_user,
username,
})
}
pub fn command() -> Command {
Command::new("userdel")
.about("Delete a user account and related files")
.arg(
Arg::new("force")
.short('f')
.long("force")
.help("force some actions that would fail otherwise\ne.g. removal of user still logged in\nor files, even if not owned by the user")
.action(clap::ArgAction::SetTrue),
)
.arg(
Arg::new("remove_home")
.short('r')
.long("remove")
.help("remove home directory and mail spool")
.action(clap::ArgAction::SetTrue),
)
.arg(
Arg::new("root")
.short('R')
.long("root")
.value_name("CHROOT_DIR")
.help("directory to chroot into"),
)
.arg(
Arg::new("prefix")
.short('P')
.long("prefix")
.value_name("PREFIX_DIR")
.help("prefix directory where are located the /etc/* files"),
)
.arg(
Arg::new("selinux_user")
.short('Z')
.long("selinux-user")
.help("Remove any SELinux user mapping for the user's login")
.action(clap::ArgAction::SetTrue),
)
.arg(
Arg::new("username")
.required(true)
.value_name("LOGIN")
.help("User name"),
)
}
pub fn run(options: UserDelOptions) -> Result<()> {
let root_path = if let Some(ref root) = options.root {
Some(Path::new(root))
} else if let Some(ref prefix) = options.prefix {
Some(Path::new(prefix))
} else {
Some(Path::new("/"))
};
if !user_exists(&options.username, root_path)? {
eprintln!("userdel: user '{}' does not exist", options.username);
std::process::exit(6);
}
if !options.force {
}
if options.selinux_user {
}
userdb::delete_user(&options.username, options.remove_home, root_path)
.map_err(|e| {
eprintln!("userdel: {}", e);
std::process::exit(1);
})
}