signstar_config/config/file/
impl_all.rs1use std::collections::HashSet;
11
12use signstar_common::backend::BackendType;
13use signstar_crypto::{
14 AdministrativeSecretHandling,
15 NonAdministrativeSecretHandling,
16 traits::UserWithPassphrase,
17};
18
19use crate::{
20 config::{
21 AuthorizedKeyEntry,
22 Config,
23 ConfigAuthorizedKeyEntries,
24 ConfigBuilder,
25 ConfigSystemUserData,
26 ConfigSystemUserIds,
27 MappingAuthorizedKeyEntry,
28 MappingBackendUserSecrets,
29 MappingSystemUserId,
30 SystemConfig,
31 SystemUserData,
32 SystemUserId,
33 UserBackendConnection,
34 UserBackendConnectionFilter,
35 traits::NonAdminBackendUserIdFilter,
36 },
37 nethsm::NetHsmUserMapping,
38 yubihsm2::YubiHsm2UserMapping,
39};
40
41impl UserBackendConnection {
42 pub fn admin_secret_handling(&self) -> AdministrativeSecretHandling {
44 match self {
45 Self::NetHsm {
46 admin_secret_handling,
47 ..
48 } => *admin_secret_handling,
49 Self::YubiHsm2 {
50 admin_secret_handling,
51 ..
52 } => *admin_secret_handling,
53 }
54 }
55
56 pub fn non_admin_secret_handling(&self) -> NonAdministrativeSecretHandling {
58 match self {
59 Self::NetHsm {
60 non_admin_secret_handling,
61 ..
62 } => *non_admin_secret_handling,
63 Self::YubiHsm2 {
64 non_admin_secret_handling,
65 ..
66 } => *non_admin_secret_handling,
67 }
68 }
69
70 pub fn create_non_admin_backend_user_secrets(
81 &self,
82 ) -> Result<Option<Vec<Box<dyn UserWithPassphrase>>>, crate::Error> {
83 match self {
84 Self::NetHsm {
85 non_admin_secret_handling,
86 mapping,
87 ..
88 } => mapping.create_non_admin_backend_user_secrets(*non_admin_secret_handling),
89 Self::YubiHsm2 {
90 non_admin_secret_handling,
91 mapping,
92 ..
93 } => mapping.create_non_admin_backend_user_secrets(*non_admin_secret_handling),
94 }
95 }
96
97 pub fn load_non_admin_backend_user_secrets(
108 &self,
109 filter: NonAdminBackendUserIdFilter,
110 ) -> Result<Option<Vec<Box<dyn UserWithPassphrase>>>, crate::Error> {
111 match self {
112 Self::NetHsm {
113 non_admin_secret_handling,
114 mapping,
115 ..
116 } => mapping.load_non_admin_backend_user_secrets(*non_admin_secret_handling, filter),
117 Self::YubiHsm2 {
118 non_admin_secret_handling,
119 mapping,
120 ..
121 } => mapping.load_non_admin_backend_user_secrets(*non_admin_secret_handling, filter),
122 }
123 }
124}
125
126impl MappingSystemUserId for UserBackendConnection {
127 fn system_user_id(&self) -> Option<&SystemUserId> {
128 match self {
129 Self::NetHsm { mapping, .. } => mapping.system_user_id(),
130 Self::YubiHsm2 { mapping, .. } => mapping.system_user_id(),
131 }
132 }
133}
134
135impl MappingAuthorizedKeyEntry for UserBackendConnection {
136 fn authorized_key_entry(&self) -> Option<&AuthorizedKeyEntry> {
137 match self {
138 Self::NetHsm { mapping, .. } => mapping.authorized_key_entry(),
139 Self::YubiHsm2 { mapping, .. } => mapping.authorized_key_entry(),
140 }
141 }
142}
143
144impl Config {
145 pub fn user_backend_connection(&self, user: &SystemUserId) -> Option<UserBackendConnection> {
147 if let Some(nethsm_config) = self.nethsm.as_ref()
148 && let Some(mapping) = nethsm_config
149 .mappings()
150 .iter()
151 .find(|mapping| mapping.system_user_id().is_some_and(|id| id == user))
152 {
153 return Some(UserBackendConnection::NetHsm {
154 admin_secret_handling: *self.system.admin_secret_handling(),
155 non_admin_secret_handling: *self.system.non_admin_secret_handling(),
156 connections: nethsm_config.connections().clone(),
157 mapping: mapping.clone(),
158 });
159 }
160
161 if let Some(yubihsm2_config) = self.yubihsm2.as_ref()
162 && let Some(mapping) = yubihsm2_config
163 .mappings()
164 .iter()
165 .find(|mapping| mapping.system_user_id().is_some_and(|id| id == user))
166 {
167 return Some(UserBackendConnection::YubiHsm2 {
168 admin_secret_handling: *self.system.admin_secret_handling(),
169 non_admin_secret_handling: *self.system.non_admin_secret_handling(),
170 connections: yubihsm2_config.connections().clone(),
171 mapping: mapping.clone(),
172 });
173 }
174
175 None
176 }
177
178 pub fn user_backend_connections(
186 &self,
187 filters: &[UserBackendConnectionFilter],
188 ) -> Vec<UserBackendConnection> {
189 let mut user_backend_connections = Vec::new();
190
191 if let Some(nethsm_config) = &self.nethsm
192 && (filters.is_empty()
193 || filters.contains(&UserBackendConnectionFilter::Backend(BackendType::NetHsm))
194 || !filters
195 .iter()
196 .any(|filter| matches!(filter, UserBackendConnectionFilter::Backend(_))))
197 {
198 let mappings = nethsm_config
199 .mappings()
200 .iter()
201 .filter(|mapping| {
202 filters.is_empty()
203 || (matches!(mapping, NetHsmUserMapping::Admin(_))
204 && filters.contains(&UserBackendConnectionFilter::Admin))
205 || (!matches!(mapping, NetHsmUserMapping::Admin(_))
206 && filters.contains(&UserBackendConnectionFilter::NonAdmin))
207 })
208 .collect::<Vec<_>>();
209 for mapping in mappings {
210 user_backend_connections.push(UserBackendConnection::NetHsm {
211 admin_secret_handling: *self.system.admin_secret_handling(),
212 non_admin_secret_handling: *self.system.non_admin_secret_handling(),
213 connections: nethsm_config.connections().clone(),
214 mapping: mapping.clone(),
215 });
216 }
217 }
218
219 if let Some(yubihsm2_config) = &self.yubihsm2
220 && (filters.is_empty()
221 || filters.contains(&UserBackendConnectionFilter::Backend(BackendType::YubiHsm2))
222 || !filters
223 .iter()
224 .any(|filter| matches!(filter, UserBackendConnectionFilter::Backend(_))))
225 {
226 let mappings = yubihsm2_config
227 .mappings()
228 .iter()
229 .filter(|mapping| {
230 filters.is_empty()
231 || (matches!(mapping, YubiHsm2UserMapping::Admin { .. })
232 && filters.contains(&UserBackendConnectionFilter::Admin))
233 || (!matches!(mapping, YubiHsm2UserMapping::Admin { .. })
234 && filters.contains(&UserBackendConnectionFilter::NonAdmin))
235 })
236 .collect::<Vec<_>>();
237 for mapping in mappings {
238 user_backend_connections.push(UserBackendConnection::YubiHsm2 {
239 admin_secret_handling: *self.system.admin_secret_handling(),
240 non_admin_secret_handling: *self.system.non_admin_secret_handling(),
241 connections: yubihsm2_config.connections().clone(),
242 mapping: mapping.clone(),
243 });
244 }
245 }
246
247 user_backend_connections
248 }
249}
250
251impl ConfigAuthorizedKeyEntries for Config {
252 fn authorized_key_entries(&self) -> HashSet<&AuthorizedKeyEntry> {
253 let mut output = self.system.authorized_key_entries();
254 if let Some(nethsm) = &self.nethsm {
255 output.extend(nethsm.authorized_key_entries());
256 }
257 if let Some(yubihsm2) = &self.yubihsm2 {
258 output.extend(yubihsm2.authorized_key_entries());
259 }
260
261 output
262 }
263}
264
265impl<'a> ConfigSystemUserData<'a> for Config {
266 fn system_user_data(&'a self) -> HashSet<SystemUserData<'a>> {
267 let mut output = HashSet::new();
268
269 for mapping in self.system.mappings() {
270 output.insert(mapping.into());
271 }
272
273 if let Some(config) = self.nethsm() {
274 for mapping in config.mappings() {
275 output.insert(mapping.into());
276 }
277 }
278
279 if let Some(config) = self.yubihsm2() {
280 for mapping in config.mappings() {
281 output.insert(mapping.into());
282 }
283 }
284
285 output
286 }
287}
288
289impl ConfigSystemUserIds for Config {
290 fn system_user_ids(&self) -> HashSet<&SystemUserId> {
291 let mut output = self.system.system_user_ids();
292 if let Some(nethsm) = &self.nethsm {
293 output.extend(nethsm.system_user_ids());
294 }
295 if let Some(yubihsm2) = &self.yubihsm2 {
296 output.extend(yubihsm2.system_user_ids());
297 }
298
299 output
300 }
301}
302
303impl ConfigBuilder {
304 pub fn new(system: SystemConfig) -> Self {
306 Self(Config {
307 system,
308 nethsm: None,
309 yubihsm2: None,
310 })
311 }
312}