kanidmd_lib/valueset/
totp.rs
1use crate::be::dbvalue::DbTotpV1;
2use crate::credential::totp::Totp;
3use crate::prelude::*;
4use crate::schema::SchemaAttribute;
5use crate::valueset::{DbValueSetV2, ScimResolveStatus, ValueSet};
6use std::collections::btree_map::Entry as BTreeEntry;
7use std::collections::BTreeMap;
8
9#[derive(Debug, Clone)]
10pub struct ValueSetTotpSecret {
11 map: BTreeMap<String, Totp>,
12}
13
14impl ValueSetTotpSecret {
15 pub fn new(l: String, t: Totp) -> Box<Self> {
16 let mut map = BTreeMap::new();
17 map.insert(l, t);
18 Box::new(ValueSetTotpSecret { map })
19 }
20
21 pub fn push(&mut self, l: String, t: Totp) -> bool {
22 self.map.insert(l, t).is_none()
23 }
24
25 pub fn from_dbvs2(data: Vec<(String, DbTotpV1)>) -> Result<ValueSet, OperationError> {
26 let map = data
27 .into_iter()
28 .map(|(l, data)| {
29 Totp::try_from(data)
30 .map_err(|()| OperationError::InvalidValueState)
31 .map(|t| (l, t))
32 })
33 .collect::<Result<_, _>>()?;
34 Ok(Box::new(ValueSetTotpSecret { map }))
35 }
36
37 #[allow(clippy::should_implement_trait)]
40 pub fn from_iter<T>(iter: T) -> Option<Box<Self>>
41 where
42 T: IntoIterator<Item = (String, Totp)>,
43 {
44 let map = iter.into_iter().collect();
45 Some(Box::new(ValueSetTotpSecret { map }))
46 }
47}
48
49impl ValueSetT for ValueSetTotpSecret {
50 fn insert_checked(&mut self, value: Value) -> Result<bool, OperationError> {
51 match value {
52 Value::TotpSecret(l, t) => {
53 if let BTreeEntry::Vacant(e) = self.map.entry(l) {
54 e.insert(t);
55 Ok(true)
56 } else {
57 Ok(false)
58 }
59 }
60 _ => Err(OperationError::InvalidValueState),
61 }
62 }
63
64 fn clear(&mut self) {
65 self.map.clear();
66 }
67
68 fn remove(&mut self, pv: &PartialValue, _cid: &Cid) -> bool {
69 match pv {
70 PartialValue::Utf8(l) => self.map.remove(l.as_str()).is_some(),
71 _ => false,
72 }
73 }
74
75 fn contains(&self, pv: &PartialValue) -> bool {
76 match pv {
77 PartialValue::Utf8(l) => self.map.contains_key(l.as_str()),
78 _ => false,
79 }
80 }
81
82 fn substring(&self, _pv: &PartialValue) -> bool {
83 false
84 }
85
86 fn startswith(&self, _pv: &PartialValue) -> bool {
87 false
88 }
89
90 fn endswith(&self, _pv: &PartialValue) -> bool {
91 false
92 }
93
94 fn lessthan(&self, _pv: &PartialValue) -> bool {
95 false
96 }
97
98 fn len(&self) -> usize {
99 self.map.len()
100 }
101
102 fn generate_idx_eq_keys(&self) -> Vec<String> {
103 self.map.keys().cloned().collect()
104 }
105
106 fn syntax(&self) -> SyntaxType {
107 SyntaxType::TotpSecret
108 }
109
110 fn validate(&self, _schema_attr: &SchemaAttribute) -> bool {
111 true
112 }
113
114 fn to_proto_string_clone_iter(&self) -> Box<dyn Iterator<Item = String> + '_> {
115 Box::new(self.map.keys().cloned())
116 }
117
118 fn to_scim_value(&self) -> Option<ScimResolveStatus> {
119 None
120 }
121
122 fn to_db_valueset_v2(&self) -> DbValueSetV2 {
123 DbValueSetV2::TotpSecret(
124 self.map
125 .iter()
126 .map(|(label, totp)| (label.clone(), totp.to_dbtotpv1()))
127 .collect(),
128 )
129 }
130
131 fn to_partialvalue_iter(&self) -> Box<dyn Iterator<Item = PartialValue> + '_> {
132 Box::new(self.map.keys().cloned().map(PartialValue::Utf8))
133 }
134
135 fn to_value_iter(&self) -> Box<dyn Iterator<Item = Value> + '_> {
136 Box::new(
137 self.map
138 .iter()
139 .map(|(l, t)| Value::TotpSecret(l.clone(), t.clone())),
140 )
141 }
142
143 fn equal(&self, _other: &ValueSet) -> bool {
144 debug_assert!(false);
154 false
155 }
156
157 fn merge(&mut self, _other: &ValueSet) -> Result<(), OperationError> {
158 debug_assert!(false);
168 Err(OperationError::InvalidValueState)
169 }
170
171 fn as_totp_map(&self) -> Option<&BTreeMap<String, Totp>> {
172 Some(&self.map)
173 }
174}