use anyhow::{anyhow, bail};
use clap::Parser;
use dialtone_common::ap::pun::is_valid_pun;
use dialtone_common::rest::users::web_user::UserStatus;
use dialtone_common::utils::make_acct::make_acct;
use dialtone_sqlx::db::user_principal::change_status::change_user_status;
use validator::Validate;
use dialtone_common::utils::version::DT_VERSION;
use dialtone_sqlx::constants::HOST_NAME_RE;
use dialtone_sqlx::constants::USER_NAME_RE;
use dialtone_sqlx::control::user::check_name_availability::check_user_name_availability;
use dialtone_sqlx::control::user::create_with_actor::create_user_with_default_actor;
use dialtone_sqlx::db::get_pooled_connection;
use dialtone_sqlx::db::site_info::fetch_site;
#[derive(Parser, Debug, Validate)]
#[clap(name = "create_user", 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(length(min = 1))]
password: String,
#[clap(value_parser, short, long)]
no_active: bool,
}
#[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?;
fetch_site(&pg_pool, &opts.host_name)
.await?
.ok_or(anyhow!(format!(
"Unable to create users for sites {}. Does it exist?",
opts.host_name
)))?;
let valid_name = is_valid_pun(&opts.user_name, false);
if !valid_name {
println!("{} contains characters that are not allowed actors names. A default actors is created when creating a users.", &opts.user_name);
return Ok(());
}
let available =
check_user_name_availability(&pg_pool, &opts.user_name, &opts.host_name).await?;
if !available {
println!("{} at {} is already used", &opts.user_name, &opts.host_name);
} else {
println!("Creating users {} at {}", &opts.user_name, &opts.host_name);
create_user_with_default_actor(
&pg_pool,
&opts.user_name,
&opts.host_name,
&opts.password,
)
.await?;
}
if !opts.no_active {
let acct = make_acct(&opts.user_name, &opts.host_name);
println!("Changing {} to Active", acct);
change_user_status(&pg_pool, &acct, &UserStatus::Active).await?;
}
Ok(())
}
}
}