summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2022-08-22 23:03:59 +0200
committerSanto Cariotti <santo@dcariotti.me>2022-08-22 23:03:59 +0200
commitea2ac88a83b6de15beb8b9727f88d498a56fb5b3 (patch)
tree826154c0118505f73fea21c80435b4c6e6a4e71e
parent3092a758f382680a56e7343b036468db26111f98 (diff)
Add validation
-rw-r--r--server/Cargo.lock86
-rw-r--r--server/Cargo.toml3
-rw-r--r--server/src/errors.rs6
-rw-r--r--server/src/models/user.rs10
-rw-r--r--server/src/routes/user.rs8
5 files changed, 103 insertions, 10 deletions
diff --git a/server/Cargo.lock b/server/Cargo.lock
index fcc90ba..9148b0d 100644
--- a/server/Cargo.lock
+++ b/server/Cargo.lock
@@ -14,6 +14,15 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -567,6 +576,12 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -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]]
@@ -910,6 +928,30 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -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",
]
@@ -1643,6 +1687,48 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
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 <santo@dcariotti.me>"]
[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<bool>,
}
@@ -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<Json<Vec<UserList>>, AppError> {
async fn create_user(Json(payload): Json<UserCreate>) -> Result<Json<UserList>, 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))