From 23cf79911e20eac981a25dc1c2f839d37f98c296 Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Mon, 21 Nov 2022 12:11:38 +0100 Subject: Add fields for users --- server/src/models/user.rs | 71 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 21 deletions(-) (limited to 'server/src/models/user.rs') diff --git a/server/src/models/user.rs b/server/src/models/user.rs index ace4266..356b9a2 100644 --- a/server/src/models/user.rs +++ b/server/src/models/user.rs @@ -9,37 +9,42 @@ use validator::Validate; #[derive(Deserialize, Serialize, Validate, sqlx::FromRow)] pub struct User { id: i32, - #[validate(length(min = 1, message = "Can not be empty"))] + name: String, + #[validate(length(min = 4, message = "Can not be empty"))] email: String, + #[validate(length(min = 2, message = "Can not be empty"))] + username: String, #[validate(length(min = 8, message = "Must be min 8 chars length"))] password: String, is_staff: Option, + avatar: Option, } /// Response used to print a user (or a users list) -#[derive(Deserialize, Serialize, sqlx::FromRow)] +#[derive(Deserialize, Serialize, Validate, sqlx::FromRow)] pub struct UserList { // It is public because it used by `Claims` creation pub id: i32, - email: String, - is_staff: Option, -} - -/// Payload used for user creation -#[derive(Deserialize)] -pub struct UserCreate { + pub name: String, + #[validate(length(min = 4, message = "Can not be empty"))] pub email: String, - pub password: String, + #[validate(length(min = 2, message = "Can not be empty"))] + pub username: String, + pub is_staff: Option, + pub avatar: Option, } impl User { /// By default an user has id = 0. It is not created yet - pub fn new(email: String, password: String) -> Self { + pub fn new(name: String, email: String, username: String, password: String) -> Self { Self { id: 0, + name, email, + username, password, is_staff: Some(false), + avatar: None, } } @@ -54,12 +59,14 @@ impl User { let rec: UserList = sqlx::query_as( r#" - INSERT INTO users (email, password) - VALUES ( $1, $2 ) - RETURNING id, email, is_staff + INSERT INTO users (name, email, username, password) + VALUES ( $1, $2, $3, $4) + RETURNING id, name, email, username, is_staff, avatar "#, ) + .bind(user.name) .bind(user.email) + .bind(user.username) .bind(crypted_password) .fetch_one(pool) .await?; @@ -75,11 +82,11 @@ impl User { let rec: UserList = sqlx::query_as( r#" - SELECT id, email, is_staff FROM "users" - WHERE email = $1 AND password = $2 + SELECT id, name, email, username, is_staff, avatar FROM "users" + WHERE username = $1 AND password = $2 "#, ) - .bind(user.email) + .bind(user.username) .bind(crypted_password) .fetch_one(pool) .await?; @@ -93,7 +100,7 @@ impl User { let rec: UserList = sqlx::query_as( r#" - SELECT id, email, is_staff FROM "users" + SELECT id, name, email, username, is_staff, avatar FROM "users" WHERE id = $1 "#, ) @@ -107,13 +114,35 @@ impl User { /// List all users pub async fn list() -> Result, AppError> { let pool = unsafe { get_client() }; - let rows: Vec = sqlx::query_as(r#"SELECT id, email, is_staff FROM users"#) - .fetch_all(pool) - .await?; + let rows: Vec = sqlx::query_as( + r#"SELECT id, name, email, username, is_staff, avatar FROM users + ORDER BY id DESC + LIMIT $1 OFFSET $2 + "#, + ) + .fetch_all(pool) + .await?; Ok(rows) } + /// Prevent the "uniquess" Postgres fields check. Check if username has been taken + pub async fn username_has_taken(username: &String) -> Result { + let pool = unsafe { get_client() }; + let cursor = sqlx::query( + r#" + SELECT COUNT(id) as count FROM users WHERE username = $1 + "#, + ) + .bind(username) + .fetch_one(pool) + .await?; + + let count: i64 = cursor.try_get(0).unwrap(); + + Ok(count > 0) + } + /// Prevent the "uniquess" Postgres fields check. Check if email has been taken pub async fn email_has_taken(email: &String) -> Result { let pool = unsafe { get_client() }; -- cgit v1.2.3-18-g5258