feat: port el-ui vessels — rename crates→vessels, add El source + manifests
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
//! Role and permission model.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// A fine-grained permission (e.g., "read", "write", "delete").
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Permission(pub String);
|
||||
|
||||
impl Permission {
|
||||
pub fn new(name: impl Into<String>) -> Self {
|
||||
Self(name.into())
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Permission {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// A role that grants a set of permissions.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Role {
|
||||
pub name: String,
|
||||
pub permissions: Vec<Permission>,
|
||||
}
|
||||
|
||||
impl Role {
|
||||
pub fn new(name: impl Into<String>) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
permissions: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_permission(mut self, perm: impl Into<String>) -> Self {
|
||||
self.permissions.push(Permission::new(perm));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_permissions(mut self, perms: Vec<impl Into<String>>) -> Self {
|
||||
self.permissions.extend(perms.into_iter().map(Permission::new));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn has_permission(&self, perm: &str) -> bool {
|
||||
self.permissions.iter().any(|p| p.0 == perm)
|
||||
}
|
||||
}
|
||||
|
||||
/// The registry of all roles in the application.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct RoleRegistry {
|
||||
roles: HashMap<String, Role>,
|
||||
}
|
||||
|
||||
impl RoleRegistry {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Register a role.
|
||||
pub fn register(&mut self, role: Role) {
|
||||
self.roles.insert(role.name.clone(), role);
|
||||
}
|
||||
|
||||
/// Get a role by name.
|
||||
pub fn get(&self, name: &str) -> Option<&Role> {
|
||||
self.roles.get(name)
|
||||
}
|
||||
|
||||
/// Check if the given role names grant the given permission.
|
||||
pub fn has_permission(&self, role_names: &[String], permission: &str) -> bool {
|
||||
role_names.iter().any(|role_name| {
|
||||
self.roles
|
||||
.get(role_name)
|
||||
.map(|r| r.has_permission(permission))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
/// List all registered role names.
|
||||
pub fn role_names(&self) -> Vec<&str> {
|
||||
self.roles.keys().map(|s| s.as_str()).collect()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user