kanidmd_lib/server/keys/
provider.rs

1use crate::prelude::*;
2
3use concread::cowcell::*;
4use uuid::Uuid;
5
6use std::collections::BTreeMap;
7use std::fmt;
8use std::ops::Deref;
9use std::sync::Arc;
10
11use super::internal::KeyProviderInternal;
12use super::object::KeyObject;
13
14#[cfg(test)]
15use super::object::KeyObjectRef;
16
17#[derive(Clone)]
18pub enum KeyProvider {
19    // Mostly this is a wrapper to store the loaded providers, which are then downcast into
20    // their concrete type and associated with key objects.
21    Internal(Arc<KeyProviderInternal>),
22}
23
24impl fmt::Display for KeyProvider {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        f.debug_struct("KeyProvider")
27            .field("name", &self.name())
28            .field("uuid", &self.uuid())
29            .finish()
30    }
31}
32
33impl KeyProvider {
34    pub(crate) fn uuid(&self) -> Uuid {
35        match self {
36            KeyProvider::Internal(inner) => inner.uuid(),
37        }
38    }
39
40    pub(crate) fn name(&self) -> &str {
41        match self {
42            KeyProvider::Internal(inner) => inner.name(),
43        }
44    }
45
46    pub(crate) fn test(&self) -> Result<(), OperationError> {
47        match self {
48            KeyProvider::Internal(inner) => inner.test(),
49        }
50    }
51
52    fn create_new_key_object(&self, key_object_uuid: Uuid) -> Result<KeyObject, OperationError> {
53        match self {
54            KeyProvider::Internal(inner) => {
55                inner.create_new_key_object(key_object_uuid, inner.clone())
56            }
57        }
58    }
59
60    fn load_key_object(
61        &self,
62        entry: &EntrySealedCommitted,
63    ) -> Result<Arc<KeyObject>, OperationError> {
64        match self {
65            KeyProvider::Internal(inner) => inner.load_key_object(entry, inner.clone()),
66        }
67    }
68
69    pub(crate) fn try_from(
70        value: &Entry<EntrySealed, EntryCommitted>,
71    ) -> Result<Arc<Self>, OperationError> {
72        if !value.attribute_equality(Attribute::Class, &EntryClass::KeyProvider.into()) {
73            error!("class key_provider not present.");
74            return Err(OperationError::KP0002KeyProviderInvalidClass);
75        }
76
77        if value.attribute_equality(Attribute::Class, &EntryClass::KeyProviderInternal.into()) {
78            KeyProviderInternal::try_from(value)
79                .map(|kpi| KeyProvider::Internal(Arc::new(kpi)))
80                .map(Arc::new)
81        } else {
82            error!("No supported key provider type present");
83            Err(OperationError::KP0003KeyProviderInvalidType)
84        }
85    }
86}
87
88#[derive(Clone)]
89struct KeyProvidersInner {
90    // Wondering if this should be Arc later to allow KeyObjects to refer to their provider directly.
91    providers: BTreeMap<Uuid, Arc<KeyProvider>>,
92    objects: BTreeMap<Uuid, Arc<KeyObject>>,
93}
94
95pub struct KeyProviders {
96    inner: CowCell<KeyProvidersInner>,
97}
98
99impl Default for KeyProviders {
100    fn default() -> Self {
101        KeyProviders {
102            inner: CowCell::new(KeyProvidersInner {
103                providers: BTreeMap::default(),
104                objects: BTreeMap::default(),
105            }),
106        }
107    }
108}
109
110impl KeyProviders {
111    pub fn read(&self) -> KeyProvidersReadTransaction {
112        KeyProvidersReadTransaction {
113            inner: self.inner.read(),
114        }
115    }
116
117    pub fn write(&self) -> KeyProvidersWriteTransaction {
118        KeyProvidersWriteTransaction {
119            inner: self.inner.write(),
120        }
121    }
122}
123
124pub trait KeyProvidersTransaction {
125    #[cfg(test)]
126    fn get_uuid(&self, key_provider_uuid: Uuid) -> Option<&KeyProvider>;
127
128    #[cfg(test)]
129    fn get_key_object(&self, key_object_uuid: Uuid) -> Option<KeyObjectRef>;
130
131    fn get_key_object_handle(&self, key_object_uuid: Uuid) -> Option<Arc<KeyObject>>;
132}
133
134pub struct KeyProvidersReadTransaction {
135    inner: CowCellReadTxn<KeyProvidersInner>,
136}
137
138impl KeyProvidersTransaction for KeyProvidersReadTransaction {
139    #[cfg(test)]
140    fn get_uuid(&self, key_provider_uuid: Uuid) -> Option<&KeyProvider> {
141        self.inner
142            .deref()
143            .providers
144            .get(&key_provider_uuid)
145            .map(|k| k.as_ref())
146    }
147
148    #[cfg(test)]
149    fn get_key_object(&self, key_object_uuid: Uuid) -> Option<KeyObjectRef> {
150        self.inner
151            .deref()
152            .objects
153            .get(&key_object_uuid)
154            .map(|k| k.as_ref().as_ref())
155    }
156
157    fn get_key_object_handle(&self, key_object_uuid: Uuid) -> Option<Arc<KeyObject>> {
158        self.inner.deref().objects.get(&key_object_uuid).cloned()
159    }
160}
161
162pub struct KeyProvidersWriteTransaction<'a> {
163    inner: CowCellWriteTxn<'a, KeyProvidersInner>,
164}
165
166impl KeyProvidersTransaction for KeyProvidersWriteTransaction<'_> {
167    #[cfg(test)]
168    fn get_uuid(&self, key_provider_uuid: Uuid) -> Option<&KeyProvider> {
169        self.inner
170            .deref()
171            .providers
172            .get(&key_provider_uuid)
173            .map(|k| k.as_ref())
174    }
175
176    #[cfg(test)]
177    fn get_key_object(&self, key_object_uuid: Uuid) -> Option<KeyObjectRef> {
178        self.inner
179            .deref()
180            .objects
181            .get(&key_object_uuid)
182            .map(|k| k.as_ref().as_ref())
183    }
184
185    fn get_key_object_handle(&self, key_object_uuid: Uuid) -> Option<Arc<KeyObject>> {
186        self.inner.deref().objects.get(&key_object_uuid).cloned()
187    }
188}
189
190impl KeyProvidersWriteTransaction<'_> {
191    #[cfg(test)]
192    pub(crate) fn get_default(&self) -> Result<&KeyProvider, OperationError> {
193        // In future we will make this configurable, and we'll load the default into
194        // the write txn during a reload.
195        self.get_uuid(UUID_KEY_PROVIDER_INTERNAL)
196            .ok_or(OperationError::KP0007KeyProviderDefaultNotAvailable)
197    }
198
199    pub(crate) fn get_or_create_in_default(
200        &mut self,
201        key_object_uuid: Uuid,
202    ) -> Result<KeyObject, OperationError> {
203        self.get_or_create(UUID_KEY_PROVIDER_INTERNAL, key_object_uuid)
204    }
205
206    pub(crate) fn get_or_create(
207        &mut self,
208        key_provider_uuid: Uuid,
209        key_object_uuid: Uuid,
210    ) -> Result<KeyObject, OperationError> {
211        if let Some(key_object) = self.inner.deref().objects.get(&key_object_uuid) {
212            Ok(key_object.as_ref().duplicate())
213        } else {
214            let provider = self
215                .inner
216                .deref()
217                .providers
218                .get(&key_provider_uuid)
219                .map(|k| k.as_ref())
220                .ok_or(OperationError::KP0025KeyProviderNotAvailable)?;
221
222            provider.create_new_key_object(key_object_uuid)
223        }
224    }
225}
226
227impl KeyProvidersWriteTransaction<'_> {
228    pub(crate) fn update_providers(
229        &mut self,
230        providers: Vec<Arc<KeyProvider>>,
231    ) -> Result<(), OperationError> {
232        // Clear the current set.
233        self.inner.providers.clear();
234
235        // For each provider insert.
236        for provider in providers.into_iter() {
237            let uuid = provider.uuid();
238            if self.inner.providers.insert(uuid, provider).is_some() {
239                error!(key_provider_uuid = ?uuid, "duplicate key provider detected");
240                return Err(OperationError::KP0005KeyProviderDuplicate);
241            }
242        }
243
244        Ok(())
245    }
246
247    pub(crate) fn load_key_object(
248        &mut self,
249        entry: &EntrySealedCommitted,
250    ) -> Result<(), OperationError> {
251        // Object UUID
252        let object_uuid = entry.get_uuid();
253
254        if !entry.attribute_equality(Attribute::Class, &EntryClass::KeyObject.into()) {
255            error!(?object_uuid, "Invalid entry, keyobject class not found.");
256            return Err(OperationError::KP0011KeyObjectMissingClass);
257        }
258
259        // Get provider UUID.
260        let provider_uuid = entry
261            .get_ava_single_refer(Attribute::KeyProvider)
262            .ok_or_else(|| {
263                error!(
264                    ?object_uuid,
265                    "Invalid key object, key provider referenced is not found."
266                );
267                OperationError::KP0012KeyObjectMissingProvider
268            })?;
269
270        let provider = self.inner.providers.get(&provider_uuid).ok_or_else(|| {
271            error!(
272                ?object_uuid,
273                ?provider_uuid,
274                "Invalid reference state, key provider has not be loaded."
275            );
276            OperationError::KP0012KeyProviderNotLoaded
277        })?;
278
279        // Ask the provider to load this object.
280        let key_object = provider.load_key_object(entry)?;
281
282        // Can't be duplicate as uuid is enforced unique in other layers.
283        self.inner.objects.insert(object_uuid, key_object);
284
285        Ok(())
286    }
287
288    pub(crate) fn commit(self) -> Result<(), OperationError> {
289        self.inner.commit();
290
291        Ok(())
292    }
293}
294
295/*
296#[cfg(test)]
297mod tests {
298    use super::{KeyProvider, KeyProvidersTransaction};
299    use crate::prelude::*;
300    use crate::value::KeyStatus;
301    use compact_jwt::{JwsEs256Signer, JwsSigner};
302
303}
304*/