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}