Create new user sign-up page
This commit is contained in:
parent
fd770124ae
commit
04e4bc1f55
|
|
@ -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(
|
||||||
|
¶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 {},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}New User Welcome - Locality{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
TBD
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -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 %}
|
||||||
Loading…
Reference in New Issue