diff options
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() };  |