1use crate::errors::{AuthError, Result};
4use crate::permissions::{Permission, PermissionChecker, Role};
5use crate::storage::AuthStorage;
6use crate::tokens::AuthToken;
7use std::sync::Arc;
8use tokio::sync::RwLock;
9use tracing::{debug, info};
10
11pub struct AuthorizationManager {
21 checker: Arc<RwLock<PermissionChecker>>,
22 storage: Arc<dyn AuthStorage>,
23}
24
25impl AuthorizationManager {
26 pub fn new(checker: Arc<RwLock<PermissionChecker>>, storage: Arc<dyn AuthStorage>) -> Self {
33 Self { checker, storage }
34 }
35
36 pub async fn create_default_roles(&self) {
43 let mut c = self.checker.write().await;
44 c.create_default_roles();
45 }
46
47 pub async fn load_persisted_roles(&self) -> Result<()> {
57 let role_keys = self.storage.list_kv_keys("rbac:role:").await?;
59 if !role_keys.is_empty() {
60 let mut c = self.checker.write().await;
61 for key in &role_keys {
62 if let Some(bytes) = self.storage.get_kv(key).await? {
63 if let Ok(role) = serde_json::from_slice::<Role>(&bytes) {
64 c.add_role(role);
65 }
66 }
67 }
68 }
69
70 let assignment_keys = self.storage.list_kv_keys("rbac:user_roles:").await?;
72 if !assignment_keys.is_empty() {
73 let mut c = self.checker.write().await;
74 for key in &assignment_keys {
75 let user_id = key.strip_prefix("rbac:user_roles:").unwrap_or(key);
76 if let Some(bytes) = self.storage.get_kv(key).await? {
77 if let Ok(roles) = serde_json::from_slice::<Vec<String>>(&bytes) {
78 for role_name in roles {
79 if let Err(e) = c.assign_role_to_user(user_id, &role_name) {
80 tracing::warn!("Failed to assign role '{}' to user '{}': {}", role_name, user_id, e);
81 }
82 }
83 }
84 }
85 }
86 }
87
88 Ok(())
89 }
90
91 pub async fn reset_runtime_state(&self) {
98 let mut c = self.checker.write().await;
99 c.clear();
100 c.create_default_roles();
101
102 if let Ok(keys) = self.storage.list_kv_keys("rbac:role:").await {
104 for key in keys {
105 let _ = self.storage.delete_kv(&key).await;
106 }
107 }
108 if let Ok(keys) = self.storage.list_kv_keys("rbac:user_roles:").await {
109 for key in keys {
110 let _ = self.storage.delete_kv(&key).await;
111 }
112 }
113 }
114
115 pub async fn grant_permission(
122 &self,
123 user_id: &str,
124 action: &str,
125 resource: &str,
126 ) -> Result<()> {
127 debug!(
128 "Granting permission '{}:{}' to user '{}'",
129 action, resource, user_id
130 );
131 let mut c = self.checker.write().await;
132 let permission = Permission::new(action, resource);
133 c.add_user_permission(user_id, permission);
134 info!(
135 "Permission '{}:{}' granted to user '{}'",
136 action, resource, user_id
137 );
138 Ok(())
139 }
140
141 pub async fn revoke_permission(
148 &self,
149 user_id: &str,
150 action: &str,
151 resource: &str,
152 ) -> Result<()> {
153 debug!(
154 "Revoking permission '{}:{}' from user '{}'",
155 action, resource, user_id
156 );
157 if user_id.is_empty() || action.is_empty() || resource.is_empty() {
158 return Err(AuthError::validation(
159 "User ID, action, and resource cannot be empty",
160 ));
161 }
162 let mut c = self.checker.write().await;
163 let permission = Permission::new(action, resource);
164 c.remove_user_permission(user_id, &permission);
165 info!(
166 "Permission '{}:{}' revoked from user '{}'",
167 action, resource, user_id
168 );
169 Ok(())
170 }
171
172 pub async fn create_role(&self, role: Role) -> Result<()> {
180 debug!("Creating role '{}'", role.name);
181 if role.name.is_empty() {
182 return Err(AuthError::validation("Role name cannot be empty"));
183 }
184 let mut c = self.checker.write().await;
185 c.add_role(role.clone());
186 drop(c);
187
188 let key = format!("rbac:role:{}", role.name);
190 let role_json = serde_json::to_vec(&role)
191 .map_err(|e| AuthError::internal(format!("Failed to serialize role: {e}")))?;
192 self.storage.store_kv(&key, &role_json, None).await?;
193
194 info!("Role '{}' created", role.name);
195 Ok(())
196 }
197
198 pub async fn list_roles(&self) -> Vec<Role> {
206 let c = self.checker.read().await;
207 c.list_roles()
208 }
209
210 pub async fn get_role(&self, role_name: &str) -> Result<Role> {
218 if role_name.is_empty() {
219 return Err(AuthError::validation("Role name cannot be empty"));
220 }
221
222 let c = self.checker.read().await;
223 c.get_role(role_name)
224 .cloned()
225 .ok_or_else(|| AuthError::validation(format!("Role '{role_name}' not found")))
226 }
227
228 pub async fn add_role_permission(&self, role_name: &str, permission: Permission) -> Result<()> {
236 if role_name.is_empty() {
237 return Err(AuthError::validation("Role name cannot be empty"));
238 }
239
240 let mut c = self.checker.write().await;
241 let role = c
242 .get_role(role_name)
243 .cloned()
244 .ok_or_else(|| AuthError::validation(format!("Role '{role_name}' not found")))?;
245 let mut updated_role = role;
246 updated_role.add_permission(permission);
247 c.add_role(updated_role.clone());
248 drop(c);
249
250 let key = format!("rbac:role:{}", role_name);
252 let role_json = serde_json::to_vec(&updated_role)
253 .map_err(|e| AuthError::internal(format!("Failed to serialize role: {e}")))?;
254 self.storage.store_kv(&key, &role_json, None).await?;
255
256 Ok(())
257 }
258
259 pub async fn assign_role(&self, user_id: &str, role_name: &str) -> Result<()> {
266 debug!("Assigning role '{}' to user '{}'", role_name, user_id);
267 if user_id.is_empty() {
268 return Err(AuthError::validation("User ID cannot be empty"));
269 }
270 if role_name.is_empty() {
271 return Err(AuthError::validation("Role name cannot be empty"));
272 }
273 let mut c = self.checker.write().await;
274 c.assign_role_to_user(user_id, role_name)?;
275 let roles = c.get_user_roles(user_id);
276 drop(c);
277
278 let key = format!("rbac:user_roles:{}", user_id);
280 let roles_json = serde_json::to_vec(&roles)
281 .map_err(|e| AuthError::internal(format!("Failed to serialize user roles: {e}")))?;
282 self.storage.store_kv(&key, &roles_json, None).await?;
283
284 info!("Role '{}' assigned to user '{}'", role_name, user_id);
285 Ok(())
286 }
287
288 pub async fn remove_role(&self, user_id: &str, role_name: &str) -> Result<()> {
295 debug!("Removing role '{}' from user '{}'", role_name, user_id);
296 if user_id.is_empty() || role_name.is_empty() {
297 return Err(AuthError::validation(
298 "User ID and role name cannot be empty",
299 ));
300 }
301 let mut c = self.checker.write().await;
302 c.remove_user_role(user_id, role_name);
303 let roles = c.get_user_roles(user_id);
304 drop(c);
305
306 let key = format!("rbac:user_roles:{}", user_id);
308 if roles.is_empty() {
309 let _ = self.storage.delete_kv(&key).await;
310 } else {
311 let roles_json = serde_json::to_vec(&roles)
312 .map_err(|e| AuthError::internal(format!("Failed to serialize user roles: {e}")))?;
313 self.storage.store_kv(&key, &roles_json, None).await?;
314 }
315
316 info!("Role '{}' removed from user '{}'", role_name, user_id);
317 Ok(())
318 }
319
320 pub async fn set_role_inheritance(&self, child_role: &str, parent_role: &str) -> Result<()> {
327 debug!(
328 "Setting inheritance: '{}' inherits from '{}'",
329 child_role, parent_role
330 );
331 if child_role.is_empty() || parent_role.is_empty() {
332 return Err(AuthError::validation("Role names cannot be empty"));
333 }
334 let mut c = self.checker.write().await;
335 c.set_role_inheritance(child_role, parent_role)?;
336 info!(
337 "Role inheritance set: '{}' inherits from '{}'",
338 child_role, parent_role
339 );
340 Ok(())
341 }
342
343 pub async fn check_token_permission(
353 &self,
354 token: &AuthToken,
355 action: &str,
356 resource: &str,
357 ) -> Result<bool> {
358 let permission = Permission::new(action, resource);
359 let mut c = self.checker.write().await;
360 c.check_token_permission(token, &permission)
361 }
362
363 pub async fn check_user_permission(&self, user_id: &str, action: &str, resource: &str) -> bool {
372 let permission = Permission::new(action, resource);
373 let mut c = self.checker.write().await;
374 c.check_permission(user_id, &permission).unwrap_or(false)
375 }
376
377 pub async fn user_has_role(&self, user_id: &str, role_name: &str) -> Result<bool> {
384 debug!("Checking if user '{}' has role '{}'", user_id, role_name);
385 if user_id.is_empty() || role_name.is_empty() {
386 return Err(AuthError::validation(
387 "User ID and role name cannot be empty",
388 ));
389 }
390 let c = self.checker.read().await;
391 let has_role = c.user_has_role(user_id, role_name);
392 debug!("User '{}' has role '{}': {}", user_id, role_name, has_role);
393 Ok(has_role)
394 }
395
396 pub async fn get_effective_permissions(&self, user_id: &str) -> Result<Vec<String>> {
404 debug!("Getting effective permissions for user '{}'", user_id);
405 if user_id.is_empty() {
406 return Err(AuthError::validation("User ID cannot be empty"));
407 }
408 let c = self.checker.read().await;
409 let permissions = c.get_effective_permissions(user_id);
410 debug!(
411 "User '{}' has {} effective permissions",
412 user_id,
413 permissions.len()
414 );
415 Ok(permissions)
416 }
417
418 pub async fn list_user_roles(&self, user_id: &str) -> Result<Vec<String>> {
425 if user_id.is_empty() {
426 return Err(AuthError::validation("User ID cannot be empty"));
427 }
428
429 let c = self.checker.read().await;
430 Ok(c.get_user_roles(user_id))
431 }
432
433 pub async fn get_metrics(&self) -> (usize, usize, usize) {
440 let c = self.checker.read().await;
441 (
442 c.role_count(),
443 c.user_count(),
444 c.total_direct_permission_count(),
445 )
446 }
447
448 pub async fn create_abac_policy(&self, name: &str, description: &str) -> Result<()> {
457 debug!("Creating ABAC policy '{}'", name);
458 if name.is_empty() {
459 return Err(AuthError::validation("Policy name cannot be empty"));
460 }
461 if description.is_empty() {
462 return Err(AuthError::validation("Policy description cannot be empty"));
463 }
464 let policy_data = serde_json::json!({
465 "name": name,
466 "description": description,
467 "created_at": chrono::Utc::now(),
468 "rules": [],
469 "active": true
470 });
471 let key = format!("abac:policy:{}", name);
472 let policy_json = serde_json::to_vec(&policy_data)
473 .map_err(|e| AuthError::validation(format!("Failed to serialize policy: {}", e)))?;
474 self.storage.store_kv(&key, &policy_json, None).await?;
475 info!("ABAC policy '{}' created", name);
476 Ok(())
477 }
478
479 pub async fn map_user_attribute(
486 &self,
487 user_id: &str,
488 attribute: &str,
489 value: &str,
490 ) -> Result<()> {
491 debug!(
492 "Mapping attribute '{}' = '{}' for user '{}'",
493 attribute, value, user_id
494 );
495 if user_id.is_empty() || attribute.is_empty() {
496 return Err(AuthError::validation(
497 "User ID and attribute name cannot be empty",
498 ));
499 }
500 let attrs_key = format!("user:{}:attributes", user_id);
501 let mut user_attrs = if let Some(bytes) = self.storage.get_kv(&attrs_key).await? {
502 serde_json::from_slice::<std::collections::HashMap<String, String>>(&bytes)
503 .unwrap_or_default()
504 } else {
505 std::collections::HashMap::new()
506 };
507 user_attrs.insert(attribute.to_string(), value.to_string());
508 let attrs_json = serde_json::to_vec(&user_attrs)
509 .map_err(|e| AuthError::validation(format!("Failed to serialize attributes: {}", e)))?;
510 self.storage.store_kv(&attrs_key, &attrs_json, None).await?;
511 info!("Attribute '{}' mapped for user '{}'", attribute, user_id);
512 Ok(())
513 }
514
515 pub async fn get_user_attribute(
522 &self,
523 user_id: &str,
524 attribute: &str,
525 ) -> Result<Option<String>> {
526 debug!("Getting attribute '{}' for user '{}'", attribute, user_id);
527 if user_id.is_empty() || attribute.is_empty() {
528 return Err(AuthError::validation(
529 "User ID and attribute name cannot be empty",
530 ));
531 }
532 let attrs_key = format!("user:{}:attributes", user_id);
533 if let Some(bytes) = self.storage.get_kv(&attrs_key).await? {
534 let user_attrs: std::collections::HashMap<String, String> =
535 serde_json::from_slice(&bytes).unwrap_or_default();
536 Ok(user_attrs.get(attribute).cloned())
537 } else {
538 Ok(None)
539 }
540 }
541
542 pub async fn check_dynamic_permission(
552 &self,
553 user_id: &str,
554 action: &str,
555 resource: &str,
556 context: std::collections::HashMap<String, String>,
557 ) -> Result<bool> {
558 debug!(
559 "Checking dynamic permission for user '{}': {}:{} with context: {:?}",
560 user_id, action, resource, context
561 );
562 if user_id.is_empty() || action.is_empty() || resource.is_empty() {
563 return Err(AuthError::validation(
564 "User ID, action, and resource cannot be empty",
565 ));
566 }
567 let user_attrs_key = format!("user:{}:attributes", user_id);
569 let user_attrs = if let Some(bytes) = self.storage.get_kv(&user_attrs_key).await? {
570 serde_json::from_slice::<std::collections::HashMap<String, String>>(&bytes)
571 .unwrap_or_default()
572 } else {
573 std::collections::HashMap::new()
574 };
575 let mut permission_granted = self.check_user_permission(user_id, action, resource).await;
577 if permission_granted {
579 if let Some(time_restriction) = context.get("time_restriction") {
581 let current_hour = chrono::Utc::now()
582 .format("%H")
583 .to_string()
584 .parse::<u32>()
585 .unwrap_or(0);
586 if time_restriction == "business_hours" && !(9..=17).contains(¤t_hour) {
587 permission_granted = false;
588 debug!("Access denied: outside business hours");
589 }
590 }
591 if let Some(required_location) = context.get("required_location")
593 && let Some(user_location) = user_attrs.get("location")
594 && user_location != required_location
595 {
596 permission_granted = false;
597 debug!(
598 "Access denied: user location {} != required {}",
599 user_location, required_location
600 );
601 }
602 if let Some(required_clearance) = context.get("required_clearance")
604 && let Some(user_clearance) = user_attrs.get("clearance_level")
605 {
606 let required_level = required_clearance.parse::<u32>().unwrap_or(0);
607 let user_level = user_clearance.parse::<u32>().unwrap_or(0);
608 if user_level < required_level {
609 permission_granted = false;
610 debug!(
611 "Access denied: user clearance {} < required {}",
612 user_level, required_level
613 );
614 }
615 }
616 }
617 debug!(
618 "Dynamic permission check result for user '{}': {}",
619 user_id, permission_granted
620 );
621 Ok(permission_granted)
622 }
623
624 pub async fn create_resource(&self, resource: &str) -> Result<()> {
631 debug!("Creating resource '{}'", resource);
632 if resource.is_empty() {
633 return Err(AuthError::validation("Resource name cannot be empty"));
634 }
635 let resource_data = serde_json::json!({
636 "name": resource,
637 "created_at": chrono::Utc::now(),
638 "active": true
639 });
640 let key = format!("resource:{}", resource);
641 let resource_json = serde_json::to_vec(&resource_data)
642 .map_err(|e| AuthError::validation(format!("Failed to serialize resource: {}", e)))?;
643 self.storage.store_kv(&key, &resource_json, None).await?;
644 info!("Resource '{}' created", resource);
645 Ok(())
646 }
647
648 pub async fn delegate_permission(
658 &self,
659 delegator_id: &str,
660 delegatee_id: &str,
661 action: &str,
662 resource: &str,
663 duration: std::time::Duration,
664 ) -> Result<()> {
665 debug!(
666 "Delegating permission '{}:{}' from '{}' to '{}' for {:?}",
667 action, resource, delegator_id, delegatee_id, duration
668 );
669 if delegator_id.is_empty()
670 || delegatee_id.is_empty()
671 || action.is_empty()
672 || resource.is_empty()
673 {
674 return Err(AuthError::validation(
675 "All delegation parameters cannot be empty",
676 ));
677 }
678 if !self
679 .check_user_permission(delegator_id, action, resource)
680 .await
681 {
682 return Err(AuthError::authorization(
683 "Delegator does not have the permission to delegate",
684 ));
685 }
686 let delegation_id = uuid::Uuid::new_v4().to_string();
687 let expires_secs = std::time::SystemTime::now()
688 .checked_add(duration)
689 .and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok())
690 .map(|d| d.as_secs())
691 .unwrap_or(0);
692 let delegation_data = serde_json::json!({
693 "id": delegation_id,
694 "delegator_id": delegator_id,
695 "delegatee_id": delegatee_id,
696 "action": action,
697 "resource": resource,
698 "created_at": chrono::Utc::now(),
699 "expires_at": expires_secs
700 });
701 let key = format!("delegation:{}", delegation_id);
702 let delegation_json = serde_json::to_vec(&delegation_data)
703 .map_err(|e| AuthError::validation(format!("Failed to serialize delegation: {}", e)))?;
704 self.storage
705 .store_kv(&key, &delegation_json, Some(duration))
706 .await?;
707 let index_key = format!("delegations_index:{}", delegatee_id);
709 let mut ids: Vec<String> = match self.storage.get_kv(&index_key).await? {
710 Some(bytes) => serde_json::from_slice(&bytes).unwrap_or_default(),
711 None => vec![],
712 };
713 ids.push(delegation_id.clone());
714 let ids_json = serde_json::to_vec(&ids).map_err(|e| {
715 AuthError::validation(format!("Failed to serialize delegation index: {}", e))
716 })?;
717 self.storage.store_kv(&index_key, &ids_json, None).await?;
718 info!(
719 "Permission '{}:{}' delegated from '{}' to '{}' for {:?}",
720 action, resource, delegator_id, delegatee_id, duration
721 );
722 Ok(())
723 }
724
725 pub async fn get_active_delegations(&self, user_id: &str) -> Result<Vec<String>> {
732 debug!("Getting active delegations for user '{}'", user_id);
733 if user_id.is_empty() {
734 return Err(AuthError::validation("User ID cannot be empty"));
735 }
736 let index_key = format!("delegations_index:{}", user_id);
737 let delegation_ids: Vec<String> = match self.storage.get_kv(&index_key).await? {
738 Some(bytes) => serde_json::from_slice(&bytes).unwrap_or_default(),
739 None => return Ok(vec![]),
740 };
741 let now_secs = std::time::SystemTime::now()
742 .duration_since(std::time::UNIX_EPOCH)
743 .unwrap_or_default()
744 .as_secs();
745 let mut result = Vec::new();
746 let mut active_ids = Vec::new();
747 for id in &delegation_ids {
748 let key = format!("delegation:{}", id);
749 if let Some(bytes) = self.storage.get_kv(&key).await?
750 && let Ok(data) = serde_json::from_slice::<serde_json::Value>(&bytes)
751 {
752 let expires_at = data["expires_at"].as_u64().unwrap_or(0);
753 if expires_at > now_secs {
754 let action = data["action"].as_str().unwrap_or("unknown");
755 let resource = data["resource"].as_str().unwrap_or("unknown");
756 let delegator = data["delegator_id"].as_str().unwrap_or("unknown");
757 result.push(format!(
758 "{}:{}:delegated_from:{}",
759 action, resource, delegator
760 ));
761 active_ids.push(id.clone());
762 }
763 }
764 }
765 if active_ids.len() != delegation_ids.len()
767 && let Ok(pruned) = serde_json::to_vec(&active_ids)
768 {
769 let _ = self.storage.store_kv(&index_key, &pruned, None).await;
770 }
771 debug!(
772 "Found {} active delegations for user '{}'",
773 result.len(),
774 user_id
775 );
776 Ok(result)
777 }
778
779 pub async fn get_permission_metrics(
791 &self,
792 active_sessions: u64,
793 permission_checks_last_hour: u64,
794 ) -> Result<std::collections::HashMap<String, u64>> {
795 let (total_roles, total_users, total_permissions) = self.get_metrics().await;
796 let mut metrics = std::collections::HashMap::new();
797 metrics.insert(
798 "total_users_with_permissions".to_string(),
799 total_users as u64,
800 );
801 metrics.insert("total_roles".to_string(), total_roles as u64);
802 metrics.insert("total_permissions".to_string(), total_permissions as u64);
803 metrics.insert("active_sessions".to_string(), active_sessions);
804 metrics.insert(
805 "permission_checks_last_hour".to_string(),
806 permission_checks_last_hour,
807 );
808 debug!("Retrieved {} permission metrics", metrics.len());
809 Ok(metrics)
810 }
811}
812
813#[cfg(test)]
814mod tests {
815 use super::*;
816 use crate::storage::MemoryStorage;
817
818 fn make_manager() -> AuthorizationManager {
819 let checker = Arc::new(RwLock::new(PermissionChecker::new()));
820 let storage: Arc<dyn AuthStorage> = Arc::new(MemoryStorage::new());
821 AuthorizationManager::new(checker, storage)
822 }
823
824 #[tokio::test]
827 async fn test_create_role_success() {
828 let mgr = make_manager();
829 let role = Role::new("editor");
830 assert!(mgr.create_role(role).await.is_ok());
831 let roles = mgr.list_roles().await;
832 assert!(roles.iter().any(|r| r.name == "editor"));
833 }
834
835 #[tokio::test]
836 async fn test_create_role_persists_to_storage() {
837 let mgr = make_manager();
838 mgr.create_role(Role::new("persisted_role")).await.unwrap();
839 let data = mgr
840 .storage
841 .get_kv("rbac:role:persisted_role")
842 .await
843 .unwrap();
844 assert!(data.is_some());
845 let role: Role = serde_json::from_slice(&data.unwrap()).unwrap();
846 assert_eq!(role.name, "persisted_role");
847 }
848
849 #[tokio::test]
850 async fn test_create_role_empty_name_rejected() {
851 let mgr = make_manager();
852 let role = Role::new("");
853 let err = mgr.create_role(role).await;
854 assert!(err.is_err());
855 }
856
857 #[tokio::test]
858 async fn test_create_role_duplicate_overwrites() {
859 let mgr = make_manager();
860 let mut role1 = Role::new("dup");
861 role1.description = Some("first".into());
862 mgr.create_role(role1).await.unwrap();
863
864 let mut role2 = Role::new("dup");
865 role2.description = Some("second".into());
866 mgr.create_role(role2).await.unwrap();
867
868 let fetched = mgr.get_role("dup").await.unwrap();
869 assert_eq!(fetched.description.as_deref(), Some("second"));
870 }
871
872 #[tokio::test]
875 async fn test_get_role_not_found() {
876 let mgr = make_manager();
877 assert!(mgr.get_role("nonexistent").await.is_err());
878 }
879
880 #[tokio::test]
881 async fn test_get_role_empty_name_rejected() {
882 let mgr = make_manager();
883 assert!(mgr.get_role("").await.is_err());
884 }
885
886 #[tokio::test]
889 async fn test_assign_role_success() {
890 let mgr = make_manager();
891 mgr.create_role(Role::new("viewer")).await.unwrap();
892 mgr.assign_role("user1", "viewer").await.unwrap();
893 assert!(mgr.user_has_role("user1", "viewer").await.unwrap());
894 }
895
896 #[tokio::test]
897 async fn test_assign_role_persists_to_storage() {
898 let mgr = make_manager();
899 mgr.create_role(Role::new("writer")).await.unwrap();
900 mgr.assign_role("u2", "writer").await.unwrap();
901 let data = mgr.storage.get_kv("rbac:user_roles:u2").await.unwrap();
902 assert!(data.is_some());
903 let roles: Vec<String> = serde_json::from_slice(&data.unwrap()).unwrap();
904 assert!(roles.contains(&"writer".to_string()));
905 }
906
907 #[tokio::test]
908 async fn test_assign_role_empty_user_rejected() {
909 let mgr = make_manager();
910 mgr.create_role(Role::new("r")).await.unwrap();
911 assert!(mgr.assign_role("", "r").await.is_err());
912 }
913
914 #[tokio::test]
915 async fn test_assign_role_empty_role_rejected() {
916 let mgr = make_manager();
917 assert!(mgr.assign_role("u", "").await.is_err());
918 }
919
920 #[tokio::test]
923 async fn test_remove_role_success() {
924 let mgr = make_manager();
925 mgr.create_role(Role::new("temp")).await.unwrap();
926 mgr.assign_role("u3", "temp").await.unwrap();
927 assert!(mgr.user_has_role("u3", "temp").await.unwrap());
928 mgr.remove_role("u3", "temp").await.unwrap();
929 assert!(!mgr.user_has_role("u3", "temp").await.unwrap());
930 }
931
932 #[tokio::test]
933 async fn test_remove_role_cleans_storage() {
934 let mgr = make_manager();
935 mgr.create_role(Role::new("temp")).await.unwrap();
936 mgr.assign_role("u4", "temp").await.unwrap();
937 mgr.remove_role("u4", "temp").await.unwrap();
938 let data = mgr.storage.get_kv("rbac:user_roles:u4").await.unwrap();
939 assert!(data.is_none());
941 }
942
943 #[tokio::test]
944 async fn test_remove_role_empty_params_rejected() {
945 let mgr = make_manager();
946 assert!(mgr.remove_role("", "role").await.is_err());
947 assert!(mgr.remove_role("user", "").await.is_err());
948 }
949
950 #[tokio::test]
953 async fn test_add_role_permission_success() {
954 let mgr = make_manager();
955 mgr.create_role(Role::new("admin")).await.unwrap();
956 let perm = Permission::new("write", "documents");
957 mgr.add_role_permission("admin", perm).await.unwrap();
958 let role = mgr.get_role("admin").await.unwrap();
959 assert!(
960 role.permissions
961 .iter()
962 .any(|p| p.action == "write" && p.resource == "documents")
963 );
964 }
965
966 #[tokio::test]
967 async fn test_add_role_permission_persists() {
968 let mgr = make_manager();
969 mgr.create_role(Role::new("admin2")).await.unwrap();
970 mgr.add_role_permission("admin2", Permission::new("read", "reports"))
971 .await
972 .unwrap();
973 let data = mgr
974 .storage
975 .get_kv("rbac:role:admin2")
976 .await
977 .unwrap()
978 .unwrap();
979 let role: Role = serde_json::from_slice(&data).unwrap();
980 assert!(role.permissions.iter().any(|p| p.action == "read"));
981 }
982
983 #[tokio::test]
984 async fn test_add_role_permission_nonexistent_role() {
985 let mgr = make_manager();
986 let result = mgr
987 .add_role_permission("ghost", Permission::new("x", "y"))
988 .await;
989 assert!(result.is_err());
990 }
991
992 #[tokio::test]
995 async fn test_set_role_inheritance_success() {
996 let mgr = make_manager();
997 mgr.create_role(Role::new("parent")).await.unwrap();
998 mgr.create_role(Role::new("child")).await.unwrap();
999 assert!(mgr.set_role_inheritance("child", "parent").await.is_ok());
1000 }
1001
1002 #[tokio::test]
1003 async fn test_set_role_inheritance_empty_names_rejected() {
1004 let mgr = make_manager();
1005 assert!(mgr.set_role_inheritance("", "parent").await.is_err());
1006 assert!(mgr.set_role_inheritance("child", "").await.is_err());
1007 }
1008
1009 #[tokio::test]
1012 async fn test_grant_and_check_permission() {
1013 let mgr = make_manager();
1014 mgr.grant_permission("u5", "read", "files").await.unwrap();
1015 assert!(mgr.check_user_permission("u5", "read", "files").await);
1016 }
1017
1018 #[tokio::test]
1019 async fn test_check_permission_not_granted() {
1020 let mgr = make_manager();
1021 assert!(!mgr.check_user_permission("u6", "delete", "files").await);
1022 }
1023
1024 #[tokio::test]
1025 async fn test_revoke_permission() {
1026 let mgr = make_manager();
1027 mgr.grant_permission("u7", "write", "data").await.unwrap();
1028 assert!(mgr.check_user_permission("u7", "write", "data").await);
1029 mgr.revoke_permission("u7", "write", "data").await.unwrap();
1030 assert!(!mgr.check_user_permission("u7", "write", "data").await);
1031 }
1032
1033 #[tokio::test]
1034 async fn test_revoke_permission_empty_params_rejected() {
1035 let mgr = make_manager();
1036 assert!(mgr.revoke_permission("", "a", "r").await.is_err());
1037 assert!(mgr.revoke_permission("u", "", "r").await.is_err());
1038 assert!(mgr.revoke_permission("u", "a", "").await.is_err());
1039 }
1040
1041 #[tokio::test]
1044 async fn test_user_has_role_false_when_not_assigned() {
1045 let mgr = make_manager();
1046 mgr.create_role(Role::new("r")).await.unwrap();
1047 assert!(!mgr.user_has_role("u", "r").await.unwrap());
1048 }
1049
1050 #[tokio::test]
1051 async fn test_user_has_role_empty_params_rejected() {
1052 let mgr = make_manager();
1053 assert!(mgr.user_has_role("", "r").await.is_err());
1054 assert!(mgr.user_has_role("u", "").await.is_err());
1055 }
1056
1057 #[tokio::test]
1060 async fn test_list_user_roles() {
1061 let mgr = make_manager();
1062 mgr.create_role(Role::new("a")).await.unwrap();
1063 mgr.create_role(Role::new("b")).await.unwrap();
1064 mgr.assign_role("u8", "a").await.unwrap();
1065 mgr.assign_role("u8", "b").await.unwrap();
1066 let roles = mgr.list_user_roles("u8").await.unwrap();
1067 assert!(roles.contains(&"a".to_string()));
1068 assert!(roles.contains(&"b".to_string()));
1069 }
1070
1071 #[tokio::test]
1072 async fn test_list_user_roles_empty_user_rejected() {
1073 let mgr = make_manager();
1074 assert!(mgr.list_user_roles("").await.is_err());
1075 }
1076
1077 #[tokio::test]
1080 async fn test_get_effective_permissions() {
1081 let mgr = make_manager();
1082 mgr.grant_permission("u9", "read", "docs").await.unwrap();
1083 let perms = mgr.get_effective_permissions("u9").await.unwrap();
1084 assert!(!perms.is_empty());
1085 }
1086
1087 #[tokio::test]
1088 async fn test_get_effective_permissions_empty_user_rejected() {
1089 let mgr = make_manager();
1090 assert!(mgr.get_effective_permissions("").await.is_err());
1091 }
1092
1093 #[tokio::test]
1096 async fn test_load_persisted_roles_restores_roles() {
1097 let storage: Arc<dyn AuthStorage> = Arc::new(MemoryStorage::new());
1098
1099 {
1101 let checker = Arc::new(RwLock::new(PermissionChecker::new()));
1102 let mgr = AuthorizationManager::new(checker, storage.clone());
1103 mgr.create_role(Role::new("restored_role")).await.unwrap();
1104 mgr.assign_role("restored_user", "restored_role")
1105 .await
1106 .unwrap();
1107 }
1108
1109 let checker2 = Arc::new(RwLock::new(PermissionChecker::new()));
1111 let mgr2 = AuthorizationManager::new(checker2, storage);
1112 mgr2.load_persisted_roles().await.unwrap();
1113
1114 assert!(mgr2.get_role("restored_role").await.is_ok());
1115 assert!(
1116 mgr2.user_has_role("restored_user", "restored_role")
1117 .await
1118 .unwrap()
1119 );
1120 }
1121
1122 #[tokio::test]
1123 async fn test_load_persisted_roles_empty_storage_ok() {
1124 let mgr = make_manager();
1125 assert!(mgr.load_persisted_roles().await.is_ok());
1126 }
1127
1128 #[tokio::test]
1131 async fn test_reset_runtime_state_clears_roles() {
1132 let mgr = make_manager();
1133 mgr.create_role(Role::new("custom")).await.unwrap();
1134 mgr.assign_role("u10", "custom").await.unwrap();
1135 mgr.reset_runtime_state().await;
1136 assert!(!mgr.user_has_role("u10", "custom").await.unwrap_or(false));
1137 assert!(
1139 mgr.storage
1140 .get_kv("rbac:role:custom")
1141 .await
1142 .unwrap()
1143 .is_none()
1144 );
1145 assert!(
1146 mgr.storage
1147 .get_kv("rbac:user_roles:u10")
1148 .await
1149 .unwrap()
1150 .is_none()
1151 );
1152 }
1153
1154 #[tokio::test]
1157 async fn test_create_abac_policy() {
1158 let mgr = make_manager();
1159 mgr.create_abac_policy("location_gate", "Restricts by location")
1160 .await
1161 .unwrap();
1162 let data = mgr
1163 .storage
1164 .get_kv("abac:policy:location_gate")
1165 .await
1166 .unwrap();
1167 assert!(data.is_some());
1168 }
1169
1170 #[tokio::test]
1171 async fn test_create_abac_policy_empty_name_rejected() {
1172 let mgr = make_manager();
1173 assert!(mgr.create_abac_policy("", "desc").await.is_err());
1174 }
1175
1176 #[tokio::test]
1177 async fn test_create_abac_policy_empty_description_rejected() {
1178 let mgr = make_manager();
1179 assert!(mgr.create_abac_policy("name", "").await.is_err());
1180 }
1181
1182 #[tokio::test]
1183 async fn test_map_and_get_user_attribute() {
1184 let mgr = make_manager();
1185 mgr.map_user_attribute("u11", "department", "engineering")
1186 .await
1187 .unwrap();
1188 let val = mgr.get_user_attribute("u11", "department").await.unwrap();
1189 assert_eq!(val.as_deref(), Some("engineering"));
1190 }
1191
1192 #[tokio::test]
1193 async fn test_get_user_attribute_nonexistent() {
1194 let mgr = make_manager();
1195 let val = mgr.get_user_attribute("nobody", "x").await.unwrap();
1196 assert!(val.is_none());
1197 }
1198
1199 #[tokio::test]
1200 async fn test_map_user_attribute_empty_params_rejected() {
1201 let mgr = make_manager();
1202 assert!(mgr.map_user_attribute("", "a", "v").await.is_err());
1203 assert!(mgr.map_user_attribute("u", "", "v").await.is_err());
1204 }
1205
1206 #[tokio::test]
1207 async fn test_get_user_attribute_empty_params_rejected() {
1208 let mgr = make_manager();
1209 assert!(mgr.get_user_attribute("", "x").await.is_err());
1210 assert!(mgr.get_user_attribute("u", "").await.is_err());
1211 }
1212
1213 #[tokio::test]
1216 async fn test_check_dynamic_permission_granted() {
1217 let mgr = make_manager();
1218 mgr.grant_permission("u12", "read", "reports")
1219 .await
1220 .unwrap();
1221 let ctx = std::collections::HashMap::new();
1222 assert!(
1223 mgr.check_dynamic_permission("u12", "read", "reports", ctx)
1224 .await
1225 .unwrap()
1226 );
1227 }
1228
1229 #[tokio::test]
1230 async fn test_check_dynamic_permission_denied_no_permission() {
1231 let mgr = make_manager();
1232 let ctx = std::collections::HashMap::new();
1233 assert!(
1234 !mgr.check_dynamic_permission("u13", "read", "reports", ctx)
1235 .await
1236 .unwrap()
1237 );
1238 }
1239
1240 #[tokio::test]
1241 async fn test_check_dynamic_permission_location_mismatch() {
1242 let mgr = make_manager();
1243 mgr.grant_permission("u14", "read", "files").await.unwrap();
1244 mgr.map_user_attribute("u14", "location", "US")
1245 .await
1246 .unwrap();
1247 let mut ctx = std::collections::HashMap::new();
1248 ctx.insert("required_location".to_string(), "EU".to_string());
1249 assert!(
1250 !mgr.check_dynamic_permission("u14", "read", "files", ctx)
1251 .await
1252 .unwrap()
1253 );
1254 }
1255
1256 #[tokio::test]
1257 async fn test_check_dynamic_permission_clearance_insufficient() {
1258 let mgr = make_manager();
1259 mgr.grant_permission("u15", "read", "secret").await.unwrap();
1260 mgr.map_user_attribute("u15", "clearance_level", "2")
1261 .await
1262 .unwrap();
1263 let mut ctx = std::collections::HashMap::new();
1264 ctx.insert("required_clearance".to_string(), "5".to_string());
1265 assert!(
1266 !mgr.check_dynamic_permission("u15", "read", "secret", ctx)
1267 .await
1268 .unwrap()
1269 );
1270 }
1271
1272 #[tokio::test]
1273 async fn test_check_dynamic_permission_empty_params_rejected() {
1274 let mgr = make_manager();
1275 let ctx = std::collections::HashMap::new();
1276 assert!(
1277 mgr.check_dynamic_permission("", "r", "x", ctx.clone())
1278 .await
1279 .is_err()
1280 );
1281 assert!(
1282 mgr.check_dynamic_permission("u", "", "x", ctx.clone())
1283 .await
1284 .is_err()
1285 );
1286 assert!(
1287 mgr.check_dynamic_permission("u", "r", "", ctx)
1288 .await
1289 .is_err()
1290 );
1291 }
1292
1293 #[tokio::test]
1296 async fn test_create_resource() {
1297 let mgr = make_manager();
1298 mgr.create_resource("documents").await.unwrap();
1299 let data = mgr.storage.get_kv("resource:documents").await.unwrap();
1300 assert!(data.is_some());
1301 }
1302
1303 #[tokio::test]
1304 async fn test_create_resource_empty_name_rejected() {
1305 let mgr = make_manager();
1306 assert!(mgr.create_resource("").await.is_err());
1307 }
1308
1309 #[tokio::test]
1312 async fn test_delegate_permission_success() {
1313 let mgr = make_manager();
1314 mgr.grant_permission("delegator", "read", "files")
1315 .await
1316 .unwrap();
1317 mgr.delegate_permission(
1318 "delegator",
1319 "delegatee",
1320 "read",
1321 "files",
1322 std::time::Duration::from_secs(3600),
1323 )
1324 .await
1325 .unwrap();
1326 let delegations = mgr.get_active_delegations("delegatee").await.unwrap();
1327 assert!(!delegations.is_empty());
1328 }
1329
1330 #[tokio::test]
1331 async fn test_delegate_permission_without_holding_it() {
1332 let mgr = make_manager();
1333 let result = mgr
1334 .delegate_permission(
1335 "delegator",
1336 "delegatee",
1337 "write",
1338 "files",
1339 std::time::Duration::from_secs(3600),
1340 )
1341 .await;
1342 assert!(result.is_err());
1343 }
1344
1345 #[tokio::test]
1346 async fn test_delegate_permission_empty_params_rejected() {
1347 let mgr = make_manager();
1348 let dur = std::time::Duration::from_secs(60);
1349 assert!(
1350 mgr.delegate_permission("", "d", "a", "r", dur)
1351 .await
1352 .is_err()
1353 );
1354 assert!(
1355 mgr.delegate_permission("d", "", "a", "r", dur)
1356 .await
1357 .is_err()
1358 );
1359 assert!(
1360 mgr.delegate_permission("d", "d2", "", "r", dur)
1361 .await
1362 .is_err()
1363 );
1364 assert!(
1365 mgr.delegate_permission("d", "d2", "a", "", dur)
1366 .await
1367 .is_err()
1368 );
1369 }
1370
1371 #[tokio::test]
1374 async fn test_get_active_delegations_empty() {
1375 let mgr = make_manager();
1376 let delegations = mgr.get_active_delegations("nobody").await.unwrap();
1377 assert!(delegations.is_empty());
1378 }
1379
1380 #[tokio::test]
1381 async fn test_get_active_delegations_empty_user_rejected() {
1382 let mgr = make_manager();
1383 assert!(mgr.get_active_delegations("").await.is_err());
1384 }
1385
1386 #[tokio::test]
1389 async fn test_get_permission_metrics() {
1390 let mgr = make_manager();
1391 mgr.create_default_roles().await;
1392 mgr.create_role(Role::new("custom")).await.unwrap();
1393 let metrics = mgr.get_permission_metrics(10, 100).await.unwrap();
1394 assert!(metrics.get("total_roles").copied().unwrap_or(0) > 0);
1395 assert_eq!(metrics["active_sessions"], 10);
1396 assert_eq!(metrics["permission_checks_last_hour"], 100);
1397 }
1398
1399 #[tokio::test]
1402 async fn test_get_metrics() {
1403 let mgr = make_manager();
1404 mgr.create_role(Role::new("m")).await.unwrap();
1405 mgr.grant_permission("u16", "a", "r").await.unwrap();
1406 let (roles, users, perms) = mgr.get_metrics().await;
1407 assert!(roles >= 1);
1408 assert!(users >= 1);
1409 assert!(perms >= 1);
1410 }
1411}