use std::path::PathBuf;
use clap::Parser;
use ironoxide::{
IronOxideErr,
group::GroupAccessEditResult,
prelude::{BlockingIronOxide, GroupId, GroupName, UserId},
};
use itertools::Either;
use crate::{
group_maps::{self, convert_group_names_to_ids},
util,
};
const EXAMPLE: &str = "EXAMPLE
$ ironhide group remove-member -u test@example.com,test2@example.com myGroup
";
#[derive(Parser)]
#[clap(after_help = EXAMPLE)]
pub struct RemoveMember {
#[clap(value_parser = util::group_identifier_from_string)]
group: Either<GroupName, GroupId>,
#[clap(value_parser = clap::value_parser!(PathBuf), short, long)]
keyfile: Option<PathBuf>,
#[clap(value_parser = util::try_from_email, short, long, use_value_delimiter = true, value_delimiter = ',', required = true)]
users: Vec<UserId>,
}
impl util::GetKeyfile for RemoveMember {
fn get_keyfile(&self) -> Option<&PathBuf> {
self.keyfile.as_ref()
}
}
pub fn group_remove_members(
sdk: &BlockingIronOxide,
RemoveMember { group, users, .. }: RemoveMember,
) -> Result<(), String> {
let (groups_by_name, _) = group_maps::get_group_maps(sdk);
let group_id = convert_group_names_to_ids(&[group], &groups_by_name)
.first()
.cloned()
.expect("Group doesn't have an ID.");
let removed_members = sdk.group_remove_members(&group_id, &users);
let table = build_result_table(removed_members);
table.printstd();
Ok(())
}
fn build_result_table(
remove_member_results: Result<GroupAccessEditResult, IronOxideErr>,
) -> prettytable::Table {
let mut table = table!([Fbb->"User", Fbb->"Result"]);
match remove_member_results {
Ok(results) => {
for succeeded_id in results.succeeded() {
table.add_row(row![
Fw -> succeeded_id.id(),
Fg -> format!("{}", "✔ Removed as member"),
]);
}
for failure in results.failed() {
table.add_row(row![
Fw -> failure.user().id(),
Fr -> failure.error(),
]);
}
}
Err(e) => {
table.add_row(
row![Fw -> "ALL", Fr -> format!("Removing members failed catastrophically: {}", e)],
);
}
}
table
}