From ea2ac88a83b6de15beb8b9727f88d498a56fb5b3 Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Mon, 22 Aug 2022 23:03:59 +0200 Subject: Add validation --- server/Cargo.lock | 86 +++++++++++++++++++++++++++++++++++++++++++++++ server/Cargo.toml | 3 ++ server/src/errors.rs | 6 ++-- server/src/models/user.rs | 10 +++--- server/src/routes/user.rs | 8 ++--- 5 files changed, 103 insertions(+), 10 deletions(-) (limited to 'server') diff --git a/server/Cargo.lock b/server/Cargo.lock index fcc90ba..9148b0d 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -13,6 +13,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "alloc-no-stdlib" version = "2.0.3" @@ -566,6 +575,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + [[package]] name = "indexmap" version = "1.9.1" @@ -658,7 +673,9 @@ dependencies = [ name = "m6-ie-2022" version = "0.1.0" dependencies = [ + "async-trait", "axum", + "http-body", "jsonwebtoken", "once_cell", "serde", @@ -669,6 +686,7 @@ dependencies = [ "tower-http", "tracing", "tracing-subscriber", + "validator", ] [[package]] @@ -909,6 +927,30 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.43" @@ -983,6 +1025,8 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", ] @@ -1642,6 +1686,48 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "validator" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32ad5bf234c7d3ad1042e5252b7eddb2c4669ee23f32c7dd0e9b7705f07ef591" +dependencies = [ + "idna", + "lazy_static", + "regex", + "serde", + "serde_derive", + "serde_json", + "url", + "validator_derive", +] + +[[package]] +name = "validator_derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc44ca3088bb3ba384d9aecf40c6a23a676ce23e09bdaca2073d99c207f864af" +dependencies = [ + "if_chain", + "lazy_static", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn", + "validator_types", +] + +[[package]] +name = "validator_types" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111abfe30072511849c5910134e8baf8dc05de4c0e5903d681cbd5c9c4d611e3" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "valuable" version = "0.1.0" diff --git a/server/Cargo.toml b/server/Cargo.toml index dca788a..8527fdb 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -5,7 +5,9 @@ edition = "2021" authors = ["Santo Cariotti "] [dependencies] +async-trait = "0.1" axum = { version = "0.5.15", features = ["headers"] } +http-body = "0.4.3" jsonwebtoken = "8.1" once_cell = "1.13" serde = { version = "1.0", features = ["derive"] } @@ -16,3 +18,4 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } tower-http = { version = "0.3.4", features = ["trace", "compression-br", "propagate-header", "sensitive-headers"] } sqlx = { version = "0.6", features = [ "runtime-tokio-rustls", "postgres" ] } sha256 = "1.0.3" +validator = { version = "0.16.0", features = ["derive"] } diff --git a/server/src/errors.rs b/server/src/errors.rs index dc0468e..9221fea 100644 --- a/server/src/errors.rs +++ b/server/src/errors.rs @@ -8,6 +8,7 @@ use serde_json::json; pub enum AppError { Generic, Database, + BadRequest(String), } impl IntoResponse for AppError { @@ -15,12 +16,13 @@ impl IntoResponse for AppError { let (status, error_message) = match self { AppError::Generic => ( StatusCode::INTERNAL_SERVER_ERROR, - "Generic error, can't find why", + "Generic error, can't find why".to_string(), ), AppError::Database => ( StatusCode::INTERNAL_SERVER_ERROR, - "Error with database connection", + "Error with database connection".to_string(), ), + AppError::BadRequest(value) => (StatusCode::BAD_REQUEST, value), }; let body = Json(json!({ diff --git a/server/src/models/user.rs b/server/src/models/user.rs index 9545fac..76cb4b5 100644 --- a/server/src/models/user.rs +++ b/server/src/models/user.rs @@ -2,11 +2,14 @@ use crate::db::get_client; use crate::errors::AppError; use serde::{Deserialize, Serialize}; +use validator::Validate; -#[derive(Deserialize, Serialize)] +#[derive(Deserialize, Serialize, Validate)] pub struct User { id: i32, + #[validate(length(min = 1, message = "Can not be empty"))] email: String, + #[validate(length(min = 8, message = "Must be min 8 chars length"))] password: String, is_staff: Option, } @@ -26,11 +29,10 @@ pub struct UserCreate { impl User { pub fn new(email: String, password: String) -> Self { - let crypted_password = sha256::digest(password); Self { id: 0, email, - password: crypted_password, + password, is_staff: Some(false), } } @@ -45,7 +47,7 @@ impl User { RETURNING id, email, is_staff "#, user.email, - user.password + sha256::digest(user.password) ) .fetch_one(pool) .await?; diff --git a/server/src/routes/user.rs b/server/src/routes/user.rs index 7aecccb..c15b5aa 100644 --- a/server/src/routes/user.rs +++ b/server/src/routes/user.rs @@ -1,9 +1,7 @@ use crate::errors::AppError; use crate::models::user::{User, UserCreate, UserList}; -use axum::{ - routing::{get}, - Json, Router, -}; +use axum::{routing::get, Json, Router}; +use validator::Validate; pub fn create_route() -> Router { Router::new().route("/", get(list_users).post(create_user)) @@ -17,6 +15,8 @@ async fn list_users() -> Result>, AppError> { async fn create_user(Json(payload): Json) -> Result, AppError> { let user = User::new(payload.email, payload.password); + user.validate() + .map_err(|error| AppError::BadRequest(error.to_string()))?; let user_new = User::create(user).await?; Ok(Json(user_new)) -- cgit v1.2.3-18-g5258