casbin/
rbac_api.rs

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