nethsm/base/impl_user.rs
1//! [`NetHsm`] implementation for user and namespace handling.
2
3use log::debug;
4use nethsm_sdk_rs::{
5 apis::default_api::{
6 namespaces_get,
7 namespaces_namespace_id_delete,
8 namespaces_namespace_id_put,
9 users_get,
10 users_post,
11 users_user_id_delete,
12 users_user_id_get,
13 users_user_id_passphrase_post,
14 users_user_id_put,
15 users_user_id_tags_get,
16 users_user_id_tags_tag_delete,
17 users_user_id_tags_tag_put,
18 },
19 models::{UserData, UserPassphrasePostData, UserPostData},
20};
21
22#[cfg(doc)]
23use crate::SystemState;
24use crate::{
25 Credentials,
26 Error,
27 NamespaceId,
28 NetHsm,
29 Passphrase,
30 UserError,
31 UserId,
32 UserRole,
33 base::utils::user_or_no_user_string,
34 nethsm_sdk::NetHsmApiError,
35 user::NamespaceSupport,
36};
37
38impl NetHsm {
39 /// Adds a new namespace.
40 ///
41 /// Adds a new [namespace] with the ID `namespace_id`.
42 ///
43 /// **WARNING**: A user in the [`Administrator`][`UserRole::Administrator`] [role] must be added
44 /// for the [namespace] using [`add_user`][`NetHsm::add_user`] **before** creating the
45 /// [namespace]! Otherwise there is no user to administrate the new [namespace]!
46 ///
47 /// This call requires using [`Credentials`] of a system-wide user in the
48 /// [`Administrator`][`UserRole::Administrator`] [role] (*R-Administrator*).
49 ///
50 /// # Errors
51 ///
52 /// Returns an [`Error::Api`] if adding the namespace fails:
53 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
54 /// * the namespace identified by `namespace_id` exists already
55 /// * the used [`Credentials`] are not correct
56 /// * the used [`Credentials`] are not that of a system-wide user in the
57 /// [`Administrator`][`UserRole::Administrator`] [role] (*R-Administrator*)
58 ///
59 /// # Examples
60 ///
61 /// ```no_run
62 /// use nethsm::{Connection, ConnectionSecurity, Credentials, NetHsm, Passphrase, UserRole};
63 ///
64 /// # fn main() -> testresult::TestResult {
65 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
66 /// let nethsm = NetHsm::new(
67 /// Connection::new(
68 /// "https://example.org/api/v1".try_into()?,
69 /// ConnectionSecurity::Unsafe,
70 /// ),
71 /// Some(Credentials::new(
72 /// "admin".parse()?,
73 /// Some(Passphrase::new("passphrase".to_string())),
74 /// )),
75 /// None,
76 /// None,
77 /// )?;
78 ///
79 /// // add a user in the Administrator role for a namespace (N-Administrator)
80 /// nethsm.add_user(
81 /// "Namespace1 Admin".to_string(),
82 /// UserRole::Administrator,
83 /// Passphrase::new("namespace1-admin-passphrase".to_string()),
84 /// Some("namespace1~admin1".parse()?),
85 /// )?;
86 /// // create accompanying namespace
87 /// nethsm.add_namespace(&"namespace1".parse()?)?;
88 ///
89 /// // N-Administrator can not create namespaces
90 /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?;
91 /// assert!(nethsm.add_namespace(&"namespace2".parse()?).is_err());
92 /// # Ok(())
93 /// # }
94 /// ```
95 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
96 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
97 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
98 pub fn add_namespace(&self, namespace_id: &NamespaceId) -> Result<(), Error> {
99 debug!(
100 "Add the namespace {namespace_id} on the NetHSM at {} using {}",
101 self.url.borrow(),
102 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
103 );
104
105 self.validate_namespace_access(NamespaceSupport::Unsupported, None, None)?;
106 namespaces_namespace_id_put(&self.create_connection_config(), namespace_id.as_ref())
107 .map_err(|error| {
108 Error::Api(format!(
109 "Adding namespace failed: {}",
110 NetHsmApiError::from(error)
111 ))
112 })?;
113 Ok(())
114 }
115
116 /// Gets all available [namespaces].
117 ///
118 /// This call requires using [`Credentials`] of a system-wide user in the
119 /// [`Administrator`][`UserRole::Administrator`] [role] (*R-Administrator*).
120 ///
121 /// # Errors
122 ///
123 /// Returns an [`Error::Api`] if getting the namespaces fails:
124 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
125 /// * the used [`Credentials`] are not correct
126 /// * the used [`Credentials`] are not that of a system-wide user in the
127 /// [`Administrator`][`UserRole::Administrator`] [role] (*R-Administrator*)
128 ///
129 /// # Examples
130 ///
131 /// ```no_run
132 /// use nethsm::{Connection, ConnectionSecurity, Credentials, NetHsm, Passphrase, UserRole};
133 ///
134 /// # fn main() -> testresult::TestResult {
135 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
136 /// let nethsm = NetHsm::new(
137 /// Connection::new(
138 /// "https://example.org/api/v1".try_into()?,
139 /// ConnectionSecurity::Unsafe,
140 /// ),
141 /// Some(Credentials::new(
142 /// "admin".parse()?,
143 /// Some(Passphrase::new("passphrase".to_string())),
144 /// )),
145 /// None,
146 /// None,
147 /// )?;
148 ///
149 /// // print list of all namespaces
150 /// println!("{:?}", nethsm.get_namespaces()?);
151 ///
152 /// // add a user in the Administrator role for a namespace (N-Administrator)
153 /// nethsm.add_user(
154 /// "Namespace1 Admin".to_string(),
155 /// UserRole::Administrator,
156 /// Passphrase::new("namespace1-admin-passphrase".to_string()),
157 /// Some("namespace1~admin1".parse()?),
158 /// )?;
159 /// // create accompanying namespace
160 /// nethsm.add_namespace(&"namespace1".parse()?)?;
161 ///
162 /// // N-Administrator can not get namespaces
163 /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?;
164 /// assert!(nethsm.get_namespaces().is_err());
165 /// # Ok(())
166 /// # }
167 /// ```
168 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
169 /// [namespaces]: https://docs.nitrokey.com/nethsm/administration#namespaces
170 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
171 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
172 pub fn get_namespaces(&self) -> Result<Vec<NamespaceId>, Error> {
173 debug!(
174 "Retrieve all available namespaces from the NetHSM at {} using {}",
175 self.url.borrow(),
176 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
177 );
178
179 self.validate_namespace_access(NamespaceSupport::Unsupported, None, None)?;
180 let valid_namespaces = {
181 let mut invalid_namespaces = Vec::new();
182 let valid_namespaces = namespaces_get(&self.create_connection_config())
183 .map_err(|error| {
184 Error::Api(format!(
185 "Getting namespaces failed: {}",
186 NetHsmApiError::from(error)
187 ))
188 })?
189 .entity
190 .into_iter()
191 .filter_map(|x| {
192 if let Ok(namespace) = NamespaceId::new(x.id.clone()) {
193 Some(namespace)
194 } else {
195 invalid_namespaces.push(x.id);
196 None
197 }
198 })
199 .collect::<Vec<NamespaceId>>();
200
201 if !invalid_namespaces.is_empty() {
202 return Err(UserError::InvalidNamespaceIds {
203 namespace_ids: invalid_namespaces,
204 }
205 .into());
206 }
207 valid_namespaces
208 };
209
210 Ok(valid_namespaces)
211 }
212
213 /// Deletes an existing [namespace].
214 ///
215 /// Deletes the [namespace] identified by `namespace_id`.
216 ///
217 /// **WARNING**: This call deletes the [namespace] and all keys in it! Make sure to create a
218 /// [`backup`][`NetHsm::backup`]!
219 ///
220 /// This call requires using [`Credentials`] of a system-wide user in the
221 /// [`Administrator`][`UserRole::Administrator`] [role] (*R-Administrator*).
222 ///
223 /// # Errors
224 ///
225 /// Returns an [`Error::Api`] if deleting the namespace fails:
226 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
227 /// * the [namespace] identified by `namespace_id` does not exist
228 /// * the used [`Credentials`] are not correct
229 /// * the used [`Credentials`] are not that of a system-wide user in the
230 /// [`Administrator`][`UserRole::Administrator`] [role] (*R-Administrator*)
231 ///
232 /// # Examples
233 ///
234 /// ```no_run
235 /// use nethsm::{Connection, ConnectionSecurity, Credentials, NetHsm, Passphrase, UserRole};
236 ///
237 /// # fn main() -> testresult::TestResult {
238 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
239 /// let nethsm = NetHsm::new(
240 /// Connection::new(
241 /// "https://example.org/api/v1".try_into()?,
242 /// ConnectionSecurity::Unsafe,
243 /// ),
244 /// Some(Credentials::new(
245 /// "admin".parse()?,
246 /// Some(Passphrase::new("passphrase".to_string())),
247 /// )),
248 /// None,
249 /// None,
250 /// )?;
251 /// // add a user in the Administrator role for a namespace (N-Administrator)
252 /// nethsm.add_user(
253 /// "Namespace1 Admin".to_string(),
254 /// UserRole::Administrator,
255 /// Passphrase::new("namespace1-admin-passphrase".to_string()),
256 /// Some("namespace1~admin1".parse()?),
257 /// )?;
258 /// // create accompanying namespace
259 /// nethsm.add_namespace(&"namespace1".parse()?)?;
260 ///
261 /// // N-Administrators can not delete namespaces
262 /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?;
263 /// assert!(nethsm.delete_namespace(&"namespace1".parse()?).is_err());
264 ///
265 /// // R-Administrators can delete namespaces
266 /// nethsm.use_credentials(&"admin".parse()?)?;
267 /// nethsm.delete_namespace(&"namespace1".parse()?)?;
268 /// # Ok(())
269 /// # }
270 /// ```
271 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
272 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
273 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
274 pub fn delete_namespace(&self, namespace_id: &NamespaceId) -> Result<(), Error> {
275 debug!(
276 "Delete the namespace {namespace_id} from the NetHSM at {} using {}",
277 self.url.borrow(),
278 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
279 );
280
281 self.validate_namespace_access(NamespaceSupport::Unsupported, None, None)?;
282 namespaces_namespace_id_delete(&self.create_connection_config(), namespace_id.as_ref())
283 .map_err(|error| {
284 Error::Api(format!(
285 "Deleting namespace failed: {}",
286 NetHsmApiError::from(error)
287 ))
288 })?;
289 Ok(())
290 }
291
292 /// [Adds a user] and returns its User ID.
293 ///
294 /// A new user is created by providing a `real_name` from which a User ID is derived (optionally
295 /// a User ID can be provided with `user_id`), a `role` which describes the user's access rights
296 /// on the NetHSM (see [`UserRole`]) and a `passphrase`.
297 ///
298 /// Internally, this function also calls [`add_credentials`][`NetHsm::add_credentials`] to
299 /// add the new user to the list of available credentials.
300 ///
301 /// This call requires using [`Credentials`] of a user in the
302 /// [`Administrator`][`UserRole::Administrator`] [role].
303 /// When adding a user to a [namespace], that does not yet exist, the caller must
304 /// be a system-wide [`Administrator`][`UserRole::Administrator`] (*R-Administrator*).
305 /// When adding a user to an already existing [namespace], the caller must be an
306 /// [`Administrator`][`UserRole::Administrator`] in that [namespace]
307 /// (*N-Administrator*).
308 ///
309 /// ## Namespaces
310 ///
311 /// New users *implicitly* inherit the [namespace] of the caller.
312 /// A [namespace] can be provided *explicitly* by prefixing the User ID with the ID of a
313 /// [namespace] and the `~` character (e.g. `namespace1~user1`).
314 /// When specifying a namespace as part of the User ID and the [namespace] exists already, the
315 /// caller must be an [`Administrator`][`UserRole::Administrator`] of that [namespace]
316 /// (*N-Administrator*).
317 /// When specifying a [namespace] as part of the User ID and the [namespace] does not yet exist,
318 /// the caller must be a system-wide [`Administrator`][`UserRole::Administrator`]
319 /// (*R-Administrator*).
320 ///
321 /// **NOTE**: Users in the [`Backup`][`UserRole::Backup`] and [`Metrics`][`UserRole::Metrics`]
322 /// [role] can not be created for a [namespace], as their underlying functionality can only be
323 /// used in a system-wide context!
324 ///
325 /// # Errors
326 ///
327 /// Returns an [`Error::Api`] if adding the user fails:
328 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
329 /// * the provided `real_name`, `passphrase` or `user_id` are not valid
330 /// * the provided `user_id` exists already
331 /// * the used [`Credentials`] are not correct
332 /// * the used [`Credentials`] are not that of a system-wide
333 /// [`Administrator`][`UserRole::Administrator`], when adding a user to a not yet existing
334 /// [namespace]
335 /// * the used [`Credentials`] are not that of an [`Administrator`][`UserRole::Administrator`]
336 /// in the [namespace] the user is about to be added to
337 ///
338 /// # Examples
339 ///
340 /// ```no_run
341 /// use nethsm::{Connection, ConnectionSecurity, Credentials, NetHsm, Passphrase, UserRole};
342 ///
343 /// # fn main() -> testresult::TestResult {
344 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
345 /// let nethsm = NetHsm::new(
346 /// Connection::new(
347 /// "https://example.org/api/v1".try_into()?,
348 /// ConnectionSecurity::Unsafe,
349 /// ),
350 /// Some(Credentials::new(
351 /// "admin".parse()?,
352 /// Some(Passphrase::new("passphrase".to_string())),
353 /// )),
354 /// None,
355 /// None,
356 /// )?;
357 ///
358 /// // add a system-wide user in the Operator role
359 /// nethsm.add_user(
360 /// "Operator One".to_string(),
361 /// UserRole::Operator,
362 /// Passphrase::new("operator1-passphrase".to_string()),
363 /// Some("user1".parse()?),
364 /// )?;
365 ///
366 /// // this fails because the user exists already
367 /// assert!(nethsm
368 /// .add_user(
369 /// "Operator One".to_string(),
370 /// UserRole::Operator,
371 /// Passphrase::new("operator1-passphrase".to_string()),
372 /// Some("user1".parse()?),
373 /// )
374 /// .is_err());
375 ///
376 /// // add a user in the Administrator role (N-Administrator) for a not yet existing namespace "namespace1"
377 /// nethsm.add_user(
378 /// "Namespace1 Admin".to_string(),
379 /// UserRole::Administrator,
380 /// Passphrase::new("namespace1-admin-passphrase".to_string()),
381 /// Some("namespace1~admin1".parse()?),
382 /// )?;
383 ///
384 /// # Ok(())
385 /// # }
386 /// ```
387 /// [Adds a user]: https://docs.nitrokey.com/nethsm/administration#add-user
388 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
389 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
390 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
391 pub fn add_user(
392 &self,
393 real_name: String,
394 role: UserRole,
395 passphrase: Passphrase,
396 user_id: Option<UserId>,
397 ) -> Result<UserId, Error> {
398 debug!(
399 "Add the user \"{real_name}\"{} in the role {role} to the NetHSM at {} using {}",
400 if let Some(user_id) = user_id.as_ref() {
401 format!(" (\"{user_id}\")")
402 } else {
403 "".to_string()
404 },
405 self.url.borrow(),
406 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
407 );
408
409 self.validate_namespace_access(NamespaceSupport::Supported, user_id.as_ref(), Some(&role))?;
410 let user_id = if let Some(user_id) = user_id {
411 users_user_id_put(
412 &self.create_connection_config(),
413 &user_id.to_string(),
414 UserPostData::new(real_name, role.into(), passphrase.expose_owned()),
415 )
416 .map_err(|error| {
417 Error::Api(format!(
418 "Adding user failed: {}",
419 NetHsmApiError::from(error)
420 ))
421 })?;
422 user_id
423 } else {
424 UserId::new(
425 users_post(
426 &self.create_connection_config(),
427 UserPostData::new(real_name, role.into(), passphrase.expose_owned()),
428 )
429 .map_err(|error| {
430 Error::Api(format!(
431 "Adding user failed: {}",
432 NetHsmApiError::from(error)
433 ))
434 })?
435 .entity
436 .id,
437 )?
438 };
439
440 // add to list of users
441 self.add_credentials(Credentials::new(user_id.clone(), Some(passphrase)));
442
443 Ok(user_id)
444 }
445
446 /// Deletes an existing user.
447 ///
448 /// [Deletes a user] identified by `user_id`.
449 ///
450 /// Internally, this function also calls [`remove_credentials`][`NetHsm::remove_credentials`] to
451 /// remove the user from the list of available credentials.
452 ///
453 /// This call requires using [`Credentials`] of a user in the
454 /// [`Administrator`][`UserRole::Administrator`] [role].
455 ///
456 /// ## Namespaces
457 ///
458 /// * *N-Administrators* ([`Administrator`][`UserRole::Administrator`] users in a given
459 /// [namespace]) can only delete users in their own [namespace].
460 /// * *R-Administrators* (system-wide [`Administrator`][`UserRole::Administrator`] users) can
461 /// only delete system-wide users, but not those in a [namespace]. To allow *R-Administrators*
462 /// to delete users in a [namespace], the given [namespace] has to be deleted first using
463 /// [`delete_namespace`][`NetHsm::delete_namespace`].
464 ///
465 /// # Errors
466 ///
467 /// Returns an [`Error::Api`] if deleting a user fails:
468 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
469 /// * the user identified by `user_id` does not exist
470 /// * the used [`Credentials`] are not correct
471 /// * the used [`Credentials`] are not that of a user in the
472 /// [`Administrator`][`UserRole::Administrator`] role
473 /// * the targeted user is in an existing [namespace], but the caller is an *R-Administrator* or
474 /// an *N-Administrator* in a different [namespace]
475 /// * the targeted user is a system-wide user, but the caller is not an *R-Administrator*
476 /// * the user attempts to delete itself
477 ///
478 /// # Examples
479 ///
480 /// ```no_run
481 /// use nethsm::{Connection, ConnectionSecurity, Credentials, NetHsm, Passphrase, UserRole};
482 ///
483 /// # fn main() -> testresult::TestResult {
484 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
485 /// let nethsm = NetHsm::new(
486 /// Connection::new(
487 /// "https://example.org/api/v1".try_into()?,
488 /// ConnectionSecurity::Unsafe,
489 /// ),
490 /// Some(Credentials::new(
491 /// "admin".parse()?,
492 /// Some(Passphrase::new("passphrase".to_string())),
493 /// )),
494 /// None,
495 /// None,
496 /// )?;
497 ///
498 /// // add a system-wide user in the Operator role
499 /// nethsm.add_user(
500 /// "Operator One".to_string(),
501 /// UserRole::Operator,
502 /// Passphrase::new("operator1-passphrase".to_string()),
503 /// Some("user1".parse()?),
504 /// )?;
505 ///
506 /// // add a user in the Administrator role for a namespace (N-Administrator)
507 /// nethsm.add_user(
508 /// "Namespace1 Admin".to_string(),
509 /// UserRole::Administrator,
510 /// Passphrase::new("namespce1-admin-passphrase".to_string()),
511 /// Some("namespace1~admin1".parse()?),
512 /// )?;
513 /// // add the accompanying namespace
514 /// nethsm.add_namespace(&"namespace1".parse()?)?;
515 ///
516 /// // R-Administrators can not delete N-Administrators, as long as their namespace exists
517 /// assert!(nethsm.delete_user(&"namespace1~admin1".parse()?).is_err());
518 /// // however, after deleting the namespace, this becomes possible
519 /// nethsm.delete_namespace(&"namespace1".parse()?)?;
520 /// nethsm.delete_user(&"namespace1~admin1".parse()?)?;
521 ///
522 /// // R-Administrators can delete system-wide users
523 /// nethsm.delete_user(&"user1".parse()?)?;
524 /// # Ok(())
525 /// # }
526 /// ```
527 /// [Deletes a user]: https://docs.nitrokey.com/nethsm/administration#delete-user
528 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
529 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
530 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
531 pub fn delete_user(&self, user_id: &UserId) -> Result<(), Error> {
532 debug!(
533 "Delete the user \"{user_id}\" from the NetHSM at {} using {}",
534 self.url.borrow(),
535 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
536 );
537
538 self.validate_namespace_access(NamespaceSupport::Supported, Some(user_id), None)?;
539 users_user_id_delete(&self.create_connection_config(), &user_id.to_string()).map_err(
540 |error| {
541 Error::Api(format!(
542 "Deleting user failed: {}",
543 NetHsmApiError::from(error)
544 ))
545 },
546 )?;
547
548 // remove from list of credentials
549 self.remove_credentials(user_id);
550
551 Ok(())
552 }
553
554 /// Gets a [list of all User IDs].
555 ///
556 /// This call requires using [`Credentials`] of a user in the
557 /// [`Administrator`][`UserRole::Administrator`] [role].
558 ///
559 /// ## Namespaces
560 ///
561 /// * *N-Administrators* ([`Administrator`][`UserRole::Administrator`] users in a given
562 /// [namespace]) can only list users in their own [namespace].
563 /// * *R-Administrators* (system-wide [`Administrator`][`UserRole::Administrator`] users) can
564 /// list all users on the system.
565 ///
566 /// # Errors
567 ///
568 /// Returns an [`Error::Api`] if retrieving the list of all User IDs fails:
569 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
570 /// * the used [`Credentials`] are not correct
571 /// * the used [`Credentials`] are not that of a user in the
572 /// [`Administrator`][`UserRole::Administrator`] role
573 ///
574 /// # Examples
575 ///
576 /// ```no_run
577 /// use nethsm::{Connection, ConnectionSecurity, Credentials, NetHsm, Passphrase, UserRole};
578 ///
579 /// # fn main() -> testresult::TestResult {
580 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
581 /// let nethsm = NetHsm::new(
582 /// Connection::new(
583 /// "https://example.org/api/v1".try_into()?,
584 /// ConnectionSecurity::Unsafe,
585 /// ),
586 /// Some(Credentials::new(
587 /// "admin".parse()?,
588 /// Some(Passphrase::new("passphrase".to_string())),
589 /// )),
590 /// None,
591 /// None,
592 /// )?;
593 ///
594 /// // add a user in the Administrator role for a namespace (N-Administrator)
595 /// nethsm.add_user(
596 /// "Namespace1 Admin".to_string(),
597 /// UserRole::Administrator,
598 /// Passphrase::new("namespce1-admin-passphrase".to_string()),
599 /// Some("namespace1~admin1".parse()?),
600 /// )?;
601 /// // add the accompanying namespace
602 /// nethsm.add_namespace(&"namespace1".parse()?)?;
603 /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?;
604 /// // the N-Administrator only sees itself
605 /// assert_eq!(nethsm.get_users()?.len(), 1);
606 ///
607 /// // use the credentials of the R-Administrator
608 /// nethsm.use_credentials(&"admin".parse()?)?;
609 /// // the R-Administrator sees at least itself and the previously created N-Administrator
610 /// assert!(nethsm.get_users()?.len() >= 2);
611 /// # Ok(())
612 /// # }
613 /// ```
614 /// [list of all User IDs]: https://docs.nitrokey.com/nethsm/administration#list-users
615 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
616 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
617 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
618 pub fn get_users(&self) -> Result<Vec<UserId>, Error> {
619 debug!(
620 "Get the users of the NetHSM at {} using {}",
621 self.url.borrow(),
622 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
623 );
624
625 self.validate_namespace_access(NamespaceSupport::Supported, None, None)?;
626 let valid_users = {
627 let mut invalid_users = Vec::new();
628 let valid_users = users_get(&self.create_connection_config())
629 .map_err(|error| {
630 Error::Api(format!(
631 "Getting users failed: {}",
632 NetHsmApiError::from(error)
633 ))
634 })?
635 .entity
636 .into_iter()
637 .filter_map(|x| {
638 if let Ok(user) = UserId::new(x.user.clone()) {
639 Some(user)
640 } else {
641 invalid_users.push(x.user);
642 None
643 }
644 })
645 .collect::<Vec<UserId>>();
646
647 if !invalid_users.is_empty() {
648 return Err(UserError::InvalidUserIds {
649 user_ids: invalid_users,
650 }
651 .into());
652 }
653
654 valid_users
655 };
656
657 Ok(valid_users)
658 }
659
660 /// Gets [information of a user].
661 ///
662 /// This call requires using [`Credentials`] of a user in the
663 /// [`Administrator`][`UserRole::Administrator`] [role].
664 ///
665 /// ## Namespaces
666 ///
667 /// * *N-Administrators* ([`Administrator`][`UserRole::Administrator`] users in a given
668 /// [namespace]) can only access information about users in their own [namespace].
669 /// * *R-Administrators* (system-wide [`Administrator`][`UserRole::Administrator`] users) can
670 /// access information about all users on the system.
671 ///
672 /// # Errors
673 ///
674 /// Returns an [`Error::Api`] if retrieving information of the user fails:
675 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
676 /// * the user identified by `user_id` does not exist
677 /// * the used [`Credentials`] are not correct
678 /// * the used [`Credentials`] are not that of a user in the
679 /// [`Administrator`][`UserRole::Administrator`] role
680 /// * the used [`Credentials`] do not provide access to information about a user in the targeted
681 /// [namespace] (*N-Administrator* of a different [namespace])
682 ///
683 /// # Examples
684 ///
685 /// ```no_run
686 /// use nethsm::{Connection, ConnectionSecurity, Credentials, NetHsm, Passphrase, UserRole};
687 ///
688 /// # fn main() -> testresult::TestResult {
689 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
690 /// let nethsm = NetHsm::new(
691 /// Connection::new(
692 /// "https://example.org/api/v1".try_into()?,
693 /// ConnectionSecurity::Unsafe,
694 /// ),
695 /// Some(Credentials::new(
696 /// "admin".parse()?,
697 /// Some(Passphrase::new("passphrase".to_string())),
698 /// )),
699 /// None,
700 /// None,
701 /// )?;
702 ///
703 /// // add a user in the Administrator role for a namespace (N-Administrator)
704 /// nethsm.add_user(
705 /// "Namespace1 Admin".to_string(),
706 /// UserRole::Administrator,
707 /// Passphrase::new("namespce1-admin-passphrase".to_string()),
708 /// Some("namespace1~admin1".parse()?),
709 /// )?;
710 /// // add the accompanying namespace
711 /// nethsm.add_namespace(&"namespace1".parse()?)?;
712 /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?;
713 /// // the N-Administrator sees itself
714 /// println!("{:?}", nethsm.get_user(&"namespace1~admin1".parse()?)?);
715 /// // the N-Administrator can not see the R-Administrator
716 /// assert!(nethsm.get_user(&"admin".parse()?).is_err());
717 ///
718 /// nethsm.use_credentials(&"admin".parse()?)?;
719 /// // the R-Administrator sees itself
720 /// println!("{:?}", nethsm.get_user(&"admin".parse()?)?);
721 /// // the R-Administrator sees the N-Administrator
722 /// println!("{:?}", nethsm.get_user(&"namespace1~admin1".parse()?)?);
723 /// // this fails if the user does not exist
724 /// assert!(nethsm.get_user(&"user1".parse()?).is_err());
725 /// # Ok(())
726 /// # }
727 /// ```
728 /// [information of a user]: https://docs.nitrokey.com/nethsm/administration#list-users
729 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
730 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
731 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
732 pub fn get_user(&self, user_id: &UserId) -> Result<UserData, Error> {
733 debug!(
734 "Get the information of the user \"{user_id}\" on the NetHSM at {} using {}",
735 self.url.borrow(),
736 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
737 );
738
739 self.validate_namespace_access(NamespaceSupport::Supported, Some(user_id), None)?;
740 Ok(
741 users_user_id_get(&self.create_connection_config(), &user_id.to_string())
742 .map_err(|error| {
743 Error::Api(format!(
744 "Getting user failed: {}",
745 NetHsmApiError::from(error)
746 ))
747 })?
748 .entity,
749 )
750 }
751
752 /// Sets the [passphrase for a user] on the NetHSM.
753 ///
754 /// ## Namespaces
755 ///
756 /// *N-Administrators* ([`Administrator`][`UserRole::Administrator`] users in a given
757 /// [namespace]) are only able to set the passphrases for users in their own [namespace].
758 /// *R-Administrators* (system-wide [`Administrator`][`UserRole::Administrator`] users) are only
759 /// able to set the passphrases for system-wide users.
760 ///
761 /// Internally, this function also calls [`add_credentials`][`NetHsm::add_credentials`] to add
762 /// the updated user [`Credentials`] to the list of available ones.
763 /// If the calling user is in the [`Administrator`][`UserRole::Administrator`] [role] and
764 /// changes their own passphrase, additionally
765 /// [`use_credentials`][`NetHsm::use_credentials`] is called to use the updated passphrase
766 /// after changing it.
767 ///
768 /// This call requires using [`Credentials`] of a user in the
769 /// [`Administrator`][`UserRole::Administrator`] [role].
770 ///
771 /// # Errors
772 ///
773 /// Returns an [`Error::Api`] if setting the passphrase for the user fails:
774 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
775 /// * the user identified by `user_id` does not exist
776 /// * the used [`Credentials`] are not correct
777 /// * the used [`Credentials`] are not that of a user in the
778 /// [`Administrator`][`UserRole::Administrator`] [role]
779 /// * the targeted user is in a [namespace], but the caller is not an
780 /// [`Administrator`][`UserRole::Administrator`] of that [namespace] (*N-Administrator*)
781 /// * the targeted user is a system-wide user, but the caller is not a system-wide
782 /// [`Administrator`][`UserRole::Administrator`] (*R-Administrator*)
783 ///
784 /// # Examples
785 ///
786 /// ```no_run
787 /// use nethsm::{Connection, ConnectionSecurity, Credentials, NetHsm, Passphrase, UserRole};
788 ///
789 /// # fn main() -> testresult::TestResult {
790 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
791 /// let nethsm = NetHsm::new(
792 /// Connection::new(
793 /// "https://example.org/api/v1".try_into()?,
794 /// ConnectionSecurity::Unsafe,
795 /// ),
796 /// Some(Credentials::new(
797 /// "admin".parse()?,
798 /// Some(Passphrase::new("passphrase".to_string())),
799 /// )),
800 /// None,
801 /// None,
802 /// )?;
803 /// // add a user in the Administrator role for a namespace (N-Administrator)
804 /// nethsm.add_user(
805 /// "Namespace1 Admin".to_string(),
806 /// UserRole::Administrator,
807 /// Passphrase::new("namespce1-admin-passphrase".to_string()),
808 /// Some("namespace1~admin1".parse()?),
809 /// )?;
810 /// // add the accompanying namespace
811 /// nethsm.add_namespace(&"namespace1".parse()?)?;
812 ///
813 /// // the R-Administrator can set its own passphrase
814 /// nethsm.set_user_passphrase(
815 /// "admin".parse()?,
816 /// Passphrase::new("new-admin-passphrase".to_string()),
817 /// )?;
818 /// // the R-Administrator can not set the N-Administrator's passphrase
819 /// assert!(
820 /// nethsm
821 /// .set_user_passphrase(
822 /// "namespace1~admin".parse()?,
823 /// Passphrase::new("new-admin-passphrase".to_string()),
824 /// )
825 /// .is_err()
826 /// );
827 ///
828 /// // the N-Administrator can set its own passphrase
829 /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?;
830 /// nethsm.set_user_passphrase(
831 /// "namespace1~admin1".parse()?,
832 /// Passphrase::new("new-admin-passphrase".to_string()),
833 /// )?;
834 /// // the N-Administrator can not set the R-Administrator's passphrase
835 /// assert!(
836 /// nethsm
837 /// .set_user_passphrase(
838 /// "admin".parse()?,
839 /// Passphrase::new("new-admin-passphrase".to_string())
840 /// )
841 /// .is_err()
842 /// );
843 /// # Ok(())
844 /// # }
845 /// ```
846 /// [passphrase for a user]: https://docs.nitrokey.com/nethsm/administration#user-passphrase
847 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
848 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
849 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
850 pub fn set_user_passphrase(
851 &self,
852 user_id: UserId,
853 passphrase: Passphrase,
854 ) -> Result<(), Error> {
855 debug!(
856 "Set the passphrase of the user \"{user_id}\" on the NetHSM at {} using {}",
857 self.url.borrow(),
858 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
859 );
860
861 self.validate_namespace_access(NamespaceSupport::Supported, Some(&user_id), None)?;
862 users_user_id_passphrase_post(
863 &self.create_connection_config(),
864 &user_id.to_string(),
865 UserPassphrasePostData::new(passphrase.expose_owned()),
866 )
867 .map_err(|error| {
868 Error::Api(format!(
869 "Setting user passphrase failed: {}",
870 NetHsmApiError::from(error)
871 ))
872 })?;
873
874 // add to list of available credentials
875 self.add_credentials(Credentials::new(user_id, Some(passphrase)));
876
877 Ok(())
878 }
879
880 /// [Adds a tag] to a user in the [`Operator`][`UserRole::Operator`] [role].
881 ///
882 /// A `tag` provides the user identified by `user_id` with access to keys in their [namespace],
883 /// that are tagged with that same `tag`.
884 ///
885 /// **NOTE**: The tag for the key in the same [namespace] must be added beforehand, by calling
886 /// [`add_key_tag`][`NetHsm::add_key_tag`].
887 ///
888 /// This call requires using [`Credentials`] of a user in the
889 /// [`Administrator`][`UserRole::Administrator`] [role].
890 ///
891 /// ## Namespaces
892 ///
893 /// * *N-Administrators* ([`Administrator`][`UserRole::Administrator`] users in a given
894 /// [namespace]) are only able to add tags for users in their own [namespace].
895 /// * *R-Administrators* (system-wide [`Administrator`][`UserRole::Administrator`] users) are
896 /// only able to add tags for system-wide users.
897 ///
898 /// # Errors
899 ///
900 /// Returns an [`Error::Api`] if adding the tag for the user fails:
901 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
902 /// * the user identified by `user_id` does not exist
903 /// * the user identified by `user_id` is not in the [`Operator`][`UserRole::Operator`] [role]
904 /// * the used [`Credentials`] are not correct
905 /// * the used [`Credentials`] are not that of a user in the
906 /// [`Administrator`][`UserRole::Administrator`] [role]
907 /// * the caller does not have access to the target user's [namespace]
908 ///
909 /// # Examples
910 ///
911 /// ```no_run
912 /// use nethsm::{
913 /// Connection,
914 /// ConnectionSecurity,
915 /// Credentials,
916 /// KeyMechanism,
917 /// KeyType,
918 /// NetHsm,
919 /// Passphrase,
920 /// UserRole,
921 /// };
922 ///
923 /// # fn main() -> testresult::TestResult {
924 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
925 /// let nethsm = NetHsm::new(
926 /// Connection::new(
927 /// "https://example.org/api/v1".try_into()?,
928 /// ConnectionSecurity::Unsafe,
929 /// ),
930 /// Some(Credentials::new(
931 /// "admin".parse()?,
932 /// Some(Passphrase::new("passphrase".to_string())),
933 /// )),
934 /// None,
935 /// None,
936 /// )?;
937 /// // add a user in the Administrator role for a namespace (N-Administrator)
938 /// nethsm.add_user(
939 /// "Namespace1 Admin".to_string(),
940 /// UserRole::Administrator,
941 /// Passphrase::new("namespce1-admin-passphrase".to_string()),
942 /// Some("namespace1~admin1".parse()?),
943 /// )?;
944 /// // add a user in the Operator role for a namespace
945 /// nethsm.add_user(
946 /// "Namespace1 Operator".to_string(),
947 /// UserRole::Operator,
948 /// Passphrase::new("namespce1-operator-passphrase".to_string()),
949 /// Some("namespace1~operator1".parse()?),
950 /// )?;
951 /// // add the accompanying namespace
952 /// nethsm.add_namespace(&"namespace1".parse()?)?;
953 /// // add a system-wide user in the Operator role
954 /// nethsm.add_user(
955 /// "Operator One".to_string(),
956 /// UserRole::Operator,
957 /// Passphrase::new("operator1-passphrase".to_string()),
958 /// Some("user1".parse()?),
959 /// )?;
960 /// // generate system-wide key with tag
961 /// nethsm.generate_key(
962 /// KeyType::Curve25519,
963 /// vec![KeyMechanism::EdDsaSignature],
964 /// None,
965 /// Some("signing1".parse()?),
966 /// Some(vec!["tag1".to_string()]),
967 /// )?;
968 ///
969 /// // R-Administrators can add tags for system-wide users
970 /// nethsm.add_user_tag(&"user1".parse()?, "tag1")?;
971 /// // R-Administrators can not add tags for namespace users
972 /// assert!(
973 /// nethsm
974 /// .add_user_tag(&"namespace1~user1".parse()?, "tag1")
975 /// .is_err()
976 /// );
977 ///
978 /// // user tags in namespaces
979 /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?;
980 /// // generate key in namespace1 with tag
981 /// nethsm.generate_key(
982 /// KeyType::Curve25519,
983 /// vec![KeyMechanism::EdDsaSignature],
984 /// None,
985 /// Some("signing2".parse()?),
986 /// Some(vec!["tag2".to_string()]),
987 /// )?;
988 /// // N-Administrators can not add tags to system-wide users
989 /// assert!(nethsm.add_user_tag(&"user1".parse()?, "tag2").is_err());
990 /// // N-Administrators can add tags to users in their own namespace
991 /// nethsm.add_user_tag(&"namespace1~user1".parse()?, "tag2")?;
992 /// # Ok(())
993 /// # }
994 /// ```
995 /// [Adds a tag]: https://docs.nitrokey.com/nethsm/administration#tags-for-users
996 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
997 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
998 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
999 pub fn add_user_tag(&self, user_id: &UserId, tag: &str) -> Result<(), Error> {
1000 debug!(
1001 "Add the tag \"{tag}\" for the user \"{user_id}\" on the NetHSM at {} using {}",
1002 self.url.borrow(),
1003 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
1004 );
1005
1006 self.validate_namespace_access(NamespaceSupport::Supported, Some(user_id), None)?;
1007 users_user_id_tags_tag_put(&self.create_connection_config(), &user_id.to_string(), tag)
1008 .map_err(|error| {
1009 Error::Api(format!(
1010 "Adding tag for user failed: {}",
1011 NetHsmApiError::from(error)
1012 ))
1013 })?;
1014 Ok(())
1015 }
1016
1017 /// [Deletes a tag] from a user in the [`Operator`][`UserRole::Operator`] [role].
1018 ///
1019 /// Removes a `tag` from a target user identified by `user_id`, which removes its access to any
1020 /// key in their [namespace], that carries the same `tag`.
1021 ///
1022 /// This call requires using [`Credentials`] of a user in the
1023 /// [`Administrator`][`UserRole::Administrator`] [role].
1024 ///
1025 /// ## Namespaces
1026 ///
1027 /// * *N-Administrators* ([`Administrator`][`UserRole::Administrator`] users in a given
1028 /// [namespace]) are only able to delete tags for users in their own [namespace].
1029 /// * *R-Administrators* (system-wide [`Administrator`][`UserRole::Administrator`] users) are
1030 /// only able to delete tags for system-wide users.
1031 ///
1032 /// # Errors
1033 ///
1034 /// Returns an [`Error::Api`] if deleting the tag from the user fails:
1035 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
1036 /// * the user identified by `user_id` does not exist
1037 /// * the user identified by `user_id` is not in the [`Operator`][`UserRole::Operator`] [role]
1038 /// * the `tag` is not added to user identified by `user_id`
1039 /// * the used [`Credentials`] are not correct
1040 /// * the used [`Credentials`] are not that of a user in the
1041 /// [`Administrator`][`UserRole::Administrator`] [role]
1042 /// * the caller does not have access to the target user's [namespace]
1043 ///
1044 /// # Examples
1045 ///
1046 /// ```no_run
1047 /// use nethsm::{
1048 /// Connection,
1049 /// ConnectionSecurity,
1050 /// Credentials,
1051 /// KeyMechanism,
1052 /// KeyType,
1053 /// NetHsm,
1054 /// Passphrase,
1055 /// UserRole,
1056 /// };
1057 ///
1058 /// # fn main() -> testresult::TestResult {
1059 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
1060 /// let nethsm = NetHsm::new(
1061 /// Connection::new(
1062 /// "https://example.org/api/v1".try_into()?,
1063 /// ConnectionSecurity::Unsafe,
1064 /// ),
1065 /// Some(Credentials::new(
1066 /// "admin".parse()?,
1067 /// Some(Passphrase::new("passphrase".to_string())),
1068 /// )),
1069 /// None,
1070 /// None,
1071 /// )?;
1072 /// // add a user in the Administrator role for a namespace (N-Administrator)
1073 /// nethsm.add_user(
1074 /// "Namespace1 Admin".to_string(),
1075 /// UserRole::Administrator,
1076 /// Passphrase::new("namespce1-admin-passphrase".to_string()),
1077 /// Some("namespace1~admin1".parse()?),
1078 /// )?;
1079 /// // add a user in the Operator role for a namespace
1080 /// nethsm.add_user(
1081 /// "Namespace1 Operator".to_string(),
1082 /// UserRole::Operator,
1083 /// Passphrase::new("namespce1-operator-passphrase".to_string()),
1084 /// Some("namespace1~operator1".parse()?),
1085 /// )?;
1086 /// // add the accompanying namespace
1087 /// nethsm.add_namespace(&"namespace1".parse()?)?;
1088 /// // add a system-wide user in the Operator role
1089 /// nethsm.add_user(
1090 /// "Operator One".to_string(),
1091 /// UserRole::Operator,
1092 /// Passphrase::new("operator1-passphrase".to_string()),
1093 /// Some("user1".parse()?),
1094 /// )?;
1095 /// // generate system-wide key with tag
1096 /// nethsm.generate_key(
1097 /// KeyType::Curve25519,
1098 /// vec![KeyMechanism::EdDsaSignature],
1099 /// None,
1100 /// Some("signing1".parse()?),
1101 /// Some(vec!["tag1".to_string()]),
1102 /// )?;
1103 /// // add tag for system-wide user
1104 /// nethsm.add_user_tag(&"user1".parse()?, "tag1")?;
1105 ///
1106 /// // N-Administrators can not delete tags from system-wide Operator users
1107 /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?;
1108 /// assert!(nethsm.delete_user_tag(&"user1".parse()?, "tag2").is_err());
1109 ///
1110 /// // R-Administrators can delete tags from system-wide Operator users
1111 /// nethsm.use_credentials(&"admin".parse()?)?;
1112 /// nethsm.delete_user_tag(&"user1".parse()?, "tag1")?;
1113 /// # Ok(())
1114 /// # }
1115 /// ```
1116 /// [Deletes a tag]: https://docs.nitrokey.com/nethsm/administration#tags-for-users
1117 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
1118 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
1119 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
1120 pub fn delete_user_tag(&self, user_id: &UserId, tag: &str) -> Result<(), Error> {
1121 debug!(
1122 "Delete the tag \"{tag}\" from the user \"{user_id}\" on the NetHSM at {} using {}",
1123 self.url.borrow(),
1124 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
1125 );
1126
1127 self.validate_namespace_access(NamespaceSupport::Supported, Some(user_id), None)?;
1128 users_user_id_tags_tag_delete(&self.create_connection_config(), &user_id.to_string(), tag)
1129 .map_err(|error| {
1130 Error::Api(format!(
1131 "Deleting tag for user failed: {}",
1132 NetHsmApiError::from(error)
1133 ))
1134 })?;
1135 Ok(())
1136 }
1137
1138 /// [Gets all tags] of a user in the [`Operator`][`UserRole::Operator`] [role].
1139 ///
1140 /// This call requires using [`Credentials`] of a user in the
1141 /// [`Administrator`][`UserRole::Administrator`] [role].
1142 ///
1143 /// ## Namespaces
1144 ///
1145 /// * *N-Administrators* ([`Administrator`][`UserRole::Administrator`] users in a given
1146 /// [namespace]) are only able to get tags of users in their own [namespace].
1147 /// * *R-Administrators* (system-wide [`Administrator`][`UserRole::Administrator`] users) are
1148 /// able to get tags of system-wide and all [namespace] users.
1149 ///
1150 /// # Errors
1151 ///
1152 /// Returns an [`Error::Api`] if getting the tags for the user fails:
1153 /// * the NetHSM is not in [`Operational`][`SystemState::Operational`] [state]
1154 /// * the user identified by `user_id` does not exist
1155 /// * the user identified by `user_id` is not in the [`Operator`][`UserRole::Operator`] [role]
1156 /// * the used [`Credentials`] are not correct
1157 /// * the used [`Credentials`] are not that of a user in the
1158 /// [`Administrator`][`UserRole::Administrator`] [role]
1159 /// * the caller does not have access to the target user's [namespace]
1160 ///
1161 /// # Examples
1162 ///
1163 /// ```no_run
1164 /// use nethsm::{Connection, ConnectionSecurity, Credentials, NetHsm, Passphrase, UserRole};
1165 ///
1166 /// # fn main() -> testresult::TestResult {
1167 /// // create a connection with a system-wide user in the Administrator role (R-Administrator)
1168 /// let nethsm = NetHsm::new(
1169 /// Connection::new(
1170 /// "https://example.org/api/v1".try_into()?,
1171 /// ConnectionSecurity::Unsafe,
1172 /// ),
1173 /// Some(Credentials::new(
1174 /// "admin".parse()?,
1175 /// Some(Passphrase::new("passphrase".to_string())),
1176 /// )),
1177 /// None,
1178 /// None,
1179 /// )?;
1180 /// // add a user in the Administrator role for a namespace (N-Administrator)
1181 /// nethsm.add_user(
1182 /// "Namespace1 Admin".to_string(),
1183 /// UserRole::Administrator,
1184 /// Passphrase::new("namespce1-admin-passphrase".to_string()),
1185 /// Some("namespace1~admin1".parse()?),
1186 /// )?;
1187 /// // add the accompanying namespace
1188 /// nethsm.add_namespace(&"namespace1".parse()?)?;
1189 /// // add a system-wide user in the Operator role
1190 /// nethsm.add_user(
1191 /// "Operator One".to_string(),
1192 /// UserRole::Operator,
1193 /// Passphrase::new("operator1-passphrase".to_string()),
1194 /// Some("user1".parse()?),
1195 /// )?;
1196 ///
1197 /// // R-Administrators can access tags of all users
1198 /// assert!(nethsm.get_user_tags(&"user1".parse()?)?.is_empty());
1199 /// // add a tag for the user
1200 /// nethsm.add_user_tag(&"user1".parse()?, "tag1")?;
1201 /// assert_eq!(nethsm.get_user_tags(&"user1".parse()?)?.len(), 1);
1202 ///
1203 /// // N-Administrators can not access tags of system-wide users
1204 /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?;
1205 /// assert!(nethsm.get_user_tags(&"user1".parse()?).is_err());
1206 /// # Ok(())
1207 /// # }
1208 /// ```
1209 /// [Gets all tags]: https://docs.nitrokey.com/nethsm/administration#tags-for-users
1210 /// [namespace]: https://docs.nitrokey.com/nethsm/administration#namespaces
1211 /// [role]: https://docs.nitrokey.com/nethsm/administration#roles
1212 /// [state]: https://docs.nitrokey.com/nethsm/administration#state
1213 pub fn get_user_tags(&self, user_id: &UserId) -> Result<Vec<String>, Error> {
1214 debug!(
1215 "Get the tags of the user \"{user_id}\" on the NetHSM at {} using {}",
1216 self.url.borrow(),
1217 user_or_no_user_string(self.current_credentials.borrow().as_ref()),
1218 );
1219
1220 self.validate_namespace_access(NamespaceSupport::Supported, Some(user_id), None)?;
1221 Ok(
1222 users_user_id_tags_get(&self.create_connection_config(), &user_id.to_string())
1223 .map_err(|error| {
1224 Error::Api(format!(
1225 "Getting tags of user failed: {}",
1226 NetHsmApiError::from(error)
1227 ))
1228 })?
1229 .entity,
1230 )
1231 }
1232}