openauth_plugins/access/
control.rs1use super::error::AccessError;
2use super::types::{AccessRequest, ResourceRequest, Role, Statements};
3use std::collections::{BTreeMap, BTreeSet};
4
5#[derive(Clone, Debug, Eq, PartialEq)]
7pub struct AccessControl {
8 statements: Statements,
9}
10
11impl AccessControl {
12 pub fn new(statements: Statements) -> Result<Self, AccessError> {
14 Ok(Self { statements })
15 }
16
17 pub fn new_role(&self, statements: Statements) -> Result<Role, AccessError> {
19 self.validate_role_statements(&statements)?;
20 Ok(Role::new(statements))
21 }
22
23 pub fn statements(&self) -> &Statements {
25 &self.statements
26 }
27
28 fn validate_role_statements(&self, statements: &Statements) -> Result<(), AccessError> {
29 for (resource, actions) in statements {
30 let allowed_actions =
31 self.statements
32 .get(resource)
33 .ok_or_else(|| AccessError::UnknownResource {
34 resource: resource.clone(),
35 })?;
36
37 for action in actions {
38 if !allowed_actions.contains(action) {
39 return Err(AccessError::UnknownAction {
40 resource: resource.clone(),
41 action: action.clone(),
42 });
43 }
44 }
45 }
46
47 Ok(())
48 }
49}
50
51pub fn create_access_control(statements: Statements) -> Result<AccessControl, AccessError> {
53 AccessControl::new(statements)
54}
55
56pub fn role(statements: Statements) -> Role {
58 Role::new(statements)
59}
60
61pub fn statements<I, R, A, S>(entries: I) -> Statements
63where
64 I: IntoIterator<Item = (R, A)>,
65 R: Into<String>,
66 A: IntoIterator<Item = S>,
67 S: Into<String>,
68{
69 entries
70 .into_iter()
71 .map(|(resource, actions)| {
72 (
73 resource.into(),
74 actions.into_iter().map(Into::into).collect::<BTreeSet<_>>(),
75 )
76 })
77 .collect::<BTreeMap<_, _>>()
78}
79
80pub fn request<I, R, A, S>(entries: I) -> AccessRequest
82where
83 I: IntoIterator<Item = (R, A)>,
84 R: Into<String>,
85 A: IntoIterator<Item = S>,
86 S: Into<String>,
87{
88 entries
89 .into_iter()
90 .map(|(resource, actions)| (resource.into(), ResourceRequest::all(actions)))
91 .collect()
92}