diff options
author | Santo Cariotti <santo@dcariotti.me> | 2022-11-21 12:11:38 +0100 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2022-11-21 12:11:38 +0100 |
commit | 23cf79911e20eac981a25dc1c2f839d37f98c296 (patch) | |
tree | e0ed1e287121bbdc2bbe1ac3aff11273f730c741 /server/src/models | |
parent | 7d661b657bbc31062e90b1a9c2bd8666627c2e07 (diff) |
Add fields for users
Diffstat (limited to 'server/src/models')
-rw-r--r-- | server/src/models/auth.rs | 9 | ||||
-rw-r--r-- | server/src/models/user.rs | 71 |
2 files changed, 59 insertions, 21 deletions
diff --git a/server/src/models/auth.rs b/server/src/models/auth.rs index f798eee..cf69f50 100644 --- a/server/src/models/auth.rs +++ b/server/src/models/auth.rs @@ -32,10 +32,19 @@ pub struct AuthBody { token_type: String, } +/// Payload used for login +#[derive(Deserialize)] +pub struct LoginCredentials { + pub username: String, + pub password: String, +} + /// Paylod used for user creation #[derive(Deserialize)] pub struct SignUpForm { + pub name: String, pub email: String, + pub username: String, pub password1: String, pub password2: String, } 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<bool>, + avatar: Option<String>, } /// 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<bool>, -} - -/// 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<bool>, + pub avatar: Option<String>, } 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<Vec<UserList>, AppError> { let pool = unsafe { get_client() }; - let rows: Vec<UserList> = sqlx::query_as(r#"SELECT id, email, is_staff FROM users"#) - .fetch_all(pool) - .await?; + let rows: Vec<UserList> = 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<bool, AppError> { + 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<bool, AppError> { let pool = unsafe { get_client() }; |