openauth_plugins/access/
authorize.rs1use super::error::AccessError;
2use super::types::{AccessRequest, Connector, ResourceRequest, Role};
3
4impl Role {
5 pub fn authorize_all(&self, request: AccessRequest) -> Result<(), AccessError> {
7 self.authorize(request, Connector::And)
8 }
9
10 pub fn authorize_any(&self, request: AccessRequest) -> Result<(), AccessError> {
12 self.authorize(request, Connector::Or)
13 }
14
15 pub fn authorize(
17 &self,
18 request: AccessRequest,
19 connector: Connector,
20 ) -> Result<(), AccessError> {
21 if request.is_empty() {
22 return Err(AccessError::EmptyRequest);
23 }
24
25 for (resource, resource_request) in request {
26 match self.authorize_resource(&resource, &resource_request) {
27 Ok(()) if connector == Connector::Or => return Ok(()),
28 Ok(()) => {}
29 Err(error) if connector == Connector::And => return Err(error),
30 Err(error @ AccessError::ResourceDenied { .. }) => return Err(error),
31 Err(_) => {}
32 }
33 }
34
35 if connector == Connector::Or {
36 Err(AccessError::NotAuthorized)
37 } else {
38 Ok(())
39 }
40 }
41
42 fn authorize_resource(
43 &self,
44 resource: &str,
45 request: &ResourceRequest,
46 ) -> Result<(), AccessError> {
47 let allowed_actions =
48 self.statements
49 .get(resource)
50 .ok_or_else(|| AccessError::ResourceDenied {
51 resource: resource.to_string(),
52 })?;
53
54 match request.connector() {
55 Connector::And if request.actions().is_subset(allowed_actions) => Ok(()),
56 Connector::Or
57 if request
58 .actions()
59 .iter()
60 .any(|action| allowed_actions.contains(action)) =>
61 {
62 Ok(())
63 }
64 _ => Err(AccessError::UnauthorizedResource {
65 resource: resource.to_string(),
66 }),
67 }
68 }
69}