dialtone_ctrl 0.1.0

Dialtone Back-End Control Programs
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 {
    /// Users names (i.e. the local part of users@thefoo.example)
    #[clap(value_parser, short, long)]
    #[validate(regex = "USER_NAME_RE")]
    user_name: String,

    /// DNS host names of the sites (e.g. thefoo.example)
    #[clap(value_parser, short, long)]
    #[validate(regex = "HOST_NAME_RE")]
    host_name: String,

    /// System role from which to remove the users.
    #[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(())
        }
    }
}