ezidam: setup: redirect to /setup if setup is not complete, create first user, redirect to / if setup is complete

This commit is contained in:
Philippe Loctaux 2023-03-05 23:36:33 +01:00
parent c95800330a
commit 2425a4cb50
4 changed files with 105 additions and 35 deletions

View file

@ -1,6 +1,7 @@
use rocket::{Build, Rocket}; use rocket::{Build, Rocket};
pub mod root; pub mod root;
pub mod setup;
pub(self) mod prelude { pub(self) mod prelude {
pub use crate::database::Database; pub use crate::database::Database;
@ -22,6 +23,9 @@ pub(self) mod prelude {
} }
pub fn routes(rocket_builder: Rocket<Build>) -> Rocket<Build> { pub fn routes(rocket_builder: Rocket<Build>) -> Rocket<Build> {
rocket_builder
// Root // Root
rocket_builder.mount("/", root::routes()) .mount("/", root::routes())
// Setup
.mount("/setup", setup::routes())
} }

View file

@ -1,9 +1,9 @@
use super::prelude::*; use super::prelude::*;
use rocket::{get, routes}; use rocket::get;
use settings::Settings; use settings::Settings;
pub fn routes() -> Vec<rocket::Route> { pub fn routes() -> Vec<Route> {
routes![logo, setup, homepage] routes![logo, homepage, redirect_to_setup]
} }
#[get("/logo")] #[get("/logo")]
@ -39,11 +39,6 @@ mod test {
} }
} }
#[get("/setup")]
async fn setup() -> Page {
Page::Setup()
}
pub mod content { pub mod content {
use rocket::serde::Serialize; use rocket::serde::Serialize;
@ -54,7 +49,12 @@ pub mod content {
} }
} }
#[get("/homepage")] #[get("/")]
async fn redirect_to_setup(_setup: NeedSetup) -> Redirect {
Redirect::to(uri!("/setup"))
}
#[get("/", rank = 2)]
async fn homepage() -> Page { async fn homepage() -> Page {
Page::Homepage(content::Homepage { Page::Homepage(content::Homepage {
abc: "string".to_string(), abc: "string".to_string(),

View file

@ -0,0 +1,61 @@
use super::prelude::*;
use rocket::{get, post};
use settings::Settings;
use users::User;
pub fn routes() -> Vec<Route> {
routes![setup_completed, setup, create_first_account]
}
#[get("/")]
async fn setup_completed(_setup: CompletedSetup) -> Redirect {
Redirect::to(uri!(super::root::homepage))
}
#[get("/", rank = 2)]
async fn setup() -> Page {
Page::Setup
}
#[derive(Debug, FromForm)]
pub struct CreateFirstAccount<'r> {
pub username: &'r str,
pub password: &'r str,
}
#[post("/", data = "<form>")]
async fn create_first_account(
form: Form<CreateFirstAccount<'_>>,
_setup: NeedSetup,
mut db: Connection<Database>,
) -> Result<Redirect> {
let form = form.into_inner();
// Generate UserID
let user_id = task::spawn_blocking(UserID::default).await?;
// Hash password
let password = form.password.to_string();
let password = task::spawn_blocking(move || Password::new(&password)).await??;
let mut transaction = db.begin().await?;
// Insert in database
User::insert(
&mut transaction,
&user_id,
true,
form.username,
Some(&password),
)
.await?;
// Store UserID in settings
Settings::set_first_admin(&mut transaction, &user_id).await?;
transaction.commit().await?;
// TODO: login with openid/oauth
Ok(Redirect::to(uri!("/")))
}

View file

@ -6,8 +6,11 @@
<div class="page page-center"> <div class="page page-center">
<div class="container container-tight py-4"> <div class="container container-tight py-4">
<div class="text-center mb-4"> <div class="text-center mb-4">
<a href="/" class="navbar-brand navbar-brand-autodark"><img src="http://localhost:8000/logo" height="96" alt=""></a> <a href="/" class="navbar-brand navbar-brand-autodark">
<img src="http://localhost:8000/logo" height="96" alt="">
</a>
</div> </div>
<form action="/setup" method="post">
<div class="card card-md"> <div class="card card-md">
<div class="card-body text-center py-4 p-sm-5"> <div class="card-body text-center py-4 p-sm-5">
<h1 class="">Welcome to Ezidam!</h1> <h1 class="">Welcome to Ezidam!</h1>
@ -16,13 +19,13 @@
<div class="hr-text hr-text-center hr-text-spaceless">first admin account</div> <div class="hr-text hr-text-center hr-text-spaceless">first admin account</div>
<div class="card-body"> <div class="card-body">
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Username</label> <label class="form-label required" for="username">Username</label>
<input type="text" class="form-control"> <input name="username" id="username" type="text" class="form-control" required>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Password</label> <label class="form-label required" for="password">Password</label>
<div class="input-group input-group-flat"> <div class="input-group input-group-flat">
<input type="password" class="form-control" autocomplete="off"> <input name="password" id="password" type="password" class="form-control" autocomplete="off" required>
</div> </div>
</div> </div>
</div> </div>
@ -30,12 +33,14 @@
<div class="row align-items-center mt-3"> <div class="row align-items-center mt-3">
<div class="col"> <div class="col">
<div class="btn-list justify-content-end"> <div class="btn-list justify-content-end">
<a href="#" class="btn btn-primary"> <button type="submit" class="btn btn-primary">Create account</button>
Continue <!-- <a href="#" class="btn btn-primary">-->
</a> <!-- Create account-->
<!-- </a>-->
</div> </div>
</div> </div>
</div> </div>
</form>
</div> </div>
</div> </div>
<!-- Libs JS --> <!-- Libs JS -->