kanidmd_lib/valueset/
secret.rs

1use crate::prelude::*;
2use crate::schema::SchemaAttribute;
3use crate::valueset::{DbValueSetV2, ScimResolveStatus, ValueSet};
4use smolset::SmolSet;
5
6#[derive(Debug, Clone)]
7pub struct ValueSetSecret {
8    set: SmolSet<[String; 1]>,
9}
10
11impl ValueSetSecret {
12    pub fn new(b: String) -> Box<Self> {
13        let mut set = SmolSet::new();
14        set.insert(b);
15        Box::new(ValueSetSecret { set })
16    }
17
18    pub fn push(&mut self, b: String) -> bool {
19        self.set.insert(b)
20    }
21
22    pub fn from_dbvs2(data: Vec<String>) -> Result<ValueSet, OperationError> {
23        let set = data.into_iter().collect();
24        Ok(Box::new(ValueSetSecret { set }))
25    }
26
27    // We need to allow this, because rust doesn't allow us to impl FromIterator on foreign
28    // types, and String is foreign.
29    #[allow(clippy::should_implement_trait)]
30    pub fn from_iter<T>(iter: T) -> Option<Box<Self>>
31    where
32        T: IntoIterator<Item = String>,
33    {
34        let set = iter.into_iter().collect();
35        Some(Box::new(ValueSetSecret { set }))
36    }
37}
38
39impl ValueSetT for ValueSetSecret {
40    fn insert_checked(&mut self, value: Value) -> Result<bool, OperationError> {
41        match value {
42            Value::SecretValue(u) => Ok(self.set.insert(u)),
43            _ => {
44                debug_assert!(false);
45                Err(OperationError::InvalidValueState)
46            }
47        }
48    }
49
50    fn clear(&mut self) {
51        self.set.clear();
52    }
53
54    fn remove(&mut self, _pv: &PartialValue, _cid: &Cid) -> bool {
55        false
56    }
57
58    fn contains(&self, _pv: &PartialValue) -> bool {
59        false
60    }
61
62    fn substring(&self, _pv: &PartialValue) -> bool {
63        false
64    }
65
66    fn startswith(&self, _pv: &PartialValue) -> bool {
67        false
68    }
69
70    fn endswith(&self, _pv: &PartialValue) -> bool {
71        false
72    }
73
74    fn lessthan(&self, _pv: &PartialValue) -> bool {
75        false
76    }
77
78    fn len(&self) -> usize {
79        self.set.len()
80    }
81
82    fn generate_idx_eq_keys(&self) -> Vec<String> {
83        Vec::with_capacity(0)
84    }
85
86    fn syntax(&self) -> SyntaxType {
87        SyntaxType::SecretUtf8String
88    }
89
90    fn validate(&self, _schema_attr: &SchemaAttribute) -> bool {
91        true
92    }
93
94    fn to_proto_string_clone_iter(&self) -> Box<dyn Iterator<Item = String> + '_> {
95        Box::new(self.set.iter().map(|_| "hidden".to_string()))
96    }
97
98    fn to_scim_value(&self) -> Option<ScimResolveStatus> {
99        None
100    }
101
102    fn to_db_valueset_v2(&self) -> DbValueSetV2 {
103        DbValueSetV2::SecretValue(self.set.iter().cloned().collect())
104    }
105
106    fn to_partialvalue_iter(&self) -> Box<dyn Iterator<Item = PartialValue> + '_> {
107        Box::new(self.set.iter().map(|_| PartialValue::SecretValue))
108    }
109
110    fn to_value_iter(&self) -> Box<dyn Iterator<Item = Value> + '_> {
111        Box::new(self.set.iter().cloned().map(Value::SecretValue))
112    }
113
114    fn equal(&self, other: &ValueSet) -> bool {
115        if let Some(other) = other.as_secret_set() {
116            &self.set == other
117        } else {
118            debug_assert!(false);
119            false
120        }
121    }
122
123    fn merge(&mut self, other: &ValueSet) -> Result<(), OperationError> {
124        if let Some(b) = other.as_secret_set() {
125            mergesets!(self.set, b)
126        } else {
127            debug_assert!(false);
128            Err(OperationError::InvalidValueState)
129        }
130    }
131
132    fn to_secret_single(&self) -> Option<&str> {
133        if self.set.len() == 1 {
134            self.set.iter().map(|s| s.as_str()).take(1).next()
135        } else {
136            None
137        }
138    }
139
140    fn as_secret_set(&self) -> Option<&SmolSet<[String; 1]>> {
141        Some(&self.set)
142    }
143}
144
145#[cfg(test)]
146mod tests {
147    use crate::valueset::{ValueSet, ValueSetSecret};
148
149    #[test]
150    fn test_scim_secret() {
151        let vs: ValueSet = ValueSetSecret::new("super secret special awesome value".to_string());
152
153        assert!(vs.to_scim_value().is_none());
154    }
155}