feat: add basic commands for setting up

This commit is contained in:
Max Hohlfeld 2024-03-10 23:28:41 +01:00
parent 3d3e92cf38
commit 0172e9bdad
3 changed files with 99 additions and 0 deletions

7
Cargo.lock generated
View File

@ -649,6 +649,7 @@ dependencies = [
"chrono",
"dotenv",
"futures-util",
"pico-args",
"serde",
"serde_json",
"sqlx",
@ -1617,6 +1618,12 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]]
name = "pico-args"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]]
name = "pin-project-lite"
version = "0.2.9"

View File

@ -20,3 +20,4 @@ actix-files = "0.6.5"
askama_actix = "0.14.0"
futures-util = "0.3.30"
serde_json = "1.0.114"
pico-args = "0.5.0"

View File

@ -1,4 +1,6 @@
use std::env;
use std::io::{stdin, stdout, Write};
use std::process::exit;
use actix_identity::IdentityMiddleware;
use actix_session::{storage::CookieSessionStore, SessionMiddleware};
@ -8,17 +10,106 @@ use dotenv::dotenv;
use sqlx::postgres::PgPool;
use crate::auth::redirect;
use crate::auth::utils::generate_salt_and_hash_plain_password;
use crate::models::User;
mod auth;
mod calendar;
mod models;
mod endpoints;
pub enum Command {
Migrate,
CreateAdmin
}
pub struct Args {
command: Option<Command>
}
fn parse_args() -> Result<Args, pico_args::Error> {
let mut pargs = pico_args::Arguments::from_env();
let command = pargs.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),
_ => ()
}
}
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())
}
#[actix_web::main]
async fn main() -> anyhow::Result<()> {
dotenv()?;
let args = match parse_args() {
Ok(v) => v,
Err(err) => {
eprintln!("Error: {err}");
std::process::exit(1);
}
};
let pool = PgPool::connect(&env::var("DATABASE_URL")?).await?;
let secret_key = Key::generate();
match args.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("admin")?;
User::create(
&pool,
&name,
&email,
&hash,
&salt,
models::Role::Admin,
models::Function::Wachhabender,
1,
)
.await?;
exit(0);
},
None => ()
};
println!("Starting server on http://localhost:8080.");
HttpServer::new(move || {