1use crate::{
4 core::{RoleSystem, RoleSystemConfig},
5 error::Result,
6 resource::Resource,
7 role::Role,
8 storage::Storage,
9 subject::Subject,
10};
11use std::{
12 collections::{HashMap, HashSet},
13 sync::Arc,
14 time::Duration,
15};
16use tokio::sync::{RwLock, Mutex};
17
18pub struct AsyncRoleSystem<S>
20where
21 S: Storage + Send + Sync,
22{
23 inner: Arc<RwLock<RoleSystem<S>>>,
24}
25
26impl<S> AsyncRoleSystem<S>
27where
28 S: Storage + Send + Sync,
29{
30 pub fn new(role_system: RoleSystem<S>) -> Self {
32 Self {
33 inner: Arc::new(RwLock::new(role_system)),
34 }
35 }
36
37 pub async fn register_role(&self, role: Role) -> Result<()> {
39 let mut system = self.inner.write().await;
40 system.register_role(role)
41 }
42
43 pub async fn get_role(&self, name: &str) -> Result<Option<Role>> {
45 let system = self.inner.read().await;
46 system.get_role(name)
47 }
48
49 pub async fn add_role_inheritance(&self, child: &str, parent: &str) -> Result<()> {
51 let mut system = self.inner.write().await;
52 system.add_role_inheritance(child, parent)
53 }
54
55 pub async fn remove_role_inheritance(&self, child: &str, parent: &str) -> Result<()> {
57 let mut system = self.inner.write().await;
58 system.remove_role_inheritance(child, parent)
59 }
60
61 pub async fn assign_role(&self, subject: &Subject, role_name: &str) -> Result<()> {
63 let mut system = self.inner.write().await;
64 system.assign_role(subject, role_name)
65 }
66
67 pub async fn remove_role(&self, subject: &Subject, role_name: &str) -> Result<()> {
69 let mut system = self.inner.write().await;
70 system.remove_role(subject, role_name)
71 }
72
73 pub async fn elevate_role(
75 &self,
76 subject: &Subject,
77 role_name: &str,
78 duration: Option<Duration>,
79 ) -> Result<()> {
80 let mut system = self.inner.write().await;
81 system.elevate_role(subject, role_name, duration)
82 }
83
84 pub async fn check_permission(
86 &self,
87 subject: &Subject,
88 action: &str,
89 resource: &Resource,
90 ) -> Result<bool> {
91 let system = self.inner.read().await;
92 system.check_permission(subject, action, resource)
93 }
94
95 pub async fn check_permission_with_context(
97 &self,
98 subject: &Subject,
99 action: &str,
100 resource: &Resource,
101 context: &HashMap<String, String>,
102 ) -> Result<bool> {
103 let system = self.inner.read().await;
104 system.check_permission_with_context(subject, action, resource, context)
105 }
106
107 pub async fn get_subject_roles(&self, subject: &Subject) -> Result<HashSet<String>> {
109 let system = self.inner.read().await;
110 system.get_subject_roles(subject)
111 }
112
113 pub async fn batch_check_permissions(
115 &self,
116 subject: &Subject,
117 checks: &[(String, Resource)], ) -> Result<Vec<(String, Resource, bool)>> {
119 let system = self.inner.read().await;
120 let mut results = Vec::new();
121
122 for (action, resource) in checks {
123 let granted = system.check_permission(subject, action, resource)?;
124 results.push((action.clone(), resource.clone(), granted));
125 }
126
127 Ok(results)
128 }
129
130 pub async fn atomic_role_operations<F, R>(&self, operations: F) -> Result<R>
132 where
133 F: FnOnce(&mut RoleSystem<S>) -> Result<R> + Send,
134 {
135 let mut system = self.inner.write().await;
136 operations(&mut *system)
137 }
138
139 pub async fn with_read_access<F, R>(&self, operation: F) -> R
141 where
142 F: FnOnce(&RoleSystem<S>) -> R + Send,
143 {
144 let system = self.inner.read().await;
145 operation(&*system)
146 }
147}
148
149impl<S> Clone for AsyncRoleSystem<S>
150where
151 S: Storage + Send + Sync,
152{
153 fn clone(&self) -> Self {
154 Self {
155 inner: Arc::clone(&self.inner),
156 }
157 }
158}
159
160#[async_trait::async_trait]
162pub trait AsyncStorage: Send + Sync {
163 async fn store_role(&mut self, role: Role) -> Result<()>;
165
166 async fn get_role(&self, name: &str) -> Result<Option<Role>>;
168
169 async fn role_exists(&self, name: &str) -> Result<bool>;
171
172 async fn delete_role(&mut self, name: &str) -> Result<bool>;
174
175 async fn list_roles(&self) -> Result<Vec<String>>;
177
178 async fn update_role(&mut self, role: Role) -> Result<()>;
180}
181
182#[derive(Debug, Default)]
184pub struct AsyncMemoryStorage {
185 roles: Arc<RwLock<HashMap<String, Role>>>,
186}
187
188impl AsyncMemoryStorage {
189 pub fn new() -> Self {
191 Self {
192 roles: Arc::new(RwLock::new(HashMap::new())),
193 }
194 }
195
196 pub async fn role_count(&self) -> usize {
198 self.roles.read().await.len()
199 }
200
201 pub async fn clear(&self) {
203 self.roles.write().await.clear();
204 }
205}
206
207#[async_trait::async_trait]
208impl AsyncStorage for AsyncMemoryStorage {
209 async fn store_role(&mut self, role: Role) -> Result<()> {
210 let name = role.name().to_string();
211 self.roles.write().await.insert(name, role);
212 Ok(())
213 }
214
215 async fn get_role(&self, name: &str) -> Result<Option<Role>> {
216 Ok(self.roles.read().await.get(name).cloned())
217 }
218
219 async fn role_exists(&self, name: &str) -> Result<bool> {
220 Ok(self.roles.read().await.contains_key(name))
221 }
222
223 async fn delete_role(&mut self, name: &str) -> Result<bool> {
224 Ok(self.roles.write().await.remove(name).is_some())
225 }
226
227 async fn list_roles(&self) -> Result<Vec<String>> {
228 Ok(self.roles.read().await.keys().cloned().collect())
229 }
230
231 async fn update_role(&mut self, role: Role) -> Result<()> {
232 let name = role.name().to_string();
233 self.roles.write().await.insert(name, role);
234 Ok(())
235 }
236}
237
238pub struct AsyncStorageAdapter<S>
240where
241 S: Storage + Send + Sync,
242{
243 storage: Arc<Mutex<S>>,
244}
245
246impl<S> AsyncStorageAdapter<S>
247where
248 S: Storage + Send + Sync,
249{
250 pub fn new(storage: S) -> Self {
252 Self {
253 storage: Arc::new(Mutex::new(storage)),
254 }
255 }
256}
257
258#[async_trait::async_trait]
259impl<S> AsyncStorage for AsyncStorageAdapter<S>
260where
261 S: Storage + Send + Sync,
262{
263 async fn store_role(&mut self, role: Role) -> Result<()> {
264 let mut storage = self.storage.lock().await;
265 storage.store_role(role)
266 }
267
268 async fn get_role(&self, name: &str) -> Result<Option<Role>> {
269 let storage = self.storage.lock().await;
270 storage.get_role(name)
271 }
272
273 async fn role_exists(&self, name: &str) -> Result<bool> {
274 let storage = self.storage.lock().await;
275 storage.role_exists(name)
276 }
277
278 async fn delete_role(&mut self, name: &str) -> Result<bool> {
279 let mut storage = self.storage.lock().await;
280 storage.delete_role(name)
281 }
282
283 async fn list_roles(&self) -> Result<Vec<String>> {
284 let storage = self.storage.lock().await;
285 storage.list_roles()
286 }
287
288 async fn update_role(&mut self, role: Role) -> Result<()> {
289 let mut storage = self.storage.lock().await;
290 storage.update_role(role)
291 }
292}
293
294pub struct AsyncRoleSystemBuilder<S>
296where
297 S: Storage + Send + Sync,
298{
299 config: RoleSystemConfig,
300 storage: Option<S>,
301}
302
303impl<S> AsyncRoleSystemBuilder<S>
304where
305 S: Storage + Send + Sync + Default,
306{
307 pub fn new() -> Self {
309 Self {
310 config: RoleSystemConfig::default(),
311 storage: None,
312 }
313 }
314}
315
316impl<S> Default for AsyncRoleSystemBuilder<S>
317where
318 S: Storage + Send + Sync + Default,
319{
320 fn default() -> Self {
321 Self::new()
322 }
323}
324
325impl<S> AsyncRoleSystemBuilder<S>
326where
327 S: Storage + Send + Sync,
328{
329 pub fn with_storage(storage: S) -> Self {
331 Self {
332 config: RoleSystemConfig::default(),
333 storage: Some(storage),
334 }
335 }
336
337 pub fn config(mut self, config: RoleSystemConfig) -> Self {
339 self.config = config;
340 self
341 }
342
343 pub fn max_hierarchy_depth(mut self, depth: usize) -> Self {
345 self.config.max_hierarchy_depth = depth;
346 self
347 }
348
349 pub fn enable_caching(mut self, enabled: bool) -> Self {
351 self.config.enable_caching = enabled;
352 self
353 }
354
355 pub fn cache_ttl_seconds(mut self, ttl: u64) -> Self {
357 self.config.cache_ttl_seconds = ttl;
358 self
359 }
360
361 pub fn enable_audit(mut self, enabled: bool) -> Self {
363 self.config.enable_audit = enabled;
364 self
365 }
366
367 pub fn build(self) -> AsyncRoleSystem<S>
369 where
370 S: Default,
371 {
372 let storage = self.storage.unwrap_or_default();
373 let role_system = RoleSystem::with_storage(storage, self.config);
374 AsyncRoleSystem::new(role_system)
375 }
376
377 pub fn build_with_storage(self, storage: S) -> AsyncRoleSystem<S> {
379 let role_system = RoleSystem::with_storage(storage, self.config);
380 AsyncRoleSystem::new(role_system)
381 }
382}
383
384#[cfg(test)]
385mod tests {
386 use super::*;
387 use crate::{permission::Permission, storage::MemoryStorage};
388
389 #[tokio::test]
390 async fn test_async_role_system() {
391 let storage = MemoryStorage::new();
392 let config = RoleSystemConfig::default();
393 let role_system = RoleSystem::with_storage(storage, config);
394 let async_system = AsyncRoleSystem::new(role_system);
395
396 let role = Role::new("async-test")
398 .add_permission(Permission::new("read", "documents"));
399
400 async_system.register_role(role).await.unwrap();
401
402 let subject = Subject::user("user1");
404 async_system.assign_role(&subject, "async-test").await.unwrap();
405
406 let resource = Resource::new("doc1", "documents");
408 let can_read = async_system
409 .check_permission(&subject, "read", &resource)
410 .await
411 .unwrap();
412
413 assert!(can_read);
414 }
415
416 #[tokio::test]
417 async fn test_async_batch_permissions() {
418 let storage = MemoryStorage::new();
419 let config = RoleSystemConfig::default();
420 let role_system = RoleSystem::with_storage(storage, config);
421 let async_system = AsyncRoleSystem::new(role_system);
422
423 let role = Role::new("batch-test")
425 .add_permission(Permission::new("read", "documents"))
426 .add_permission(Permission::new("write", "documents"));
427
428 async_system.register_role(role).await.unwrap();
429
430 let subject = Subject::user("user1");
431 async_system.assign_role(&subject, "batch-test").await.unwrap();
432
433 let checks = vec![
435 ("read".to_string(), Resource::new("doc1", "documents")),
436 ("write".to_string(), Resource::new("doc1", "documents")),
437 ("delete".to_string(), Resource::new("doc1", "documents")),
438 ];
439
440 let results = async_system
441 .batch_check_permissions(&subject, &checks)
442 .await
443 .unwrap();
444
445 assert_eq!(results.len(), 3);
446 assert!(results[0].2); assert!(results[1].2); assert!(!results[2].2); }
450
451 #[tokio::test]
452 async fn test_async_memory_storage() {
453 let mut storage = AsyncMemoryStorage::new();
454
455 let role = Role::new("async-storage-test")
456 .add_permission(Permission::new("read", "documents"));
457
458 storage.store_role(role.clone()).await.unwrap();
460 assert_eq!(storage.role_count().await, 1);
461
462 assert!(storage.role_exists("async-storage-test").await.unwrap());
464
465 let retrieved = storage.get_role("async-storage-test").await.unwrap().unwrap();
467 assert_eq!(retrieved.name(), "async-storage-test");
468
469 let roles = storage.list_roles().await.unwrap();
471 assert_eq!(roles.len(), 1);
472
473 assert!(storage.delete_role("async-storage-test").await.unwrap());
475 assert_eq!(storage.role_count().await, 0);
476 }
477
478 #[tokio::test]
479 async fn test_async_builder() {
480 let async_system = AsyncRoleSystemBuilder::<MemoryStorage>::new()
481 .max_hierarchy_depth(5)
482 .enable_caching(false)
483 .build();
484
485 let role = Role::new("builder-test");
487 async_system.register_role(role).await.unwrap();
488
489 let retrieved = async_system.get_role("builder-test").await.unwrap();
490 assert!(retrieved.is_some());
491 }
492}