Files
oxspeak_server/src/services/user.rs
T
2026-07-29 18:09:38 +02:00

105 lines
2.8 KiB
Rust

use crate::services::ServicesContext;
use crate::models::{role, user};
use crate::auth::password;
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, TransactionTrait, Set};
use std::sync::Arc;
use uuid::Uuid;
#[derive(Debug, Clone)]
pub struct UserService {
service_context: Arc<ServicesContext>,
}
impl UserService {
pub fn new(service_context: Arc<ServicesContext>) -> Self {
Self { service_context }
}
pub async fn create_user(
&self,
active: user::ActiveModel,
) -> Result<user::Model, anyhow::Error> {
let db = &self.service_context.repositories.server.context.db;
let event_bus = &self.service_context.event_bus;
let txn = db.begin().await?;
let usr = active.insert(&txn).await?;
txn.commit().await?;
event_bus.emit("user_created", usr.clone());
Ok(usr)
}
pub async fn update_user(
&self,
active: user::ActiveModel,
) -> Result<user::Model, anyhow::Error> {
let db = &self.service_context.repositories.server.context.db;
let event_bus = &self.service_context.event_bus;
let txn = db.begin().await?;
let usr = active.update(&txn).await?;
txn.commit().await?;
event_bus.emit("user_updated", usr.clone());
Ok(usr)
}
pub async fn set_password(&self, id: Uuid, password_str: String) -> Result<(), anyhow::Error> {
let db = &self.service_context.repositories.server.context.db;
let event_bus = &self.service_context.event_bus;
let txn = db.begin().await?;
let user_model = user::Entity::find_by_id(id)
.one(&txn)
.await?
.ok_or_else(|| anyhow::anyhow!("User not found"))?;
let mut active = user_model.into_active_model();
let password_to_hash = password_str.clone();
let hashed = tokio::task::spawn_blocking(move || password::hash_password(&password_to_hash))
.await
.map_err(|e| anyhow::anyhow!("Join error: {}", e))?
.map_err(|e| anyhow::anyhow!("Password hashing failed: {}", e))?;
active.password = Set(hashed);
let usr = active.update(&txn).await?;
txn.commit().await?;
event_bus.emit("user_changed", usr);
Ok(())
}
pub async fn delete_user(&self, id: Uuid) -> Result<bool, anyhow::Error> {
let db = &self.service_context.repositories.server.context.db;
let event_bus = &self.service_context.event_bus;
let txn = db.begin().await?;
let res = user::Entity::delete_by_id(id)
.exec(&txn)
.await?;
let deleted = res.rows_affected > 0;
txn.commit().await?;
if deleted {
event_bus.emit("user_deleted", id);
}
Ok(deleted)
}
}