mod permission;
mod policy;
mod role;
pub use permission::{Action, Permission, PermissionSet, Resource};
pub use policy::{
Decision, DecisionReason, Policy, PolicyBuilder, PolicyEffect, PolicyEngine, PolicyEvaluator,
Subject,
};
pub use role::{InMemoryRoleStore, Role, RoleBuilder, RoleManager, RoleStore};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_rbac_workflow() {
let read_posts = Permission::new("posts", "read");
let write_posts = Permission::new("posts", "write");
let delete_posts = Permission::new("posts", "delete");
let editor = RoleBuilder::new("editor")
.description("Content editor")
.permission(read_posts.clone())
.permission(write_posts.clone())
.build();
assert!(editor.has_permission(&read_posts));
assert!(editor.has_permission(&write_posts));
assert!(!editor.has_permission(&delete_posts));
}
#[test]
fn test_policy_engine_workflow() {
let mut engine = PolicyEngine::new();
engine.add_policy(
Policy::allow("editor-posts-read")
.role("editor")
.resource("posts")
.action("read")
.build(),
);
engine.add_policy(
Policy::deny("no-delete")
.resource("posts")
.action("delete")
.priority(100)
.build(),
);
let user = Subject::new("user1").with_role("editor");
let decision = engine.evaluate(&user, &Resource::new("posts"), &Action::new("read"));
assert!(decision.is_allowed());
let decision = engine.evaluate(&user, &Resource::new("posts"), &Action::new("delete"));
assert!(decision.is_denied());
let decision = engine.evaluate(&user, &Resource::new("users"), &Action::new("read"));
assert!(decision.is_denied());
}
#[tokio::test]
async fn test_role_inheritance() {
let manager = RoleManager::new();
let viewer = RoleBuilder::new("viewer")
.permission(Permission::new("posts", "read"))
.build();
let editor = RoleBuilder::new("editor")
.inherit("viewer")
.permission(Permission::new("posts", "write"))
.build();
manager.add_role(viewer).await;
manager.add_role(editor).await;
let effective = manager.get_effective_permissions("editor").await;
assert!(effective.contains(&Permission::new("posts", "read")));
assert!(effective.contains(&Permission::new("posts", "write")));
}
#[test]
fn test_wildcard_permissions() {
let super_admin = RoleBuilder::new("super_admin")
.permission(Permission::wildcard())
.build();
let posts_admin = RoleBuilder::new("posts_admin")
.permission(Permission::resource_wildcard("posts"))
.build();
let read_posts = Permission::new("posts", "read");
let delete_posts = Permission::new("posts", "delete");
let read_users = Permission::new("users", "read");
assert!(super_admin.has_permission(&read_posts));
assert!(super_admin.has_permission(&delete_posts));
assert!(super_admin.has_permission(&read_users));
assert!(posts_admin.has_permission(&read_posts));
assert!(posts_admin.has_permission(&delete_posts));
assert!(!posts_admin.has_permission(&read_users));
}
}