Fixed redirect on success, removed DbUser struct.

This commit is contained in:
Joe Ardent 2023-05-22 15:08:14 -07:00
parent b7eb56e0e7
commit 06d7b4a514
2 changed files with 22 additions and 43 deletions

View file

@ -4,7 +4,7 @@ use axum::{routing::get, Router};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
use witch_watch::{
db,
users::{get_create_user, get_signup_success, post_create_user},
users::{get_create_user, handle_signup_success, post_create_user},
};
#[tokio::main]
@ -23,8 +23,8 @@ async fn main() {
let app = Router::new()
.route("/signup", get(get_create_user).post(post_create_user))
.route(
"/signup_success",
get(get_signup_success).post(get_signup_success),
"/signup_success/:id",
get(handle_signup_success).post(handle_signup_success),
)
.with_state(pool);

View file

@ -1,4 +1,4 @@
use std::{array, fmt::Display, ops::Deref};
use std::fmt::Display;
use argon2::{
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
@ -6,7 +6,7 @@ use argon2::{
};
use askama::Template;
use axum::{
extract::{Form, State},
extract::{Form, Path, State},
http::StatusCode,
response::{IntoResponse, Response},
};
@ -21,8 +21,6 @@ const CREATE_QUERY: &str =
const ID_QUERY: &str = "select * from witches where id = $1";
const WITCH_SUCCESS_HEADER: &str = "X-Witch-Success";
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct User {
id: Uuid,
@ -45,16 +43,6 @@ impl Display for User {
}
}
#[derive(Debug, Default, Clone, sqlx::Encode)]
pub(crate) struct DbUser {
id: Uuid,
username: String,
displayname: Option<String>,
email: Option<String>,
last_seen: Option<i64>,
pwhash: String,
}
#[derive(Debug, Clone, Template)]
#[template(path = "signup_success.html")]
pub struct CreateUserSuccess(User);
@ -80,18 +68,6 @@ impl sqlx::FromRow<'_, SqliteRow> for User {
}
}
impl From<DbUser> for User {
fn from(dbu: DbUser) -> Self {
User {
id: dbu.id,
username: dbu.username,
displayname: dbu.displayname,
email: dbu.email,
last_seen: dbu.last_seen,
}
}
}
/// Get Handler: displays the form to create a user
pub async fn get_create_user() -> CreateUser {
CreateUser::default()
@ -117,6 +93,12 @@ pub async fn post_create_user(
return Err(CreateUserErrorKind::BadUsername.into());
}
if let Some(ref dn) = displayname {
if dn.len() > 50 {
return Err(CreateUserErrorKind::BadDisplayname.into());
}
}
if password != verify {
return Err(CreateUserErrorKind::PasswordMismatch.into());
}
@ -149,31 +131,28 @@ pub async fn post_create_user(
let user = create_user(username, displayname, email, password, &pool).await?;
tracing::debug!("created {user:?}");
let mut resp = axum::response::Redirect::temporary("/signup_success").into_response();
resp.headers_mut().append(
WITCH_SUCCESS_HEADER,
user.id.simple().to_string().parse().unwrap(),
);
let id = user.id.simple().to_string();
let location = format!("/signup_success/{id}");
let resp = axum::response::Redirect::temporary(&location).into_response();
Ok(resp)
}
/// Get handler for successful signup; only meaningful
pub async fn get_signup_success(
headers: axum::http::HeaderMap,
/// Get handler for successful signup
pub async fn handle_signup_success(
Path(id): Path<String>,
State(pool): State<SqlitePool>,
) -> Response {
let user = if let Some(id) = headers.get(WITCH_SUCCESS_HEADER) {
let id = id.to_str().unwrap();
let id = Uuid::try_parse(id).unwrap_or_default();
let id_bytes = id.as_bytes();
let user: User = {
let id = id;
let id = Uuid::try_parse(&id).unwrap_or_default();
let id_bytes = id.to_bytes_le();
sqlx::query_as(ID_QUERY)
.bind(id_bytes.as_slice())
.fetch_one(&pool)
.await
.unwrap_or_default()
} else {
User::default()
};
let mut resp = CreateUserSuccess(user.clone()).into_response();