Skip to main content

openstack_keystone_core/role/
mod.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//     http://www.apache.org/licenses/LICENSE-2.0
5//
6// Unless required by applicable law or agreed to in writing, software
7// distributed under the License is distributed on an "AS IS" BASIS,
8// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9// See the License for the specific language governing permissions and
10// limitations under the License.
11//
12// SPDX-License-Identifier: Apache-2.0
13//! # Role provider
14//!
15//! Role provider provides possibility to manage roles (part of RBAC).
16//!
17//! Following Keystone concepts are covered by the provider:
18//!
19//! ## Role inference
20//!
21//! Roles in Keystone may imply other roles building an inference chain. For
22//! example a role `manager` can imply the `member` role, which in turn implies
23//! the `reader` role. As such with a single assignment of the `manager` role
24//! the user will automatically get `manager`, `member` and `reader` roles. This
25//! helps limiting number of necessary direct assignments.
26//!
27//! ## Role
28//!
29//! A personality with a defined set of user rights and privileges to perform a
30//! specific set of operations. The Identity service issues a token to a user
31//! that includes a list of roles. When a user calls a service, that service
32//! interprets the user role set, and determines to which operations or
33//! resources each role grants access.
34use async_trait::async_trait;
35use std::collections::{BTreeMap, BTreeSet};
36
37pub mod backend;
38pub mod error;
39#[cfg(any(test, feature = "mock"))]
40mod mock;
41pub mod service;
42pub mod types;
43
44use crate::config::Config;
45use crate::keystone::ServiceState;
46use crate::plugin_manager::PluginManagerApi;
47use crate::role::{service::RoleService, types::*};
48
49pub use error::RoleProviderError;
50#[cfg(any(test, feature = "mock"))]
51pub use mock::MockRoleProvider;
52pub use types::RoleApi;
53
54pub enum RoleProvider {
55    Service(RoleService),
56    #[cfg(any(test, feature = "mock"))]
57    Mock(MockRoleProvider),
58}
59
60impl RoleProvider {
61    pub fn new<P: PluginManagerApi>(
62        config: &Config,
63        plugin_manager: &P,
64    ) -> Result<Self, RoleProviderError> {
65        Ok(Self::Service(RoleService::new(config, plugin_manager)?))
66    }
67}
68
69#[async_trait]
70impl RoleApi for RoleProvider {
71    /// Create role.
72    #[tracing::instrument(level = "info", skip(self, state))]
73    async fn create_role(
74        &self,
75        state: &ServiceState,
76        params: RoleCreate,
77    ) -> Result<Role, RoleProviderError> {
78        match self {
79            Self::Service(provider) => provider.create_role(state, params).await,
80            #[cfg(any(test, feature = "mock"))]
81            Self::Mock(provider) => provider.create_role(state, params).await,
82        }
83    }
84
85    /// Delete a role by the ID.
86    #[tracing::instrument(level = "info", skip(self, state))]
87    async fn delete_role<'a>(
88        &self,
89        state: &ServiceState,
90        id: &'a str,
91    ) -> Result<(), RoleProviderError> {
92        match self {
93            Self::Service(provider) => provider.delete_role(state, id).await,
94            #[cfg(any(test, feature = "mock"))]
95            Self::Mock(provider) => provider.delete_role(state, id).await,
96        }
97    }
98
99    /// Get single role.
100    async fn get_role<'a>(
101        &self,
102        state: &ServiceState,
103        id: &'a str,
104    ) -> Result<Option<Role>, RoleProviderError> {
105        match self {
106            Self::Service(provider) => provider.get_role(state, id).await,
107            #[cfg(any(test, feature = "mock"))]
108            Self::Mock(provider) => provider.get_role(state, id).await,
109        }
110    }
111
112    /// Expand implied roles.
113    ///
114    /// Return list of the roles with the imply rules being considered.
115    async fn expand_implied_roles(
116        &self,
117        state: &ServiceState,
118        roles: &mut Vec<RoleRef>,
119    ) -> Result<(), RoleProviderError> {
120        match self {
121            Self::Service(provider) => provider.expand_implied_roles(state, roles).await,
122            #[cfg(any(test, feature = "mock"))]
123            Self::Mock(provider) => provider.expand_implied_roles(state, roles).await,
124        }
125    }
126
127    /// List role imply rules.
128    async fn list_imply_rules(
129        &self,
130        state: &ServiceState,
131        resolve: bool,
132    ) -> Result<BTreeMap<String, BTreeSet<String>>, RoleProviderError> {
133        match self {
134            Self::Service(provider) => provider.list_imply_rules(state, resolve).await,
135            #[cfg(any(test, feature = "mock"))]
136            Self::Mock(provider) => provider.list_imply_rules(state, resolve).await,
137        }
138    }
139
140    /// List roles.
141    async fn list_roles(
142        &self,
143        state: &ServiceState,
144        params: &RoleListParameters,
145    ) -> Result<Vec<Role>, RoleProviderError> {
146        match self {
147            Self::Service(provider) => provider.list_roles(state, params).await,
148            #[cfg(any(test, feature = "mock"))]
149            Self::Mock(provider) => provider.list_roles(state, params).await,
150        }
151    }
152}