rust-rbac 0.1.0

A flexible Role-Based Access Control (RBAC) system for Rust applications
Documentation
//! A flexible Role-Based Access Control (RBAC) system for Rust applications.
//!
//! This crate provides a trait-based approach to implementing RBAC in Rust applications,
//! with support for various storage backends and web frameworks.
//!
//! # Features
//!
//! - Role-based permissions
//! - Direct permissions to users
//! - Multiple roles per user
//! - Multiple permissions per role
//! - Permission inheritance through roles
//! - Flexible storage backends
//!
//! # Example
//!
//! ```rust
//! use rust_rbac::{RbacService, MemoryStorage, Permission, Role};
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//!     // Create a new RBAC service with in-memory storage
//!     let storage = MemoryStorage::new();
//!     let rbac = RbacService::new(storage);
//!
//!     // Create permissions
//!     let create_post = Permission::new("create-post");
//!     let edit_post = Permission::new("edit-post");
//!     let delete_post = Permission::new("delete-post");
//!
//!     rbac.create_permission(&create_post).await?;
//!     rbac.create_permission(&edit_post).await?;
//!     rbac.create_permission(&delete_post).await?;
//!
//!     // Create roles
//!     let author = Role::new("author");
//!     let editor = Role::new("editor");
//!     let admin = Role::new("admin");
//!
//!     rbac.create_role(&author).await?;
//!     rbac.create_role(&editor).await?;
//!     rbac.create_role(&admin).await?;
//!
//!     // Assign permissions to roles
//!     rbac.assign_permission_to_role("create-post", "author").await?;
//!     rbac.assign_permission_to_role("edit-post", "editor").await?;
//!     rbac.assign_permission_to_role("delete-post", "admin").await?;
//!
//!     // Assign roles to users
//!     let user_id = "user123";
//!     rbac.assign_role_to_subject("author", user_id).await?;
//!
//!     // Check permissions
//!     assert!(rbac.subject_has_permission(user_id, "create-post").await?);
//!     assert!(!rbac.subject_has_permission(user_id, "delete-post").await?);
//!
//!     Ok(())
//! }
//! ```

pub mod error;
pub mod models;
pub mod storage;
pub mod cache;
pub mod middleware;

pub use models::permission::Permission;
pub use models::role::Role;
pub use models::subject::RbacSubject;
pub use storage::traits::RbacStorage;
pub use storage::memory::MemoryStorage;

/// Main RBAC service that coordinates permission checking
pub struct RbacService<S: RbacStorage> {
    storage: S,
}

impl<S: RbacStorage> RbacService<S> {
    /// Create a new RBAC service with the given storage backend
    pub fn new(storage: S) -> Self {
        Self { storage }
    }
    
    /// Create a new permission
    pub async fn create_permission(&self, permission: &Permission) -> Result<(), error::RbacError> {
        self.storage.create_permission(permission).await
    }
    
    /// Get a permission by name
    pub async fn get_permission(&self, name: &str) -> Result<Option<Permission>, error::RbacError> {
        self.storage.get_permission(name).await
    }
    
    /// Delete a permission
    pub async fn delete_permission(&self, name: &str) -> Result<(), error::RbacError> {
        self.storage.delete_permission(name).await
    }
    
    /// Create a new role
    pub async fn create_role(&self, role: &Role) -> Result<(), error::RbacError> {
        self.storage.create_role(role).await
    }
    
    /// Get a role by name
    pub async fn get_role(&self, name: &str) -> Result<Option<Role>, error::RbacError> {
        self.storage.get_role(name).await
    }
    
    /// Delete a role
    pub async fn delete_role(&self, name: &str) -> Result<(), error::RbacError> {
        self.storage.delete_role(name).await
    }
    
    /// Assign a permission to a role
    pub async fn assign_permission_to_role(&self, permission_name: &str, role_name: &str) -> Result<(), error::RbacError> {
        self.storage.assign_permission_to_role(permission_name, role_name).await
    }
    
    /// Remove a permission from a role
    pub async fn remove_permission_from_role(&self, permission_name: &str, role_name: &str) -> Result<(), error::RbacError> {
        self.storage.remove_permission_from_role(permission_name, role_name).await
    }
    
    /// Get all permissions for a role
    pub async fn get_permissions_for_role(&self, role_name: &str) -> Result<Vec<Permission>, error::RbacError> {
        self.storage.get_permissions_for_role(role_name).await
    }
    
    /// Assign a role to a subject
    pub async fn assign_role_to_subject(&self, role_name: &str, subject_id: &str) -> Result<(), error::RbacError> {
        self.storage.assign_role_to_subject(role_name, subject_id).await
    }
    
    /// Remove a role from a subject
    pub async fn remove_role_from_subject(&self, role_name: &str, subject_id: &str) -> Result<(), error::RbacError> {
        self.storage.remove_role_from_subject(role_name, subject_id).await
    }
    
    /// Get all roles for a subject
    pub async fn get_roles_for_subject(&self, subject_id: &str) -> Result<Vec<Role>, error::RbacError> {
        self.storage.get_roles_for_subject(subject_id).await
    }
    
    /// Assign a permission directly to a subject
    pub async fn assign_permission_to_subject(&self, permission_name: &str, subject_id: &str) -> Result<(), error::RbacError> {
        self.storage.assign_permission_to_subject(permission_name, subject_id).await
    }
    
    /// Remove a permission from a subject
    pub async fn remove_permission_from_subject(&self, permission_name: &str, subject_id: &str) -> Result<(), error::RbacError> {
        self.storage.remove_permission_from_subject(permission_name, subject_id).await
    }
    
    /// Get all direct permissions for a subject (not including those from roles)
    pub async fn get_direct_permissions_for_subject(&self, subject_id: &str) -> Result<Vec<Permission>, error::RbacError> {
        self.storage.get_direct_permissions_for_subject(subject_id).await
    }
    
    /// Check if a subject has a specific permission (either directly or via roles)
    pub async fn subject_has_permission(&self, subject_id: &str, permission_name: &str) -> Result<bool, error::RbacError> {
        self.storage.subject_has_permission(subject_id, permission_name).await
    }
}