NewUser validation

This commit is contained in:
2025-11-28 23:49:27 +01:00
parent d7374504f8
commit 4c6e0142ca
5 changed files with 37 additions and 1 deletions

View File

@@ -7,8 +7,10 @@ edition = "2024"
anyhow = "1.0.100" anyhow = "1.0.100"
argon2 = "0.5.3" argon2 = "0.5.3"
axum = "0.8.7" axum = "0.8.7"
lazy_static = "1.5.0"
password-hash = "0.5.0" password-hash = "0.5.0"
rand_core = { version = "0.6", features = ["getrandom"] } rand_core = { version = "0.6", features = ["getrandom"] }
regex = "1.12.2"
serde = { version = "1.0.228", features = ["derive", "serde_derive"] } serde = { version = "1.0.228", features = ["derive", "serde_derive"] }
serde_json = "1.0.145" serde_json = "1.0.145"
tokio = { version = "1.48.0", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.48.0", features = ["macros", "rt-multi-thread"] }

View File

@@ -1 +1,2 @@
pub mod user; pub mod user;
pub mod validation;

View File

@@ -1,16 +1,29 @@
use std::fmt::Display; use std::fmt::Display;
use axum::response::IntoResponse; use axum::response::IntoResponse;
use lazy_static::lazy_static;
use regex::Regex;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use validator::Validate;
use crate::domain::validation;
use crate::auth; use crate::auth;
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize, Validate)]
pub struct NewUser { pub struct NewUser {
#[validate(
length(min = 4, max = 16),
custom(function = "validation::validate_alphanum")
)]
username: String, username: String,
#[validate(email)]
email: Option<String>, email: Option<String>,
#[validate(length(min = 8))]
password: String, password: String,
#[validate(length(min = 1, max = 64))]
first_name: Option<String>, first_name: Option<String>,
#[validate(length(min = 1, max = 64))]
last_name: Option<String>, last_name: Option<String>,
} }

View File

@@ -0,0 +1,15 @@
use lazy_static::lazy_static;
use regex::Regex;
use validator::ValidationError;
lazy_static! {
static ref ALPHANUM: Regex = Regex::new(r"^[a-zA-Z0-9]+$").unwrap();
}
pub fn validate_alphanum(input: &str) -> Result<(), ValidationError> {
if ALPHANUM.is_match(input) {
Ok(())
} else {
Err(ValidationError::new("alphanum"))
}
}

View File

@@ -3,6 +3,7 @@ use std::sync::Arc;
use axum::{Json, extract::State, http::StatusCode}; use axum::{Json, extract::State, http::StatusCode};
use serde_json::json; use serde_json::json;
use tracing::{debug, error, info, warn}; use tracing::{debug, error, info, warn};
use validator::Validate;
use crate::{ use crate::{
domain::user::{InternalUser, NewUser, User}, domain::user::{InternalUser, NewUser, User},
@@ -13,6 +14,10 @@ pub async fn create(
State(state): State<Arc<AppState>>, State(state): State<Arc<AppState>>,
Json(new_user): Json<NewUser>, Json(new_user): Json<NewUser>,
) -> Result<Json<User>, StatusCode> { ) -> Result<Json<User>, StatusCode> {
if let Err(_) = new_user.validate() {
return Err(StatusCode::BAD_REQUEST);
}
let internal = InternalUser::try_from(new_user).map_err(|e| { let internal = InternalUser::try_from(new_user).map_err(|e| {
error!("Conversion to InternalUser failed: {e}"); error!("Conversion to InternalUser failed: {e}");
StatusCode::INTERNAL_SERVER_ERROR StatusCode::INTERNAL_SERVER_ERROR