From 1daec804307b9833b27b1dad9f25d901d6f400c8 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Sun, 25 Feb 2024 18:39:42 -0800 Subject: [PATCH] make valid ranges into constants --- src/handlers.rs | 27 ++++++++++++++++----------- src/main.rs | 6 +++++- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/handlers.rs b/src/handlers.rs index 3f757cd..8f12c87 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -1,4 +1,4 @@ -use std::{error::Error, fmt::Debug, ops::Range}; +use std::{error::Error, fmt::Debug, ops::RangeInclusive}; use axum::{ extract::{Form, Path}, @@ -13,6 +13,11 @@ use crate::{templates::*, User}; const SIGNUP_KEY: &str = "meow"; +const PASSWORD_LEN: RangeInclusive = 4..=100; +const USERNAME_LEN: RangeInclusive = 1..=50; +const DISPLAYNAME_LEN: RangeInclusive = 0..=100; +const EMAIL_LEN: RangeInclusive = 4..=50; + #[Error(desc = "Could not create user.")] #[non_exhaustive] pub struct CreateUserError(#[from] CreateUserErrorKind); @@ -27,10 +32,10 @@ impl IntoResponse for CreateUserError { #[non_exhaustive] pub enum CreateUserErrorKind { AlreadyExists, - #[error(desc = "Usernames must be between 1 and 20 characters long")] + #[error(desc = "Usernames must be between 1 and 50 characters long")] BadUsername, PasswordMismatch, - #[error(desc = "Password must have at least 4 and at most 50 characters")] + #[error(desc = "Password must have at least 4 and at most 100 characters")] BadPassword, #[error(desc = "Display name must be less than 100 characters long")] BadDisplayname, @@ -60,7 +65,7 @@ pub async fn post_signup( session: Session, Form(form): Form, ) -> Result { - let user = verify_user(&form).await?; + let user = validate_signup(&form).await?; session.insert(SIGNUP_KEY, user).await.unwrap(); Ok(Redirect::to( @@ -96,14 +101,14 @@ pub async fn signup_success(session: Session, receipt: Option>) -> //-************************************************************************ // helpers //-************************************************************************ -async fn verify_user(form: &SignupForm) -> Result { +async fn validate_signup(form: &SignupForm) -> Result { let username = form.username.trim(); let password = form.password.trim(); let verify = form.pw_verify.trim(); let name_len = username.graphemes(true).size_hint().1.unwrap(); // we are not ascii exclusivists around here - if !(1..=20).contains(&name_len) { + if !USERNAME_LEN.contains(&name_len) { return Err(CreateUserErrorKind::BadUsername.into()); } @@ -111,18 +116,18 @@ async fn verify_user(form: &SignupForm) -> Result { return Err(CreateUserErrorKind::PasswordMismatch.into()); } let pwlen = password.graphemes(true).size_hint().1.unwrap_or(0); - if !(4..=50).contains(&pwlen) { + if !PASSWORD_LEN.contains(&pwlen) { return Err(CreateUserErrorKind::BadPassword.into()); } // clean up the optionals let displayname = validate_optional_length( &form.displayname, - 0..100, + DISPLAYNAME_LEN, CreateUserErrorKind::BadDisplayname, )?; - let email = validate_length(&form.email, 5..30, CreateUserErrorKind::BadEmail)?; + let email = validate_length(&form.email, EMAIL_LEN, CreateUserErrorKind::BadEmail)?; let user = User { username: username.to_string(), @@ -152,7 +157,7 @@ where pub(crate) fn validate_optional_length( opt: &Option, - len_range: Range, + len_range: RangeInclusive, err: E, ) -> Result, E> { if let Some(opt) = opt { @@ -170,7 +175,7 @@ pub(crate) fn validate_optional_length( pub(crate) fn validate_length( thing: &str, - len_range: Range, + len_range: RangeInclusive, err: E, ) -> Result { let thing = thing.trim(); diff --git a/src/main.rs b/src/main.rs index bfabdab..9f5fe4d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::{ use axum::{routing::get, Router}; use serde::{Deserialize, Serialize}; +use tower_http::services::ServeDir; use tower_sessions::{MemoryStore, SessionManagerLayer}; #[macro_use] @@ -20,8 +21,11 @@ async fn main() { let session_store = MemoryStore::default(); let session_layer = SessionManagerLayer::new(session_store).with_secure(false); + let assets_dir = std::env::current_dir().unwrap().join("assets"); + let assets_svc = ServeDir::new(assets_dir.as_path()); + let app = Router::new() - //.nest_service("/assets", assets_svc) + .nest_service("/assets", assets_svc) .route("/signup", get(get_signup).post(post_signup)) .route("/signup_success/:receipt", get(signup_success)) .layer(session_layer);