openstack_keystone_core/identity_mapping/
service.rs1use async_trait::async_trait;
18use std::sync::Arc;
19
20use crate::config::Config;
21use crate::identity_mapping::{
22 IdentityMappingProviderError, backend::IdentityMappingBackend, types::*,
23};
24use crate::keystone::ServiceState;
25use crate::plugin_manager::PluginManagerApi;
26
27pub struct IdentityMappingService {
28 backend_driver: Arc<dyn IdentityMappingBackend>,
30}
31
32impl IdentityMappingService {
33 pub fn new<P: PluginManagerApi>(
34 config: &Config,
35 plugin_manager: &P,
36 ) -> Result<Self, IdentityMappingProviderError> {
37 let backend_driver = plugin_manager
38 .get_identity_mapping_backend(config.identity_mapping.driver.clone())?
39 .clone();
40 Ok(Self { backend_driver })
41 }
42}
43
44#[async_trait]
45impl IdentityMappingApi for IdentityMappingService {
46 async fn get_by_local_id<'a>(
48 &self,
49 state: &ServiceState,
50 local_id: &'a str,
51 domain_id: &'a str,
52 entity_type: IdMappingEntityType,
53 ) -> Result<Option<IdMapping>, IdentityMappingProviderError> {
54 self.backend_driver
55 .get_by_local_id(state, local_id, domain_id, entity_type)
56 .await
57 }
58
59 #[tracing::instrument(level = "info", skip(self, state))]
61 async fn get_by_public_id<'a>(
62 &self,
63 state: &ServiceState,
64 public_id: &'a str,
65 ) -> Result<Option<IdMapping>, IdentityMappingProviderError> {
66 self.backend_driver.get_by_public_id(state, public_id).await
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use std::sync::Arc;
73
74 use super::*;
75 use crate::identity_mapping::backend::MockIdentityMappingBackend;
76 use crate::tests::get_mocked_state;
77
78 #[tokio::test]
79 async fn test_get_by_local_id() {
80 let state = get_mocked_state(None, None);
81 let sot = IdMapping {
82 public_id: "pid".into(),
83 local_id: "lid".into(),
84 domain_id: "did".into(),
85 entity_type: IdMappingEntityType::User,
86 };
87 let mut backend = MockIdentityMappingBackend::default();
88 let sot_clone = sot.clone();
89 backend
90 .expect_get_by_local_id()
91 .withf(|_, lid: &'_ str, did: &'_ str, _et: &IdMappingEntityType| {
92 lid == "lid" && did == "did"
93 })
94 .returning(move |_, _, _, _| Ok(Some(sot_clone.clone())));
95 let provider = IdentityMappingService {
96 backend_driver: Arc::new(backend),
97 };
98
99 let res: IdMapping = provider
100 .get_by_local_id(&state, "lid", "did", IdMappingEntityType::User)
101 .await
102 .unwrap()
103 .expect("id mapping should be there");
104 assert_eq!(res, sot);
105 }
106
107 #[tokio::test]
108 async fn test_get_by_public_id() {
109 let state = get_mocked_state(None, None);
110 let sot = IdMapping {
111 public_id: "pid".into(),
112 local_id: "lid".into(),
113 domain_id: "did".into(),
114 entity_type: IdMappingEntityType::User,
115 };
116 let mut backend = MockIdentityMappingBackend::default();
117 let sot_clone = sot.clone();
118 backend
119 .expect_get_by_public_id()
120 .withf(|_, pid: &'_ str| pid == "pid")
121 .returning(move |_, _| Ok(Some(sot_clone.clone())));
122 let provider = IdentityMappingService {
123 backend_driver: Arc::new(backend),
124 };
125
126 let res: IdMapping = provider
127 .get_by_public_id(&state, "pid")
128 .await
129 .unwrap()
130 .expect("id mapping should be there");
131 assert_eq!(res, sot);
132 }
133}