Skip to main content

openstack_keystone_core/assignment/
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//! # Assignments provider
14//!
15//! Assignments provider implements RBAC concept of granting an actor set of
16//! roles on the target. An actor could be a user or a group of users, in which
17//! case such roles are granted implicitly to the all users which are the member
18//! of the group. The target is the domain, project or the system.
19//!
20//! Keystone implements few additional features for the role assignments:
21//!
22//! ## Role inference
23//!
24//! Roles in Keystone may imply other roles building an inference chain. For
25//! example a role `manager` can imply the `member` role, which in turn implies
26//! the `reader` role. As such with a single assignment of the `manager` role
27//! the user will automatically get `manager`, `member` and `reader` roles. This
28//! helps limiting number of necessary direct assignments.
29//!
30//! ## Target assignment inheritance
31//!
32//! Keystone adds `inherited` parameter to the assignment of the role on the
33//! target. In such case an assignment actor gets this role assignment
34//! (including role inference) on the whole subtree targets excluding the target
35//! itself. This way for an assignment on the domain level the actor
36//! will get the role on the every project of the domain, but not the domain
37//! itself.
38use async_trait::async_trait;
39
40pub mod backend;
41pub mod error;
42#[cfg(any(test, feature = "mock"))]
43mod mock;
44pub mod service;
45pub mod types;
46
47use crate::assignment::service::AssignmentService;
48use crate::config::Config;
49use crate::keystone::ServiceState;
50use crate::plugin_manager::PluginManagerApi;
51use types::*;
52
53pub use error::AssignmentProviderError;
54#[cfg(any(test, feature = "mock"))]
55pub use mock::MockAssignmentProvider;
56pub use types::AssignmentApi;
57
58pub enum AssignmentProvider {
59    Service(AssignmentService),
60    #[cfg(any(test, feature = "mock"))]
61    Mock(MockAssignmentProvider),
62}
63
64impl AssignmentProvider {
65    pub fn new<P: PluginManagerApi>(
66        config: &Config,
67        plugin_manager: &P,
68    ) -> Result<Self, AssignmentProviderError> {
69        Ok(Self::Service(AssignmentService::new(
70            config,
71            plugin_manager,
72        )?))
73    }
74}
75
76#[async_trait]
77impl AssignmentApi for AssignmentProvider {
78    /// Create assignment grant.
79    #[tracing::instrument(level = "info", skip(self, state))]
80    async fn create_grant(
81        &self,
82        state: &ServiceState,
83        grant: AssignmentCreate,
84    ) -> Result<Assignment, AssignmentProviderError> {
85        match self {
86            Self::Service(provider) => provider.create_grant(state, grant).await,
87            #[cfg(any(test, feature = "mock"))]
88            Self::Mock(provider) => provider.create_grant(state, grant).await,
89        }
90    }
91
92    /// List role assignments
93    #[tracing::instrument(level = "info", skip(self, state))]
94    async fn list_role_assignments(
95        &self,
96        state: &ServiceState,
97        params: &RoleAssignmentListParameters,
98    ) -> Result<Vec<Assignment>, AssignmentProviderError> {
99        match self {
100            Self::Service(provider) => provider.list_role_assignments(state, params).await,
101            #[cfg(any(test, feature = "mock"))]
102            Self::Mock(provider) => provider.list_role_assignments(state, params).await,
103        }
104    }
105
106    /// Revoke grant
107    #[tracing::instrument(level = "info", skip(self, state))]
108    async fn revoke_grant(
109        &self,
110        state: &ServiceState,
111        grant: Assignment,
112    ) -> Result<(), AssignmentProviderError> {
113        match self {
114            Self::Service(provider) => provider.revoke_grant(state, grant).await,
115            #[cfg(any(test, feature = "mock"))]
116            Self::Mock(provider) => provider.revoke_grant(state, grant).await,
117        }
118    }
119}