Skip to main content

openstack_keystone_core/trust/
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//
5//     http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12//
13// SPDX-License-Identifier: Apache-2.0
14//! # Trust provider.
15//!
16//! Trusts.
17//!
18//! A trust represents a user's (the trustor) authorization to delegate roles to
19//! another user (the trustee), and optionally allow the trustee to impersonate
20//! the trustor. After the trustor has created a trust, the trustee can specify
21//! the trust's id attribute as part of an authentication request to then create
22//! a token representing the delegated authority of the trustor.
23//!
24//! The trust contains constraints on the delegated attributes. A token created
25//! based on a trust will convey a subset of the trustor's roles on the
26//! specified project. Optionally, the trust may only be valid for a specified
27//! time period, as defined by expires_at. If no expires_at is specified, then
28//! the trust is valid until it is explicitly revoked.
29//!
30//! The impersonation flag allows the trustor to optionally delegate
31//! impersonation abilities to the trustee. To services validating the token,
32//! the trustee will appear as the trustor, although the token will also contain
33//! the impersonation flag to indicate that this behavior is in effect.
34//!
35//! A project_id may not be specified without at least one role, and vice versa.
36//! In other words, there is no way of implicitly delegating all roles to a
37//! trustee, in order to prevent users accidentally creating trust that are much
38//! more broad in scope than intended. A trust without a project_id or any
39//! delegated roles is unscoped, and therefore does not represent authorization
40//! on a specific resource.
41//!
42//! Trusts are immutable. If the trustee or trustor wishes to modify the
43//! attributes of the trust, they should create a new trust and delete the old
44//! trust. If a trust is deleted, any tokens generated based on the trust are
45//! immediately revoked.
46//!
47//! If the trustor loses access to any delegated attributes, the trust becomes
48//! immediately invalid and any tokens generated based on the trust are
49//! immediately revoked.
50//!
51//! Trusts can also be chained, meaning, a trust can be created by using a trust
52//! scoped token.
53
54use async_trait::async_trait;
55
56pub mod api;
57pub mod backend;
58pub mod error;
59#[cfg(any(test, feature = "mock"))]
60mod mock;
61pub mod service;
62pub mod types;
63
64use crate::config::Config;
65use crate::keystone::ServiceState;
66use crate::plugin_manager::PluginManagerApi;
67use crate::trust::service::TrustService;
68
69pub use error::TrustProviderError;
70#[cfg(any(test, feature = "mock"))]
71pub use mock::MockTrustProvider;
72pub use types::*;
73
74/// Trust provider.
75pub enum TrustProvider {
76    Service(TrustService),
77    #[cfg(any(test, feature = "mock"))]
78    Mock(MockTrustProvider),
79}
80
81impl TrustProvider {
82    pub fn new<P: PluginManagerApi>(
83        config: &Config,
84        plugin_manager: &P,
85    ) -> Result<Self, TrustProviderError> {
86        Ok(Self::Service(TrustService::new(config, plugin_manager)?))
87    }
88}
89
90#[async_trait]
91impl TrustApi for TrustProvider {
92    /// Get trust by ID.
93    async fn get_trust<'a>(
94        &self,
95        state: &ServiceState,
96        id: &'a str,
97    ) -> Result<Option<Trust>, TrustProviderError> {
98        match self {
99            Self::Service(provider) => provider.get_trust(state, id).await,
100            #[cfg(any(test, feature = "mock"))]
101            Self::Mock(provider) => provider.get_trust(state, id).await,
102        }
103    }
104
105    /// Resolve trust delegation chain by the trust ID.
106    async fn get_trust_delegation_chain<'a>(
107        &self,
108        state: &ServiceState,
109        id: &'a str,
110    ) -> Result<Option<Vec<Trust>>, TrustProviderError> {
111        match self {
112            Self::Service(provider) => provider.get_trust_delegation_chain(state, id).await,
113            #[cfg(any(test, feature = "mock"))]
114            Self::Mock(provider) => provider.get_trust_delegation_chain(state, id).await,
115        }
116    }
117
118    /// List trusts.
119    async fn list_trusts(
120        &self,
121        state: &ServiceState,
122        params: &TrustListParameters,
123    ) -> Result<Vec<Trust>, TrustProviderError> {
124        match self {
125            Self::Service(provider) => provider.list_trusts(state, params).await,
126            #[cfg(any(test, feature = "mock"))]
127            Self::Mock(provider) => provider.list_trusts(state, params).await,
128        }
129    }
130
131    /// Validate trust delegation chain.
132    ///
133    /// - redelegation deepness cannot exceed the global limit.
134    /// - redelegated trusts must not specify use limit.
135    /// - validate redelegated trust expiration is not later than of the
136    ///   original.
137    /// - redelegated trust must not add new roles.
138    async fn validate_trust_delegation_chain(
139        &self,
140        state: &ServiceState,
141        trust: &Trust,
142    ) -> Result<bool, TrustProviderError> {
143        match self {
144            Self::Service(provider) => provider.validate_trust_delegation_chain(state, trust).await,
145            #[cfg(any(test, feature = "mock"))]
146            Self::Mock(provider) => provider.validate_trust_delegation_chain(state, trust).await,
147        }
148    }
149}