This commit is contained in:
2026-07-11 11:21:09 +02:00
parent 75bc9d2440
commit 825db3a292
9 changed files with 207 additions and 94 deletions
+98 -64
View File
@@ -27,30 +27,13 @@ impl MigrationTrait for Migration {
.not_null() .not_null()
.default(Expr::current_timestamp()), .default(Expr::current_timestamp()),
) )
.col(
ColumnDef::new(Alias::new("default_server_permissions"))
.big_integer()
.not_null()
.default(0),
)
.col(
ColumnDef::new(Alias::new("default_channel_permissions"))
.big_integer()
.not_null()
.default(0),
)
.col(
ColumnDef::new(Alias::new("default_voice_permissions"))
.big_integer()
.not_null()
.default(0),
)
.col( .col(
ColumnDef::new(Alias::new("is_default")) ColumnDef::new(Alias::new("is_default"))
.boolean() .boolean()
.not_null() .not_null()
.default(false), .default(false),
) )
.col(ColumnDef::new(Alias::new("owner_id")).uuid().not_null())
.to_owned(), .to_owned(),
) )
.await?; .await?;
@@ -125,16 +108,6 @@ impl MigrationTrait for Migration {
.integer() .integer()
.not_null(), .not_null(),
) )
.col(
ColumnDef::new(Alias::new("default_channel_permissions"))
.big_integer()
.null(),
)
.col(
ColumnDef::new(Alias::new("default_voice_permissions"))
.big_integer()
.null(),
)
.col(ColumnDef::new(Alias::new("name")).string().null()) .col(ColumnDef::new(Alias::new("name")).string().null())
.col( .col(
ColumnDef::new(Alias::new("created_at")) ColumnDef::new(Alias::new("created_at"))
@@ -327,36 +300,6 @@ impl MigrationTrait for Migration {
.not_null() .not_null()
.default(Expr::current_timestamp()), .default(Expr::current_timestamp()),
) )
.col(
ColumnDef::new(Alias::new("is_admin"))
.boolean()
.not_null()
.default(false),
)
.col(
ColumnDef::new(Alias::new("is_owner"))
.boolean()
.not_null()
.default(false),
)
.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"))
.big_integer()
.not_null()
.default(0),
)
// Indexes créés après // Indexes créés après
.foreign_key( .foreign_key(
ForeignKey::create() ForeignKey::create()
@@ -390,12 +333,6 @@ 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(
ColumnDef::new(Alias::new("role"))
.string()
.not_null()
.default("member".to_owned()),
)
.col( .col(
ColumnDef::new(Alias::new("joined_at")) ColumnDef::new(Alias::new("joined_at"))
.timestamp_with_time_zone() .timestamp_with_time_zone()
@@ -636,6 +573,8 @@ impl MigrationTrait for Migration {
.if_not_exists() .if_not_exists()
.col(ColumnDef::new("group_id").uuid().not_null()) .col(ColumnDef::new("group_id").uuid().not_null())
.col(ColumnDef::new("user_id").uuid().not_null()) .col(ColumnDef::new("user_id").uuid().not_null())
.col(ColumnDef::new("scope_type").integer().not_null())
.col(ColumnDef::new("scope_id").uuid().not_null())
.primary_key( .primary_key(
Index::create() Index::create()
.col(Alias::new("group_id")) .col(Alias::new("group_id"))
@@ -681,6 +620,101 @@ impl MigrationTrait for Migration {
) )
.await?; .await?;
// Create table `user_permission`
manager
.create_table(
Table::create()
.table(Alias::new("user_permission"))
.if_not_exists()
.col(ColumnDef::new("id").uuid().primary_key().not_null())
.col(ColumnDef::new("user_id").uuid().not_null())
.col(ColumnDef::new("server_id").uuid().not_null())
.col(ColumnDef::new("scope_type").integer().not_null())
.col(ColumnDef::new("scope_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"))
.big_integer()
.not_null()
.default(0),
)
.col(
ColumnDef::new("created_at")
.timestamp_with_time_zone()
.not_null()
.default(Expr::current_timestamp()),
)
.foreign_key(
ForeignKey::create()
.name("fk_user_permission_user")
.from(Alias::new("user_permission"), Alias::new("user_id"))
.to(Alias::new("user"), Alias::new("id"))
.on_delete(ForeignKeyAction::Cascade),
)
.foreign_key(
ForeignKey::create()
.name("fk_user_permission_server")
.from(Alias::new("user_permission"), Alias::new("server_id"))
.to(Alias::new("server"), Alias::new("id"))
.on_delete(ForeignKeyAction::Cascade),
)
.to_owned(),
)
.await?;
// Create CACHE table `computed_permission`
manager
.create_table(
Table::create()
.table(Alias::new("computed_permission"))
.if_not_exists()
.col(ColumnDef::new("user_id").uuid().not_null())
.col(ColumnDef::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"))
.big_integer()
.not_null()
.default(0),
)
.primary_key(
Index::create()
.col(Alias::new("user_id"))
.col(Alias::new("resource_id")),
)
.foreign_key(
ForeignKey::create()
.name("fk_computed_permission_user")
.from(Alias::new("computed_permission"), Alias::new("user_id"))
.to(Alias::new("user"), Alias::new("id"))
.on_delete(ForeignKeyAction::Cascade),
)
.to_owned(),
)
.await?;
Ok(()) Ok(())
} }
-2
View File
@@ -32,8 +32,6 @@ pub struct Model {
pub name: Option<String>, pub name: Option<String>,
pub created_at: DateTimeUtc, pub created_at: DateTimeUtc,
pub updated_at: DateTimeUtc, pub updated_at: DateTimeUtc,
pub default_channel_permissions: Option<i64>,
pub default_voice_permissions: Option<i64>,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
-1
View File
@@ -12,7 +12,6 @@ pub struct Model {
pub channel_id: Uuid, pub channel_id: Uuid,
pub user_id: Uuid, pub user_id: Uuid,
pub role: String, pub role: String,
pub permissions: u64,
pub joined_at: DateTimeUtc, pub joined_at: DateTimeUtc,
} }
+38
View File
@@ -0,0 +1,38 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "computed_permission")]
pub struct Model {
/// L'utilisateur à qui appartiennent ces permissions
#[sea_orm(primary_key, auto_increment = false)]
pub user_id: Uuid,
/// L'ID de la ressource (soit un Uuid de Channel, soit l'Uuid du Server)
#[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,
pub voice_permissions: i64,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
+17
View File
@@ -1,6 +1,21 @@
//! `SeaORM` Entity. //! `SeaORM` Entity.
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(
Debug, Clone, Copy, PartialEq, Eq, EnumIter, DeriveActiveEnum, Serialize, Deserialize, ToSchema,
)]
#[sea_orm(rs_type = "i32", db_type = "Integer")]
pub enum PermissionScopeType {
#[sea_orm(num_value = 0)]
Server,
#[sea_orm(num_value = 1)]
Category,
#[sea_orm(num_value = 2)]
Channel,
}
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "group_member")] #[sea_orm(table_name = "group_member")]
@@ -9,6 +24,8 @@ pub struct Model {
pub group_id: Uuid, pub group_id: Uuid,
#[sea_orm(primary_key, auto_increment = false)] #[sea_orm(primary_key, auto_increment = false)]
pub user_id: Uuid, pub user_id: Uuid,
pub scope_type: PermissionScopeType,
pub scope_id: Uuid,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
+2
View File
@@ -6,9 +6,11 @@ pub mod attachment;
pub mod category; pub mod category;
pub mod channel; pub mod channel;
pub mod channel_user; pub mod channel_user;
mod computed_permission;
pub mod group; pub mod group;
pub mod group_member; pub mod group_member;
pub mod message; pub mod message;
pub mod server; pub mod server;
pub mod server_user; pub mod server_user;
pub mod user; pub mod user;
mod user_permission;
+1 -20
View File
@@ -1,6 +1,5 @@
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 //! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19
use crate::permissions::{ChannelPermission, PermissionSet, ServerPermission, VoicePermission};
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use sea_orm::prelude::async_trait::async_trait; use sea_orm::prelude::async_trait::async_trait;
use sea_orm::Set; use sea_orm::Set;
@@ -15,11 +14,7 @@ pub struct Model {
pub created_at: DateTimeUtc, pub created_at: DateTimeUtc,
pub updated_at: DateTimeUtc, pub updated_at: DateTimeUtc,
pub is_default: bool, pub is_default: bool,
pub owned_id: Uuid,
/// Permissions serveur par défaut (stockées en i64, lues en u64)
pub default_server_permissions: i64,
pub default_channel_permissions: i64,
pub default_voice_permissions: i64,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
@@ -53,24 +48,10 @@ impl Related<super::server_user::Entity> for Entity {
#[async_trait] #[async_trait]
impl ActiveModelBehavior for ActiveModel { impl ActiveModelBehavior for ActiveModel {
fn new() -> Self { fn new() -> Self {
let default_perm = PermissionSet::DEFAULT;
Self { Self {
id: Set(Uuid::new_v4()), id: Set(Uuid::new_v4()),
is_default: Set(false), is_default: Set(false),
default_server_permissions: Set(default_perm.server.bits() as i64),
default_channel_permissions: Set(default_perm.channel.bits() as i64),
default_voice_permissions: Set(default_perm.voice.bits() as i64),
..ActiveModelTrait::default() ..ActiveModelTrait::default()
} }
} }
} }
impl Model {
pub fn default_permissions(&self) -> PermissionSet {
PermissionSet {
server: ServerPermission::from_bits_truncate(self.default_server_permissions as u64),
channel: ChannelPermission::from_bits_truncate(self.default_channel_permissions as u64),
voice: VoicePermission::from_bits_truncate(self.default_voice_permissions as u64),
}
}
}
-7
View File
@@ -14,13 +14,6 @@ pub struct Model {
pub username: Option<String>, pub username: Option<String>,
pub joined_at: DateTimeUtc, pub joined_at: DateTimeUtc,
pub updated_at: DateTimeUtc, pub updated_at: DateTimeUtc,
pub is_admin: bool,
pub is_owner: bool,
/// Permissions serveur par défaut (stockées en i64, lues en u64)
pub server_permissions: i64,
pub channel_permissions: i64,
pub voice_permissions: i64,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
+51
View File
@@ -0,0 +1,51 @@
use super::group_member::PermissionScopeType;
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "user_permission")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
pub user_id: Uuid,
pub server_id: Uuid,
pub scope_type: PermissionScopeType,
pub scope_id: Uuid,
pub server_permissions: i64,
pub channel_permissions: i64,
pub voice_permissions: i64,
pub created_at: DateTimeUtc,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
#[sea_orm(
belongs_to = "super::server::Entity",
from = "Column::ServerId",
to = "super::server::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Server,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::server::Entity> for Entity {
fn to() -> RelationDef {
Relation::Server.def()
}
}
impl ActiveModelBehavior for ActiveModel {}