use anyhow::{bail, Context};
use clap::Parser;
use dialtone_common::utils::make_acct::make_acct;
use std::str::FromStr;
use validator::{Validate, ValidationError};
use dialtone_common::utils::version::DT_VERSION;
use dialtone_sqlx::constants::HOST_NAME_RE;
use dialtone_sqlx::constants::USER_NAME_RE;
use dialtone_sqlx::db::get_pooled_connection;
use dialtone_sqlx::db::system_role::remove::remove_system_role;
use dialtone_sqlx::db::system_role::SystemRoleType;
#[derive(Parser, Debug, Validate)]
#[clap(name = "remove_from_role", version = DT_VERSION)]
struct Opts {
#[clap(value_parser, short, long)]
#[validate(regex = "USER_NAME_RE")]
user_name: String,
#[clap(value_parser, short, long)]
#[validate(regex = "HOST_NAME_RE")]
host_name: String,
#[clap(value_parser, short, long)]
#[validate(custom(function = "validate_role_name"))]
role_name: String,
}
fn validate_role_name(value: &str) -> Result<(), ValidationError> {
let system_role = SystemRoleType::from_str(value);
match system_role {
Ok(_) => Ok(()),
Err(_) => Err(ValidationError::new("Unknown system role.")),
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dotenv::dotenv().ok();
let opts: Opts = Opts::parse();
let v = opts.validate();
match v {
Err(errors) => bail!(errors),
_ => {
let pg_pool = get_pooled_connection().await?;
let acct = make_acct(&opts.user_name, &opts.host_name);
let system_role = SystemRoleType::from_str(&opts.role_name).unwrap();
println!("Removing {} from '{}' role", acct, system_role.to_string());
remove_system_role(&pg_pool, &system_role, &acct, &opts.host_name).await
.with_context(||
format!("Unable to remove {} from '{}' role. Does the users exist? Was the users already removed from the role?",
acct,
system_role.to_string()))?;
Ok(())
}
}
}