1use crate::{InternalApi, Result};
2
3use async_trait::async_trait;
4
5#[async_trait]
6pub trait MgmtApi: InternalApi {
7 async fn add_policy(&mut self, params: Vec<String>) -> Result<bool> {
8 self.add_named_policy("p", params).await
9 }
10
11 async fn add_policies(
12 &mut self,
13 paramss: Vec<Vec<String>>,
14 ) -> Result<bool> {
15 self.add_named_policies("p", paramss).await
16 }
17
18 async fn remove_policy(&mut self, params: Vec<String>) -> Result<bool> {
19 self.remove_named_policy("p", params).await
20 }
21
22 async fn remove_policies(
23 &mut self,
24 paramss: Vec<Vec<String>>,
25 ) -> Result<bool> {
26 self.remove_named_policies("p", paramss).await
27 }
28
29 async fn add_named_policy(
30 &mut self,
31 ptype: &str,
32 params: Vec<String>,
33 ) -> Result<bool>;
34 async fn add_named_policies(
35 &mut self,
36 ptype: &str,
37 paramss: Vec<Vec<String>>,
38 ) -> Result<bool>;
39 async fn remove_named_policy(
40 &mut self,
41 ptype: &str,
42 params: Vec<String>,
43 ) -> Result<bool>;
44 async fn remove_named_policies(
45 &mut self,
46 ptype: &str,
47 paramss: Vec<Vec<String>>,
48 ) -> Result<bool>;
49
50 async fn add_grouping_policy(
51 &mut self,
52 params: Vec<String>,
53 ) -> Result<bool> {
54 self.add_named_grouping_policy("g", params).await
55 }
56
57 async fn add_grouping_policies(
58 &mut self,
59 paramss: Vec<Vec<String>>,
60 ) -> Result<bool> {
61 self.add_named_grouping_policies("g", paramss).await
62 }
63
64 async fn remove_grouping_policy(
65 &mut self,
66 params: Vec<String>,
67 ) -> Result<bool> {
68 self.remove_named_grouping_policy("g", params).await
69 }
70
71 async fn remove_grouping_policies(
72 &mut self,
73 paramss: Vec<Vec<String>>,
74 ) -> Result<bool> {
75 self.remove_named_grouping_policies("g", paramss).await
76 }
77
78 async fn add_named_grouping_policy(
79 &mut self,
80 ptype: &str,
81 params: Vec<String>,
82 ) -> Result<bool>;
83 async fn add_named_grouping_policies(
84 &mut self,
85 ptype: &str,
86 paramss: Vec<Vec<String>>,
87 ) -> Result<bool>;
88 async fn remove_named_grouping_policy(
89 &mut self,
90 ptype: &str,
91 params: Vec<String>,
92 ) -> Result<bool>;
93 async fn remove_named_grouping_policies(
94 &mut self,
95 ptype: &str,
96 paramss: Vec<Vec<String>>,
97 ) -> Result<bool>;
98
99 async fn remove_filtered_policy(
100 &mut self,
101 field_index: usize,
102 field_values: Vec<String>,
103 ) -> Result<bool> {
104 self.remove_filtered_named_policy("p", field_index, field_values)
105 .await
106 }
107
108 async fn remove_filtered_grouping_policy(
109 &mut self,
110 field_index: usize,
111 field_values: Vec<String>,
112 ) -> Result<bool> {
113 self.remove_filtered_named_grouping_policy(
114 "g",
115 field_index,
116 field_values,
117 )
118 .await
119 }
120
121 async fn remove_filtered_named_policy(
122 &mut self,
123 ptype: &str,
124 field_index: usize,
125 field_values: Vec<String>,
126 ) -> Result<bool>;
127 async fn remove_filtered_named_grouping_policy(
128 &mut self,
129 ptype: &str,
130 field_index: usize,
131 field_values: Vec<String>,
132 ) -> Result<bool>;
133
134 fn get_policy(&self) -> Vec<Vec<String>> {
135 self.get_named_policy("p")
136 }
137
138 fn get_all_policy(&self) -> Vec<Vec<String>>;
139 fn get_named_policy(&self, ptype: &str) -> Vec<Vec<String>>;
140
141 fn get_filtered_policy(
142 &self,
143 field_index: usize,
144 field_values: Vec<String>,
145 ) -> Vec<Vec<String>> {
146 self.get_filtered_named_policy("p", field_index, field_values)
147 }
148
149 fn get_filtered_named_policy(
150 &self,
151 ptype: &str,
152 field_index: usize,
153 field_values: Vec<String>,
154 ) -> Vec<Vec<String>>;
155
156 fn has_policy(&self, params: Vec<String>) -> bool {
157 self.has_named_policy("p", params)
158 }
159
160 fn has_named_policy(&self, ptype: &str, params: Vec<String>) -> bool;
161
162 fn get_grouping_policy(&self) -> Vec<Vec<String>> {
163 self.get_named_grouping_policy("g")
164 }
165
166 fn get_all_grouping_policy(&self) -> Vec<Vec<String>>;
167 fn get_named_grouping_policy(&self, ptype: &str) -> Vec<Vec<String>>;
168
169 fn get_filtered_grouping_policy(
170 &self,
171 field_index: usize,
172 field_values: Vec<String>,
173 ) -> Vec<Vec<String>> {
174 self.get_filtered_named_grouping_policy("g", field_index, field_values)
175 }
176
177 fn get_filtered_named_grouping_policy(
178 &self,
179 ptype: &str,
180 field_index: usize,
181 field_values: Vec<String>,
182 ) -> Vec<Vec<String>>;
183 fn has_grouping_policy(&self, params: Vec<String>) -> bool {
184 self.has_grouping_named_policy("g", params)
185 }
186 fn has_grouping_named_policy(
187 &self,
188 ptype: &str,
189 params: Vec<String>,
190 ) -> bool;
191
192 fn get_all_subjects(&self) -> Vec<String> {
193 self.get_all_named_subjects("p")
194 }
195
196 fn get_all_named_subjects(&self, ptype: &str) -> Vec<String>;
197
198 fn get_all_objects(&self) -> Vec<String> {
199 self.get_all_named_objects("p")
200 }
201
202 fn get_all_named_objects(&self, ptype: &str) -> Vec<String>;
203
204 fn get_all_actions(&self) -> Vec<String> {
205 self.get_all_named_actions("p")
206 }
207
208 fn get_all_roles(&self) -> Vec<String> {
209 self.get_all_named_roles("g")
210 }
211
212 fn get_all_named_actions(&self, ptype: &str) -> Vec<String>;
213
214 fn get_all_named_roles(&self, ptype: &str) -> Vec<String>;
215}
216
217#[async_trait]
218impl<T> MgmtApi for T
219where
220 T: InternalApi,
221{
222 async fn add_named_policy(
223 &mut self,
224 ptype: &str,
225 params: Vec<String>,
226 ) -> Result<bool> {
227 self.add_policy_internal("p", ptype, params).await
228 }
229
230 async fn add_named_policies(
231 &mut self,
232 ptype: &str,
233 paramss: Vec<Vec<String>>,
234 ) -> Result<bool> {
235 self.add_policies_internal("p", ptype, paramss).await
236 }
237
238 async fn remove_named_policy(
239 &mut self,
240 ptype: &str,
241 params: Vec<String>,
242 ) -> Result<bool> {
243 self.remove_policy_internal("p", ptype, params).await
244 }
245
246 async fn remove_named_policies(
247 &mut self,
248 ptype: &str,
249 paramss: Vec<Vec<String>>,
250 ) -> Result<bool> {
251 self.remove_policies_internal("p", ptype, paramss).await
252 }
253
254 async fn add_named_grouping_policy(
255 &mut self,
256 ptype: &str,
257 params: Vec<String>,
258 ) -> Result<bool> {
259 let rule_added = self.add_policy_internal("g", ptype, params).await?;
260 Ok(rule_added)
261 }
262
263 async fn add_named_grouping_policies(
264 &mut self,
265 ptype: &str,
266 paramss: Vec<Vec<String>>,
267 ) -> Result<bool> {
268 let all_added = self.add_policies_internal("g", ptype, paramss).await?;
269 Ok(all_added)
270 }
271
272 async fn remove_named_grouping_policy(
273 &mut self,
274 ptype: &str,
275 params: Vec<String>,
276 ) -> Result<bool> {
277 let rule_removed =
278 self.remove_policy_internal("g", ptype, params).await?;
279 Ok(rule_removed)
280 }
281
282 async fn remove_named_grouping_policies(
283 &mut self,
284 ptype: &str,
285 paramss: Vec<Vec<String>>,
286 ) -> Result<bool> {
287 let all_removed =
288 self.remove_policies_internal("g", ptype, paramss).await?;
289 Ok(all_removed)
290 }
291
292 async fn remove_filtered_named_grouping_policy(
293 &mut self,
294 ptype: &str,
295 field_index: usize,
296 field_values: Vec<String>,
297 ) -> Result<bool> {
298 #[allow(unused_variables)]
299 let (rule_removed, rules) = self
300 .remove_filtered_policy_internal(
301 "g",
302 ptype,
303 field_index,
304 field_values,
305 )
306 .await?;
307 Ok(rule_removed)
308 }
309
310 async fn remove_filtered_named_policy(
311 &mut self,
312 ptype: &str,
313 field_index: usize,
314 field_values: Vec<String>,
315 ) -> Result<bool> {
316 Ok(self
317 .remove_filtered_policy_internal(
318 "p",
319 ptype,
320 field_index,
321 field_values,
322 )
323 .await?
324 .0)
325 }
326
327 fn get_named_policy(&self, ptype: &str) -> Vec<Vec<String>> {
328 self.get_model().get_policy("p", ptype)
329 }
330
331 fn get_all_policy(&self) -> Vec<Vec<String>> {
332 let mut res: Vec<Vec<String>> = vec![];
333 let sec = "p";
334 if let Some(ast_map) = self.get_model().get_model().get(sec) {
335 for (ptype, ast) in ast_map {
336 res.extend(ast.get_policy().clone().into_iter().map(|mut x| {
337 x.insert(0, ptype.clone());
338 x.insert(0, sec.to_owned());
339 x
340 }))
341 }
342 }
343
344 res
345 }
346
347 fn get_filtered_named_policy(
348 &self,
349 ptype: &str,
350 field_index: usize,
351 field_values: Vec<String>,
352 ) -> Vec<Vec<String>> {
353 self.get_model().get_filtered_policy(
354 "p",
355 ptype,
356 field_index,
357 field_values,
358 )
359 }
360
361 fn has_named_policy(&self, ptype: &str, params: Vec<String>) -> bool {
362 self.get_model().has_policy("p", ptype, params)
363 }
364
365 fn get_named_grouping_policy(&self, ptype: &str) -> Vec<Vec<String>> {
366 self.get_model().get_policy("g", ptype)
367 }
368
369 fn get_all_grouping_policy(&self) -> Vec<Vec<String>> {
370 let mut res: Vec<Vec<String>> = vec![];
371 let sec = "g";
372 if let Some(ast_map) = self.get_model().get_model().get(sec) {
373 for (ptype, ast) in ast_map {
374 res.extend(ast.get_policy().clone().into_iter().map(|mut x| {
375 x.insert(0, ptype.clone());
376 x.insert(0, sec.to_owned());
377 x
378 }))
379 }
380 }
381
382 res
383 }
384
385 fn get_filtered_named_grouping_policy(
386 &self,
387 ptype: &str,
388 field_index: usize,
389 field_values: Vec<String>,
390 ) -> Vec<Vec<String>> {
391 self.get_model().get_filtered_policy(
392 "g",
393 ptype,
394 field_index,
395 field_values,
396 )
397 }
398
399 fn has_grouping_named_policy(
400 &self,
401 ptype: &str,
402 params: Vec<String>,
403 ) -> bool {
404 self.get_model().has_policy("g", ptype, params)
405 }
406
407 fn get_all_named_subjects(&self, ptype: &str) -> Vec<String> {
408 self.get_model()
409 .get_values_for_field_in_policy("p", ptype, 0)
410 }
411
412 fn get_all_named_objects(&self, ptype: &str) -> Vec<String> {
413 self.get_model()
414 .get_values_for_field_in_policy("p", ptype, 1)
415 }
416
417 fn get_all_named_actions(&self, ptype: &str) -> Vec<String> {
418 self.get_model()
419 .get_values_for_field_in_policy("p", ptype, 2)
420 }
421
422 fn get_all_named_roles(&self, ptype: &str) -> Vec<String> {
423 self.get_model()
424 .get_values_for_field_in_policy("g", ptype, 1)
425 }
426}
427
428#[cfg(test)]
429mod tests {
430 use crate::prelude::*;
431
432 fn sort_unstable<T: Ord>(mut v: Vec<T>) -> Vec<T> {
433 v.sort_unstable();
434 v
435 }
436
437 #[cfg(not(target_arch = "wasm32"))]
438 #[cfg_attr(
439 all(feature = "runtime-async-std", not(target_arch = "wasm32")),
440 async_std::test
441 )]
442 #[cfg_attr(
443 all(feature = "runtime-tokio", not(target_arch = "wasm32")),
444 tokio::test
445 )]
446 async fn test_modify_grouping_policy_api() {
447 let m = DefaultModel::from_file("examples/rbac_model.conf")
448 .await
449 .unwrap();
450
451 let adapter = FileAdapter::new("examples/rbac_policy.csv");
452 let mut e = Enforcer::new(m, adapter).await.unwrap();
453
454 assert_eq!(vec!["data2_admin"], e.get_roles_for_user("alice", None));
455 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("bob", None));
456 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("eve", None));
457 assert_eq!(
458 vec![String::new(); 0],
459 e.get_roles_for_user("non_exist", None)
460 );
461
462 e.remove_grouping_policy(
463 vec!["alice", "data2_admin"]
464 .iter()
465 .map(|s| s.to_string())
466 .collect(),
467 )
468 .await
469 .unwrap();
470 e.add_grouping_policy(
471 vec!["bob", "data1_admin"]
472 .iter()
473 .map(|s| s.to_string())
474 .collect(),
475 )
476 .await
477 .unwrap();
478 e.add_grouping_policy(
479 vec!["eve", "data3_admin"]
480 .iter()
481 .map(|s| s.to_string())
482 .collect(),
483 )
484 .await
485 .unwrap();
486
487 let named_grouping_policy =
488 vec!["alice".to_string(), "data2_admin".to_string()];
489 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("alice", None));
490 e.add_named_grouping_policy("g", named_grouping_policy.clone())
491 .await
492 .unwrap();
493 assert_eq!(vec!["data2_admin"], e.get_roles_for_user("alice", None));
494 e.remove_named_grouping_policy("g", named_grouping_policy.clone())
495 .await
496 .unwrap();
497
498 e.remove_grouping_policy(
499 vec!["alice", "data2_admin"]
500 .iter()
501 .map(|s| s.to_string())
502 .collect(),
503 )
504 .await
505 .unwrap();
506 e.add_grouping_policy(
507 vec!["bob", "data1_admin"]
508 .iter()
509 .map(|s| s.to_string())
510 .collect(),
511 )
512 .await
513 .unwrap();
514 e.add_grouping_policy(
515 vec!["eve", "data3_admin"]
516 .iter()
517 .map(|s| s.to_string())
518 .collect(),
519 )
520 .await
521 .unwrap();
522
523 assert_eq!(vec!["bob"], e.get_users_for_role("data1_admin", None));
524 assert_eq!(
525 vec![String::new(); 0],
526 e.get_users_for_role("data2_admin", None)
527 );
528 assert_eq!(vec!["eve"], e.get_users_for_role("data3_admin", None));
529
530 e.remove_filtered_grouping_policy(
531 0,
532 vec!["bob"].iter().map(|s| s.to_string()).collect(),
533 )
534 .await
535 .unwrap();
536
537 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("alice", None));
538 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("bob", None));
539 assert_eq!(vec!["data3_admin"], e.get_roles_for_user("eve", None));
540 assert_eq!(
541 vec![String::new(); 0],
542 e.get_roles_for_user("non_exist", None)
543 );
544
545 assert_eq!(
546 vec![String::new(); 0],
547 e.get_users_for_role("data1_admin", None)
548 );
549 assert_eq!(
550 vec![String::new(); 0],
551 e.get_users_for_role("data2_admin", None)
552 );
553 assert_eq!(vec!["eve"], e.get_users_for_role("data3_admin", None));
554 }
555
556 #[cfg(not(target_arch = "wasm32"))]
557 #[cfg_attr(
558 all(feature = "runtime-async-std", not(target_arch = "wasm32")),
559 async_std::test
560 )]
561 #[cfg_attr(
562 all(feature = "runtime-tokio", not(target_arch = "wasm32")),
563 tokio::test
564 )]
565 async fn test_modify_policy_api() {
566 let m = DefaultModel::from_file("examples/rbac_model.conf")
567 .await
568 .unwrap();
569
570 let adapter = FileAdapter::new("examples/rbac_policy.csv");
571 let mut e = Enforcer::new(m, adapter).await.unwrap();
572
573 assert_eq!(
574 vec![
575 vec!["alice", "data1", "read"],
576 vec!["bob", "data2", "write"],
577 vec!["data2_admin", "data2", "read"],
578 vec!["data2_admin", "data2", "write"],
579 ],
580 sort_unstable(e.get_policy())
581 );
582
583 e.remove_policy(
584 vec!["alice", "data1", "read"]
585 .iter()
586 .map(|s| s.to_string())
587 .collect(),
588 )
589 .await
590 .unwrap();
591 e.remove_policy(
592 vec!["bob", "data2", "write"]
593 .iter()
594 .map(|s| s.to_string())
595 .collect(),
596 )
597 .await
598 .unwrap();
599 e.remove_policy(
600 vec!["alice", "data1", "read"]
601 .iter()
602 .map(|s| s.to_string())
603 .collect(),
604 )
605 .await
606 .unwrap();
607 e.add_policy(
608 vec!["eve", "data3", "read"]
609 .iter()
610 .map(|s| s.to_string())
611 .collect(),
612 )
613 .await
614 .unwrap();
615 e.add_policy(
616 vec!["eve", "data3", "read"]
617 .iter()
618 .map(|s| s.to_string())
619 .collect(),
620 )
621 .await
622 .unwrap();
623
624 let named_policy =
625 vec!["eve".to_string(), "data3".to_string(), "read".to_string()];
626 e.remove_named_policy("p", named_policy.clone())
627 .await
628 .unwrap();
629 e.add_named_policy("p", named_policy.clone()).await.unwrap();
630
631 assert_eq!(
632 vec![
633 vec!["data2_admin", "data2", "read"],
634 vec!["data2_admin", "data2", "write"],
635 vec!["eve", "data3", "read"],
636 ],
637 sort_unstable(e.get_policy())
638 );
639
640 e.remove_filtered_policy(
641 1,
642 vec!["data2"].iter().map(|s| s.to_string()).collect(),
643 )
644 .await
645 .unwrap();
646 assert_eq!(vec![vec!["eve", "data3", "read"],], e.get_policy());
647 }
648
649 #[cfg(not(target_arch = "wasm32"))]
650 #[cfg_attr(
651 all(feature = "runtime-async-std", not(target_arch = "wasm32")),
652 async_std::test
653 )]
654 #[cfg_attr(
655 all(feature = "runtime-tokio", not(target_arch = "wasm32")),
656 tokio::test
657 )]
658 async fn test_get_policy_api() {
659 let m = DefaultModel::from_file("examples/rbac_model.conf")
660 .await
661 .unwrap();
662
663 let adapter = FileAdapter::new("examples/rbac_policy.csv");
664 let e = Enforcer::new(m, adapter).await.unwrap();
665
666 assert_eq!(
667 vec![
668 vec!["alice", "data1", "read"],
669 vec!["bob", "data2", "write"],
670 vec!["data2_admin", "data2", "read"],
671 vec!["data2_admin", "data2", "write"],
672 ],
673 sort_unstable(e.get_policy())
674 );
675
676 assert_eq!(
677 vec![vec!["alice", "data1", "read"]],
678 e.get_filtered_policy(
679 0,
680 vec!["alice"].iter().map(|s| s.to_string()).collect()
681 )
682 );
683 assert_eq!(
684 vec![vec!["bob", "data2", "write"]],
685 e.get_filtered_policy(
686 0,
687 vec!["bob"].iter().map(|s| s.to_string()).collect()
688 )
689 );
690 assert_eq!(
691 vec![
692 vec!["data2_admin", "data2", "read"],
693 vec!["data2_admin", "data2", "write"],
694 ],
695 sort_unstable(e.get_filtered_policy(
696 0,
697 vec!["data2_admin"].iter().map(|s| s.to_string()).collect()
698 ))
699 );
700 assert_eq!(
701 vec![vec!["alice", "data1", "read"],],
702 e.get_filtered_policy(
703 1,
704 vec!["data1"].iter().map(|s| s.to_string()).collect()
705 )
706 );
707 assert_eq!(
708 vec![
709 vec!["bob", "data2", "write"],
710 vec!["data2_admin", "data2", "read"],
711 vec!["data2_admin", "data2", "write"],
712 ],
713 sort_unstable(e.get_filtered_policy(
714 1,
715 vec!["data2"].iter().map(|s| s.to_string()).collect()
716 ))
717 );
718 assert_eq!(
719 vec![
720 vec!["alice", "data1", "read"],
721 vec!["data2_admin", "data2", "read"],
722 ],
723 sort_unstable(e.get_filtered_policy(
724 2,
725 vec!["read"].iter().map(|s| s.to_string()).collect()
726 ))
727 );
728 assert_eq!(
729 vec![
730 vec!["bob", "data2", "write"],
731 vec!["data2_admin", "data2", "write"],
732 ],
733 sort_unstable(e.get_filtered_policy(
734 2,
735 vec!["write"].iter().map(|s| s.to_string()).collect()
736 ))
737 );
738 assert_eq!(
739 vec![
740 vec!["data2_admin", "data2", "read"],
741 vec!["data2_admin", "data2", "write"],
742 ],
743 sort_unstable(
744 e.get_filtered_policy(
745 0,
746 vec!["data2_admin", "data2"]
747 .iter()
748 .map(|s| s.to_string())
749 .collect()
750 )
751 )
752 );
753 assert_eq!(
755 vec![vec!["data2_admin", "data2", "read"],],
756 e.get_filtered_policy(
757 0,
758 vec!["data2_admin", "", "read"]
759 .iter()
760 .map(|s| s.to_string())
761 .collect()
762 )
763 );
764 assert_eq!(
765 vec![
766 vec!["bob", "data2", "write"],
767 vec!["data2_admin", "data2", "write"],
768 ],
769 sort_unstable(
770 e.get_filtered_policy(
771 1,
772 vec!["data2", "write"]
773 .iter()
774 .map(|s| s.to_string())
775 .collect()
776 )
777 )
778 );
779
780 assert_eq!(
781 true,
782 e.has_policy(
783 vec!["alice", "data1", "read"]
784 .iter()
785 .map(|s| s.to_string())
786 .collect()
787 )
788 );
789 assert_eq!(
790 true,
791 e.has_policy(
792 vec!["bob", "data2", "write"]
793 .iter()
794 .map(|s| s.to_string())
795 .collect()
796 )
797 );
798 assert_eq!(
799 false,
800 e.has_policy(
801 vec!["alice", "data2", "read"]
802 .iter()
803 .map(|s| s.to_string())
804 .collect()
805 )
806 );
807 assert_eq!(
808 false,
809 e.has_policy(
810 vec!["bob", "data3", "write"]
811 .iter()
812 .map(|s| s.to_string())
813 .collect()
814 )
815 );
816
817 assert_eq!(
818 vec![vec!["alice", "data2_admin"]],
819 e.get_filtered_grouping_policy(
820 0,
821 vec!["alice"].iter().map(|s| s.to_string()).collect()
822 )
823 );
824 let empty_policy: Vec<Vec<String>> = vec![];
825 assert_eq!(
826 empty_policy,
827 e.get_filtered_grouping_policy(
828 0,
829 vec!["bob"].iter().map(|s| s.to_string()).collect()
830 )
831 );
832 assert_eq!(
833 empty_policy,
834 e.get_filtered_grouping_policy(
835 1,
836 vec!["data1_admin"].iter().map(|s| s.to_string()).collect()
837 )
838 );
839 assert_eq!(
840 vec![vec!["alice", "data2_admin"],],
841 e.get_filtered_grouping_policy(
842 1,
843 vec!["data2_admin"].iter().map(|s| s.to_string()).collect()
844 )
845 );
846 assert_eq!(
848 empty_policy,
849 e.get_filtered_grouping_policy(
850 0,
851 vec!["data2_admin"].iter().map(|s| s.to_string()).collect()
852 )
853 );
854
855 assert_eq!(
856 true,
857 e.has_grouping_policy(
858 vec!["alice", "data2_admin"]
859 .iter()
860 .map(|s| s.to_string())
861 .collect()
862 )
863 );
864 assert_eq!(
865 false,
866 e.has_grouping_policy(
867 vec!["bob", "data2_admin"]
868 .iter()
869 .map(|s| s.to_string())
870 .collect()
871 )
872 );
873 }
874
875 #[cfg(not(target_arch = "wasm32"))]
876 #[cfg_attr(
877 all(feature = "runtime-async-std", not(target_arch = "wasm32")),
878 async_std::test
879 )]
880 #[cfg_attr(
881 all(feature = "runtime-tokio", not(target_arch = "wasm32")),
882 tokio::test
883 )]
884 async fn test_get_list() {
885 let m = DefaultModel::from_file("examples/rbac_model.conf")
886 .await
887 .unwrap();
888
889 let adapter = FileAdapter::new("examples/rbac_policy.csv");
890 let e = Enforcer::new(m, adapter).await.unwrap();
891
892 assert_eq!(
893 vec!["alice", "bob", "data2_admin"],
894 sort_unstable(e.get_all_subjects())
895 );
896 assert_eq!(vec!["data1", "data2"], sort_unstable(e.get_all_objects()));
897 assert_eq!(vec!["read", "write"], sort_unstable(e.get_all_actions()));
898 assert_eq!(vec!["data2_admin"], e.get_all_roles());
899 }
900
901 #[cfg(not(target_arch = "wasm32"))]
902 #[cfg_attr(
903 all(feature = "runtime-async-std", not(target_arch = "wasm32")),
904 async_std::test
905 )]
906 #[cfg_attr(
907 all(feature = "runtime-tokio", not(target_arch = "wasm32")),
908 tokio::test
909 )]
910 async fn test_modify_policies_api() {
911 let m = DefaultModel::from_file("examples/rbac_model.conf")
912 .await
913 .unwrap();
914
915 let adapter = FileAdapter::new("examples/rbac_policy.csv");
916 let mut e = Enforcer::new(m, adapter).await.unwrap();
917
918 assert_eq!(
919 vec![
920 vec!["alice", "data1", "read"],
921 vec!["bob", "data2", "write"],
922 vec!["data2_admin", "data2", "read"],
923 vec!["data2_admin", "data2", "write"],
924 ],
925 sort_unstable(e.get_policy())
926 );
927
928 e.remove_policies(vec![
929 vec!["alice", "data1", "read"]
930 .iter()
931 .map(|s| s.to_string())
932 .collect(),
933 vec!["bob", "data2", "write"]
934 .iter()
935 .map(|s| s.to_string())
936 .collect(),
937 ])
938 .await
939 .unwrap();
940 e.remove_policies(vec![vec!["alice", "data1", "read"]
941 .iter()
942 .map(|s| s.to_string())
943 .collect()])
944 .await
945 .unwrap();
946 assert_eq!(
947 false,
948 e.has_policy(
949 vec!["alice", "data1", "read"]
950 .iter()
951 .map(|s| s.to_string())
952 .collect()
953 )
954 );
955 assert_eq!(
956 false,
957 e.has_policy(
958 vec!["bob", "data2", "write"]
959 .iter()
960 .map(|s| s.to_string())
961 .collect()
962 )
963 );
964 assert_eq!(
965 true,
966 e.has_policy(
967 vec!["data2_admin", "data2", "read"]
968 .iter()
969 .map(|s| s.to_string())
970 .collect()
971 )
972 );
973 assert_eq!(
974 true,
975 e.has_policy(
976 vec!["data2_admin", "data2", "write"]
977 .iter()
978 .map(|s| s.to_string())
979 .collect()
980 )
981 );
982 e.add_policies(vec![vec!["eve", "data3", "read"]
983 .iter()
984 .map(|s| s.to_string())
985 .collect()])
986 .await
987 .unwrap();
988 e.add_policies(vec![
989 vec!["eve", "data3", "read"]
990 .iter()
991 .map(|s| s.to_string())
992 .collect(),
993 vec!["eve", "data3", "read"]
994 .iter()
995 .map(|s| s.to_string())
996 .collect(),
997 ])
998 .await
999 .unwrap();
1000 assert_eq!(
1001 false,
1002 e.has_policy(
1003 vec!["alice", "data1", "read"]
1004 .iter()
1005 .map(|s| s.to_string())
1006 .collect()
1007 )
1008 );
1009 assert_eq!(
1010 false,
1011 e.has_policy(
1012 vec!["bob", "data2", "write"]
1013 .iter()
1014 .map(|s| s.to_string())
1015 .collect()
1016 )
1017 );
1018 assert_eq!(
1019 true,
1020 e.has_policy(
1021 vec!["eve", "data3", "read"]
1022 .iter()
1023 .map(|s| s.to_string())
1024 .collect()
1025 )
1026 );
1027 assert_eq!(
1028 true,
1029 e.has_policy(
1030 vec!["data2_admin", "data2", "read"]
1031 .iter()
1032 .map(|s| s.to_string())
1033 .collect()
1034 )
1035 );
1036 assert_eq!(
1037 true,
1038 e.has_policy(
1039 vec!["data2_admin", "data2", "write"]
1040 .iter()
1041 .map(|s| s.to_string())
1042 .collect()
1043 )
1044 );
1045
1046 let named_policy =
1047 vec!["eve".to_string(), "data3".to_string(), "read".to_string()];
1048 e.remove_named_policies("p", vec![named_policy.clone()])
1049 .await
1050 .unwrap();
1051 e.add_named_policies("p", vec![named_policy.clone()])
1052 .await
1053 .unwrap();
1054
1055 assert_eq!(
1056 vec![
1057 vec!["data2_admin", "data2", "read"],
1058 vec!["data2_admin", "data2", "write"],
1059 vec!["eve", "data3", "read"],
1060 ],
1061 sort_unstable(e.get_policy())
1062 );
1063
1064 e.remove_filtered_policy(
1065 1,
1066 vec!["data2"].iter().map(|s| s.to_string()).collect(),
1067 )
1068 .await
1069 .unwrap();
1070 assert_eq!(vec![vec!["eve", "data3", "read"],], e.get_policy());
1071 }
1072
1073 #[cfg(not(target_arch = "wasm32"))]
1074 #[cfg_attr(
1075 all(feature = "runtime-async-std", not(target_arch = "wasm32")),
1076 async_std::test
1077 )]
1078 #[cfg_attr(
1079 all(feature = "runtime-tokio", not(target_arch = "wasm32")),
1080 tokio::test
1081 )]
1082 async fn test_modify_grouping_policies_api() {
1083 let m = DefaultModel::from_file("examples/rbac_model.conf")
1084 .await
1085 .unwrap();
1086
1087 let adapter = FileAdapter::new("examples/rbac_policy.csv");
1088 let mut e = Enforcer::new(m, adapter).await.unwrap();
1089
1090 assert_eq!(vec!["data2_admin"], e.get_roles_for_user("alice", None));
1091 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("bob", None));
1092 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("eve", None));
1093 assert_eq!(
1094 vec![String::new(); 0],
1095 e.get_roles_for_user("non_exist", None)
1096 );
1097
1098 e.remove_grouping_policies(vec![vec!["alice", "data2_admin"]
1099 .iter()
1100 .map(|s| s.to_string())
1101 .collect()])
1102 .await
1103 .unwrap();
1104 e.add_grouping_policies(vec![
1105 vec!["bob", "data1_admin"]
1106 .iter()
1107 .map(|s| s.to_string())
1108 .collect(),
1109 vec!["eve", "data3_admin"]
1110 .iter()
1111 .map(|s| s.to_string())
1112 .collect(),
1113 ])
1114 .await
1115 .unwrap();
1116 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("alice", None));
1117 assert_eq!(vec!["data1_admin"], e.get_roles_for_user("bob", None));
1118 assert_eq!(vec!["data3_admin"], e.get_roles_for_user("eve", None));
1119
1120 let named_grouping_policy =
1121 vec!["alice".to_string(), "data2_admin".to_string()];
1122 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("alice", None));
1123 e.add_named_grouping_policies("g", vec![named_grouping_policy.clone()])
1124 .await
1125 .unwrap();
1126 assert_eq!(vec!["data2_admin"], e.get_roles_for_user("alice", None));
1127 e.remove_named_grouping_policies(
1128 "g",
1129 vec![named_grouping_policy.clone()],
1130 )
1131 .await
1132 .unwrap();
1133
1134 e.remove_grouping_policies(vec![vec!["alice", "data2_admin"]
1135 .iter()
1136 .map(|s| s.to_string())
1137 .collect()])
1138 .await
1139 .unwrap();
1140
1141 e.add_grouping_policies(vec![
1142 vec!["bob", "data1_admin"]
1143 .iter()
1144 .map(|s| s.to_string())
1145 .collect(),
1146 vec!["eve", "data3_admin"]
1147 .iter()
1148 .map(|s| s.to_string())
1149 .collect(),
1150 ])
1151 .await
1152 .unwrap();
1153
1154 assert_eq!(vec!["bob"], e.get_users_for_role("data1_admin", None));
1155 assert_eq!(
1156 vec![String::new(); 0],
1157 e.get_users_for_role("data2_admin", None)
1158 );
1159 assert_eq!(vec!["eve"], e.get_users_for_role("data3_admin", None));
1160
1161 e.remove_filtered_grouping_policy(
1162 0,
1163 vec!["bob"].iter().map(|s| s.to_string()).collect(),
1164 )
1165 .await
1166 .unwrap();
1167
1168 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("alice", None));
1169 assert_eq!(vec![String::new(); 0], e.get_roles_for_user("bob", None));
1170 assert_eq!(vec!["data3_admin"], e.get_roles_for_user("eve", None));
1171 assert_eq!(
1172 vec![String::new(); 0],
1173 e.get_roles_for_user("non_exist", None)
1174 );
1175
1176 assert_eq!(
1177 vec![String::new(); 0],
1178 e.get_users_for_role("data1_admin", None)
1179 );
1180 assert_eq!(
1181 vec![String::new(); 0],
1182 e.get_users_for_role("data2_admin", None)
1183 );
1184 assert_eq!(vec!["eve"], e.get_users_for_role("data3_admin", None));
1185 }
1186}