veza/veza-chat-server/src/permissions.rs

219 lines
6.4 KiB
Rust

use crate::error::{ChatError, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
/// Rôles disponibles dans le système de chat
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Role {
/// Utilisateur standard
User,
/// Modérateur avec permissions étendues
Moderator,
/// Administrateur avec tous les pouvoirs
Admin,
/// Super administrateur
SuperAdmin,
}
/// Permissions granulaires dans le système
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Permission {
// Messages
SendMessage,
EditMessage,
DeleteMessage,
PinMessage,
// Modération
ModerateMessages,
BanUsers,
KickUsers,
MuteUsers,
// Administration
ManageRoles,
ManageChannels,
ManageServer,
ViewAuditLog,
// Avancé
ManageWebhooks,
BypassRateLimit,
}
impl Role {
/// Retourne les permissions par défaut pour un rôle
pub fn default_permissions(&self) -> HashSet<Permission> {
match self {
Role::User => [Permission::SendMessage, Permission::EditMessage]
.into_iter()
.collect(),
Role::Moderator => [
Permission::SendMessage,
Permission::EditMessage,
Permission::DeleteMessage,
Permission::PinMessage,
Permission::ModerateMessages,
Permission::KickUsers,
Permission::MuteUsers,
]
.into_iter()
.collect(),
Role::Admin => [
Permission::SendMessage,
Permission::EditMessage,
Permission::DeleteMessage,
Permission::PinMessage,
Permission::ModerateMessages,
Permission::BanUsers,
Permission::KickUsers,
Permission::MuteUsers,
Permission::ManageRoles,
Permission::ManageChannels,
Permission::ViewAuditLog,
]
.into_iter()
.collect(),
Role::SuperAdmin => {
// Toutes les permissions
[
Permission::SendMessage,
Permission::EditMessage,
Permission::DeleteMessage,
Permission::PinMessage,
Permission::ModerateMessages,
Permission::BanUsers,
Permission::KickUsers,
Permission::MuteUsers,
Permission::ManageRoles,
Permission::ManageChannels,
Permission::ManageServer,
Permission::ViewAuditLog,
Permission::ManageWebhooks,
Permission::BypassRateLimit,
]
.into_iter()
.collect()
}
}
}
pub fn get_permissions(&self) -> Vec<Permission> {
self.default_permissions().into_iter().collect()
}
pub fn has_permission(&self, permission: &Permission) -> bool {
self.default_permissions().contains(permission)
}
pub fn from_string(role_str: &str) -> Result<Self> {
match role_str.to_lowercase().as_str() {
"admin" => Ok(Role::Admin),
"moderator" | "mod" => Ok(Role::Moderator),
"user" => Ok(Role::User),
"superadmin" => Ok(Role::SuperAdmin),
_ => Err(ChatError::configuration_error(&format!(
"Rôle invalide: {}",
role_str
))),
}
}
}
/// Structure représentant les permissions d'un utilisateur
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserPermissions {
pub user_id: i64,
pub roles: HashSet<Role>,
pub custom_permissions: HashSet<Permission>,
}
impl UserPermissions {
/// Crée une nouvelle instance avec des permissions utilisateur de base
pub fn new_user(user_id: i64) -> Self {
Self {
user_id,
roles: [Role::User].into_iter().collect(),
custom_permissions: HashSet::new(),
}
}
/// Vérifie si l'utilisateur possède une permission spécifique
pub fn has_permission(&self, permission: &Permission) -> bool {
// Vérifier les permissions custom
if self.custom_permissions.contains(permission) {
return true;
}
// Vérifier les permissions des rôles
self.roles
.iter()
.any(|role| role.default_permissions().contains(permission))
}
/// Ajoute un rôle à l'utilisateur
pub fn add_role(&mut self, role: Role) {
self.roles.insert(role);
}
/// Retire un rôle de l'utilisateur
pub fn remove_role(&mut self, role: &Role) {
self.roles.remove(role);
}
/// Ajoute une permission custom
pub fn grant_permission(&mut self, permission: Permission) {
self.custom_permissions.insert(permission);
}
/// Retire une permission custom
pub fn revoke_permission(&mut self, permission: &Permission) {
self.custom_permissions.remove(permission);
}
}
/// Fonction utilitaire pour vérifier les permissions
pub fn check_permission(
user_permissions: &UserPermissions,
required_permission: &Permission,
) -> bool {
user_permissions.has_permission(required_permission)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_user_permissions() {
let mut perms = UserPermissions::new_user(123);
// Utilisateur de base peut envoyer des messages
assert!(perms.has_permission(&Permission::SendMessage));
// Mais ne peut pas bannir
assert!(!perms.has_permission(&Permission::BanUsers));
// Ajouter le rôle modérateur
perms.add_role(Role::Moderator);
assert!(perms.has_permission(&Permission::KickUsers));
// Ajouter permission custom
perms.grant_permission(Permission::ManageServer);
assert!(perms.has_permission(&Permission::ManageServer));
}
#[test]
fn test_role_permissions() {
let admin_perms = Role::Admin.default_permissions();
assert!(admin_perms.contains(&Permission::ManageRoles));
assert!(admin_perms.contains(&Permission::BanUsers));
let user_perms = Role::User.default_permissions();
assert!(!user_perms.contains(&Permission::BanUsers));
assert!(user_perms.contains(&Permission::SendMessage));
}
}