diff --git a/migration/src/m20220101_000001_create_table.rs b/migration/src/m20220101_000001_create_table.rs index f7cf460..88372a4 100644 --- a/migration/src/m20220101_000001_create_table.rs +++ b/migration/src/m20220101_000001_create_table.rs @@ -490,7 +490,7 @@ impl MigrationTrait for Migration { .col(ColumnDef::new(Alias::new("server_id")).uuid().not_null()) .col(ColumnDef::new(Alias::new("role_id")).uuid().not_null()) .col( - ColumnDef::new(Alias::new("permission")) + ColumnDef::new(Alias::new("permissions")) .big_integer() .not_null() .default(0), @@ -537,7 +537,7 @@ impl MigrationTrait for Migration { .col(ColumnDef::new(Alias::new("channel_id")).uuid().not_null()) .col(ColumnDef::new(Alias::new("role_id")).uuid().not_null()) .col( - ColumnDef::new(Alias::new("permission")) + ColumnDef::new(Alias::new("permissions")) .big_integer() .not_null() .default(0), @@ -584,7 +584,7 @@ impl MigrationTrait for Migration { .col(ColumnDef::new(Alias::new("channel_id")).uuid().not_null()) .col(ColumnDef::new(Alias::new("user_id")).uuid().not_null()) .col( - ColumnDef::new(Alias::new("permission")) + ColumnDef::new(Alias::new("permissions")) .big_integer() .not_null() .default(0), @@ -635,19 +635,7 @@ impl MigrationTrait for Migration { ) .col(ColumnDef::new(Alias::new("resource_id")).uuid().not_null()) .col( - ColumnDef::new(Alias::new("server_permissions")) - .big_integer() - .not_null() - .default(0), - ) - .col( - ColumnDef::new(Alias::new("channel_permissions")) - .big_integer() - .not_null() - .default(0), - ) - .col( - ColumnDef::new(Alias::new("voice_permissions")) + ColumnDef::new(Alias::new("permissions")) .big_integer() .not_null() .default(0), diff --git a/src/core/mod.rs b/src/core/mod.rs index 32fdcfa..9656e8e 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,6 +1,9 @@ +mod permission_sync; pub mod state; use crate::config::AppConfig; +use crate::core::permission_sync::PermissionSyncService; +use crate::core::state::Services; use crate::database::Database; use crate::http::server::HttpServer; use crate::metrics::{reporter, AppMetrics}; @@ -16,6 +19,7 @@ use uuid::Uuid; pub struct App { pub state: AppState, + pub services: Services, } impl App { @@ -31,7 +35,7 @@ impl App { let event_bus = Arc::new(EventBus::with_capacity(1024)); // Initialize shared repositories - let repositories = Repositories::new(db.clone(), event_bus.clone()); + let repositories = Arc::new(Repositories::new(db.clone(), event_bus.clone())); // Initialize gateway manager let gateway = Arc::new(GatewayManager::default()); @@ -66,6 +70,8 @@ impl App { let metrics = AppMetrics::new(); + let permission_sync = PermissionSyncService::new(repositories.clone(), event_bus.clone()); + let state = AppState { db, config: Arc::new(config), @@ -77,7 +83,11 @@ impl App { event_bus, }; - Ok(Self { state }) + let services = Services { + permission_sync: Arc::new(permission_sync), + }; + + Ok(Self { state, services }) } pub async fn run(self) -> Result<(), Box> { diff --git a/src/core/permission_sync.rs b/src/core/permission_sync.rs new file mode 100644 index 0000000..401fd0c --- /dev/null +++ b/src/core/permission_sync.rs @@ -0,0 +1,44 @@ +use crate::repositories::Repositories; +use event_bus::EventBus; +use std::sync::Arc; + +// list of all events : +// server_user_created +// server_user_deleted +// +// role_user_created +// role_user_deleted +// +// server_role_permission_created +// server_role_permission_updated +// server_role_permission_deleted +// +// server_user_permission_created +// server_user_permission_updated +// server_user_permission_deleted +// +// channel_role_permission_created +// channel_role_permission_updated +// channel_role_permission_deleted +// +// channel_user_permission_created +// channel_user_permission_updated +// channel_user_permission_deleted +// +// channel_created +// channel_deleted + +#[derive(Debug, Clone)] +pub struct PermissionSyncService { + repositories: Arc, + event_bus: Arc, +} + +impl PermissionSyncService { + pub fn new(repositories: Arc, event_bus: Arc) -> Self { + Self { + repositories, + event_bus, + } + } +} diff --git a/src/core/state.rs b/src/core/state.rs index 71d8e6f..0bb8086 100644 --- a/src/core/state.rs +++ b/src/core/state.rs @@ -1,4 +1,5 @@ use crate::config::AppConfig; +use crate::core::permission_sync::PermissionSyncService; use crate::metrics::AppMetrics; use crate::models::server; use crate::repositories::Repositories; @@ -11,7 +12,7 @@ use std::sync::{Arc, RwLock}; pub struct AppState { pub db: DatabaseConnection, pub config: Arc, - pub repositories: Repositories, + pub repositories: Arc, pub init_token: Arc>>, pub default_server: Arc, pub metrics: AppMetrics, @@ -20,3 +21,8 @@ pub struct AppState { } impl AppState {} + +#[derive(Debug, Clone)] +pub struct Services { + pub permission_sync: Arc, +} diff --git a/src/models/channel_role_permission.rs b/src/models/channel_role_permission.rs index ff95d27..4f85a33 100644 --- a/src/models/channel_role_permission.rs +++ b/src/models/channel_role_permission.rs @@ -17,7 +17,8 @@ pub struct Model { pub role_id: Uuid, /// Bitmask des permissions accordées au rôle dans ce canal. - pub permission: i64, + pub permissions: i64, + #[sea_orm( belongs_to, from = "channel_id", @@ -43,7 +44,7 @@ impl ActiveModelBehavior for ActiveModel { id: Set(Uuid::new_v4()), channel_id: NotSet, role_id: NotSet, - permission: Set(ChannelPermission::empty().bits() as i64), + permissions: Set(ChannelPermission::empty().bits() as i64), } } } diff --git a/src/models/channel_user_permission.rs b/src/models/channel_user_permission.rs index 6ad4e9b..591bd2c 100644 --- a/src/models/channel_user_permission.rs +++ b/src/models/channel_user_permission.rs @@ -17,7 +17,8 @@ pub struct Model { pub user_id: Uuid, /// Bitmask des permissions accordées directement à l'utilisateur dans ce canal. - pub permission: i64, + pub permissions: i64, + #[sea_orm( belongs_to, from = "channel_id", @@ -43,7 +44,7 @@ impl ActiveModelBehavior for ActiveModel { id: Set(Uuid::new_v4()), channel_id: NotSet, user_id: NotSet, - permission: Set(ChannelPermission::empty().bits() as i64), + permissions: Set(ChannelPermission::empty().bits() as i64), } } } diff --git a/src/models/computed_permission.rs b/src/models/computed_permission.rs index 82c5f6d..429eb63 100644 --- a/src/models/computed_permission.rs +++ b/src/models/computed_permission.rs @@ -37,9 +37,9 @@ pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub resource_id: Uuid, - /// Cache des permissions serveur (stocké en i64 pour SQL, utilisé en u64) - pub server_permissions: i64, - pub channel_permissions: i64, + /// Cache des permissions (stocké en i64 pour SQL, utilisé en u64) + pub permissions: i64, + #[sea_orm( belongs_to, from = "user_id", @@ -59,8 +59,7 @@ impl ActiveModelBehavior for ActiveModel { server_id: NotSet, scope_type: NotSet, resource_id: NotSet, - server_permissions: Set(0), - channel_permissions: Set(0), + permissions: Set(0), } } } diff --git a/src/models/server_role_permission.rs b/src/models/server_role_permission.rs index e6a436d..623dbd1 100644 --- a/src/models/server_role_permission.rs +++ b/src/models/server_role_permission.rs @@ -17,7 +17,8 @@ pub struct Model { pub role_id: Uuid, /// Bitmask des permissions accordées directement à l'utilisateur. - pub permission: i64, + pub permissions: i64, + #[sea_orm( belongs_to, from = "server_id", @@ -43,7 +44,7 @@ impl ActiveModelBehavior for ActiveModel { id: Set(Uuid::new_v4()), server_id: NotSet, role_id: NotSet, - permission: Set(ServerPermission::empty().bits() as i64), + permissions: Set(ServerPermission::empty().bits() as i64), } } } diff --git a/src/models/server_user_permission.rs b/src/models/server_user_permission.rs index fa19e51..7ed93c6 100644 --- a/src/models/server_user_permission.rs +++ b/src/models/server_user_permission.rs @@ -17,7 +17,7 @@ pub struct Model { pub user_id: Uuid, /// Bitmask des permissions accordées directement à l'utilisateur. - pub permission: i64, + pub permissions: i64, #[sea_orm( belongs_to, from = "server_id", @@ -43,7 +43,7 @@ impl ActiveModelBehavior for ActiveModel { id: Set(Uuid::new_v4()), server_id: NotSet, user_id: NotSet, - permission: Set(ServerPermission::empty().bits() as i64), + permissions: Set(ServerPermission::empty().bits() as i64), } } } diff --git a/src/repositories/computed_permission.rs b/src/repositories/computed_permission.rs index c47cdac..b5e9c9a 100644 --- a/src/repositories/computed_permission.rs +++ b/src/repositories/computed_permission.rs @@ -1,6 +1,6 @@ use crate::models::{ channel, channel_role_permission, channel_user_permission, computed_permission, role_user, - server_role_permission, server_user, + server_role_permission, server_user, server_user_permission, }; use crate::permissions::{ChannelPermission, ServerPermission}; use crate::repositories::{AnyResult, RepositoryContext}; @@ -46,6 +46,7 @@ impl ComputedPermissionRepository { /// Les permissions effectives sont composées de : /// /// - permissions serveur accordées aux rôles de l'utilisateur ; + /// - permissions serveur accordées directement à l'utilisateur ; /// - permissions de canal accordées aux rôles de l'utilisateur ; /// - permissions directes de l'utilisateur dans les canaux. pub async fn full_sync_user(&self, user_id: Uuid, server_id: Uuid) -> AnyResult<()> { @@ -76,10 +77,23 @@ impl ComputedPermissionRepository { for permission in role_permissions { server_permissions |= - ServerPermission::from_bits_retain(permission.permission as u64); + ServerPermission::from_bits_retain(permission.permissions as u64); } } + // --------------------------------------------------------------------- + // Permissions serveur directes de l'utilisateur + // --------------------------------------------------------------------- + + if let Some(permission) = server_user_permission::Entity::find() + .filter(server_user_permission::Column::ServerId.eq(server_id)) + .filter(server_user_permission::Column::UserId.eq(user_id)) + .one(&self.context.db) + .await? + { + server_permissions |= ServerPermission::from_bits_retain(permission.permissions as u64); + } + // --------------------------------------------------------------------- // Canaux du serveur // --------------------------------------------------------------------- @@ -112,7 +126,7 @@ impl ComputedPermissionRepository { .entry(permission.channel_id) .or_default() .insert(ChannelPermission::from_bits_retain( - permission.permission as u64, + permission.permissions as u64, )); } @@ -135,7 +149,7 @@ impl ComputedPermissionRepository { .entry(permission.channel_id) .or_default() .insert(ChannelPermission::from_bits_retain( - permission.permission as u64, + permission.permissions as u64, )); } @@ -151,7 +165,7 @@ impl ComputedPermissionRepository { server_id: Set(server_id), scope_type: Set(PermissionScopeType::Server), resource_id: Set(server_id), - server_permissions: Set(server_permissions.bits() as i64), + permissions: Set(server_permissions.bits() as i64), ..Default::default() }); @@ -166,7 +180,7 @@ impl ComputedPermissionRepository { server_id: Set(server_id), scope_type: Set(PermissionScopeType::Channel), resource_id: Set(channel.id), - channel_permissions: Set(channel_permissions.bits() as i64), + permissions: Set(channel_permissions.bits() as i64), ..Default::default() }); }