| use crate::{InternalApi, Result}; |
| |
| use async_trait::async_trait; |
| |
| #[async_trait] |
| pub trait MgmtApi: InternalApi { |
| async fn add_policy(&mut self, params: Vec<String>) -> Result<bool> { |
| self.add_named_policy("p", params).await |
| } |
| |
| async fn add_policies( |
| &mut self, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool> { |
| self.add_named_policies("p", paramss).await |
| } |
| |
| async fn remove_policy(&mut self, params: Vec<String>) -> Result<bool> { |
| self.remove_named_policy("p", params).await |
| } |
| |
| async fn remove_policies( |
| &mut self, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool> { |
| self.remove_named_policies("p", paramss).await |
| } |
| |
| async fn add_named_policy( |
| &mut self, |
| ptype: &str, |
| params: Vec<String>, |
| ) -> Result<bool>; |
| async fn add_named_policies( |
| &mut self, |
| ptype: &str, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool>; |
| async fn remove_named_policy( |
| &mut self, |
| ptype: &str, |
| params: Vec<String>, |
| ) -> Result<bool>; |
| async fn remove_named_policies( |
| &mut self, |
| ptype: &str, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool>; |
| |
| async fn add_grouping_policy( |
| &mut self, |
| params: Vec<String>, |
| ) -> Result<bool> { |
| self.add_named_grouping_policy("g", params).await |
| } |
| |
| async fn add_grouping_policies( |
| &mut self, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool> { |
| self.add_named_grouping_policies("g", paramss).await |
| } |
| |
| async fn remove_grouping_policy( |
| &mut self, |
| params: Vec<String>, |
| ) -> Result<bool> { |
| self.remove_named_grouping_policy("g", params).await |
| } |
| |
| async fn remove_grouping_policies( |
| &mut self, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool> { |
| self.remove_named_grouping_policies("g", paramss).await |
| } |
| |
| async fn add_named_grouping_policy( |
| &mut self, |
| ptype: &str, |
| params: Vec<String>, |
| ) -> Result<bool>; |
| async fn add_named_grouping_policies( |
| &mut self, |
| ptype: &str, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool>; |
| async fn remove_named_grouping_policy( |
| &mut self, |
| ptype: &str, |
| params: Vec<String>, |
| ) -> Result<bool>; |
| async fn remove_named_grouping_policies( |
| &mut self, |
| ptype: &str, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool>; |
| |
| async fn remove_filtered_policy( |
| &mut self, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Result<bool> { |
| self.remove_filtered_named_policy("p", field_index, field_values) |
| .await |
| } |
| |
| async fn remove_filtered_grouping_policy( |
| &mut self, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Result<bool> { |
| self.remove_filtered_named_grouping_policy( |
| "g", |
| field_index, |
| field_values, |
| ) |
| .await |
| } |
| |
| async fn remove_filtered_named_policy( |
| &mut self, |
| ptype: &str, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Result<bool>; |
| async fn remove_filtered_named_grouping_policy( |
| &mut self, |
| ptype: &str, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Result<bool>; |
| |
| fn get_policy(&self) -> Vec<Vec<String>> { |
| self.get_named_policy("p") |
| } |
| |
| fn get_all_policy(&self) -> Vec<Vec<String>>; |
| fn get_named_policy(&self, ptype: &str) -> Vec<Vec<String>>; |
| |
| fn get_filtered_policy( |
| &self, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Vec<Vec<String>> { |
| self.get_filtered_named_policy("p", field_index, field_values) |
| } |
| |
| fn get_filtered_named_policy( |
| &self, |
| ptype: &str, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Vec<Vec<String>>; |
| |
| fn has_policy(&self, params: Vec<String>) -> bool { |
| self.has_named_policy("p", params) |
| } |
| |
| fn has_named_policy(&self, ptype: &str, params: Vec<String>) -> bool; |
| |
| fn get_grouping_policy(&self) -> Vec<Vec<String>> { |
| self.get_named_grouping_policy("g") |
| } |
| |
| fn get_all_grouping_policy(&self) -> Vec<Vec<String>>; |
| fn get_named_grouping_policy(&self, ptype: &str) -> Vec<Vec<String>>; |
| |
| fn get_filtered_grouping_policy( |
| &self, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Vec<Vec<String>> { |
| self.get_filtered_named_grouping_policy("g", field_index, field_values) |
| } |
| |
| fn get_filtered_named_grouping_policy( |
| &self, |
| ptype: &str, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Vec<Vec<String>>; |
| fn has_grouping_policy(&self, params: Vec<String>) -> bool { |
| self.has_grouping_named_policy("g", params) |
| } |
| fn has_grouping_named_policy( |
| &self, |
| ptype: &str, |
| params: Vec<String>, |
| ) -> bool; |
| |
| fn get_all_subjects(&self) -> Vec<String> { |
| self.get_all_named_subjects("p") |
| } |
| |
| fn get_all_named_subjects(&self, ptype: &str) -> Vec<String>; |
| |
| fn get_all_objects(&self) -> Vec<String> { |
| self.get_all_named_objects("p") |
| } |
| |
| fn get_all_named_objects(&self, ptype: &str) -> Vec<String>; |
| |
| fn get_all_actions(&self) -> Vec<String> { |
| self.get_all_named_actions("p") |
| } |
| |
| fn get_all_roles(&self) -> Vec<String> { |
| self.get_all_named_roles("g") |
| } |
| |
| fn get_all_named_actions(&self, ptype: &str) -> Vec<String>; |
| |
| fn get_all_named_roles(&self, ptype: &str) -> Vec<String>; |
| } |
| |
| #[async_trait] |
| impl<T> MgmtApi for T |
| where |
| T: InternalApi, |
| { |
| async fn add_named_policy( |
| &mut self, |
| ptype: &str, |
| params: Vec<String>, |
| ) -> Result<bool> { |
| self.add_policy_internal("p", ptype, params).await |
| } |
| |
| async fn add_named_policies( |
| &mut self, |
| ptype: &str, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool> { |
| self.add_policies_internal("p", ptype, paramss).await |
| } |
| |
| async fn remove_named_policy( |
| &mut self, |
| ptype: &str, |
| params: Vec<String>, |
| ) -> Result<bool> { |
| self.remove_policy_internal("p", ptype, params).await |
| } |
| |
| async fn remove_named_policies( |
| &mut self, |
| ptype: &str, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool> { |
| self.remove_policies_internal("p", ptype, paramss).await |
| } |
| |
| async fn add_named_grouping_policy( |
| &mut self, |
| ptype: &str, |
| params: Vec<String>, |
| ) -> Result<bool> { |
| let rule_added = self.add_policy_internal("g", ptype, params).await?; |
| Ok(rule_added) |
| } |
| |
| async fn add_named_grouping_policies( |
| &mut self, |
| ptype: &str, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool> { |
| let all_added = self.add_policies_internal("g", ptype, paramss).await?; |
| Ok(all_added) |
| } |
| |
| async fn remove_named_grouping_policy( |
| &mut self, |
| ptype: &str, |
| params: Vec<String>, |
| ) -> Result<bool> { |
| let rule_removed = |
| self.remove_policy_internal("g", ptype, params).await?; |
| Ok(rule_removed) |
| } |
| |
| async fn remove_named_grouping_policies( |
| &mut self, |
| ptype: &str, |
| paramss: Vec<Vec<String>>, |
| ) -> Result<bool> { |
| let all_removed = |
| self.remove_policies_internal("g", ptype, paramss).await?; |
| Ok(all_removed) |
| } |
| |
| async fn remove_filtered_named_grouping_policy( |
| &mut self, |
| ptype: &str, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Result<bool> { |
| #[allow(unused_variables)] |
| let (rule_removed, rules) = self |
| .remove_filtered_policy_internal( |
| "g", |
| ptype, |
| field_index, |
| field_values, |
| ) |
| .await?; |
| Ok(rule_removed) |
| } |
| |
| async fn remove_filtered_named_policy( |
| &mut self, |
| ptype: &str, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Result<bool> { |
| Ok(self |
| .remove_filtered_policy_internal( |
| "p", |
| ptype, |
| field_index, |
| field_values, |
| ) |
| .await? |
| .0) |
| } |
| |
| fn get_named_policy(&self, ptype: &str) -> Vec<Vec<String>> { |
| self.get_model().get_policy("p", ptype) |
| } |
| |
| fn get_all_policy(&self) -> Vec<Vec<String>> { |
| let mut res: Vec<Vec<String>> = vec![]; |
| let sec = "p"; |
| if let Some(ast_map) = self.get_model().get_model().get(sec) { |
| for (ptype, ast) in ast_map { |
| res.extend(ast.get_policy().clone().into_iter().map(|mut x| { |
| x.insert(0, ptype.clone()); |
| x.insert(0, sec.to_owned()); |
| x |
| })) |
| } |
| } |
| |
| res |
| } |
| |
| fn get_filtered_named_policy( |
| &self, |
| ptype: &str, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Vec<Vec<String>> { |
| self.get_model().get_filtered_policy( |
| "p", |
| ptype, |
| field_index, |
| field_values, |
| ) |
| } |
| |
| fn has_named_policy(&self, ptype: &str, params: Vec<String>) -> bool { |
| self.get_model().has_policy("p", ptype, params) |
| } |
| |
| fn get_named_grouping_policy(&self, ptype: &str) -> Vec<Vec<String>> { |
| self.get_model().get_policy("g", ptype) |
| } |
| |
| fn get_all_grouping_policy(&self) -> Vec<Vec<String>> { |
| let mut res: Vec<Vec<String>> = vec![]; |
| let sec = "g"; |
| if let Some(ast_map) = self.get_model().get_model().get(sec) { |
| for (ptype, ast) in ast_map { |
| res.extend(ast.get_policy().clone().into_iter().map(|mut x| { |
| x.insert(0, ptype.clone()); |
| x.insert(0, sec.to_owned()); |
| x |
| })) |
| } |
| } |
| |
| res |
| } |
| |
| fn get_filtered_named_grouping_policy( |
| &self, |
| ptype: &str, |
| field_index: usize, |
| field_values: Vec<String>, |
| ) -> Vec<Vec<String>> { |
| self.get_model().get_filtered_policy( |
| "g", |
| ptype, |
| field_index, |
| field_values, |
| ) |
| } |
| |
| fn has_grouping_named_policy( |
| &self, |
| ptype: &str, |
| params: Vec<String>, |
| ) -> bool { |
| self.get_model().has_policy("g", ptype, params) |
| } |
| |
| fn get_all_named_subjects(&self, ptype: &str) -> Vec<String> { |
| self.get_model() |
| .get_values_for_field_in_policy("p", ptype, 0) |
| } |
| |
| fn get_all_named_objects(&self, ptype: &str) -> Vec<String> { |
| self.get_model() |
| .get_values_for_field_in_policy("p", ptype, 1) |
| } |
| |
| fn get_all_named_actions(&self, ptype: &str) -> Vec<String> { |
| self.get_model() |
| .get_values_for_field_in_policy("p", ptype, 2) |
| } |
| |
| fn get_all_named_roles(&self, ptype: &str) -> Vec<String> { |
| self.get_model() |
| .get_values_for_field_in_policy("g", ptype, 1) |
| } |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use crate::prelude::*; |
| |
| fn sort_unstable<T: Ord>(mut v: Vec<T>) -> Vec<T> { |
| v.sort_unstable(); |
| v |
| } |
| |
| #[cfg(not(target_arch = "wasm32"))] |
| #[cfg_attr( |
| all(feature = "runtime-async-std", not(target_arch = "wasm32")), |
| async_std::test |
| )] |
| #[cfg_attr( |
| all(feature = "runtime-tokio", not(target_arch = "wasm32")), |
| tokio::test |
| )] |
| async fn test_modify_grouping_policy_api() { |
| let m = DefaultModel::from_file("examples/rbac_model.conf") |
| .await |
| .unwrap(); |
| |
| let adapter = FileAdapter::new("examples/rbac_policy.csv"); |
| let mut e = Enforcer::new(m, adapter).await.unwrap(); |
| |
| assert_eq!(vec!["data2_admin"], e.get_roles_for_user("alice", None)); |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("bob", None)); |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("eve", None)); |
| assert_eq!( |
| vec![String::new(); 0], |
| e.get_roles_for_user("non_exist", None) |
| ); |
| |
| e.remove_grouping_policy( |
| vec!["alice", "data2_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| e.add_grouping_policy( |
| vec!["bob", "data1_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| e.add_grouping_policy( |
| vec!["eve", "data3_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| |
| let named_grouping_policy = |
| vec!["alice".to_string(), "data2_admin".to_string()]; |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("alice", None)); |
| e.add_named_grouping_policy("g", named_grouping_policy.clone()) |
| .await |
| .unwrap(); |
| assert_eq!(vec!["data2_admin"], e.get_roles_for_user("alice", None)); |
| e.remove_named_grouping_policy("g", named_grouping_policy.clone()) |
| .await |
| .unwrap(); |
| |
| e.remove_grouping_policy( |
| vec!["alice", "data2_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| e.add_grouping_policy( |
| vec!["bob", "data1_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| e.add_grouping_policy( |
| vec!["eve", "data3_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| |
| assert_eq!(vec!["bob"], e.get_users_for_role("data1_admin", None)); |
| assert_eq!( |
| vec![String::new(); 0], |
| e.get_users_for_role("data2_admin", None) |
| ); |
| assert_eq!(vec!["eve"], e.get_users_for_role("data3_admin", None)); |
| |
| e.remove_filtered_grouping_policy( |
| 0, |
| vec!["bob"].iter().map(|s| s.to_string()).collect(), |
| ) |
| .await |
| .unwrap(); |
| |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("alice", None)); |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("bob", None)); |
| assert_eq!(vec!["data3_admin"], e.get_roles_for_user("eve", None)); |
| assert_eq!( |
| vec![String::new(); 0], |
| e.get_roles_for_user("non_exist", None) |
| ); |
| |
| assert_eq!( |
| vec![String::new(); 0], |
| e.get_users_for_role("data1_admin", None) |
| ); |
| assert_eq!( |
| vec![String::new(); 0], |
| e.get_users_for_role("data2_admin", None) |
| ); |
| assert_eq!(vec!["eve"], e.get_users_for_role("data3_admin", None)); |
| } |
| |
| #[cfg(not(target_arch = "wasm32"))] |
| #[cfg_attr( |
| all(feature = "runtime-async-std", not(target_arch = "wasm32")), |
| async_std::test |
| )] |
| #[cfg_attr( |
| all(feature = "runtime-tokio", not(target_arch = "wasm32")), |
| tokio::test |
| )] |
| async fn test_modify_policy_api() { |
| let m = DefaultModel::from_file("examples/rbac_model.conf") |
| .await |
| .unwrap(); |
| |
| let adapter = FileAdapter::new("examples/rbac_policy.csv"); |
| let mut e = Enforcer::new(m, adapter).await.unwrap(); |
| |
| assert_eq!( |
| vec![ |
| vec!["alice", "data1", "read"], |
| vec!["bob", "data2", "write"], |
| vec!["data2_admin", "data2", "read"], |
| vec!["data2_admin", "data2", "write"], |
| ], |
| sort_unstable(e.get_policy()) |
| ); |
| |
| e.remove_policy( |
| vec!["alice", "data1", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| e.remove_policy( |
| vec!["bob", "data2", "write"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| e.remove_policy( |
| vec!["alice", "data1", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| e.add_policy( |
| vec!["eve", "data3", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| e.add_policy( |
| vec!["eve", "data3", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ) |
| .await |
| .unwrap(); |
| |
| let named_policy = |
| vec!["eve".to_string(), "data3".to_string(), "read".to_string()]; |
| e.remove_named_policy("p", named_policy.clone()) |
| .await |
| .unwrap(); |
| e.add_named_policy("p", named_policy.clone()).await.unwrap(); |
| |
| assert_eq!( |
| vec![ |
| vec!["data2_admin", "data2", "read"], |
| vec!["data2_admin", "data2", "write"], |
| vec!["eve", "data3", "read"], |
| ], |
| sort_unstable(e.get_policy()) |
| ); |
| |
| e.remove_filtered_policy( |
| 1, |
| vec!["data2"].iter().map(|s| s.to_string()).collect(), |
| ) |
| .await |
| .unwrap(); |
| assert_eq!(vec![vec!["eve", "data3", "read"],], e.get_policy()); |
| } |
| |
| #[cfg(not(target_arch = "wasm32"))] |
| #[cfg_attr( |
| all(feature = "runtime-async-std", not(target_arch = "wasm32")), |
| async_std::test |
| )] |
| #[cfg_attr( |
| all(feature = "runtime-tokio", not(target_arch = "wasm32")), |
| tokio::test |
| )] |
| async fn test_get_policy_api() { |
| let m = DefaultModel::from_file("examples/rbac_model.conf") |
| .await |
| .unwrap(); |
| |
| let adapter = FileAdapter::new("examples/rbac_policy.csv"); |
| let e = Enforcer::new(m, adapter).await.unwrap(); |
| |
| assert_eq!( |
| vec![ |
| vec!["alice", "data1", "read"], |
| vec!["bob", "data2", "write"], |
| vec!["data2_admin", "data2", "read"], |
| vec!["data2_admin", "data2", "write"], |
| ], |
| sort_unstable(e.get_policy()) |
| ); |
| |
| assert_eq!( |
| vec![vec!["alice", "data1", "read"]], |
| e.get_filtered_policy( |
| 0, |
| vec!["alice"].iter().map(|s| s.to_string()).collect() |
| ) |
| ); |
| assert_eq!( |
| vec![vec!["bob", "data2", "write"]], |
| e.get_filtered_policy( |
| 0, |
| vec!["bob"].iter().map(|s| s.to_string()).collect() |
| ) |
| ); |
| assert_eq!( |
| vec![ |
| vec!["data2_admin", "data2", "read"], |
| vec!["data2_admin", "data2", "write"], |
| ], |
| sort_unstable(e.get_filtered_policy( |
| 0, |
| vec!["data2_admin"].iter().map(|s| s.to_string()).collect() |
| )) |
| ); |
| assert_eq!( |
| vec![vec!["alice", "data1", "read"],], |
| e.get_filtered_policy( |
| 1, |
| vec!["data1"].iter().map(|s| s.to_string()).collect() |
| ) |
| ); |
| assert_eq!( |
| vec![ |
| vec!["bob", "data2", "write"], |
| vec!["data2_admin", "data2", "read"], |
| vec!["data2_admin", "data2", "write"], |
| ], |
| sort_unstable(e.get_filtered_policy( |
| 1, |
| vec!["data2"].iter().map(|s| s.to_string()).collect() |
| )) |
| ); |
| assert_eq!( |
| vec![ |
| vec!["alice", "data1", "read"], |
| vec!["data2_admin", "data2", "read"], |
| ], |
| sort_unstable(e.get_filtered_policy( |
| 2, |
| vec!["read"].iter().map(|s| s.to_string()).collect() |
| )) |
| ); |
| assert_eq!( |
| vec![ |
| vec!["bob", "data2", "write"], |
| vec!["data2_admin", "data2", "write"], |
| ], |
| sort_unstable(e.get_filtered_policy( |
| 2, |
| vec!["write"].iter().map(|s| s.to_string()).collect() |
| )) |
| ); |
| assert_eq!( |
| vec![ |
| vec!["data2_admin", "data2", "read"], |
| vec!["data2_admin", "data2", "write"], |
| ], |
| sort_unstable( |
| e.get_filtered_policy( |
| 0, |
| vec!["data2_admin", "data2"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ) |
| ); |
| // Note: "" (empty string) in fieldValues means matching all values. |
| assert_eq!( |
| vec![vec!["data2_admin", "data2", "read"],], |
| e.get_filtered_policy( |
| 0, |
| vec!["data2_admin", "", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| vec![ |
| vec!["bob", "data2", "write"], |
| vec!["data2_admin", "data2", "write"], |
| ], |
| sort_unstable( |
| e.get_filtered_policy( |
| 1, |
| vec!["data2", "write"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ) |
| ); |
| |
| assert_eq!( |
| true, |
| e.has_policy( |
| vec!["alice", "data1", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| true, |
| e.has_policy( |
| vec!["bob", "data2", "write"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| false, |
| e.has_policy( |
| vec!["alice", "data2", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| false, |
| e.has_policy( |
| vec!["bob", "data3", "write"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| |
| assert_eq!( |
| vec![vec!["alice", "data2_admin"]], |
| e.get_filtered_grouping_policy( |
| 0, |
| vec!["alice"].iter().map(|s| s.to_string()).collect() |
| ) |
| ); |
| let empty_policy: Vec<Vec<String>> = vec![]; |
| assert_eq!( |
| empty_policy, |
| e.get_filtered_grouping_policy( |
| 0, |
| vec!["bob"].iter().map(|s| s.to_string()).collect() |
| ) |
| ); |
| assert_eq!( |
| empty_policy, |
| e.get_filtered_grouping_policy( |
| 1, |
| vec!["data1_admin"].iter().map(|s| s.to_string()).collect() |
| ) |
| ); |
| assert_eq!( |
| vec![vec!["alice", "data2_admin"],], |
| e.get_filtered_grouping_policy( |
| 1, |
| vec!["data2_admin"].iter().map(|s| s.to_string()).collect() |
| ) |
| ); |
| // Note: "" (empty string) in fieldValues means matching all values. |
| assert_eq!( |
| empty_policy, |
| e.get_filtered_grouping_policy( |
| 0, |
| vec!["data2_admin"].iter().map(|s| s.to_string()).collect() |
| ) |
| ); |
| |
| assert_eq!( |
| true, |
| e.has_grouping_policy( |
| vec!["alice", "data2_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| false, |
| e.has_grouping_policy( |
| vec!["bob", "data2_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| } |
| |
| #[cfg(not(target_arch = "wasm32"))] |
| #[cfg_attr( |
| all(feature = "runtime-async-std", not(target_arch = "wasm32")), |
| async_std::test |
| )] |
| #[cfg_attr( |
| all(feature = "runtime-tokio", not(target_arch = "wasm32")), |
| tokio::test |
| )] |
| async fn test_get_list() { |
| let m = DefaultModel::from_file("examples/rbac_model.conf") |
| .await |
| .unwrap(); |
| |
| let adapter = FileAdapter::new("examples/rbac_policy.csv"); |
| let e = Enforcer::new(m, adapter).await.unwrap(); |
| |
| assert_eq!( |
| vec!["alice", "bob", "data2_admin"], |
| sort_unstable(e.get_all_subjects()) |
| ); |
| assert_eq!(vec!["data1", "data2"], sort_unstable(e.get_all_objects())); |
| assert_eq!(vec!["read", "write"], sort_unstable(e.get_all_actions())); |
| assert_eq!(vec!["data2_admin"], e.get_all_roles()); |
| } |
| |
| #[cfg(not(target_arch = "wasm32"))] |
| #[cfg_attr( |
| all(feature = "runtime-async-std", not(target_arch = "wasm32")), |
| async_std::test |
| )] |
| #[cfg_attr( |
| all(feature = "runtime-tokio", not(target_arch = "wasm32")), |
| tokio::test |
| )] |
| async fn test_modify_policies_api() { |
| let m = DefaultModel::from_file("examples/rbac_model.conf") |
| .await |
| .unwrap(); |
| |
| let adapter = FileAdapter::new("examples/rbac_policy.csv"); |
| let mut e = Enforcer::new(m, adapter).await.unwrap(); |
| |
| assert_eq!( |
| vec![ |
| vec!["alice", "data1", "read"], |
| vec!["bob", "data2", "write"], |
| vec!["data2_admin", "data2", "read"], |
| vec!["data2_admin", "data2", "write"], |
| ], |
| sort_unstable(e.get_policy()) |
| ); |
| |
| e.remove_policies(vec![ |
| vec!["alice", "data1", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| vec!["bob", "data2", "write"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ]) |
| .await |
| .unwrap(); |
| e.remove_policies(vec![vec!["alice", "data1", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect()]) |
| .await |
| .unwrap(); |
| assert_eq!( |
| false, |
| e.has_policy( |
| vec!["alice", "data1", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| false, |
| e.has_policy( |
| vec!["bob", "data2", "write"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| true, |
| e.has_policy( |
| vec!["data2_admin", "data2", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| true, |
| e.has_policy( |
| vec!["data2_admin", "data2", "write"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| e.add_policies(vec![vec!["eve", "data3", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect()]) |
| .await |
| .unwrap(); |
| e.add_policies(vec![ |
| vec!["eve", "data3", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| vec!["eve", "data3", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ]) |
| .await |
| .unwrap(); |
| assert_eq!( |
| false, |
| e.has_policy( |
| vec!["alice", "data1", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| false, |
| e.has_policy( |
| vec!["bob", "data2", "write"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| true, |
| e.has_policy( |
| vec!["eve", "data3", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| true, |
| e.has_policy( |
| vec!["data2_admin", "data2", "read"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| assert_eq!( |
| true, |
| e.has_policy( |
| vec!["data2_admin", "data2", "write"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect() |
| ) |
| ); |
| |
| let named_policy = |
| vec!["eve".to_string(), "data3".to_string(), "read".to_string()]; |
| e.remove_named_policies("p", vec![named_policy.clone()]) |
| .await |
| .unwrap(); |
| e.add_named_policies("p", vec![named_policy.clone()]) |
| .await |
| .unwrap(); |
| |
| assert_eq!( |
| vec![ |
| vec!["data2_admin", "data2", "read"], |
| vec!["data2_admin", "data2", "write"], |
| vec!["eve", "data3", "read"], |
| ], |
| sort_unstable(e.get_policy()) |
| ); |
| |
| e.remove_filtered_policy( |
| 1, |
| vec!["data2"].iter().map(|s| s.to_string()).collect(), |
| ) |
| .await |
| .unwrap(); |
| assert_eq!(vec![vec!["eve", "data3", "read"],], e.get_policy()); |
| } |
| |
| #[cfg(not(target_arch = "wasm32"))] |
| #[cfg_attr( |
| all(feature = "runtime-async-std", not(target_arch = "wasm32")), |
| async_std::test |
| )] |
| #[cfg_attr( |
| all(feature = "runtime-tokio", not(target_arch = "wasm32")), |
| tokio::test |
| )] |
| async fn test_modify_grouping_policies_api() { |
| let m = DefaultModel::from_file("examples/rbac_model.conf") |
| .await |
| .unwrap(); |
| |
| let adapter = FileAdapter::new("examples/rbac_policy.csv"); |
| let mut e = Enforcer::new(m, adapter).await.unwrap(); |
| |
| assert_eq!(vec!["data2_admin"], e.get_roles_for_user("alice", None)); |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("bob", None)); |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("eve", None)); |
| assert_eq!( |
| vec![String::new(); 0], |
| e.get_roles_for_user("non_exist", None) |
| ); |
| |
| e.remove_grouping_policies(vec![vec!["alice", "data2_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect()]) |
| .await |
| .unwrap(); |
| e.add_grouping_policies(vec![ |
| vec!["bob", "data1_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| vec!["eve", "data3_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ]) |
| .await |
| .unwrap(); |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("alice", None)); |
| assert_eq!(vec!["data1_admin"], e.get_roles_for_user("bob", None)); |
| assert_eq!(vec!["data3_admin"], e.get_roles_for_user("eve", None)); |
| |
| let named_grouping_policy = |
| vec!["alice".to_string(), "data2_admin".to_string()]; |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("alice", None)); |
| e.add_named_grouping_policies("g", vec![named_grouping_policy.clone()]) |
| .await |
| .unwrap(); |
| assert_eq!(vec!["data2_admin"], e.get_roles_for_user("alice", None)); |
| e.remove_named_grouping_policies( |
| "g", |
| vec![named_grouping_policy.clone()], |
| ) |
| .await |
| .unwrap(); |
| |
| e.remove_grouping_policies(vec![vec!["alice", "data2_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect()]) |
| .await |
| .unwrap(); |
| |
| e.add_grouping_policies(vec![ |
| vec!["bob", "data1_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| vec!["eve", "data3_admin"] |
| .iter() |
| .map(|s| s.to_string()) |
| .collect(), |
| ]) |
| .await |
| .unwrap(); |
| |
| assert_eq!(vec!["bob"], e.get_users_for_role("data1_admin", None)); |
| assert_eq!( |
| vec![String::new(); 0], |
| e.get_users_for_role("data2_admin", None) |
| ); |
| assert_eq!(vec!["eve"], e.get_users_for_role("data3_admin", None)); |
| |
| e.remove_filtered_grouping_policy( |
| 0, |
| vec!["bob"].iter().map(|s| s.to_string()).collect(), |
| ) |
| .await |
| .unwrap(); |
| |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("alice", None)); |
| assert_eq!(vec![String::new(); 0], e.get_roles_for_user("bob", None)); |
| assert_eq!(vec!["data3_admin"], e.get_roles_for_user("eve", None)); |
| assert_eq!( |
| vec![String::new(); 0], |
| e.get_roles_for_user("non_exist", None) |
| ); |
| |
| assert_eq!( |
| vec![String::new(); 0], |
| e.get_users_for_role("data1_admin", None) |
| ); |
| assert_eq!( |
| vec![String::new(); 0], |
| e.get_users_for_role("data2_admin", None) |
| ); |
| assert_eq!(vec!["eve"], e.get_users_for_role("data3_admin", None)); |
| } |
| } |