Skip to main content

openstack_keystone_core/role/
service.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
14use std::collections::{BTreeMap, BTreeSet};
15use std::sync::Arc;
16
17use async_trait::async_trait;
18use uuid::Uuid;
19use validator::Validate;
20
21use crate::config::Config;
22use crate::keystone::ServiceState;
23use crate::plugin_manager::PluginManagerApi;
24use crate::role::{RoleProviderError, backend::RoleBackend, types::*};
25
26pub struct RoleService {
27    backend_driver: Arc<dyn RoleBackend>,
28}
29
30impl RoleService {
31    pub fn new<P: PluginManagerApi>(
32        config: &Config,
33        plugin_manager: &P,
34    ) -> Result<Self, RoleProviderError> {
35        let backend_driver = plugin_manager
36            .get_role_backend(config.role.driver.clone())?
37            .clone();
38        Ok(Self { backend_driver })
39    }
40}
41
42#[async_trait]
43impl RoleApi for RoleService {
44    /// Create role.
45    #[tracing::instrument(level = "info", skip(self, state))]
46    async fn create_role(
47        &self,
48        state: &ServiceState,
49        params: RoleCreate,
50    ) -> Result<Role, RoleProviderError> {
51        params.validate()?;
52
53        let mut new_params = params;
54
55        if new_params.id.is_none() {
56            new_params.id = Some(Uuid::new_v4().simple().to_string());
57        }
58        self.backend_driver.create_role(state, new_params).await
59    }
60
61    /// Delete a role by the ID.
62    #[tracing::instrument(level = "info", skip(self, state))]
63    async fn delete_role<'a>(
64        &self,
65        state: &ServiceState,
66        id: &'a str,
67    ) -> Result<(), RoleProviderError> {
68        self.backend_driver.delete_role(state, id).await
69    }
70
71    /// Get single role.
72    #[tracing::instrument(level = "info", skip(self, state))]
73    async fn get_role<'a>(
74        &self,
75        state: &ServiceState,
76        id: &'a str,
77    ) -> Result<Option<Role>, RoleProviderError> {
78        self.backend_driver.get_role(state, id).await
79    }
80
81    /// Expand implied roles.
82    ///
83    /// Return list of the roles with the imply rules being considered.
84    #[tracing::instrument(level = "info", skip(self, state))]
85    async fn expand_implied_roles(
86        &self,
87        state: &ServiceState,
88        roles: &mut Vec<RoleRef>,
89    ) -> Result<(), RoleProviderError> {
90        // In most of the cases a logic for expanding the roles may be implemented by
91        // the provider itself, but some backend drivers may have more efficient
92        // methods.
93        self.backend_driver
94            .expand_implied_roles(state, roles)
95            .await?;
96        Ok(())
97    }
98
99    /// List role imply rules.
100    #[tracing::instrument(level = "info", skip(self, state))]
101    async fn list_imply_rules(
102        &self,
103        state: &ServiceState,
104        resolve: bool,
105    ) -> Result<BTreeMap<String, BTreeSet<String>>, RoleProviderError> {
106        self.backend_driver.list_imply_rules(state, resolve).await
107    }
108
109    /// List roles.
110    #[tracing::instrument(level = "info", skip(self, state))]
111    async fn list_roles(
112        &self,
113        state: &ServiceState,
114        params: &RoleListParameters,
115    ) -> Result<Vec<Role>, RoleProviderError> {
116        params.validate()?;
117        self.backend_driver.list_roles(state, params).await
118    }
119}