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("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),
+12 -2
View File
@@ -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<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::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<AppConfig>,
pub repositories: Repositories,
pub repositories: Arc<Repositories>,
pub init_token: Arc<RwLock<Option<uuid::Uuid>>>,
pub default_server: Arc<server::Model>,
pub metrics: AppMetrics,
@@ -20,3 +21,8 @@ pub struct 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,
/// 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),
}
}
}
+3 -2
View File
@@ -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),
}
}
}
+4 -5
View File
@@ -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),
}
}
}
+3 -2
View File
@@ -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),
}
}
}
+2 -2
View File
@@ -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),
}
}
}
+20 -6
View File
@@ -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()
});
}