From 04e4bc1f552317500f902c33ddce50be178e00a7 Mon Sep 17 00:00:00 2001 From: Matthew Gordon Date: Mon, 4 Mar 2024 10:59:43 -0400 Subject: [PATCH] Create new user sign-up page --- src/app/mod.rs | 63 +++++++++++++++++++++++++++++++++++++-- src/authentication/mod.rs | 1 + templates/new-user.html | 7 +++++ templates/sign-up.html | 25 ++++++++++++++++ 4 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 templates/new-user.html create mode 100644 templates/sign-up.html diff --git a/src/app/mod.rs b/src/app/mod.rs index bd3d9c0..01c45bb 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1,7 +1,20 @@ use { - crate::db::Database, + crate::{ + authentication::{authenticate_user_with_password, create_jwt_for_user, Password}, + db::Database, + error::Error, + }, askama::Template, - axum::{routing::get, Router}, + axum::{ + extract::State, + routing::{get, post}, + Form, Router, + }, + axum_extra::extract::{ + cookie::{Cookie, SameSite}, + CookieJar, + }, + serde::Deserialize, }; pub mod admin; @@ -14,6 +27,8 @@ pub struct AppState { pub fn routes() -> Router> { Router::new() .route("/", get(root)) + .route("/sign_up", get(sign_up)) + .route("/create_new_user", post(create_new_user)) .nest("/admin", admin::routes()) } @@ -21,6 +36,50 @@ pub fn routes() -> Router> { #[template(path = "index.html")] struct IndexTemplate {} +#[tracing::instrument] async fn root() -> IndexTemplate { IndexTemplate {} } + +#[derive(Template)] +#[template(path = "sign-up.html")] +struct SignUpTemplate {} + +#[tracing::instrument] +async fn sign_up() -> SignUpTemplate { + SignUpTemplate {} +} + +#[derive(Template)] +#[template(path = "new-user.html")] +struct NewUserTemplate {} + +#[derive(Deserialize, Debug)] +struct CreateNewUserParameters { + real_name: String, + email: String, + password: String, +} + +#[tracing::instrument] +async fn create_new_user( + cookie_jar: CookieJar, + State(AppState:: { db, .. }): State>, + Form(params): Form, +) -> Result<(CookieJar, NewUserTemplate), Error> { + let user = db + .create_user( + ¶ms.real_name, + ¶ms.email, + &Password::new(¶ms.password)?.into(), + ) + .await?; + let user = authenticate_user_with_password(&db, user, ¶ms.password) + .await? + .ok_or_else(|| Error::new_unexpected("Could not authenticate newly-created user."))?; + Ok(( + cookie_jar + .add(Cookie::build(("jwt", create_jwt_for_user(&user)?)).same_site(SameSite::Strict)), + NewUserTemplate {}, + )) +} diff --git a/src/authentication/mod.rs b/src/authentication/mod.rs index b806161..a078640 100644 --- a/src/authentication/mod.rs +++ b/src/authentication/mod.rs @@ -81,6 +81,7 @@ pub struct Password { } impl Password { + #[tracing::instrument] pub fn new(password: &str) -> Result { let salt = SaltString::generate(&mut OsRng); let argon2 = Argon2::default(); diff --git a/templates/new-user.html b/templates/new-user.html new file mode 100644 index 0000000..bdb47fc --- /dev/null +++ b/templates/new-user.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} + +{% block title %}New User Welcome - Locality{% endblock %} + +{% block content %} +TBD +{% endblock %} diff --git a/templates/sign-up.html b/templates/sign-up.html new file mode 100644 index 0000000..9581029 --- /dev/null +++ b/templates/sign-up.html @@ -0,0 +1,25 @@ +{% extends "base.html" %} + +{% block title %}New User Sign-Up - Locality{% endblock %} + +{% block content %} +
> +
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + +
  • +
+
+{% endblock %}