diff --git a/src/core/permission_sync.rs b/src/core/permission_sync.rs index 6cc4394..31c12f6 100644 --- a/src/core/permission_sync.rs +++ b/src/core/permission_sync.rs @@ -1,4 +1,3 @@ -use crate::domain::events::server::ServerCreatedEvent; use crate::repositories::Repositories; use event_bus::EventBus; use std::sync::Arc; @@ -28,6 +27,27 @@ use uuid::Uuid; // // channel_created // channel_deleted +// [Requête HTTP Admin] +// │ +// ▼ +// 1. Repositories (Ecriture BDD) +// │ +// ▼ (Emit Event ex: server_role_permission_updated) +// 2. EventBus +// │ +// ├────────────────────────────────────────┐ +// ▼ ▼ +// 3. PermissionSyncService (Async Task) [Réponse HTTP 200/204] +// │ +// ├─► Recalcule computed_permission (full_sync_user) +// │ +// └─► Emit Event "user_permissions_updated" +// │ +// ▼ +// 4. Gateway WebSocket +// │ +// ▼ (Push WS) +// 5. Client Frontend (Vue 3 / Pinia) #[derive(Debug, Clone)] pub struct PermissionSyncService { @@ -43,23 +63,162 @@ impl PermissionSyncService { } } + /// Enregistre les listeners sur l'EventBus pour mettre à jour le cache + /// des permissions calculées lors des modifications de structure ou de droits. pub async fn start_listen_event(&self) { - // todo : compléter la liste de permission avec le déclenchement des évènements + // --------------------------------------------------------------------- + // Événements Serveur & Membres Serveur + // --------------------------------------------------------------------- + self.event_bus.on_async_with( "server_created", self.repositories.clone(), - move |repositories, payload: ServerCreatedEvent| { - Self::sync_server_permissions(repositories, payload.server.id) + move |repositories, server_id: Uuid| async move { + Self::sync_server(repositories, server_id).await; + }, + ); + + self.event_bus.on_async_with( + "server_user_created", + self.repositories.clone(), + move |repositories, (server_id, user_id): (Uuid, Uuid)| async move { + Self::sync_user(repositories, user_id, server_id).await; + }, + ); + + self.event_bus.on_async_with( + "server_user_deleted", + self.repositories.clone(), + move |repositories, (server_id, user_id): (Uuid, Uuid)| async move { + Self::sync_user(repositories, user_id, server_id).await; + }, + ); + + // --------------------------------------------------------------------- + // Événements Rôles & Membres de Rôle + // --------------------------------------------------------------------- + + self.event_bus.on_async_with( + "role_user_created", + self.repositories.clone(), + move |repositories, (_role_id, user_id, server_id): (Uuid, Uuid, Uuid)| async move { + Self::sync_user(repositories, user_id, server_id).await; + }, + ); + + self.event_bus.on_async_with( + "role_user_deleted", + self.repositories.clone(), + move |repositories, (_role_id, user_id, server_id): (Uuid, Uuid, Uuid)| async move { + Self::sync_user(repositories, user_id, server_id).await; + }, + ); + + // --------------------------------------------------------------------- + // Overrides de Permissions Serveur + // --------------------------------------------------------------------- + + self.event_bus.on_async_with( + "server_role_permission_updated", + self.repositories.clone(), + move |repositories, (role_id, server_id): (Uuid, Uuid)| async move { + Self::sync_role_members(repositories, role_id, server_id).await; + }, + ); + + self.event_bus.on_async_with( + "server_user_permission_updated", + self.repositories.clone(), + move |repositories, (server_id, user_id): (Uuid, Uuid)| async move { + Self::sync_user(repositories, user_id, server_id).await; + }, + ); + + // --------------------------------------------------------------------- + // Événements Canaux & Overrides de Permissions Canaux + // --------------------------------------------------------------------- + + self.event_bus.on_async_with( + "channel_created", + self.repositories.clone(), + move |repositories, server_id: Uuid| async move { + Self::sync_server(repositories, server_id).await; + }, + ); + + self.event_bus.on_async_with( + "channel_deleted", + self.repositories.clone(), + move |repositories, server_id: Uuid| async move { + Self::sync_server(repositories, server_id).await; + }, + ); + + self.event_bus.on_async_with( + "channel_role_permission_updated", + self.repositories.clone(), + move |repositories, (role_id, server_id): (Uuid, Uuid)| async move { + Self::sync_role_members(repositories, role_id, server_id).await; + }, + ); + + self.event_bus.on_async_with( + "channel_user_permission_updated", + self.repositories.clone(), + move |repositories, (server_id, user_id): (Uuid, Uuid)| async move { + Self::sync_user(repositories, user_id, server_id).await; }, ); } - async fn sync_server_permissions(repositories: Arc, server_id: Uuid) { - let _ = repositories + // ------------------------------------------------------------------------- + // Méthodes d'exécution Asynchrones + // ------------------------------------------------------------------------- + + /// Recalcule le cache pour un utilisateur sur un serveur donné. + async fn sync_user(repositories: Arc, user_id: Uuid, server_id: Uuid) { + if let Err(err) = repositories .computed_permission - .full_sync_server(server_id) - .await; + .full_sync_user(user_id, server_id) + .await + { + tracing::error!( + "Erreur lors de la synchronisation des permissions pour l'utilisateur {} sur le serveur {}: {:?}", + user_id, + server_id, + err + ); + } } - async fn sync_server_permissions_by_user() {} + /// Recalcule le cache pour tous les membres d'un rôle. + async fn sync_role_members(repositories: Arc, role_id: Uuid, server_id: Uuid) { + if let Err(err) = repositories + .computed_permission + .sync_role_members(role_id, server_id) + .await + { + tracing::error!( + "Erreur lors de la synchronisation des membres du rôle {} sur le serveur {}: {:?}", + role_id, + server_id, + err + ); + } + } + + /// Recalcule le cache pour TOUS les utilisateurs d'un serveur. + async fn sync_server(repositories: Arc, server_id: Uuid) { + if let Err(err) = repositories + .computed_permission + .full_sync_server(server_id) + .await + { + tracing::error!( + "Erreur lors de la synchronisation complète du serveur {}: {:?}", + server_id, + err + ); + } + } }