brass/web/src/utils/manage_commands.rs

118 lines
3.1 KiB
Rust

use std::{
error::Error,
io::{stdin, stdout, Write},
process::exit,
};
use sqlx::{Pool, Postgres};
use crate::{
mail::Mailer,
models::{Function, Role, User},
utils::auth::generate_salt_and_hash_plain_password,
};
pub enum Command {
Migrate,
CreateAdmin,
TestMail(String),
}
pub struct Args {
pub command: Option<Command>,
}
pub fn parse_args() -> Result<Args, pico_args::Error> {
let mut pargs = pico_args::Arguments::from_env();
let command = pargs.free_from_str::<String>();
let argument = pargs.opt_free_from_str::<String>()?;
let mut args = Args { command: None };
if let Ok(parsed) = command {
match parsed.trim() {
"migrate" => args.command = Some(Command::Migrate),
"createadmin" => args.command = Some(Command::CreateAdmin),
"testmail" => {
if let Some(to) = argument {
args.command = Some(Command::TestMail(to))
} else {
eprintln!("Testmail command requires an email. Use it like this 'brass testmail abc@example.com'");
exit(1)
}
}
_ => (),
}
}
Ok(args)
}
fn prompt(prompt: &str) -> anyhow::Result<String> {
print!("{}: ", prompt);
stdout().flush()?;
let mut input = String::new();
stdin().read_line(&mut input)?;
Ok(input.trim().to_string())
}
pub async fn handle_command(
command: Option<Command>,
pool: &Pool<Postgres>,
mailer: &Mailer,
) -> anyhow::Result<()> {
match command {
Some(Command::Migrate) => {
sqlx::migrate!("../migrations").run(pool).await?;
exit(0);
}
Some(Command::CreateAdmin) => {
let name = prompt("Full name of Admin")?;
let email = prompt("E-Mail of Admin (for login)")?;
let password = prompt("Password of Admin")?;
let retyped_password = prompt("Retype Passsword of Admin")?;
if password != retyped_password {
eprintln!("Given passwords don't match!");
exit(1)
}
let (hash, salt) = generate_salt_and_hash_plain_password(&password)?;
User::create_with_password(
pool,
&name,
&email,
&hash,
&salt,
Role::Admin,
&[Function::Posten, Function::Wachhabender, Function::Fuehrungsassistent],
1,
)
.await?;
exit(0);
}
Some(Command::TestMail(to)) => {
match mailer.send_test_mail(&to).await {
Ok(_) => println!("Successfully sent mail to {to}."),
Err(e) => {
if let Some(source) = e.source() {
eprintln!("Error sending mail with error source: {source}");
} else {
eprintln!("Error sending mail with unkown error source.");
}
}
}
exit(0);
}
None => (),
};
Ok(())
}