use crate::auth::password; use crate::models::user; use crate::repositories::{AnyResult, RepositoryContext}; use sea_orm::{ ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, PaginatorTrait, QueryFilter, Set, }; use std::sync::Arc; #[derive(Clone, Debug)] pub struct UserRepository { pub context: Arc, } impl UserRepository { pub async fn get_all(&self) -> AnyResult> { Ok(user::Entity::find().all(&self.context.db).await?) } pub async fn count(&self) -> AnyResult { Ok(user::Entity::find().count(&self.context.db).await?) } pub async fn get_by_id(&self, id: uuid::Uuid) -> AnyResult> { Ok(user::Entity::find_by_id(id).one(&self.context.db).await?) } pub async fn get_by_username(&self, username: String) -> AnyResult> { Ok(user::Entity::find() .filter(user::Column::Username.eq(username)) .one(&self.context.db) .await?) } pub async fn check_password(&self, username: &str, password: &str) -> AnyResult { let user = self.get_by_username(username.to_string()).await?; if let Some(user) = user { let password_ok = password::verify_password(password, user.password.as_str()) .map_err(|e| anyhow::anyhow!("Password hashing failed: {}", e))?; if password_ok { return Ok(user); } } Err(anyhow::anyhow!("Invalid username or password")) } pub async fn update(&self, active: user::ActiveModel) -> AnyResult { let user = active.update(&self.context.db).await?; self.context.events.emit("user_updated", user.clone()); Ok(user) } pub async fn create(&self, active: user::ActiveModel) -> AnyResult { let user = active.insert(&self.context.db).await?; self.context.events.emit("user_created", user.clone()); Ok(user) } pub async fn set_password(&self, id: uuid::Uuid, password: String) -> AnyResult<()> { let user = self .get_by_id(id) .await? .ok_or_else(|| anyhow::anyhow!("User not found"))?; let mut active = user.into_active_model(); let password = password::hash_password(&password) .map_err(|e| anyhow::anyhow!("Password hashing failed: {}", e))?; active.password = Set(password); let user = self.update(active).await?; self.context.events.emit("user_changed", user); Ok(()) } pub async fn delete(&self, id: uuid::Uuid) -> AnyResult { let result = user::Entity::delete_by_id(id) .exec(&self.context.db) .await?; let deleted = result.rows_affected > 0; if deleted { self.context.events.emit("user_deleted", id); } Ok(deleted) } pub async fn username_exists(&self, username: &str) -> AnyResult { Ok(user::Entity::find() .filter(user::Column::Username.eq(username)) .count(&self.context.db) .await? > 0) } }