Create new user sign-up page

This commit is contained in:
Matthew Gordon 2024-03-04 10:59:43 -04:00
parent fd770124ae
commit 04e4bc1f55
4 changed files with 94 additions and 2 deletions

View File

@ -1,7 +1,20 @@
use { use {
crate::db::Database, crate::{
authentication::{authenticate_user_with_password, create_jwt_for_user, Password},
db::Database,
error::Error,
},
askama::Template, 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; pub mod admin;
@ -14,6 +27,8 @@ pub struct AppState<D: Database> {
pub fn routes<D: Database>() -> Router<AppState<D>> { pub fn routes<D: Database>() -> Router<AppState<D>> {
Router::new() Router::new()
.route("/", get(root)) .route("/", get(root))
.route("/sign_up", get(sign_up))
.route("/create_new_user", post(create_new_user))
.nest("/admin", admin::routes()) .nest("/admin", admin::routes())
} }
@ -21,6 +36,50 @@ pub fn routes<D: Database>() -> Router<AppState<D>> {
#[template(path = "index.html")] #[template(path = "index.html")]
struct IndexTemplate {} struct IndexTemplate {}
#[tracing::instrument]
async fn root() -> IndexTemplate { async fn root() -> IndexTemplate {
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<D: Database>(
cookie_jar: CookieJar,
State(AppState::<D> { db, .. }): State<AppState<D>>,
Form(params): Form<CreateNewUserParameters>,
) -> Result<(CookieJar, NewUserTemplate), Error> {
let user = db
.create_user(
&params.real_name,
&params.email,
&Password::new(&params.password)?.into(),
)
.await?;
let user = authenticate_user_with_password(&db, user, &params.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 {},
))
}

View File

@ -81,6 +81,7 @@ pub struct Password {
} }
impl Password { impl Password {
#[tracing::instrument]
pub fn new(password: &str) -> Result<Password, AuthenticationError> { pub fn new(password: &str) -> Result<Password, AuthenticationError> {
let salt = SaltString::generate(&mut OsRng); let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default(); let argon2 = Argon2::default();

7
templates/new-user.html Normal file
View File

@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block title %}New User Welcome - Locality{% endblock %}
{% block content %}
TBD
{% endblock %}

25
templates/sign-up.html Normal file
View File

@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block title %}New User Sign-Up - Locality{% endblock %}
{% block content %}
<form action="create_new_user" method="post">>
<ul>
<li>
<label for="real_name">Name:</label>
<input type="text" id="real_name" name="real_name" />
</li>
<li>
<label for="email">Email:</label>
<input type="email" id="email" name="email" />
</li>
<li>
<label for="password">Password:</label>
<input type="password" id="password" name="password" />
</li>
<li>
<button type="submit">Create Account</button>
</li>
</ul>
</form>
{% endblock %}