Skip to main content

openstack_keystone_core/revoke/
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//
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//! # Token revocation provider.
15
16use async_trait::async_trait;
17use std::sync::Arc;
18
19use crate::config::Config;
20use crate::keystone::ServiceState;
21use crate::plugin_manager::PluginManagerApi;
22use crate::revoke::{RevokeProviderError, backend::RevokeBackend, types::*};
23use crate::token::types::Token;
24
25/// Revoke provider.
26pub struct RevokeService {
27    /// Backend driver.
28    backend_driver: Arc<dyn RevokeBackend>,
29}
30
31impl RevokeService {
32    pub fn new<P: PluginManagerApi>(
33        config: &Config,
34        plugin_manager: &P,
35    ) -> Result<Self, RevokeProviderError> {
36        let backend_driver = plugin_manager
37            .get_revoke_backend(config.revoke.driver.clone())?
38            .clone();
39        Ok(Self { backend_driver })
40    }
41}
42
43#[async_trait]
44impl RevokeApi for RevokeService {
45    /// Create revocation event.
46    #[tracing::instrument(level = "info", skip(self, state))]
47    async fn create_revocation_event(
48        &self,
49        state: &ServiceState,
50        event: RevocationEventCreate,
51    ) -> Result<RevocationEvent, RevokeProviderError> {
52        self.backend_driver
53            .create_revocation_event(state, event)
54            .await
55    }
56
57    /// Check whether the token has been revoked or not.
58    ///
59    /// Checks revocation events matching the token parameters and return
60    /// `false` if their count is more than `0`.
61    #[tracing::instrument(level = "info", skip(self, state, token))]
62    async fn is_token_revoked(
63        &self,
64        state: &ServiceState,
65        token: &Token,
66    ) -> Result<bool, RevokeProviderError> {
67        tracing::info!("Checking for the revocation events");
68        self.backend_driver.is_token_revoked(state, token).await
69    }
70
71    /// Revoke the token.
72    ///
73    /// Mark the token as revoked to prohibit from being used even while not
74    /// expired.
75    async fn revoke_token(
76        &self,
77        state: &ServiceState,
78        token: &Token,
79    ) -> Result<(), RevokeProviderError> {
80        self.backend_driver.revoke_token(state, token).await
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use std::sync::Arc;
87
88    use super::*;
89    use crate::revoke::backend::MockRevokeBackend;
90    use crate::tests::get_mocked_state;
91
92    #[tokio::test]
93    async fn test_create_revocation_event() {
94        let state = get_mocked_state(None, None);
95        let mut backend = MockRevokeBackend::default();
96        backend
97            .expect_create_revocation_event()
98            .returning(|_, _| Ok(RevocationEvent::default()));
99        let provider = RevokeService {
100            backend_driver: Arc::new(backend),
101        };
102
103        assert!(
104            provider
105                .create_revocation_event(&state, RevocationEventCreate::default())
106                .await
107                .is_ok()
108        );
109    }
110}