rust_rbac/
lib.rs

1//! A flexible Role-Based Access Control (RBAC) system for Rust applications.
2//!
3//! This crate provides a trait-based approach to implementing RBAC in Rust applications,
4//! with support for various storage backends and web frameworks.
5//!
6//! # Features
7//!
8//! - Role-based permissions
9//! - Direct permissions to users
10//! - Multiple roles per user
11//! - Multiple permissions per role
12//! - Permission inheritance through roles
13//! - Flexible storage backends
14//!
15//! # Example
16//!
17//! ```rust
18//! use rust_rbac::{RbacService, MemoryStorage, Permission, Role};
19//!
20//! #[tokio::main]
21//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
22//!     // Create a new RBAC service with in-memory storage
23//!     let storage = MemoryStorage::new();
24//!     let rbac = RbacService::new(storage);
25//!
26//!     // Create permissions
27//!     let create_post = Permission::new("create-post");
28//!     let edit_post = Permission::new("edit-post");
29//!     let delete_post = Permission::new("delete-post");
30//!
31//!     rbac.create_permission(&create_post).await?;
32//!     rbac.create_permission(&edit_post).await?;
33//!     rbac.create_permission(&delete_post).await?;
34//!
35//!     // Create roles
36//!     let author = Role::new("author");
37//!     let editor = Role::new("editor");
38//!     let admin = Role::new("admin");
39//!
40//!     rbac.create_role(&author).await?;
41//!     rbac.create_role(&editor).await?;
42//!     rbac.create_role(&admin).await?;
43//!
44//!     // Assign permissions to roles
45//!     rbac.assign_permission_to_role("create-post", "author").await?;
46//!     rbac.assign_permission_to_role("edit-post", "editor").await?;
47//!     rbac.assign_permission_to_role("delete-post", "admin").await?;
48//!
49//!     // Assign roles to users
50//!     let user_id = "user123";
51//!     rbac.assign_role_to_subject("author", user_id).await?;
52//!
53//!     // Check permissions
54//!     assert!(rbac.subject_has_permission(user_id, "create-post").await?);
55//!     assert!(!rbac.subject_has_permission(user_id, "delete-post").await?);
56//!
57//!     Ok(())
58//! }
59//! ```
60
61pub mod error;
62pub mod models;
63pub mod storage;
64pub mod cache;
65pub mod middleware;
66
67pub use models::permission::Permission;
68pub use models::role::Role;
69pub use models::subject::RbacSubject;
70pub use storage::traits::RbacStorage;
71pub use storage::memory::MemoryStorage;
72
73/// Main RBAC service that coordinates permission checking
74pub struct RbacService<S: RbacStorage> {
75    storage: S,
76}
77
78impl<S: RbacStorage> RbacService<S> {
79    /// Create a new RBAC service with the given storage backend
80    pub fn new(storage: S) -> Self {
81        Self { storage }
82    }
83    
84    /// Create a new permission
85    pub async fn create_permission(&self, permission: &Permission) -> Result<(), error::RbacError> {
86        self.storage.create_permission(permission).await
87    }
88    
89    /// Get a permission by name
90    pub async fn get_permission(&self, name: &str) -> Result<Option<Permission>, error::RbacError> {
91        self.storage.get_permission(name).await
92    }
93    
94    /// Delete a permission
95    pub async fn delete_permission(&self, name: &str) -> Result<(), error::RbacError> {
96        self.storage.delete_permission(name).await
97    }
98    
99    /// Create a new role
100    pub async fn create_role(&self, role: &Role) -> Result<(), error::RbacError> {
101        self.storage.create_role(role).await
102    }
103    
104    /// Get a role by name
105    pub async fn get_role(&self, name: &str) -> Result<Option<Role>, error::RbacError> {
106        self.storage.get_role(name).await
107    }
108    
109    /// Delete a role
110    pub async fn delete_role(&self, name: &str) -> Result<(), error::RbacError> {
111        self.storage.delete_role(name).await
112    }
113    
114    /// Assign a permission to a role
115    pub async fn assign_permission_to_role(&self, permission_name: &str, role_name: &str) -> Result<(), error::RbacError> {
116        self.storage.assign_permission_to_role(permission_name, role_name).await
117    }
118    
119    /// Remove a permission from a role
120    pub async fn remove_permission_from_role(&self, permission_name: &str, role_name: &str) -> Result<(), error::RbacError> {
121        self.storage.remove_permission_from_role(permission_name, role_name).await
122    }
123    
124    /// Get all permissions for a role
125    pub async fn get_permissions_for_role(&self, role_name: &str) -> Result<Vec<Permission>, error::RbacError> {
126        self.storage.get_permissions_for_role(role_name).await
127    }
128    
129    /// Assign a role to a subject
130    pub async fn assign_role_to_subject(&self, role_name: &str, subject_id: &str) -> Result<(), error::RbacError> {
131        self.storage.assign_role_to_subject(role_name, subject_id).await
132    }
133    
134    /// Remove a role from a subject
135    pub async fn remove_role_from_subject(&self, role_name: &str, subject_id: &str) -> Result<(), error::RbacError> {
136        self.storage.remove_role_from_subject(role_name, subject_id).await
137    }
138    
139    /// Get all roles for a subject
140    pub async fn get_roles_for_subject(&self, subject_id: &str) -> Result<Vec<Role>, error::RbacError> {
141        self.storage.get_roles_for_subject(subject_id).await
142    }
143    
144    /// Assign a permission directly to a subject
145    pub async fn assign_permission_to_subject(&self, permission_name: &str, subject_id: &str) -> Result<(), error::RbacError> {
146        self.storage.assign_permission_to_subject(permission_name, subject_id).await
147    }
148    
149    /// Remove a permission from a subject
150    pub async fn remove_permission_from_subject(&self, permission_name: &str, subject_id: &str) -> Result<(), error::RbacError> {
151        self.storage.remove_permission_from_subject(permission_name, subject_id).await
152    }
153    
154    /// Get all direct permissions for a subject (not including those from roles)
155    pub async fn get_direct_permissions_for_subject(&self, subject_id: &str) -> Result<Vec<Permission>, error::RbacError> {
156        self.storage.get_direct_permissions_for_subject(subject_id).await
157    }
158    
159    /// Check if a subject has a specific permission (either directly or via roles)
160    pub async fn subject_has_permission(&self, subject_id: &str, permission_name: &str) -> Result<bool, error::RbacError> {
161        self.storage.subject_has_permission(subject_id, permission_name).await
162    }
163}