diff --git a/src/models/computed_permission.rs b/src/models/computed_permission.rs index f3199f2..429eb63 100644 --- a/src/models/computed_permission.rs +++ b/src/models/computed_permission.rs @@ -48,9 +48,6 @@ pub struct Model { on_delete = "Cascade" )] pub user: HasOne, - - #[sea_orm(has_many)] - pub computed_permissions: HasMany, } #[async_trait] diff --git a/src/repositories/computed_permission.rs b/src/repositories/computed_permission.rs index dea7d1f..bca99a3 100644 --- a/src/repositories/computed_permission.rs +++ b/src/repositories/computed_permission.rs @@ -13,6 +13,7 @@ use std::sync::{Arc, OnceLock}; use uuid::Uuid; use crate::models::computed_permission::PermissionScopeType; +use crate::repositories::types::PermissionResource; use crate::utils::ScopedLockManager; // Instance globale du manager de verrous scopés par Server ID @@ -35,6 +36,19 @@ impl ComputedPermissionRepository { .await?) } + pub async fn get_for_resource( + &self, + user_id: Uuid, + resource: PermissionResource, + ) -> AnyResult> { + Ok(computed_permission::Entity::find() + .filter(computed_permission::Column::UserId.eq(user_id)) + .filter(computed_permission::Column::ScopeType.eq(resource.scope_type())) + .filter(computed_permission::Column::ResourceId.eq(resource.resource_id())) + .one(&self.context.db) + .await?) + } + /// Vérifie si l'utilisateur possède au moins une entrée de permission sur une ressource. pub async fn had_perm_on(&self, user_id: Uuid, resource_id: Uuid) -> AnyResult { Ok(computed_permission::Entity::find() diff --git a/src/repositories/server_tree.rs b/src/repositories/server_tree.rs index df24052..3e5ae9d 100644 --- a/src/repositories/server_tree.rs +++ b/src/repositories/server_tree.rs @@ -67,11 +67,14 @@ impl ServerTreeRepository { server_id: Uuid, user_id: Uuid, ) -> AnyResult)>> { + // Construction dynamique de la relation personnalisée (channel.id = computed_permission.resource_id) + let channel_to_permission = channel::Entity::belongs_to(computed_permission::Entity) + .from(channel::Column::Id) + .to(computed_permission::Column::ResourceId) + .into(); + let rows = channel::Entity::find() - .join( - JoinType::InnerJoin, - channel::Relation::ComputedPermission.def(), - ) + .join(JoinType::InnerJoin, channel_to_permission) .filter(channel::Column::ServerId.eq(server_id)) .filter(computed_permission::Column::UserId.eq(user_id)) .filter(computed_permission::Column::ServerId.eq(server_id)) diff --git a/src/repositories/types.rs b/src/repositories/types.rs index a7019bd..582afec 100644 --- a/src/repositories/types.rs +++ b/src/repositories/types.rs @@ -1,4 +1,5 @@ -use crate::models::{category, channel}; +use crate::models::{category, channel, computed_permission}; +use uuid::Uuid; pub enum ServerExplorerItem { Category(category::Model, Vec), @@ -32,3 +33,26 @@ pub struct ChannelFilter { pub struct UserFilter { pub server_id: Option, } + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum PermissionResource { + Server(Uuid), + Category(Uuid), + Channel(Uuid), +} + +impl PermissionResource { + pub fn scope_type(self) -> computed_permission::PermissionScopeType { + match self { + Self::Server(_) => computed_permission::PermissionScopeType::Server, + Self::Category(_) => computed_permission::PermissionScopeType::Category, + Self::Channel(_) => computed_permission::PermissionScopeType::Channel, + } + } + + pub fn resource_id(self) -> Uuid { + match self { + Self::Server(id) | Self::Category(id) | Self::Channel(id) => id, + } + } +}