295 lines
9.7 KiB
Rust
295 lines
9.7 KiB
Rust
use crate::domain::dto::channel::{CreateChannelRequest, UpdateChannelRequest};
|
|
use crate::models::server_item_order::OrderedResourceType;
|
|
use crate::models::{channel, role};
|
|
use crate::permissions::PermissionSet;
|
|
use crate::services::ServicesContext;
|
|
use crate::services::permission::PermissionService;
|
|
use sea_orm::{
|
|
ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set, TransactionTrait,
|
|
};
|
|
use std::sync::Arc;
|
|
use uuid::Uuid;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct ChannelService {
|
|
service_context: Arc<ServicesContext>,
|
|
}
|
|
|
|
impl ChannelService {
|
|
pub fn new(service_context: Arc<ServicesContext>) -> Self {
|
|
Self { service_context }
|
|
}
|
|
|
|
pub async fn create_channel(
|
|
&self,
|
|
payload: CreateChannelRequest,
|
|
) -> Result<channel::Model, anyhow::Error> {
|
|
let db = &self.service_context.repositories.server.context.db;
|
|
let event_bus = &self.service_context.event_bus;
|
|
let server_order = self
|
|
.service_context
|
|
.services
|
|
.get()
|
|
.expect("services initialized")
|
|
.server_order
|
|
.clone();
|
|
|
|
let channel = db
|
|
.transaction::<_, channel::Model, anyhow::Error>(|txn| {
|
|
Box::pin(async move {
|
|
// 1. Insertion du canal
|
|
let active_model = channel::ActiveModel {
|
|
server_id: Set(payload.server_id),
|
|
category_id: Set(payload.category_id),
|
|
channel_type: Set(payload.channel_type),
|
|
name: Set(payload.name),
|
|
..Default::default()
|
|
};
|
|
|
|
let channel = active_model.insert(txn).await?;
|
|
|
|
// 2. Si server_id est présent, enregistrement de l'ordre d'affichage
|
|
if let Some(server_id) = payload.server_id {
|
|
server_order
|
|
.append(
|
|
txn,
|
|
server_id,
|
|
channel.id,
|
|
OrderedResourceType::Channel,
|
|
payload.category_id,
|
|
)
|
|
.await?;
|
|
|
|
// 3. Attribution des permissions par défaut au rôle par défaut
|
|
if let Some(default_role) = role::Entity::find()
|
|
.filter(role::Column::ServerId.eq(server_id))
|
|
.filter(role::Column::IsDefault.eq(true))
|
|
.one(txn)
|
|
.await?
|
|
{
|
|
let default_channel_permissions =
|
|
PermissionSet::DEFAULT.channel.bits() as i64;
|
|
|
|
let role_perm = crate::models::channel_role_permission::ActiveModel {
|
|
channel_id: Set(channel.id),
|
|
role_id: Set(default_role.id),
|
|
permissions: Set(default_channel_permissions),
|
|
..Default::default()
|
|
};
|
|
role_perm.insert(txn).await?;
|
|
}
|
|
|
|
// 4. Refresh des permissions (Global pour l'instant)
|
|
// TODO: Cibler/focaliser le spectre du recalcul (ex: uniquement les membres impactés ou le canal spécifique)
|
|
PermissionService::sync_server_with_db(txn, server_id).await?;
|
|
}
|
|
|
|
Ok(channel)
|
|
})
|
|
})
|
|
.await?;
|
|
|
|
// Post-commit event emission
|
|
event_bus.emit("channel_created", channel.clone());
|
|
|
|
Ok(channel)
|
|
}
|
|
|
|
pub async fn update_channel(
|
|
&self,
|
|
id: Uuid,
|
|
payload: UpdateChannelRequest,
|
|
) -> Result<channel::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 existing = channel::Entity::find_by_id(id)
|
|
.one(&txn)
|
|
.await?
|
|
.ok_or_else(|| anyhow::anyhow!("Channel not found"))?;
|
|
|
|
let mut active: channel::ActiveModel = existing.into();
|
|
active.server_id = Set(payload.server_id);
|
|
active.category_id = Set(payload.category_id);
|
|
active.channel_type = Set(payload.channel_type);
|
|
active.name = Set(payload.name);
|
|
|
|
let channel = active.update(&txn).await?;
|
|
|
|
self.service_context
|
|
.services
|
|
.get()
|
|
.expect("services initialized")
|
|
.server_order
|
|
.sync(
|
|
&txn,
|
|
channel.id,
|
|
OrderedResourceType::Channel,
|
|
channel.server_id,
|
|
channel.category_id,
|
|
)
|
|
.await?;
|
|
|
|
txn.commit().await?;
|
|
|
|
event_bus.emit("channel_updated", channel.clone());
|
|
|
|
Ok(channel)
|
|
}
|
|
|
|
pub async fn delete_channel(&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?;
|
|
|
|
self.service_context
|
|
.services
|
|
.get()
|
|
.expect("services initialized")
|
|
.server_order
|
|
.remove(&txn, id, OrderedResourceType::Channel)
|
|
.await?;
|
|
|
|
let res = channel::Entity::delete_by_id(id).exec(&txn).await?;
|
|
|
|
let deleted = res.rows_affected > 0;
|
|
|
|
txn.commit().await?;
|
|
|
|
if deleted {
|
|
event_bus.emit("channel_deleted", id);
|
|
}
|
|
|
|
Ok(deleted)
|
|
}
|
|
|
|
pub async fn set_user_permission(
|
|
&self,
|
|
channel_id: Uuid,
|
|
user_id: Uuid,
|
|
permissions: u64,
|
|
) -> 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 permission = crate::models::channel_user_permission::ActiveModel {
|
|
channel_id: Set(channel_id),
|
|
user_id: Set(user_id),
|
|
permissions: Set(permissions as i64),
|
|
..Default::default()
|
|
};
|
|
|
|
crate::models::channel_user_permission::Entity::insert(permission)
|
|
.on_conflict(
|
|
sea_orm::sea_query::OnConflict::columns([
|
|
crate::models::channel_user_permission::Column::ChannelId,
|
|
crate::models::channel_user_permission::Column::UserId,
|
|
])
|
|
.update_columns([crate::models::channel_user_permission::Column::Permissions])
|
|
.to_owned(),
|
|
)
|
|
.exec(&txn)
|
|
.await?;
|
|
|
|
txn.commit().await?;
|
|
|
|
event_bus.emit(
|
|
"channel_user_permission_created",
|
|
(channel_id, user_id, permissions),
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn remove_user_permission(
|
|
&self,
|
|
channel_id: Uuid,
|
|
user_id: Uuid,
|
|
) -> 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?;
|
|
|
|
crate::models::channel_user_permission::Entity::delete_many()
|
|
.filter(crate::models::channel_user_permission::Column::ChannelId.eq(channel_id))
|
|
.filter(crate::models::channel_user_permission::Column::UserId.eq(user_id))
|
|
.exec(&txn)
|
|
.await?;
|
|
|
|
txn.commit().await?;
|
|
|
|
event_bus.emit("channel_user_permission_deleted", (channel_id, user_id));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn set_role_permission(
|
|
&self,
|
|
channel_id: Uuid,
|
|
role_id: Uuid,
|
|
permissions: u64,
|
|
) -> 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 permission = crate::models::channel_role_permission::ActiveModel {
|
|
channel_id: Set(channel_id),
|
|
role_id: Set(role_id),
|
|
permissions: Set(permissions as i64),
|
|
..Default::default()
|
|
};
|
|
|
|
crate::models::channel_role_permission::Entity::insert(permission)
|
|
.on_conflict(
|
|
sea_orm::sea_query::OnConflict::columns([
|
|
crate::models::channel_role_permission::Column::ChannelId,
|
|
crate::models::channel_role_permission::Column::RoleId,
|
|
])
|
|
.update_columns([crate::models::channel_role_permission::Column::Permissions])
|
|
.to_owned(),
|
|
)
|
|
.exec(&txn)
|
|
.await?;
|
|
|
|
txn.commit().await?;
|
|
|
|
event_bus.emit(
|
|
"channel_role_permission_created",
|
|
(channel_id, role_id, permissions),
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn remove_role_permission(
|
|
&self,
|
|
channel_id: Uuid,
|
|
role_id: Uuid,
|
|
) -> 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?;
|
|
|
|
crate::models::channel_role_permission::Entity::delete_many()
|
|
.filter(crate::models::channel_role_permission::Column::ChannelId.eq(channel_id))
|
|
.filter(crate::models::channel_role_permission::Column::RoleId.eq(role_id))
|
|
.exec(&txn)
|
|
.await?;
|
|
|
|
txn.commit().await?;
|
|
|
|
event_bus.emit("channel_role_permission_deleted", (channel_id, role_id));
|
|
|
|
Ok(())
|
|
}
|
|
}
|