use anyhow::bail; use persmgr_derive::TableMeta; use sqlx::prelude::FromRow; use crate::db::{ CurrPool, tables::{ForeignKey, TableMeta, assignables::ranks::Rank, groups::Groups}, }; #[derive(Debug, Default, Clone, FromRow, TableMeta)] #[meta(table = "users")] pub struct User { pub id: i64, pub email: String, pub verified_email: bool, pub username: String, pub pw_hash: String, pub pw_salt: String, pub pfp_id: i64, pub rank_id: ForeignKey, pub group_id: ForeignKey, } impl User { pub async fn get_by_id(pool: &CurrPool, id: i64) -> anyhow::Result { let user = sqlx::query_as!(User, "SELECT * FROM users WHERE id = $1", id) .fetch_one(pool) .await?; Ok(user) } pub async fn get_by_email(pool: &CurrPool, email: String) -> anyhow::Result { let user = sqlx::query_as!(User, "SELECT * FROM users WHERE email = $1", email) .fetch_one(pool) .await?; Ok(user) } pub async fn get_by_username(pool: &CurrPool, username: String) -> anyhow::Result { let user = sqlx::query_as!(User, "SELECT * FROM users WHERE username = $1", username) .fetch_one(pool) .await?; Ok(user) } pub async fn insert_new(&self, pool: &CurrPool) -> anyhow::Result<()> { sqlx::query!( r#" INSERT INTO users (email, username, pw_hash, pw_salt) VALUES ($1, $2, $3, $4) "#, self.email, self.username, self.pw_hash, self.pw_salt ) .execute(pool) .await?; Ok(()) } pub async fn set_username( &mut self, pool: &CurrPool, username: String, ) -> anyhow::Result<&mut Self> { let new_user = sqlx::query_as!( User, "UPDATE users SET username = $1 WHERE id = $2 RETURNING *", username, self.id ) .fetch_one(pool) .await?; *self = new_user; Ok(self) } pub async fn set_email(&mut self, pool: &CurrPool, email: String) -> anyhow::Result<&mut Self> { let new_user = sqlx::query_as!( User, "UPDATE users SET email = $1 WHERE id = $2 RETURNING *", email, self.id ) .fetch_one(pool) .await?; *self = new_user; Ok(self) } pub async fn set_pw_hash( &mut self, pool: &CurrPool, pw_hash: String, ) -> anyhow::Result<&mut Self> { let new_user = sqlx::query_as!( User, "UPDATE users SET pw_hash = $1 WHERE id = $2 RETURNING *", pw_hash, self.id ) .fetch_one(pool) .await?; *self = new_user; Ok(self) } pub async fn set_pw_salt( &mut self, pool: &CurrPool, pw_salt: String, ) -> anyhow::Result<&mut Self> { let new_user = sqlx::query_as!( User, "UPDATE users SET pw_salt = $1 WHERE id = $2 RETURNING *", pw_salt, self.id ) .fetch_one(pool) .await?; *self = new_user; Ok(self) } pub async fn set_email_verification_status( &mut self, pool: &CurrPool, status: bool, ) -> anyhow::Result<&mut Self> { let new_user = sqlx::query_as!( User, "UPDATE users SET verified_email = $1 WHERE id = $2 RETURNING *", status, self.id ) .fetch_one(pool) .await?; *self = new_user; Ok(self) } }