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 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 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 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 self.inner.providers.clear();
234
235 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 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 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 let key_object = provider.load_key_object(entry)?;
281
282 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