This commit is contained in:
2026-07-13 16:16:00 +02:00
parent 843dad8d79
commit dc2be94a8d
10 changed files with 102 additions and 38 deletions
+4 -16
View File
@@ -490,7 +490,7 @@ impl MigrationTrait for Migration {
.col(ColumnDef::new(Alias::new("server_id")).uuid().not_null()) .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("role_id")).uuid().not_null())
.col( .col(
ColumnDef::new(Alias::new("permission")) ColumnDef::new(Alias::new("permissions"))
.big_integer() .big_integer()
.not_null() .not_null()
.default(0), .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("channel_id")).uuid().not_null())
.col(ColumnDef::new(Alias::new("role_id")).uuid().not_null()) .col(ColumnDef::new(Alias::new("role_id")).uuid().not_null())
.col( .col(
ColumnDef::new(Alias::new("permission")) ColumnDef::new(Alias::new("permissions"))
.big_integer() .big_integer()
.not_null() .not_null()
.default(0), .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("channel_id")).uuid().not_null())
.col(ColumnDef::new(Alias::new("user_id")).uuid().not_null()) .col(ColumnDef::new(Alias::new("user_id")).uuid().not_null())
.col( .col(
ColumnDef::new(Alias::new("permission")) ColumnDef::new(Alias::new("permissions"))
.big_integer() .big_integer()
.not_null() .not_null()
.default(0), .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("resource_id")).uuid().not_null())
.col( .col(
ColumnDef::new(Alias::new("server_permissions")) ColumnDef::new(Alias::new("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"))
.big_integer() .big_integer()
.not_null() .not_null()
.default(0), .default(0),
+12 -2
View File
@@ -1,6 +1,9 @@
mod permission_sync;
pub mod state; pub mod state;
use crate::config::AppConfig; use crate::config::AppConfig;
use crate::core::permission_sync::PermissionSyncService;
use crate::core::state::Services;
use crate::database::Database; use crate::database::Database;
use crate::http::server::HttpServer; use crate::http::server::HttpServer;
use crate::metrics::{reporter, AppMetrics}; use crate::metrics::{reporter, AppMetrics};
@@ -16,6 +19,7 @@ use uuid::Uuid;
pub struct App { pub struct App {
pub state: AppState, pub state: AppState,
pub services: Services,
} }
impl App { impl App {
@@ -31,7 +35,7 @@ impl App {
let event_bus = Arc::new(EventBus::with_capacity(1024)); let event_bus = Arc::new(EventBus::with_capacity(1024));
// Initialize shared repositories // 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 // Initialize gateway manager
let gateway = Arc::new(GatewayManager::default()); let gateway = Arc::new(GatewayManager::default());
@@ -66,6 +70,8 @@ impl App {
let metrics = AppMetrics::new(); let metrics = AppMetrics::new();
let permission_sync = PermissionSyncService::new(repositories.clone(), event_bus.clone());
let state = AppState { let state = AppState {
db, db,
config: Arc::new(config), config: Arc::new(config),
@@ -77,7 +83,11 @@ impl App {
event_bus, 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<dyn std::error::Error>> { pub async fn run(self) -> Result<(), Box<dyn std::error::Error>> {
+44
View File
@@ -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<Repositories>,
event_bus: Arc<EventBus>,
}
impl PermissionSyncService {
pub fn new(repositories: Arc<Repositories>, event_bus: Arc<EventBus>) -> Self {
Self {
repositories,
event_bus,
}
}
}
+7 -1
View File
@@ -1,4 +1,5 @@
use crate::config::AppConfig; use crate::config::AppConfig;
use crate::core::permission_sync::PermissionSyncService;
use crate::metrics::AppMetrics; use crate::metrics::AppMetrics;
use crate::models::server; use crate::models::server;
use crate::repositories::Repositories; use crate::repositories::Repositories;
@@ -11,7 +12,7 @@ use std::sync::{Arc, RwLock};
pub struct AppState { pub struct AppState {
pub db: DatabaseConnection, pub db: DatabaseConnection,
pub config: Arc<AppConfig>, pub config: Arc<AppConfig>,
pub repositories: Repositories, pub repositories: Arc<Repositories>,
pub init_token: Arc<RwLock<Option<uuid::Uuid>>>, pub init_token: Arc<RwLock<Option<uuid::Uuid>>>,
pub default_server: Arc<server::Model>, pub default_server: Arc<server::Model>,
pub metrics: AppMetrics, pub metrics: AppMetrics,
@@ -20,3 +21,8 @@ pub struct AppState {
} }
impl AppState {} impl AppState {}
#[derive(Debug, Clone)]
pub struct Services {
pub permission_sync: Arc<PermissionSyncService>,
}
+3 -2
View File
@@ -17,7 +17,8 @@ pub struct Model {
pub role_id: Uuid, pub role_id: Uuid,
/// Bitmask des permissions accordées au rôle dans ce canal. /// Bitmask des permissions accordées au rôle dans ce canal.
pub permission: i64, pub permissions: i64,
#[sea_orm( #[sea_orm(
belongs_to, belongs_to,
from = "channel_id", from = "channel_id",
@@ -43,7 +44,7 @@ impl ActiveModelBehavior for ActiveModel {
id: Set(Uuid::new_v4()), id: Set(Uuid::new_v4()),
channel_id: NotSet, channel_id: NotSet,
role_id: NotSet, role_id: NotSet,
permission: Set(ChannelPermission::empty().bits() as i64), permissions: Set(ChannelPermission::empty().bits() as i64),
} }
} }
} }
+3 -2
View File
@@ -17,7 +17,8 @@ pub struct Model {
pub user_id: Uuid, pub user_id: Uuid,
/// Bitmask des permissions accordées directement à l'utilisateur dans ce canal. /// Bitmask des permissions accordées directement à l'utilisateur dans ce canal.
pub permission: i64, pub permissions: i64,
#[sea_orm( #[sea_orm(
belongs_to, belongs_to,
from = "channel_id", from = "channel_id",
@@ -43,7 +44,7 @@ impl ActiveModelBehavior for ActiveModel {
id: Set(Uuid::new_v4()), id: Set(Uuid::new_v4()),
channel_id: NotSet, channel_id: NotSet,
user_id: NotSet, user_id: NotSet,
permission: Set(ChannelPermission::empty().bits() as i64), permissions: Set(ChannelPermission::empty().bits() as i64),
} }
} }
} }
+4 -5
View File
@@ -37,9 +37,9 @@ pub struct Model {
#[sea_orm(primary_key, auto_increment = false)] #[sea_orm(primary_key, auto_increment = false)]
pub resource_id: Uuid, pub resource_id: Uuid,
/// Cache des permissions serveur (stocké en i64 pour SQL, utilisé en u64) /// Cache des permissions (stocké en i64 pour SQL, utilisé en u64)
pub server_permissions: i64, pub permissions: i64,
pub channel_permissions: i64,
#[sea_orm( #[sea_orm(
belongs_to, belongs_to,
from = "user_id", from = "user_id",
@@ -59,8 +59,7 @@ impl ActiveModelBehavior for ActiveModel {
server_id: NotSet, server_id: NotSet,
scope_type: NotSet, scope_type: NotSet,
resource_id: NotSet, resource_id: NotSet,
server_permissions: Set(0), permissions: Set(0),
channel_permissions: Set(0),
} }
} }
} }
+3 -2
View File
@@ -17,7 +17,8 @@ pub struct Model {
pub role_id: Uuid, pub role_id: Uuid,
/// Bitmask des permissions accordées directement à l'utilisateur. /// Bitmask des permissions accordées directement à l'utilisateur.
pub permission: i64, pub permissions: i64,
#[sea_orm( #[sea_orm(
belongs_to, belongs_to,
from = "server_id", from = "server_id",
@@ -43,7 +44,7 @@ impl ActiveModelBehavior for ActiveModel {
id: Set(Uuid::new_v4()), id: Set(Uuid::new_v4()),
server_id: NotSet, server_id: NotSet,
role_id: NotSet, role_id: NotSet,
permission: Set(ServerPermission::empty().bits() as i64), permissions: Set(ServerPermission::empty().bits() as i64),
} }
} }
} }
+2 -2
View File
@@ -17,7 +17,7 @@ pub struct Model {
pub user_id: Uuid, pub user_id: Uuid,
/// Bitmask des permissions accordées directement à l'utilisateur. /// Bitmask des permissions accordées directement à l'utilisateur.
pub permission: i64, pub permissions: i64,
#[sea_orm( #[sea_orm(
belongs_to, belongs_to,
from = "server_id", from = "server_id",
@@ -43,7 +43,7 @@ impl ActiveModelBehavior for ActiveModel {
id: Set(Uuid::new_v4()), id: Set(Uuid::new_v4()),
server_id: NotSet, server_id: NotSet,
user_id: NotSet, user_id: NotSet,
permission: Set(ServerPermission::empty().bits() as i64), permissions: Set(ServerPermission::empty().bits() as i64),
} }
} }
} }
+20 -6
View File
@@ -1,6 +1,6 @@
use crate::models::{ use crate::models::{
channel, channel_role_permission, channel_user_permission, computed_permission, role_user, 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::permissions::{ChannelPermission, ServerPermission};
use crate::repositories::{AnyResult, RepositoryContext}; use crate::repositories::{AnyResult, RepositoryContext};
@@ -46,6 +46,7 @@ impl ComputedPermissionRepository {
/// Les permissions effectives sont composées de : /// Les permissions effectives sont composées de :
/// ///
/// - permissions serveur accordées aux rôles de l'utilisateur ; /// - 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 de canal accordées aux rôles de l'utilisateur ;
/// - permissions directes de l'utilisateur dans les canaux. /// - permissions directes de l'utilisateur dans les canaux.
pub async fn full_sync_user(&self, user_id: Uuid, server_id: Uuid) -> AnyResult<()> { 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 { for permission in role_permissions {
server_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 // Canaux du serveur
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@@ -112,7 +126,7 @@ impl ComputedPermissionRepository {
.entry(permission.channel_id) .entry(permission.channel_id)
.or_default() .or_default()
.insert(ChannelPermission::from_bits_retain( .insert(ChannelPermission::from_bits_retain(
permission.permission as u64, permission.permissions as u64,
)); ));
} }
@@ -135,7 +149,7 @@ impl ComputedPermissionRepository {
.entry(permission.channel_id) .entry(permission.channel_id)
.or_default() .or_default()
.insert(ChannelPermission::from_bits_retain( .insert(ChannelPermission::from_bits_retain(
permission.permission as u64, permission.permissions as u64,
)); ));
} }
@@ -151,7 +165,7 @@ impl ComputedPermissionRepository {
server_id: Set(server_id), server_id: Set(server_id),
scope_type: Set(PermissionScopeType::Server), scope_type: Set(PermissionScopeType::Server),
resource_id: Set(server_id), resource_id: Set(server_id),
server_permissions: Set(server_permissions.bits() as i64), permissions: Set(server_permissions.bits() as i64),
..Default::default() ..Default::default()
}); });
@@ -166,7 +180,7 @@ impl ComputedPermissionRepository {
server_id: Set(server_id), server_id: Set(server_id),
scope_type: Set(PermissionScopeType::Channel), scope_type: Set(PermissionScopeType::Channel),
resource_id: Set(channel.id), resource_id: Set(channel.id),
channel_permissions: Set(channel_permissions.bits() as i64), permissions: Set(channel_permissions.bits() as i64),
..Default::default() ..Default::default()
}); });
} }