1use std::{
4 collections::HashSet,
5 fs::{File, Permissions, create_dir_all, read_to_string, set_permissions},
6 io::Write,
7 os::unix::fs::{PermissionsExt, chown},
8 path::{Path, PathBuf},
9 process::{Command, Stdio},
10};
11
12use log::info;
13use nethsm::{FullCredentials, KeyId, NamespaceId, Passphrase, SystemWideUserId, UserId, UserRole};
14use serde::{Deserialize, Serialize};
15use signstar_common::{
16 common::SECRET_FILE_MODE,
17 system_user::{
18 get_home_base_dir_path,
19 get_plaintext_secret_file,
20 get_systemd_creds_secret_file,
21 get_user_secrets_dir,
22 },
23};
24use signstar_crypto::{key::SigningKeySetup, traits::UserWithPassphrase};
25
26use crate::{
27 AdministrativeSecretHandling,
28 AuthorizedKeyEntry,
29 CredentialsLoading,
30 CredentialsLoadingError,
31 CredentialsLoadingErrors,
32 Error,
33 NonAdministrativeSecretHandling,
34 SignstarConfig,
35 SystemUserId,
36 config::base::BackendConnection,
37 nethsm::config::{FilterUserKeys, NetHsmMetricsUsers},
38 utils::{
39 fail_if_not_root,
40 fail_if_root,
41 get_command,
42 get_current_system_user,
43 get_system_user_pair,
44 match_current_system_user,
45 },
46};
47
48#[derive(Clone, Copy, Debug, Default)]
53pub enum BackendUserKind {
54 Admin,
56 #[default]
58 NonAdmin,
59}
60
61#[derive(Clone, Debug, Default)]
63pub struct UserMappingFilter {
64 pub backend_user_kind: BackendUserKind,
66}
67
68#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
70pub enum UserMapping {
71 #[serde(rename = "nethsm_only_admin")]
73 NetHsmOnlyAdmin(UserId),
74
75 #[serde(rename = "system_nethsm_backup")]
77 SystemNetHsmBackup {
78 nethsm_user: SystemWideUserId,
80 ssh_authorized_key: AuthorizedKeyEntry,
82 system_user: SystemUserId,
84 },
85
86 #[cfg(feature = "yubihsm2")]
99 #[serde(rename = "system_yubihsm2_backup")]
100 SystemYubiHsm2Backup {
101 authentication_key_id: u16,
103 wrapping_key_id: u16,
108 ssh_authorized_key: AuthorizedKeyEntry,
110 system_user: SystemUserId,
112 },
113
114 #[serde(rename = "system_nethsm_metrics")]
118 SystemNetHsmMetrics {
119 nethsm_users: NetHsmMetricsUsers,
122 ssh_authorized_key: AuthorizedKeyEntry,
124 system_user: SystemUserId,
126 },
127
128 #[cfg(feature = "yubihsm2")]
137 #[serde(rename = "system_yubihsm2_metrics")]
138 SystemYubiHsm2Metrics {
139 authentication_key_id: u16,
141 ssh_authorized_key: AuthorizedKeyEntry,
143 system_user: SystemUserId,
145 },
146
147 #[serde(rename = "system_nethsm_operator_signing")]
152 SystemNetHsmOperatorSigning {
153 nethsm_user: UserId,
155 key_id: KeyId,
157 nethsm_key_setup: SigningKeySetup,
159 ssh_authorized_key: AuthorizedKeyEntry,
161 system_user: SystemUserId,
163 tag: String,
165 },
166
167 #[cfg(feature = "yubihsm2")]
179 #[serde(rename = "system_yubihsm2_operator_signing")]
180 SystemYubiHsm2OperatorSigning {
181 authentication_key_id: u16,
183 backend_key_setup: SigningKeySetup,
185 backend_key_id: u16,
187 backend_key_domain: usize,
189 ssh_authorized_key: AuthorizedKeyEntry,
191 system_user: SystemUserId,
193 },
194
195 #[serde(rename = "hermetic_system_nethsm_metrics")]
199 HermeticSystemNetHsmMetrics {
200 nethsm_users: NetHsmMetricsUsers,
203 system_user: SystemUserId,
205 },
206
207 #[cfg(feature = "yubihsm2")]
216 #[serde(rename = "hermetic_system_yubihsm2_metrics")]
217 HermeticSystemYubiHsm2Metrics {
218 authentication_key_id: u16,
220 system_user: SystemUserId,
222 },
223
224 #[serde(rename = "system_only_share_download")]
227 SystemOnlyShareDownload {
228 system_user: SystemUserId,
230 ssh_authorized_key: AuthorizedKeyEntry,
232 },
233
234 #[serde(rename = "system_only_share_upload")]
237 SystemOnlyShareUpload {
238 system_user: SystemUserId,
240 ssh_authorized_key: AuthorizedKeyEntry,
242 },
243
244 #[serde(rename = "system_only_wireguard_download")]
247 SystemOnlyWireGuardDownload {
248 system_user: SystemUserId,
250 ssh_authorized_key: AuthorizedKeyEntry,
252 },
253
254 #[cfg(feature = "yubihsm2")]
300 #[serde(rename = "yubihsm2_only_admin")]
301 YubiHsm2OnlyAdmin(u16),
302}
303
304impl UserMapping {
305 pub fn get_system_user(&self) -> Option<&SystemUserId> {
325 match self {
326 UserMapping::NetHsmOnlyAdmin(_) => None,
327 UserMapping::SystemNetHsmBackup {
328 nethsm_user: _,
329 ssh_authorized_key: _,
330 system_user,
331 }
332 | UserMapping::SystemNetHsmOperatorSigning {
333 nethsm_user: _,
334 key_id: _,
335 nethsm_key_setup: _,
336 ssh_authorized_key: _,
337 system_user,
338 ..
339 }
340 | UserMapping::SystemNetHsmMetrics {
341 nethsm_users: _,
342 ssh_authorized_key: _,
343 system_user,
344 }
345 | UserMapping::HermeticSystemNetHsmMetrics {
346 nethsm_users: _,
347 system_user,
348 }
349 | UserMapping::SystemOnlyShareDownload { system_user, .. }
350 | UserMapping::SystemOnlyShareUpload { system_user, .. }
351 | UserMapping::SystemOnlyWireGuardDownload {
352 system_user,
353 ssh_authorized_key: _,
354 } => Some(system_user),
355 #[cfg(feature = "yubihsm2")]
356 UserMapping::YubiHsm2OnlyAdmin(_) => None,
357 #[cfg(feature = "yubihsm2")]
358 UserMapping::SystemYubiHsm2OperatorSigning { system_user, .. }
359 | UserMapping::SystemYubiHsm2Backup { system_user, .. }
360 | UserMapping::SystemYubiHsm2Metrics { system_user, .. }
361 | UserMapping::HermeticSystemYubiHsm2Metrics { system_user, .. } => Some(system_user),
362 }
363 }
364
365 pub fn backend_users(&self, filter: UserMappingFilter) -> Vec<String> {
401 match self {
402 UserMapping::NetHsmOnlyAdmin(user_id) => match filter.backend_user_kind {
403 BackendUserKind::Admin => vec![user_id.to_string()],
404 BackendUserKind::NonAdmin => Vec::new(),
405 },
406 UserMapping::SystemNetHsmBackup { nethsm_user, .. } => match filter.backend_user_kind {
407 BackendUserKind::Admin => Vec::new(),
408 BackendUserKind::NonAdmin => vec![nethsm_user.to_string()],
409 },
410 UserMapping::HermeticSystemNetHsmMetrics { nethsm_users, .. }
411 | UserMapping::SystemNetHsmMetrics { nethsm_users, .. } => {
412 match filter.backend_user_kind {
413 BackendUserKind::Admin => Vec::new(),
414 BackendUserKind::NonAdmin => nethsm_users
415 .get_users()
416 .iter()
417 .map(|user| user.to_string())
418 .collect(),
419 }
420 }
421 UserMapping::SystemNetHsmOperatorSigning { nethsm_user, .. } => {
422 match filter.backend_user_kind {
423 BackendUserKind::Admin => Vec::new(),
424 BackendUserKind::NonAdmin => vec![nethsm_user.to_string()],
425 }
426 }
427 UserMapping::SystemOnlyShareDownload { .. }
428 | UserMapping::SystemOnlyShareUpload { .. }
429 | UserMapping::SystemOnlyWireGuardDownload { .. } => Vec::new(),
430 #[cfg(feature = "yubihsm2")]
431 UserMapping::YubiHsm2OnlyAdmin(admin) => match filter.backend_user_kind {
432 BackendUserKind::Admin => vec![admin.to_string()],
433 BackendUserKind::NonAdmin => Vec::new(),
434 },
435 #[cfg(feature = "yubihsm2")]
436 UserMapping::SystemYubiHsm2OperatorSigning {
437 authentication_key_id,
438 ..
439 }
440 | UserMapping::SystemYubiHsm2Backup {
441 authentication_key_id,
442 ..
443 }
444 | UserMapping::SystemYubiHsm2Metrics {
445 authentication_key_id,
446 ..
447 }
448 | UserMapping::HermeticSystemYubiHsm2Metrics {
449 authentication_key_id,
450 ..
451 } => match filter.backend_user_kind {
452 BackendUserKind::Admin => Vec::new(),
453 BackendUserKind::NonAdmin => vec![authentication_key_id.to_string()],
454 },
455 }
456 }
457
458 pub fn backend_users_with_new_passphrase(
500 &self,
501 filter: UserMappingFilter,
502 ) -> Vec<Box<dyn UserWithPassphrase>> {
503 match self {
504 UserMapping::NetHsmOnlyAdmin(user_id) => match filter.backend_user_kind {
505 BackendUserKind::Admin => vec![Box::new(nethsm::FullCredentials::new(
506 user_id.clone(),
507 Passphrase::generate(None),
508 ))],
509 BackendUserKind::NonAdmin => Vec::new(),
510 },
511 UserMapping::SystemNetHsmBackup { nethsm_user, .. } => match filter.backend_user_kind {
512 BackendUserKind::Admin => Vec::new(),
513 BackendUserKind::NonAdmin => vec![Box::new(nethsm::FullCredentials::new(
514 nethsm_user.as_ref().clone(),
515 Passphrase::generate(None),
516 ))],
517 },
518 UserMapping::HermeticSystemNetHsmMetrics { nethsm_users, .. }
519 | UserMapping::SystemNetHsmMetrics { nethsm_users, .. } => {
520 match filter.backend_user_kind {
521 BackendUserKind::Admin => Vec::new(),
522 BackendUserKind::NonAdmin => nethsm_users
523 .get_users()
524 .iter()
525 .map(|user| {
526 Box::new(FullCredentials::new(
527 user.clone(),
528 Passphrase::generate(None),
529 )) as Box<dyn UserWithPassphrase>
530 })
531 .collect(),
532 }
533 }
534 UserMapping::SystemNetHsmOperatorSigning { nethsm_user, .. } => {
535 match filter.backend_user_kind {
536 BackendUserKind::Admin => Vec::new(),
537 BackendUserKind::NonAdmin => vec![Box::new(nethsm::FullCredentials::new(
538 nethsm_user.clone(),
539 Passphrase::generate(None),
540 ))],
541 }
542 }
543 UserMapping::SystemOnlyShareDownload { .. }
544 | UserMapping::SystemOnlyShareUpload { .. }
545 | UserMapping::SystemOnlyWireGuardDownload { .. } => Vec::new(),
546 #[cfg(feature = "yubihsm2")]
547 UserMapping::YubiHsm2OnlyAdmin(admin) => match filter.backend_user_kind {
548 BackendUserKind::Admin => vec![Box::new(signstar_yubihsm2::Credentials::new(
549 *admin,
550 Passphrase::generate(None),
551 ))],
552 BackendUserKind::NonAdmin => Vec::new(),
553 },
554 #[cfg(feature = "yubihsm2")]
555 UserMapping::SystemYubiHsm2OperatorSigning {
556 authentication_key_id,
557 ..
558 }
559 | UserMapping::SystemYubiHsm2Backup {
560 authentication_key_id,
561 ..
562 }
563 | UserMapping::SystemYubiHsm2Metrics {
564 authentication_key_id,
565 ..
566 }
567 | UserMapping::HermeticSystemYubiHsm2Metrics {
568 authentication_key_id,
569 ..
570 } => match filter.backend_user_kind {
571 BackendUserKind::Admin => Vec::new(),
572 BackendUserKind::NonAdmin => vec![Box::new(signstar_yubihsm2::Credentials::new(
573 *authentication_key_id,
574 Passphrase::generate(None),
575 ))],
576 },
577 }
578 }
579
580 pub fn get_nethsm_users(&self) -> Vec<UserId> {
601 match self {
602 UserMapping::SystemNetHsmBackup { nethsm_user, .. } => vec![nethsm_user.clone().into()],
603 UserMapping::NetHsmOnlyAdmin(nethsm_user)
604 | UserMapping::SystemNetHsmOperatorSigning { nethsm_user, .. } => {
605 vec![nethsm_user.clone()]
606 }
607 UserMapping::SystemNetHsmMetrics { nethsm_users, .. }
608 | UserMapping::HermeticSystemNetHsmMetrics { nethsm_users, .. } => {
609 nethsm_users.get_users()
610 }
611 UserMapping::SystemOnlyShareDownload { .. }
612 | UserMapping::SystemOnlyShareUpload { .. }
613 | UserMapping::SystemOnlyWireGuardDownload { .. } => Vec::new(),
614 #[cfg(feature = "yubihsm2")]
615 UserMapping::YubiHsm2OnlyAdmin(_)
616 | UserMapping::SystemYubiHsm2Backup { .. }
617 | UserMapping::SystemYubiHsm2Metrics { .. }
618 | UserMapping::HermeticSystemYubiHsm2Metrics { .. }
619 | UserMapping::SystemYubiHsm2OperatorSigning { .. } => Vec::new(),
620 }
621 }
622
623 pub fn get_nethsm_users_and_roles(&self) -> Vec<(UserId, UserRole)> {
644 match self {
645 UserMapping::SystemNetHsmBackup { nethsm_user, .. } => {
646 vec![(nethsm_user.clone().into(), UserRole::Backup)]
647 }
648 UserMapping::NetHsmOnlyAdmin(nethsm_user) => {
649 vec![(nethsm_user.clone(), UserRole::Administrator)]
650 }
651 UserMapping::SystemNetHsmOperatorSigning { nethsm_user, .. } => {
652 vec![(nethsm_user.clone(), UserRole::Operator)]
653 }
654 UserMapping::SystemNetHsmMetrics { nethsm_users, .. }
655 | UserMapping::HermeticSystemNetHsmMetrics { nethsm_users, .. } => {
656 nethsm_users.get_users_and_roles()
657 }
658 UserMapping::SystemOnlyShareDownload { .. }
659 | UserMapping::SystemOnlyShareUpload { .. }
660 | UserMapping::SystemOnlyWireGuardDownload { .. } => Vec::new(),
661 #[cfg(feature = "yubihsm2")]
662 UserMapping::YubiHsm2OnlyAdmin(_)
663 | UserMapping::SystemYubiHsm2Backup { .. }
664 | UserMapping::SystemYubiHsm2Metrics { .. }
665 | UserMapping::HermeticSystemYubiHsm2Metrics { .. }
666 | UserMapping::SystemYubiHsm2OperatorSigning { .. } => Vec::new(),
667 }
668 }
669
670 pub fn get_nethsm_user_role_and_tags(&self) -> Vec<(UserId, UserRole, Vec<String>)> {
710 match self {
711 UserMapping::SystemNetHsmOperatorSigning {
712 nethsm_user,
713 key_id: _,
714 nethsm_key_setup: _,
715 system_user: _,
716 ssh_authorized_key: _,
717 tag,
718 } => vec![(
719 nethsm_user.clone(),
720 UserRole::Operator,
721 vec![tag.to_string()],
722 )],
723 UserMapping::SystemNetHsmBackup { nethsm_user, .. } => {
724 vec![(nethsm_user.clone().into(), UserRole::Backup, Vec::new())]
725 }
726 UserMapping::NetHsmOnlyAdmin(user_id) => {
727 vec![(user_id.clone(), UserRole::Administrator, Vec::new())]
728 }
729 UserMapping::SystemNetHsmMetrics { nethsm_users, .. } => nethsm_users
730 .get_users_and_roles()
731 .iter()
732 .map(|(user, role)| (user.clone(), *role, Vec::new()))
733 .collect(),
734 UserMapping::HermeticSystemNetHsmMetrics { nethsm_users, .. } => nethsm_users
735 .get_users_and_roles()
736 .iter()
737 .map(|(user, role)| (user.clone(), *role, Vec::new()))
738 .collect(),
739 UserMapping::SystemOnlyShareDownload { .. }
740 | UserMapping::SystemOnlyShareUpload { .. }
741 | UserMapping::SystemOnlyWireGuardDownload { .. } => Vec::new(),
742 #[cfg(feature = "yubihsm2")]
743 UserMapping::YubiHsm2OnlyAdmin(_)
744 | UserMapping::SystemYubiHsm2Backup { .. }
745 | UserMapping::SystemYubiHsm2Metrics { .. }
746 | UserMapping::HermeticSystemYubiHsm2Metrics { .. }
747 | UserMapping::SystemYubiHsm2OperatorSigning { .. } => Vec::new(),
748 }
749 }
750
751 pub fn get_ssh_authorized_key(&self) -> Option<&AuthorizedKeyEntry> {
775 match self {
776 UserMapping::NetHsmOnlyAdmin(_) | UserMapping::HermeticSystemNetHsmMetrics { .. } => {
777 None
778 }
779 UserMapping::SystemNetHsmBackup {
780 nethsm_user: _,
781 system_user: _,
782 ssh_authorized_key,
783 }
784 | UserMapping::SystemNetHsmMetrics {
785 nethsm_users: _,
786 system_user: _,
787 ssh_authorized_key,
788 }
789 | UserMapping::SystemOnlyShareDownload {
790 system_user: _,
791 ssh_authorized_key,
792 }
793 | UserMapping::SystemOnlyShareUpload {
794 system_user: _,
795 ssh_authorized_key,
796 }
797 | UserMapping::SystemOnlyWireGuardDownload {
798 system_user: _,
799 ssh_authorized_key,
800 }
801 | UserMapping::SystemNetHsmOperatorSigning {
802 nethsm_user: _,
803 key_id: _,
804 nethsm_key_setup: _,
805 system_user: _,
806 ssh_authorized_key,
807 ..
808 } => Some(ssh_authorized_key),
809 #[cfg(feature = "yubihsm2")]
810 UserMapping::YubiHsm2OnlyAdmin(_)
811 | UserMapping::HermeticSystemYubiHsm2Metrics { .. } => None,
812 #[cfg(feature = "yubihsm2")]
813 UserMapping::SystemYubiHsm2OperatorSigning {
814 ssh_authorized_key, ..
815 }
816 | UserMapping::SystemYubiHsm2Backup {
817 ssh_authorized_key, ..
818 }
819 | UserMapping::SystemYubiHsm2Metrics {
820 ssh_authorized_key, ..
821 } => Some(ssh_authorized_key),
822 }
823 }
824
825 pub fn get_nethsm_key_ids(&self, namespace: Option<&NamespaceId>) -> Vec<KeyId> {
863 match self {
864 UserMapping::SystemNetHsmOperatorSigning {
865 nethsm_user,
866 key_id,
867 ..
868 } => {
869 if nethsm_user.namespace() == namespace {
870 vec![key_id.clone()]
871 } else {
872 Vec::new()
873 }
874 }
875 UserMapping::SystemNetHsmMetrics { .. }
876 | UserMapping::NetHsmOnlyAdmin(_)
877 | UserMapping::HermeticSystemNetHsmMetrics { .. }
878 | UserMapping::SystemNetHsmBackup { .. }
879 | UserMapping::SystemOnlyShareDownload { .. }
880 | UserMapping::SystemOnlyShareUpload { .. }
881 | UserMapping::SystemOnlyWireGuardDownload { .. } => Vec::new(),
882 #[cfg(feature = "yubihsm2")]
883 UserMapping::YubiHsm2OnlyAdmin(_)
884 | UserMapping::SystemYubiHsm2Backup { .. }
885 | UserMapping::SystemYubiHsm2Metrics { .. }
886 | UserMapping::HermeticSystemYubiHsm2Metrics { .. }
887 | UserMapping::SystemYubiHsm2OperatorSigning { .. } => Vec::new(),
888 }
889 }
890
891 pub fn get_nethsm_tags(&self, namespace: Option<&NamespaceId>) -> Vec<&str> {
936 match self {
937 UserMapping::SystemNetHsmOperatorSigning {
938 nethsm_user,
939 key_id: _,
940 nethsm_key_setup: _,
941 system_user: _,
942 ssh_authorized_key: _,
943 tag,
944 } => {
945 if nethsm_user.namespace() == namespace {
946 vec![tag.as_str()]
947 } else {
948 Vec::new()
949 }
950 }
951 UserMapping::SystemNetHsmMetrics { .. }
952 | UserMapping::NetHsmOnlyAdmin(_)
953 | UserMapping::HermeticSystemNetHsmMetrics { .. }
954 | UserMapping::SystemNetHsmBackup { .. }
955 | UserMapping::SystemOnlyShareDownload { .. }
956 | UserMapping::SystemOnlyShareUpload { .. }
957 | UserMapping::SystemOnlyWireGuardDownload { .. } => Vec::new(),
958 #[cfg(feature = "yubihsm2")]
959 UserMapping::YubiHsm2OnlyAdmin(_)
960 | UserMapping::SystemYubiHsm2Backup { .. }
961 | UserMapping::SystemYubiHsm2Metrics { .. }
962 | UserMapping::HermeticSystemYubiHsm2Metrics { .. }
963 | UserMapping::SystemYubiHsm2OperatorSigning { .. } => Vec::new(),
964 }
965 }
966
967 pub fn get_nethsm_user_key_and_tag(
1035 &self,
1036 filter: FilterUserKeys,
1037 ) -> Vec<(UserId, KeyId, SigningKeySetup, String)> {
1038 match self {
1039 UserMapping::SystemNetHsmOperatorSigning {
1040 nethsm_user,
1041 key_id,
1042 nethsm_key_setup,
1043 system_user: _,
1044 ssh_authorized_key: _,
1045 tag,
1046 } => match filter {
1047 FilterUserKeys::All => {
1048 vec![(
1049 nethsm_user.clone(),
1050 key_id.clone(),
1051 nethsm_key_setup.clone(),
1052 tag.clone(),
1053 )]
1054 }
1055 FilterUserKeys::Namespaced => {
1056 if nethsm_user.is_namespaced() {
1057 vec![(
1058 nethsm_user.clone(),
1059 key_id.clone(),
1060 nethsm_key_setup.clone(),
1061 tag.clone(),
1062 )]
1063 } else {
1064 Vec::new()
1065 }
1066 }
1067 FilterUserKeys::Namespace(namespace) => {
1068 if Some(&namespace) == nethsm_user.namespace() {
1069 vec![(
1070 nethsm_user.clone(),
1071 key_id.clone(),
1072 nethsm_key_setup.clone(),
1073 tag.clone(),
1074 )]
1075 } else {
1076 Vec::new()
1077 }
1078 }
1079 FilterUserKeys::SystemWide => {
1080 if !nethsm_user.is_namespaced() {
1081 vec![(
1082 nethsm_user.clone(),
1083 key_id.clone(),
1084 nethsm_key_setup.clone(),
1085 tag.clone(),
1086 )]
1087 } else {
1088 Vec::new()
1089 }
1090 }
1091 FilterUserKeys::Tag(filter_tag) => {
1092 if &filter_tag == tag {
1093 vec![(
1094 nethsm_user.clone(),
1095 key_id.clone(),
1096 nethsm_key_setup.clone(),
1097 tag.clone(),
1098 )]
1099 } else {
1100 Vec::new()
1101 }
1102 }
1103 },
1104 UserMapping::SystemNetHsmMetrics { .. }
1105 | UserMapping::NetHsmOnlyAdmin(_)
1106 | UserMapping::HermeticSystemNetHsmMetrics { .. }
1107 | UserMapping::SystemNetHsmBackup { .. }
1108 | UserMapping::SystemOnlyShareDownload { .. }
1109 | UserMapping::SystemOnlyShareUpload { .. }
1110 | UserMapping::SystemOnlyWireGuardDownload { .. } => Vec::new(),
1111 #[cfg(feature = "yubihsm2")]
1112 UserMapping::YubiHsm2OnlyAdmin(_)
1113 | UserMapping::SystemYubiHsm2Backup { .. }
1114 | UserMapping::SystemYubiHsm2Metrics { .. }
1115 | UserMapping::HermeticSystemYubiHsm2Metrics { .. }
1116 | UserMapping::SystemYubiHsm2OperatorSigning { .. } => Vec::new(),
1117 }
1118 }
1119
1120 pub fn get_nethsm_namespaces(&self) -> Vec<NamespaceId> {
1161 match self {
1162 UserMapping::NetHsmOnlyAdmin(nethsm_user)
1163 | UserMapping::SystemNetHsmOperatorSigning { nethsm_user, .. } => {
1164 if let Some(namespace) = nethsm_user.namespace() {
1165 vec![namespace.clone()]
1166 } else {
1167 Vec::new()
1168 }
1169 }
1170 UserMapping::HermeticSystemNetHsmMetrics { nethsm_users, .. }
1171 | UserMapping::SystemNetHsmMetrics { nethsm_users, .. } => nethsm_users
1172 .get_users()
1173 .iter()
1174 .filter_map(|user_id| user_id.namespace())
1175 .cloned()
1176 .collect(),
1177 UserMapping::SystemOnlyShareDownload { .. }
1178 | UserMapping::SystemNetHsmBackup { .. }
1179 | UserMapping::SystemOnlyShareUpload { .. }
1180 | UserMapping::SystemOnlyWireGuardDownload { .. } => Vec::new(),
1181 #[cfg(feature = "yubihsm2")]
1182 UserMapping::YubiHsm2OnlyAdmin(_)
1183 | UserMapping::SystemYubiHsm2Backup { .. }
1184 | UserMapping::SystemYubiHsm2Metrics { .. }
1185 | UserMapping::HermeticSystemYubiHsm2Metrics { .. }
1186 | UserMapping::SystemYubiHsm2OperatorSigning { .. } => Vec::new(),
1187 }
1188 }
1189
1190 pub fn has_system_and_backend_user(&self) -> bool {
1195 match self {
1196 UserMapping::SystemNetHsmOperatorSigning { .. }
1197 | UserMapping::HermeticSystemNetHsmMetrics { .. }
1198 | UserMapping::SystemNetHsmMetrics { .. }
1199 | UserMapping::SystemNetHsmBackup { .. } => true,
1200 #[cfg(feature = "yubihsm2")]
1201 UserMapping::YubiHsm2OnlyAdmin(_) => false,
1202 #[cfg(feature = "yubihsm2")]
1203 UserMapping::SystemYubiHsm2Backup { .. }
1204 | UserMapping::SystemYubiHsm2Metrics { .. }
1205 | UserMapping::HermeticSystemYubiHsm2Metrics { .. }
1206 | UserMapping::SystemYubiHsm2OperatorSigning { .. } => true,
1207 UserMapping::SystemOnlyShareDownload { .. }
1208 | UserMapping::SystemOnlyShareUpload { .. }
1209 | UserMapping::SystemOnlyWireGuardDownload { .. }
1210 | UserMapping::NetHsmOnlyAdmin(_) => false,
1211 }
1212 }
1213}
1214
1215pub(crate) fn check_secrets_file(path: impl AsRef<Path>) -> Result<(), Error> {
1233 let path = path.as_ref();
1234
1235 if !path.exists() {
1237 return Err(crate::non_admin_credentials::Error::SecretsFileMissing {
1238 path: path.to_path_buf(),
1239 }
1240 .into());
1241 }
1242
1243 if !path.is_file() {
1245 return Err(Error::NonAdminSecretHandling(
1246 crate::non_admin_credentials::Error::SecretsFileNotAFile {
1247 path: path.to_path_buf(),
1248 },
1249 ));
1250 }
1251
1252 match path.metadata() {
1254 Ok(metadata) => {
1255 let mode = metadata.permissions().mode();
1256 if mode != SECRET_FILE_MODE {
1257 return Err(Error::NonAdminSecretHandling(
1258 crate::non_admin_credentials::Error::SecretsFilePermissions {
1259 path: path.to_path_buf(),
1260 mode,
1261 },
1262 ));
1263 }
1264 }
1265 Err(source) => {
1266 return Err(Error::NonAdminSecretHandling(
1267 crate::non_admin_credentials::Error::SecretsFileMetadata {
1268 path: path.to_path_buf(),
1269 source,
1270 },
1271 ));
1272 }
1273 }
1274
1275 Ok(())
1276}
1277
1278#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
1283pub struct ExtendedUserMapping {
1284 admin_secret_handling: AdministrativeSecretHandling,
1285 non_admin_secret_handling: NonAdministrativeSecretHandling,
1286 connections: HashSet<BackendConnection>,
1287 user_mapping: UserMapping,
1288}
1289
1290impl ExtendedUserMapping {
1291 pub fn new(
1293 admin_secret_handling: AdministrativeSecretHandling,
1294 non_admin_secret_handling: NonAdministrativeSecretHandling,
1295 connections: HashSet<BackendConnection>,
1296 user_mapping: UserMapping,
1297 ) -> Self {
1298 Self {
1299 admin_secret_handling,
1300 non_admin_secret_handling,
1301 connections,
1302 user_mapping,
1303 }
1304 }
1305
1306 pub fn get_admin_secret_handling(&self) -> AdministrativeSecretHandling {
1308 self.admin_secret_handling
1309 }
1310
1311 pub fn get_connections(&self) -> HashSet<BackendConnection> {
1313 self.connections.clone()
1314 }
1315
1316 pub fn get_non_admin_secret_handling(&self) -> NonAdministrativeSecretHandling {
1318 self.non_admin_secret_handling
1319 }
1320
1321 pub fn get_user_mapping(&self) -> &UserMapping {
1323 &self.user_mapping
1324 }
1325
1326 pub fn load_credentials(&self) -> Result<CredentialsLoading, Error> {
1351 let (system_user, user) = get_system_user_pair(self)?;
1353 let current_system_user = get_current_system_user()?;
1354
1355 fail_if_root(¤t_system_user)?;
1357 match_current_system_user(¤t_system_user, &user)?;
1358
1359 let secret_handling = self.get_non_admin_secret_handling();
1360 let mut credentials: Vec<Box<dyn UserWithPassphrase>> = Vec::new();
1361 let mut errors = Vec::new();
1362
1363 for name in self.get_user_mapping().backend_users(UserMappingFilter {
1365 backend_user_kind: BackendUserKind::NonAdmin,
1366 }) {
1367 let secrets_file = match secret_handling {
1368 NonAdministrativeSecretHandling::Plaintext => {
1369 get_plaintext_secret_file(system_user.as_ref(), &name)
1370 }
1371 NonAdministrativeSecretHandling::SystemdCreds => {
1372 get_systemd_creds_secret_file(system_user.as_ref(), &name)
1373 }
1374 };
1375 info!(
1376 "Load secret for system user {system_user} and backend user {name} from file: {secrets_file:?}"
1377 );
1378 if let Err(error) = check_secrets_file(secrets_file.as_path()) {
1380 errors.push(CredentialsLoadingError::new(name.clone(), error));
1381 continue;
1382 };
1383
1384 let passphrase = match secret_handling {
1385 NonAdministrativeSecretHandling::Plaintext => {
1387 match read_to_string(&secrets_file).map_err(|source| {
1389 Error::NonAdminSecretHandling(
1390 crate::non_admin_credentials::Error::SecretsFileRead {
1391 path: secrets_file,
1392 source,
1393 },
1394 )
1395 }) {
1396 Ok(passphrase) => Passphrase::new(passphrase),
1397 Err(error) => {
1398 errors.push(CredentialsLoadingError::new(name.clone(), error));
1399 continue;
1400 }
1401 }
1402 }
1403 NonAdministrativeSecretHandling::SystemdCreds => {
1405 let creds_command = get_command("systemd-creds")?;
1407 let mut command = Command::new(creds_command);
1408 let command = command
1409 .arg("--user")
1410 .arg("decrypt")
1411 .arg(&secrets_file)
1412 .arg("-");
1413 match command.output().map_err(|source| Error::CommandExec {
1414 command: format!("{command:?}"),
1415 source,
1416 }) {
1417 Ok(command_output) => {
1418 if !command_output.status.success() {
1420 errors.push(CredentialsLoadingError::new(
1421 name.clone(),
1422 Error::CommandNonZero {
1423 command: format!("{command:?}"),
1424 exit_status: command_output.status,
1425 stderr: String::from_utf8_lossy(&command_output.stderr)
1426 .into_owned(),
1427 },
1428 ));
1429 continue;
1430 }
1431
1432 let creds = match String::from_utf8(command_output.stdout) {
1433 Ok(creds) => creds,
1434 Err(source) => {
1435 errors.push(CredentialsLoadingError::new(
1436 name.clone(),
1437 Error::Utf8String {
1438 path: secrets_file,
1439 context: format!(
1440 "converting stdout of {command:?} to string"
1441 ),
1442 source,
1443 },
1444 ));
1445 continue;
1446 }
1447 };
1448
1449 Passphrase::new(creds)
1450 }
1451 Err(error) => {
1452 errors.push(CredentialsLoadingError::new(name.clone(), error));
1453 continue;
1454 }
1455 }
1456 }
1457 };
1458
1459 match self.get_user_mapping() {
1464 UserMapping::NetHsmOnlyAdmin(_) => {}
1467 UserMapping::SystemOnlyShareDownload { .. }
1469 | UserMapping::SystemOnlyShareUpload { .. }
1470 | UserMapping::SystemOnlyWireGuardDownload { .. } => {}
1471 UserMapping::SystemNetHsmBackup { .. }
1472 | UserMapping::SystemNetHsmMetrics { .. }
1473 | UserMapping::SystemNetHsmOperatorSigning { .. }
1474 | UserMapping::HermeticSystemNetHsmMetrics { .. } => {
1475 credentials.push(Box::new(FullCredentials::new(
1476 UserId::new(name)
1479 .map_err(|source| Error::NetHsm(nethsm::Error::User(source)))?,
1480 passphrase,
1481 )));
1482 }
1483 #[cfg(feature = "yubihsm2")]
1484 UserMapping::YubiHsm2OnlyAdmin(_) => {}
1485 #[cfg(feature = "yubihsm2")]
1486 UserMapping::SystemYubiHsm2OperatorSigning {
1487 authentication_key_id,
1488 ..
1489 }
1490 | UserMapping::SystemYubiHsm2Backup {
1491 authentication_key_id,
1492 ..
1493 }
1494 | UserMapping::SystemYubiHsm2Metrics {
1495 authentication_key_id,
1496 ..
1497 }
1498 | UserMapping::HermeticSystemYubiHsm2Metrics {
1499 authentication_key_id,
1500 ..
1501 } => credentials.push(Box::new(signstar_yubihsm2::Credentials::new(
1502 *authentication_key_id,
1503 passphrase,
1504 ))),
1505 }
1506 }
1507
1508 Ok(CredentialsLoading::new(
1509 self.clone(),
1510 credentials,
1511 CredentialsLoadingErrors::new(errors),
1512 ))
1513 }
1514
1515 pub fn create_secrets_dir(&self) -> Result<(), Error> {
1530 let (system_user, user) = get_system_user_pair(self)?;
1532
1533 fail_if_not_root(&get_current_system_user()?)?;
1535
1536 let secrets_dir = get_user_secrets_dir(system_user.as_ref());
1538 create_dir_all(&secrets_dir).map_err(|source| {
1539 crate::non_admin_credentials::Error::SecretsDirCreate {
1540 path: secrets_dir.clone(),
1541 system_user: system_user.clone(),
1542 source,
1543 }
1544 })?;
1545
1546 let home_dir = get_home_base_dir_path().join(PathBuf::from(system_user.as_ref()));
1549 let mut chown_dir = secrets_dir.clone();
1550 while chown_dir != home_dir {
1551 chown(&chown_dir, Some(user.uid.as_raw()), Some(user.gid.as_raw())).map_err(
1552 |source| Error::Chown {
1553 path: chown_dir.to_path_buf(),
1554 user: system_user.to_string(),
1555 source,
1556 },
1557 )?;
1558 if let Some(parent) = &chown_dir.parent() {
1559 chown_dir = parent.to_path_buf()
1560 } else {
1561 break;
1562 }
1563 }
1564
1565 Ok(())
1566 }
1567
1568 pub fn create_non_administrative_secrets(
1594 &self,
1595 ) -> Result<Vec<Box<dyn UserWithPassphrase>>, Error> {
1596 let (system_user, user) = get_system_user_pair(self)?;
1598
1599 fail_if_not_root(&get_current_system_user()?)?;
1601
1602 let secret_handling = self.get_non_admin_secret_handling();
1603 let credentials =
1605 self.get_user_mapping()
1606 .backend_users_with_new_passphrase(UserMappingFilter {
1607 backend_user_kind: BackendUserKind::NonAdmin,
1608 });
1609
1610 for creds in credentials.iter() {
1612 let secrets_file = match secret_handling {
1613 NonAdministrativeSecretHandling::Plaintext => {
1614 get_plaintext_secret_file(system_user.as_ref(), &creds.user())
1615 }
1616 NonAdministrativeSecretHandling::SystemdCreds => {
1617 get_systemd_creds_secret_file(system_user.as_ref(), &creds.user())
1618 }
1619 };
1620
1621 info!(
1622 "Create secret for system user {system_user} and backend user {} in file: {secrets_file:?}",
1623 creds.user()
1624 );
1625 let secret = {
1626 match secret_handling {
1628 NonAdministrativeSecretHandling::Plaintext => {
1629 creds.passphrase().expose_borrowed().as_bytes().to_vec()
1630 }
1631 NonAdministrativeSecretHandling::SystemdCreds => {
1632 let creds_command = get_command("systemd-creds")?;
1634 let mut command = Command::new(creds_command);
1635 let command = command
1636 .arg("--user")
1637 .arg("--name=")
1638 .arg("--uid")
1639 .arg(system_user.as_ref())
1640 .arg("encrypt")
1641 .arg("-")
1642 .arg("-")
1643 .stdin(Stdio::piped())
1644 .stdout(Stdio::piped())
1645 .stderr(Stdio::piped());
1646 let mut command_child =
1647 command.spawn().map_err(|source| Error::CommandBackground {
1648 command: format!("{command:?}"),
1649 source,
1650 })?;
1651
1652 command_child
1654 .stdin
1655 .take()
1656 .ok_or(Error::CommandAttachToStdin {
1657 command: format!("{command:?}"),
1658 })?
1659 .write_all(creds.passphrase().expose_borrowed().as_bytes())
1660 .map_err(|source| Error::CommandWriteToStdin {
1661 command: format!("{command:?}"),
1662 source,
1663 })?;
1664
1665 let command_output =
1666 command_child.wait_with_output().map_err(|source| {
1667 Error::CommandExec {
1668 command: format!("{command:?}"),
1669 source,
1670 }
1671 })?;
1672
1673 if !command_output.status.success() {
1674 return Err(Error::CommandNonZero {
1675 command: format!("{command:?}"),
1676 exit_status: command_output.status,
1677 stderr: String::from_utf8_lossy(&command_output.stderr)
1678 .into_owned(),
1679 });
1680 }
1681 command_output.stdout
1682 }
1683 }
1684 };
1685
1686 let mut file = File::create(secrets_file.as_path()).map_err(|source| {
1688 {
1689 crate::non_admin_credentials::Error::SecretsFileCreate {
1690 path: secrets_file.clone(),
1691 system_user: system_user.clone(),
1692 source,
1693 }
1694 }
1695 })?;
1696 file.write_all(&secret).map_err(|source| {
1697 crate::non_admin_credentials::Error::SecretsFileWrite {
1698 path: secrets_file.clone(),
1699 system_user: system_user.clone(),
1700 source,
1701 }
1702 })?;
1703 chown(
1704 &secrets_file,
1705 Some(user.uid.as_raw()),
1706 Some(user.gid.as_raw()),
1707 )
1708 .map_err(|source| Error::Chown {
1709 path: secrets_file.clone(),
1710 user: system_user.to_string(),
1711 source,
1712 })?;
1713 set_permissions(
1714 secrets_file.as_path(),
1715 Permissions::from_mode(SECRET_FILE_MODE),
1716 )
1717 .map_err(|source| Error::ApplyPermissions {
1718 path: secrets_file.clone(),
1719 mode: SECRET_FILE_MODE,
1720 source,
1721 })?;
1722 }
1723
1724 Ok(credentials)
1725 }
1726}
1727
1728impl From<SignstarConfig> for Vec<ExtendedUserMapping> {
1729 fn from(value: SignstarConfig) -> Self {
1736 value
1737 .iter_user_mappings()
1738 .filter_map(|mapping| {
1739 if mapping.has_system_and_backend_user() {
1740 Some(ExtendedUserMapping {
1741 admin_secret_handling: value.get_administrative_secret_handling(),
1742 non_admin_secret_handling: value.get_non_administrative_secret_handling(),
1743 connections: value.iter_connections().cloned().collect(),
1744 user_mapping: mapping.clone(),
1745 })
1746 } else {
1747 None
1748 }
1749 })
1750 .collect()
1751 }
1752}
1753
1754#[cfg(test)]
1755mod tests {
1756 use log::{LevelFilter, debug};
1757 use rstest::rstest;
1758 use signstar_common::logging::setup_logging;
1759 use signstar_crypto::{key::CryptographicKeyContext, openpgp::OpenPgpUserIdList};
1760 use tempfile::{NamedTempFile, TempDir};
1761 use testresult::TestResult;
1762
1763 use super::*;
1764
1765 mod nethsm {
1766 use super::*;
1767
1768 #[rstest]
1771 #[case::admin(UserMapping::NetHsmOnlyAdmin("test".parse()?), None)]
1772 #[case::metrics(
1773 UserMapping::SystemNetHsmMetrics {
1774 nethsm_users: NetHsmMetricsUsers::new(
1775 SystemWideUserId::new("metrics".to_string())?,
1776 vec![
1777 UserId::new("operator".to_string())?,
1778 ],
1779 )?,
1780 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1781 system_user: "system-metrics".parse()?,
1782 },
1783 Some("system-metrics".parse()?),
1784 )]
1785 #[case::backup(
1786 UserMapping::SystemNetHsmBackup {
1787 nethsm_user: "backup".parse()?,
1788 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1789 system_user: "system-backup".parse()?,
1790 },
1791 Some("system-backup".parse()?),
1792 )]
1793 #[case::operator(
1794 UserMapping::SystemNetHsmOperatorSigning {
1795 nethsm_user: "operator".parse()?,
1796 key_id: "key1".parse()?,
1797 nethsm_key_setup: SigningKeySetup::new(
1798 "Curve25519".parse()?,
1799 vec!["EdDsaSignature".parse()?],
1800 None,
1801 "EdDsa".parse()?,
1802 CryptographicKeyContext::OpenPgp{
1803 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
1804 version: "v4".parse()?,
1805 },
1806 )?,
1807 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1808 system_user: "system-operator".parse()?,
1809 tag: "tag1".to_string(),
1810 },
1811 Some("system-operator".parse()?),
1812 )]
1813 #[case::hermetic_system_metrics(
1814 UserMapping::HermeticSystemNetHsmMetrics {
1815 nethsm_users: NetHsmMetricsUsers::new(
1816 "metrics".parse()?,
1817 vec!["operator".parse()?],
1818 )?,
1819 system_user: "system-metrics".parse()?,
1820 },
1821 Some("system-metrics".parse()?),
1822 )]
1823 fn user_mapping_get_system_user(
1824 #[case] mapping: UserMapping,
1825 #[case] result: Option<SystemUserId>,
1826 ) -> TestResult {
1827 assert_eq!(mapping.get_system_user(), result.as_ref());
1828 Ok(())
1829 }
1830
1831 #[rstest]
1834 #[case::admin_filter_default(
1835 UserMapping::NetHsmOnlyAdmin("admin".parse()?),
1836 UserMappingFilter::default(),
1837 &[],
1838 )]
1839 #[case::admin_filter_admin(
1840 UserMapping::NetHsmOnlyAdmin("admin".parse()?),
1841 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
1842 &["admin"],
1843 )]
1844 #[case::metrics_filter_default(
1845 UserMapping::SystemNetHsmMetrics {
1846 nethsm_users: NetHsmMetricsUsers::new(
1847 SystemWideUserId::new("metrics".to_string())?,
1848 vec![
1849 UserId::new("operator".to_string())?,
1850 ],
1851 )?,
1852 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1853 system_user: "system-metrics".parse()?,
1854 },
1855 UserMappingFilter::default(),
1856 &["metrics", "operator"],
1857 )]
1858 #[case::metrics_filter_admin(
1859 UserMapping::SystemNetHsmMetrics {
1860 nethsm_users: NetHsmMetricsUsers::new(
1861 SystemWideUserId::new("metrics".to_string())?,
1862 vec![
1863 UserId::new("operator".to_string())?,
1864 ],
1865 )?,
1866 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1867 system_user: "system-metrics".parse()?,
1868 },
1869 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
1870 &[],
1871 )]
1872 #[case::backup_filter_default(
1873 UserMapping::SystemNetHsmBackup {
1874 nethsm_user: "backup".parse()?,
1875 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1876 system_user: "system-backup".parse()?,
1877 },
1878 UserMappingFilter::default(),
1879 &["backup"],
1880 )]
1881 #[case::backup_filter_admin(
1882 UserMapping::SystemNetHsmBackup {
1883 nethsm_user: "backup".parse()?,
1884 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1885 system_user: "system-backup".parse()?,
1886 },
1887 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
1888 &[],
1889 )]
1890 #[case::operator_filter_default(
1891 UserMapping::SystemNetHsmOperatorSigning {
1892 nethsm_user: "operator".parse()?,
1893 key_id: "key1".parse()?,
1894 nethsm_key_setup: SigningKeySetup::new(
1895 "Curve25519".parse()?,
1896 vec!["EdDsaSignature".parse()?],
1897 None,
1898 "EdDsa".parse()?,
1899 CryptographicKeyContext::OpenPgp{
1900 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
1901 version: "v4".parse()?,
1902 },
1903 )?,
1904 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1905 system_user: "system-operator".parse()?,
1906 tag: "tag1".to_string(),
1907 },
1908 UserMappingFilter::default(),
1909 &["operator"],
1910 )]
1911 #[case::operator_filter_admin(
1912 UserMapping::SystemNetHsmOperatorSigning {
1913 nethsm_user: "operator".parse()?,
1914 key_id: "key1".parse()?,
1915 nethsm_key_setup: SigningKeySetup::new(
1916 "Curve25519".parse()?,
1917 vec!["EdDsaSignature".parse()?],
1918 None,
1919 "EdDsa".parse()?,
1920 CryptographicKeyContext::OpenPgp{
1921 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
1922 version: "v4".parse()?,
1923 },
1924 )?,
1925 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1926 system_user: "system-operator".parse()?,
1927 tag: "tag1".to_string(),
1928 },
1929 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
1930 &[],
1931 )]
1932 #[case::hermetic_system_metrics_filter_default(
1933 UserMapping::HermeticSystemNetHsmMetrics {
1934 nethsm_users: NetHsmMetricsUsers::new(
1935 "metrics".parse()?,
1936 vec!["operator".parse()?],
1937 )?,
1938 system_user: "system-metrics".parse()?,
1939 },
1940 UserMappingFilter::default(),
1941 &["metrics", "operator"],
1942 )]
1943 #[case::hermetic_system_metrics_filter_admin(
1944 UserMapping::HermeticSystemNetHsmMetrics {
1945 nethsm_users: NetHsmMetricsUsers::new(
1946 "metrics".parse()?,
1947 vec!["operator".parse()?],
1948 )?,
1949 system_user: "system-metrics".parse()?,
1950 },
1951 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
1952 &[],
1953 )]
1954 fn user_mapping_backend_users(
1955 #[case] mapping: UserMapping,
1956 #[case] filter: UserMappingFilter,
1957 #[case] expected_names: &[&str],
1958 ) -> TestResult {
1959 assert_eq!(mapping.backend_users(filter), expected_names);
1960 Ok(())
1961 }
1962
1963 #[rstest]
1966 #[case::admin_filter_default(
1967 UserMapping::NetHsmOnlyAdmin("admin".parse()?),
1968 UserMappingFilter::default(),
1969 0
1970 )]
1971 #[case::admin_filter_admin(
1972 UserMapping::NetHsmOnlyAdmin("admin".parse()?),
1973 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
1974 1
1975 )]
1976 #[case::metrics_filter_default(
1977 UserMapping::SystemNetHsmMetrics {
1978 nethsm_users: NetHsmMetricsUsers::new(
1979 SystemWideUserId::new("metrics".to_string())?,
1980 vec![
1981 UserId::new("operator".to_string())?,
1982 ],
1983 )?,
1984 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1985 system_user: "system-metrics".parse()?,
1986 },
1987 UserMappingFilter::default(),
1988 2
1989 )]
1990 #[case::metrics_filter_admin(
1991 UserMapping::SystemNetHsmMetrics {
1992 nethsm_users: NetHsmMetricsUsers::new(
1993 SystemWideUserId::new("metrics".to_string())?,
1994 vec![
1995 UserId::new("operator".to_string())?,
1996 ],
1997 )?,
1998 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
1999 system_user: "system-metrics".parse()?,
2000 },
2001 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
2002 0
2003 )]
2004 #[case::backup_filter_default(
2005 UserMapping::SystemNetHsmBackup {
2006 nethsm_user: "backup".parse()?,
2007 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2008 system_user: "system-backup".parse()?,
2009 },
2010 UserMappingFilter::default(),
2011 1
2012 )]
2013 #[case::backup_filter_admin(
2014 UserMapping::SystemNetHsmBackup {
2015 nethsm_user: "backup".parse()?,
2016 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2017 system_user: "system-backup".parse()?,
2018 },
2019 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
2020 0
2021 )]
2022 #[case::operator_filter_default(
2023 UserMapping::SystemNetHsmOperatorSigning {
2024 nethsm_user: "operator".parse()?,
2025 key_id: "key1".parse()?,
2026 nethsm_key_setup: SigningKeySetup::new(
2027 "Curve25519".parse()?,
2028 vec!["EdDsaSignature".parse()?],
2029 None,
2030 "EdDsa".parse()?,
2031 CryptographicKeyContext::OpenPgp{
2032 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2033 version: "v4".parse()?,
2034 },
2035 )?,
2036 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2037 system_user: "system-operator".parse()?,
2038 tag: "tag1".to_string(),
2039 },
2040 UserMappingFilter::default(),
2041 1
2042 )]
2043 #[case::operator_filter_admin(
2044 UserMapping::SystemNetHsmOperatorSigning {
2045 nethsm_user: "operator".parse()?,
2046 key_id: "key1".parse()?,
2047 nethsm_key_setup: SigningKeySetup::new(
2048 "Curve25519".parse()?,
2049 vec!["EdDsaSignature".parse()?],
2050 None,
2051 "EdDsa".parse()?,
2052 CryptographicKeyContext::OpenPgp{
2053 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2054 version: "v4".parse()?,
2055 },
2056 )?,
2057 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2058 system_user: "system-operator".parse()?,
2059 tag: "tag1".to_string(),
2060 },
2061 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
2062 0
2063 )]
2064 #[case::hermetic_system_metrics_filter_default(
2065 UserMapping::HermeticSystemNetHsmMetrics {
2066 nethsm_users: NetHsmMetricsUsers::new(
2067 "metrics".parse()?,
2068 vec!["operator".parse()?],
2069 )?,
2070 system_user: "system-metrics".parse()?,
2071 },
2072 UserMappingFilter::default(),
2073 2
2074 )]
2075 #[case::hermetic_system_metrics_filter_admin(
2076 UserMapping::HermeticSystemNetHsmMetrics {
2077 nethsm_users: NetHsmMetricsUsers::new(
2078 "metrics".parse()?,
2079 vec!["operator".parse()?],
2080 )?,
2081 system_user: "system-metrics".parse()?,
2082 },
2083 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
2084 0
2085 )]
2086 fn user_mapping_backend_users_with_new_passphrase(
2087 #[case] mapping: UserMapping,
2088 #[case] filter: UserMappingFilter,
2089 #[case] expected_length: usize,
2090 ) -> TestResult {
2091 assert_eq!(
2092 mapping.backend_users_with_new_passphrase(filter).len(),
2093 expected_length
2094 );
2095 Ok(())
2096 }
2097
2098 #[rstest]
2101 #[case::admin(UserMapping::NetHsmOnlyAdmin("test".parse()?), vec!["test".parse()?])]
2102 #[case::metrics(
2103 UserMapping::SystemNetHsmMetrics {
2104 nethsm_users: NetHsmMetricsUsers::new(
2105 SystemWideUserId::new("metrics".to_string())?,
2106 vec![
2107 UserId::new("operator".to_string())?,
2108 ],
2109 )?,
2110 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2111 system_user: "system-metrics".parse()?,
2112 },
2113 vec!["metrics".parse()?, "operator".parse()?],
2114 )]
2115 #[case::backup(
2116 UserMapping::SystemNetHsmBackup {
2117 nethsm_user: "backup".parse()?,
2118 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2119 system_user: "system-backup".parse()?,
2120 },
2121 vec!["backup".parse()?],
2122 )]
2123 #[case::operator(
2124 UserMapping::SystemNetHsmOperatorSigning {
2125 nethsm_user: "operator".parse()?,
2126 key_id: "key1".parse()?,
2127 nethsm_key_setup: SigningKeySetup::new(
2128 "Curve25519".parse()?,
2129 vec!["EdDsaSignature".parse()?],
2130 None,
2131 "EdDsa".parse()?,
2132 CryptographicKeyContext::OpenPgp{
2133 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2134 version: "v4".parse()?,
2135 },
2136 )?,
2137 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2138 system_user: "system-operator".parse()?,
2139 tag: "tag1".to_string(),
2140 },
2141 vec!["operator".parse()?],
2142 )]
2143 #[case::hermetic_system_metrics(
2144 UserMapping::HermeticSystemNetHsmMetrics {
2145 nethsm_users: NetHsmMetricsUsers::new(
2146 "metrics".parse()?,
2147 vec!["operator".parse()?],
2148 )?,
2149 system_user: "system-metrics".parse()?,
2150 },
2151 vec!["metrics".parse()?, "operator".parse()?],
2152 )]
2153 fn user_mapping_get_nethsm_users(
2154 #[case] mapping: UserMapping,
2155 #[case] expected: Vec<UserId>,
2156 ) -> TestResult {
2157 assert_eq!(mapping.get_nethsm_users(), expected);
2158 Ok(())
2159 }
2160
2161 #[rstest]
2164 #[case::systemwide_admin(
2165 UserMapping::NetHsmOnlyAdmin("admin".parse()?),
2166 vec![("admin".parse()?, UserRole::Administrator)],
2167 )]
2168 #[case::namespace_admin(
2169 UserMapping::NetHsmOnlyAdmin("ns1~admin".parse()?),
2170 vec![("ns1~admin".parse()?, UserRole::Administrator)],
2171 )]
2172 #[case::metrics(
2173 UserMapping::SystemNetHsmMetrics {
2174 nethsm_users: NetHsmMetricsUsers::new(
2175 SystemWideUserId::new("metrics".to_string())?,
2176 vec![
2177 UserId::new("operator".to_string())?,
2178 ],
2179 )?,
2180 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2181 system_user: "system-metrics".parse()?,
2182 },
2183 vec![("metrics".parse()?, UserRole::Metrics), ("operator".parse()?, UserRole::Operator)],
2184 )]
2185 #[case::backup(
2186 UserMapping::SystemNetHsmBackup {
2187 nethsm_user: "backup".parse()?,
2188 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2189 system_user: "system-backup".parse()?,
2190 },
2191 vec![("backup".parse()?, UserRole::Backup)],
2192 )]
2193 #[case::systemwide_operator(
2194 UserMapping::SystemNetHsmOperatorSigning {
2195 nethsm_user: "operator".parse()?,
2196 key_id: "key1".parse()?,
2197 nethsm_key_setup: SigningKeySetup::new(
2198 "Curve25519".parse()?,
2199 vec!["EdDsaSignature".parse()?],
2200 None,
2201 "EdDsa".parse()?,
2202 CryptographicKeyContext::OpenPgp{
2203 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2204 version: "v4".parse()?,
2205 },
2206 )?,
2207 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2208 system_user: "system-operator".parse()?,
2209 tag: "tag1".to_string(),
2210 },
2211 vec![(
2212 "operator".parse()?,
2213 UserRole::Operator,
2214 )],
2215 )]
2216 #[case::namespace_operator(
2217 UserMapping::SystemNetHsmOperatorSigning {
2218 nethsm_user: "ns1~operator".parse()?,
2219 key_id: "key1".parse()?,
2220 nethsm_key_setup: SigningKeySetup::new(
2221 "Curve25519".parse()?,
2222 vec!["EdDsaSignature".parse()?],
2223 None,
2224 "EdDsa".parse()?,
2225 CryptographicKeyContext::OpenPgp{
2226 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2227 version: "v4".parse()?,
2228 },
2229 )?,
2230 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2231 system_user: "system-operator".parse()?,
2232 tag: "tag1".to_string(),
2233 },
2234 vec![(
2235 "ns1~operator".parse()?,
2236 UserRole::Operator,
2237 )],
2238 )]
2239 #[case::hermetic_system_metrics(
2240 UserMapping::HermeticSystemNetHsmMetrics {
2241 nethsm_users: NetHsmMetricsUsers::new(
2242 "metrics".parse()?,
2243 vec!["operator".parse()?],
2244 )?,
2245 system_user: "system-metrics".parse()?,
2246 },
2247 vec![
2248 ("metrics".parse()?, UserRole::Metrics),
2249 ("operator".parse()?, UserRole::Operator),
2250 ],
2251 )]
2252 fn usermapping_get_nethsm_users_and_roles(
2253 #[case] mapping: UserMapping,
2254 #[case] output: Vec<(UserId, UserRole)>,
2255 ) -> TestResult {
2256 assert_eq!(mapping.get_nethsm_users_and_roles(), output);
2257 Ok(())
2258 }
2259
2260 #[rstest]
2263 #[case::admin_filter_all(UserMapping::NetHsmOnlyAdmin("test".parse()?), FilterUserKeys::All, Vec::new())]
2264 #[case::metrics(
2265 UserMapping::SystemNetHsmMetrics {
2266 nethsm_users: NetHsmMetricsUsers::new(
2267 SystemWideUserId::new("metrics".to_string())?,
2268 vec![
2269 UserId::new("operator".to_string())?,
2270 ],
2271 )?,
2272 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2273 system_user: "system-metrics".parse()?,
2274 },
2275 FilterUserKeys::All,
2276 Vec::new(),
2277 )]
2278 #[case::backup_filter_all(
2279 UserMapping::SystemNetHsmBackup {
2280 nethsm_user: "backup".parse()?,
2281 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2282 system_user: "system-backup".parse()?,
2283 },
2284 FilterUserKeys::All,
2285 Vec::new(),
2286 )]
2287 #[case::operator_signing_filter_all(
2288 UserMapping::SystemNetHsmOperatorSigning {
2289 nethsm_user: "operator".parse()?,
2290 key_id: "key1".parse()?,
2291 nethsm_key_setup: SigningKeySetup::new(
2292 "Curve25519".parse()?,
2293 vec!["EdDsaSignature".parse()?],
2294 None,
2295 "EdDsa".parse()?,
2296 CryptographicKeyContext::OpenPgp{
2297 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2298 version: "v4".parse()?,
2299 },
2300 )?,
2301 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2302 system_user: "system-operator".parse()?,
2303 tag: "tag1".to_string(),
2304 },
2305 FilterUserKeys::All,
2306 vec![(
2307 "operator".parse()?,
2308 "key1".parse()?,
2309 SigningKeySetup::new(
2310 "Curve25519".parse()?,
2311 vec!["EdDsaSignature".parse()?],
2312 None,
2313 "EdDsa".parse()?,
2314 CryptographicKeyContext::OpenPgp{
2315 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2316 version: "v4".parse()?,
2317 },
2318 )?,
2319 "tag1".to_string(),
2320 )],
2321 )]
2322 #[case::systemwide_operator_filter_namespaced(
2323 UserMapping::SystemNetHsmOperatorSigning {
2324 nethsm_user: "operator".parse()?,
2325 key_id: "key1".parse()?,
2326 nethsm_key_setup: SigningKeySetup::new(
2327 "Curve25519".parse()?,
2328 vec!["EdDsaSignature".parse()?],
2329 None,
2330 "EdDsa".parse()?,
2331 CryptographicKeyContext::OpenPgp{
2332 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2333 version: "v4".parse()?,
2334 },
2335 )?,
2336 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2337 system_user: "system-operator".parse()?,
2338 tag: "tag1".to_string(),
2339 },
2340 FilterUserKeys::Namespaced,
2341 Vec::new(),
2342 )]
2343 #[case::systemwide_operator_filter_namespace(
2344 UserMapping::SystemNetHsmOperatorSigning {
2345 nethsm_user: "operator".parse()?,
2346 key_id: "key1".parse()?,
2347 nethsm_key_setup: SigningKeySetup::new(
2348 "Curve25519".parse()?,
2349 vec!["EdDsaSignature".parse()?],
2350 None,
2351 "EdDsa".parse()?,
2352 CryptographicKeyContext::OpenPgp{
2353 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2354 version: "v4".parse()?,
2355 },
2356 )?,
2357 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2358 system_user: "system-operator".parse()?,
2359 tag: "tag1".to_string(),
2360 },
2361 FilterUserKeys::Namespace("ns1".parse()?),
2362 Vec::new(),
2363 )]
2364 #[case::namespace_operator_filter_namespaced(
2365 UserMapping::SystemNetHsmOperatorSigning {
2366 nethsm_user: "ns1~operator".parse()?,
2367 key_id: "key1".parse()?,
2368 nethsm_key_setup: SigningKeySetup::new(
2369 "Curve25519".parse()?,
2370 vec!["EdDsaSignature".parse()?],
2371 None,
2372 "EdDsa".parse()?,
2373 CryptographicKeyContext::OpenPgp{
2374 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2375 version: "v4".parse()?,
2376 },
2377 )?,
2378 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2379 system_user: "system-operator".parse()?,
2380 tag: "tag1".to_string(),
2381 },
2382 FilterUserKeys::Namespaced,
2383 vec![(
2384 "ns1~operator".parse()?,
2385 "key1".parse()?,
2386 SigningKeySetup::new(
2387 "Curve25519".parse()?,
2388 vec!["EdDsaSignature".parse()?],
2389 None,
2390 "EdDsa".parse()?,
2391 CryptographicKeyContext::OpenPgp{
2392 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2393 version: "v4".parse()?,
2394 },
2395 )?,
2396 "tag1".to_string(),
2397 )],
2398 )]
2399 #[case::namespace_operator_filter_matching_namespace(
2400 UserMapping::SystemNetHsmOperatorSigning {
2401 nethsm_user: "ns1~operator".parse()?,
2402 key_id: "key1".parse()?,
2403 nethsm_key_setup: SigningKeySetup::new(
2404 "Curve25519".parse()?,
2405 vec!["EdDsaSignature".parse()?],
2406 None,
2407 "EdDsa".parse()?,
2408 CryptographicKeyContext::OpenPgp{
2409 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2410 version: "v4".parse()?,
2411 },
2412 )?,
2413 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2414 system_user: "system-operator".parse()?,
2415 tag: "tag1".to_string(),
2416 },
2417 FilterUserKeys::Namespace("ns1".parse()?),
2418 vec![(
2419 "ns1~operator".parse()?,
2420 "key1".parse()?,
2421 SigningKeySetup::new(
2422 "Curve25519".parse()?,
2423 vec!["EdDsaSignature".parse()?],
2424 None,
2425 "EdDsa".parse()?,
2426 CryptographicKeyContext::OpenPgp{
2427 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2428 version: "v4".parse()?,
2429 },
2430 )?,
2431 "tag1".to_string(),
2432 )],
2433 )]
2434 #[case::namespace_operator_filter_matching_tag(
2435 UserMapping::SystemNetHsmOperatorSigning {
2436 nethsm_user: "ns1~operator".parse()?,
2437 key_id: "key1".parse()?,
2438 nethsm_key_setup: SigningKeySetup::new(
2439 "Curve25519".parse()?,
2440 vec!["EdDsaSignature".parse()?],
2441 None,
2442 "EdDsa".parse()?,
2443 CryptographicKeyContext::OpenPgp{
2444 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2445 version: "v4".parse()?,
2446 },
2447 )?,
2448 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2449 system_user: "system-operator".parse()?,
2450 tag: "tag1".to_string(),
2451 },
2452 FilterUserKeys::Tag("tag1".parse()?),
2453 vec![(
2454 "ns1~operator".parse()?,
2455 "key1".parse()?,
2456 SigningKeySetup::new(
2457 "Curve25519".parse()?,
2458 vec!["EdDsaSignature".parse()?],
2459 None,
2460 "EdDsa".parse()?,
2461 CryptographicKeyContext::OpenPgp{
2462 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2463 version: "v4".parse()?,
2464 },
2465 )?,
2466 "tag1".to_string(),
2467 )],
2468 )]
2469 #[case::namespace_operator_filter_mismatching_tag(
2470 UserMapping::SystemNetHsmOperatorSigning {
2471 nethsm_user: "ns1~operator".parse()?,
2472 key_id: "key1".parse()?,
2473 nethsm_key_setup: SigningKeySetup::new(
2474 "Curve25519".parse()?,
2475 vec!["EdDsaSignature".parse()?],
2476 None,
2477 "EdDsa".parse()?,
2478 CryptographicKeyContext::OpenPgp{
2479 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2480 version: "v4".parse()?,
2481 },
2482 )?,
2483 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2484 system_user: "system-operator".parse()?,
2485 tag: "tag2".to_string(),
2486 },
2487 FilterUserKeys::Tag("tag1".parse()?),
2488 Vec::new(),
2489 )]
2490 #[case::hermetic_system_metrics_filter_all(
2491 UserMapping::HermeticSystemNetHsmMetrics {
2492 nethsm_users: NetHsmMetricsUsers::new(
2493 "metrics".parse()?,
2494 vec!["operator".parse()?],
2495 )?,
2496 system_user: "system-metrics".parse()?,
2497 },
2498 FilterUserKeys::All,
2499 Vec::new(),
2500 )]
2501 fn user_mapping_get_nethsm_user_key_and_tag(
2502 #[case] mapping: UserMapping,
2503 #[case] filter: FilterUserKeys,
2504 #[case] output: Vec<(UserId, KeyId, SigningKeySetup, String)>,
2505 ) -> TestResult {
2506 assert_eq!(mapping.get_nethsm_user_key_and_tag(filter), output);
2507 Ok(())
2508 }
2509
2510 #[rstest]
2513 #[case::system_wide_admin(
2514 UserMapping::NetHsmOnlyAdmin("test".parse()?),
2515 vec![("test".parse()?, UserRole::Administrator, Vec::new())],
2516 )]
2517 #[case::metrics(
2518 UserMapping::SystemNetHsmMetrics {
2519 nethsm_users: NetHsmMetricsUsers::new(
2520 SystemWideUserId::new("metrics".to_string())?,
2521 vec![
2522 UserId::new("operator".to_string())?,
2523 ],
2524 )?,
2525 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2526 system_user: "system-metrics".parse()?,
2527 },
2528 vec![("metrics".parse()?, UserRole::Metrics, Vec::new()), ("operator".parse()?, UserRole::Operator, Vec::new())],
2529 )]
2530 #[case::backup(
2531 UserMapping::SystemNetHsmBackup {
2532 nethsm_user: "backup".parse()?,
2533 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2534 system_user: "system-backup".parse()?,
2535 },
2536 vec![("backup".parse()?, UserRole::Backup, Vec::new())],
2537 )]
2538 #[case::system_wide_operator(
2539 UserMapping::SystemNetHsmOperatorSigning {
2540 nethsm_user: "operator".parse()?,
2541 key_id: "key1".parse()?,
2542 nethsm_key_setup: SigningKeySetup::new(
2543 "Curve25519".parse()?,
2544 vec!["EdDsaSignature".parse()?],
2545 None,
2546 "EdDsa".parse()?,
2547 CryptographicKeyContext::OpenPgp{
2548 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2549 version: "v4".parse()?,
2550 },
2551 )?,
2552 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2553 system_user: "system-operator".parse()?,
2554 tag: "tag1".to_string(),
2555 },
2556 vec![("operator".parse()?, UserRole::Operator, vec!["tag1".to_string()])],
2557 )]
2558 #[case::namespace_operator(
2559 UserMapping::SystemNetHsmOperatorSigning {
2560 nethsm_user: "ns1~operator".parse()?,
2561 key_id: "key1".parse()?,
2562 nethsm_key_setup: SigningKeySetup::new(
2563 "Curve25519".parse()?,
2564 vec!["EdDsaSignature".parse()?],
2565 None,
2566 "EdDsa".parse()?,
2567 CryptographicKeyContext::OpenPgp{
2568 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2569 version: "v4".parse()?,
2570 },
2571 )?,
2572 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2573 system_user: "system-operator".parse()?,
2574 tag: "tag1".to_string(),
2575 },
2576 vec![("ns1~operator".parse()?, UserRole::Operator, vec!["tag1".to_string()])],
2577 )]
2578 #[case::hermetic_system_metrics_filter_all(
2579 UserMapping::HermeticSystemNetHsmMetrics {
2580 nethsm_users: NetHsmMetricsUsers::new(
2581 "metrics".parse()?,
2582 vec!["operator".parse()?],
2583 )?,
2584 system_user: "system-metrics".parse()?,
2585 },
2586 vec![("metrics".parse()?, UserRole::Metrics, Vec::new()), ("operator".parse()?, UserRole::Operator, Vec::new())],
2587 )]
2588 fn user_mapping_get_nethsm_user_role_and_tags(
2589 #[case] mapping: UserMapping,
2590 #[case] expected: Vec<(UserId, UserRole, Vec<String>)>,
2591 ) -> TestResult {
2592 assert_eq!(mapping.get_nethsm_user_role_and_tags(), expected);
2593 Ok(())
2594 }
2595
2596 #[rstest]
2599 #[case::system_wide_admin(UserMapping::NetHsmOnlyAdmin("test".parse()?), None)]
2600 #[case::metrics(
2601 UserMapping::SystemNetHsmMetrics {
2602 nethsm_users: NetHsmMetricsUsers::new(
2603 SystemWideUserId::new("metrics".to_string())?,
2604 vec![
2605 UserId::new("operator".to_string())?,
2606 ],
2607 )?,
2608 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2609 system_user: "system-metrics".parse()?,
2610 },
2611 Some("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?),
2612 )]
2613 #[case::backup(
2614 UserMapping::SystemNetHsmBackup {
2615 nethsm_user: "backup".parse()?,
2616 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2617 system_user: "system-backup".parse()?,
2618 },
2619 Some("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?),
2620 )]
2621 #[case::system_wide_operator(
2622 UserMapping::SystemNetHsmOperatorSigning {
2623 nethsm_user: "operator".parse()?,
2624 key_id: "key1".parse()?,
2625 nethsm_key_setup: SigningKeySetup::new(
2626 "Curve25519".parse()?,
2627 vec!["EdDsaSignature".parse()?],
2628 None,
2629 "EdDsa".parse()?,
2630 CryptographicKeyContext::OpenPgp{
2631 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2632 version: "v4".parse()?,
2633 },
2634 )?,
2635 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2636 system_user: "system-operator".parse()?,
2637 tag: "tag1".to_string(),
2638 },
2639 Some("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?),
2640 )]
2641 #[case::namespace_operator(
2642 UserMapping::SystemNetHsmOperatorSigning {
2643 nethsm_user: "ns1~operator".parse()?,
2644 key_id: "key1".parse()?,
2645 nethsm_key_setup: SigningKeySetup::new(
2646 "Curve25519".parse()?,
2647 vec!["EdDsaSignature".parse()?],
2648 None,
2649 "EdDsa".parse()?,
2650 CryptographicKeyContext::OpenPgp{
2651 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2652 version: "v4".parse()?,
2653 },
2654 )?,
2655 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2656 system_user: "system-operator".parse()?,
2657 tag: "tag1".to_string(),
2658 },
2659 Some("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?),
2660 )]
2661 #[case::hermetic_system_metrics_filter_all(
2662 UserMapping::HermeticSystemNetHsmMetrics {
2663 nethsm_users: NetHsmMetricsUsers::new(
2664 "metrics".parse()?,
2665 vec!["operator".parse()?],
2666 )?,
2667 system_user: "system-metrics".parse()?,
2668 },
2669 None,
2670 )]
2671 fn user_mapping_get_ssh_authorized_key(
2672 #[case] mapping: UserMapping,
2673 #[case] output: Option<AuthorizedKeyEntry>,
2674 ) -> TestResult {
2675 assert_eq!(mapping.get_ssh_authorized_key(), output.as_ref());
2676 Ok(())
2677 }
2678
2679 #[rstest]
2682 #[case::system_wide_admin(UserMapping::NetHsmOnlyAdmin("test".parse()?), None, Vec::new())]
2683 #[case::metrics(
2684 UserMapping::SystemNetHsmMetrics {
2685 nethsm_users: NetHsmMetricsUsers::new(
2686 SystemWideUserId::new("metrics".to_string())?,
2687 vec![
2688 UserId::new("operator".to_string())?,
2689 ],
2690 )?,
2691 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2692 system_user: "system-metrics".parse()?,
2693 },
2694 None,
2695 Vec::new()
2696 )]
2697 #[case::backup(
2698 UserMapping::SystemNetHsmBackup {
2699 nethsm_user: "backup".parse()?,
2700 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2701 system_user: "system-backup".parse()?,
2702 },
2703 None,
2704 Vec::new()
2705 )]
2706 #[case::system_wide_operator_target_system_wide(
2707 UserMapping::SystemNetHsmOperatorSigning {
2708 nethsm_user: "operator".parse()?,
2709 key_id: "key1".parse()?,
2710 nethsm_key_setup: SigningKeySetup::new(
2711 "Curve25519".parse()?,
2712 vec!["EdDsaSignature".parse()?],
2713 None,
2714 "EdDsa".parse()?,
2715 CryptographicKeyContext::OpenPgp{
2716 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2717 version: "v4".parse()?,
2718 },
2719 )?,
2720 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2721 system_user: "system-operator".parse()?,
2722 tag: "tag1".to_string(),
2723 },
2724 None,
2725 vec!["key1".parse()?],
2726 )]
2727 #[case::system_wide_operator_target_namespace(
2728 UserMapping::SystemNetHsmOperatorSigning {
2729 nethsm_user: "operator".parse()?,
2730 key_id: "key1".parse()?,
2731 nethsm_key_setup: SigningKeySetup::new(
2732 "Curve25519".parse()?,
2733 vec!["EdDsaSignature".parse()?],
2734 None,
2735 "EdDsa".parse()?,
2736 CryptographicKeyContext::OpenPgp{
2737 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2738 version: "v4".parse()?,
2739 },
2740 )?,
2741 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2742 system_user: "system-operator".parse()?,
2743 tag: "tag1".to_string(),
2744 },
2745 Some("ns1".parse()?),
2746 Vec::new(),
2747 )]
2748 #[case::namespace_operator_target_system_wide(
2749 UserMapping::SystemNetHsmOperatorSigning {
2750 nethsm_user: "ns1~operator".parse()?,
2751 key_id: "key1".parse()?,
2752 nethsm_key_setup: SigningKeySetup::new(
2753 "Curve25519".parse()?,
2754 vec!["EdDsaSignature".parse()?],
2755 None,
2756 "EdDsa".parse()?,
2757 CryptographicKeyContext::OpenPgp{
2758 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2759 version: "v4".parse()?,
2760 },
2761 )?,
2762 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2763 system_user: "system-operator".parse()?,
2764 tag: "tag1".to_string(),
2765 },
2766 None,
2767 Vec::new(),
2768 )]
2769 #[case::namespace_operator_target_namespace(
2770 UserMapping::SystemNetHsmOperatorSigning {
2771 nethsm_user: "ns1~operator".parse()?,
2772 key_id: "key1".parse()?,
2773 nethsm_key_setup: SigningKeySetup::new(
2774 "Curve25519".parse()?,
2775 vec!["EdDsaSignature".parse()?],
2776 None,
2777 "EdDsa".parse()?,
2778 CryptographicKeyContext::OpenPgp{
2779 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2780 version: "v4".parse()?,
2781 },
2782 )?,
2783 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2784 system_user: "system-operator".parse()?,
2785 tag: "tag1".to_string(),
2786 },
2787 Some("ns1".parse()?),
2788 vec!["key1".parse()?],
2789 )]
2790 #[case::hermetic_system_metrics_filter_all(
2791 UserMapping::HermeticSystemNetHsmMetrics {
2792 nethsm_users: NetHsmMetricsUsers::new(
2793 "metrics".parse()?,
2794 vec!["operator".parse()?],
2795 )?,
2796 system_user: "system-metrics".parse()?,
2797 },
2798 None,
2799 Vec::new()
2800 )]
2801 fn user_mapping_get_nethsm_key_ids(
2802 #[case] mapping: UserMapping,
2803 #[case] namespace: Option<NamespaceId>,
2804 #[case] output: Vec<KeyId>,
2805 ) -> TestResult {
2806 assert_eq!(mapping.get_nethsm_key_ids(namespace.as_ref()), output);
2807 Ok(())
2808 }
2809
2810 #[rstest]
2813 #[case::system_wide_admin(UserMapping::NetHsmOnlyAdmin("test".parse()?), None, Vec::new())]
2814 #[case::metrics(
2815 UserMapping::SystemNetHsmMetrics {
2816 nethsm_users: NetHsmMetricsUsers::new(
2817 SystemWideUserId::new("metrics".to_string())?,
2818 vec![
2819 UserId::new("operator".to_string())?,
2820 ],
2821 )?,
2822 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2823 system_user: "system-metrics".parse()?,
2824 },
2825 None,
2826 Vec::new()
2827 )]
2828 #[case::backup(
2829 UserMapping::SystemNetHsmBackup {
2830 nethsm_user: "backup".parse()?,
2831 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2832 system_user: "system-backup".parse()?,
2833 },
2834 None,
2835 Vec::new()
2836 )]
2837 #[case::system_wide_operator_target_system_wide(
2838 UserMapping::SystemNetHsmOperatorSigning {
2839 nethsm_user: "operator".parse()?,
2840 key_id: "key1".parse()?,
2841 nethsm_key_setup: SigningKeySetup::new(
2842 "Curve25519".parse()?,
2843 vec!["EdDsaSignature".parse()?],
2844 None,
2845 "EdDsa".parse()?,
2846 CryptographicKeyContext::OpenPgp{
2847 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2848 version: "v4".parse()?,
2849 },
2850 )?,
2851 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2852 system_user: "system-operator".parse()?,
2853 tag: "tag1".to_string(),
2854 },
2855 None,
2856 vec!["tag1"],
2857 )]
2858 #[case::system_wide_operator_target_namespace(
2859 UserMapping::SystemNetHsmOperatorSigning {
2860 nethsm_user: "operator".parse()?,
2861 key_id: "key1".parse()?,
2862 nethsm_key_setup: SigningKeySetup::new(
2863 "Curve25519".parse()?,
2864 vec!["EdDsaSignature".parse()?],
2865 None,
2866 "EdDsa".parse()?,
2867 CryptographicKeyContext::OpenPgp{
2868 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2869 version: "v4".parse()?,
2870 },
2871 )?,
2872 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2873 system_user: "system-operator".parse()?,
2874 tag: "tag1".to_string(),
2875 },
2876 Some("ns1".parse()?),
2877 Vec::new(),
2878 )]
2879 #[case::namespace_operator_target_system_wide(
2880 UserMapping::SystemNetHsmOperatorSigning {
2881 nethsm_user: "ns1~operator".parse()?,
2882 key_id: "key1".parse()?,
2883 nethsm_key_setup: SigningKeySetup::new(
2884 "Curve25519".parse()?,
2885 vec!["EdDsaSignature".parse()?],
2886 None,
2887 "EdDsa".parse()?,
2888 CryptographicKeyContext::OpenPgp{
2889 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2890 version: "v4".parse()?,
2891 },
2892 )?,
2893 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2894 system_user: "system-operator".parse()?,
2895 tag: "tag1".to_string(),
2896 },
2897 None,
2898 Vec::new(),
2899 )]
2900 #[case::namespace_operator_target_namespace(
2901 UserMapping::SystemNetHsmOperatorSigning {
2902 nethsm_user: "ns1~operator".parse()?,
2903 key_id: "key1".parse()?,
2904 nethsm_key_setup: SigningKeySetup::new(
2905 "Curve25519".parse()?,
2906 vec!["EdDsaSignature".parse()?],
2907 None,
2908 "EdDsa".parse()?,
2909 CryptographicKeyContext::OpenPgp{
2910 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2911 version: "v4".parse()?,
2912 },
2913 )?,
2914 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2915 system_user: "system-operator".parse()?,
2916 tag: "tag1".to_string(),
2917 },
2918 Some("ns1".parse()?),
2919 vec!["tag1"],
2920 )]
2921 #[case::hermetic_system_metrics_filter_all(
2922 UserMapping::HermeticSystemNetHsmMetrics {
2923 nethsm_users: NetHsmMetricsUsers::new(
2924 "metrics".parse()?,
2925 vec!["operator".parse()?],
2926 )?,
2927 system_user: "system-metrics".parse()?,
2928 },
2929 None,
2930 Vec::new()
2931 )]
2932 fn user_mapping_get_nethsm_tags(
2933 #[case] mapping: UserMapping,
2934 #[case] namespace: Option<NamespaceId>,
2935 #[case] output: Vec<&str>,
2936 ) -> TestResult {
2937 assert_eq!(mapping.get_nethsm_tags(namespace.as_ref()), output);
2938 Ok(())
2939 }
2940
2941 #[rstest]
2944 #[case::system_wide_admin(UserMapping::NetHsmOnlyAdmin("test".parse()?), Vec::new())]
2945 #[case::namespace_admin(UserMapping::NetHsmOnlyAdmin("ns1~test".parse()?), vec!["ns1".parse()?])]
2946 #[case::metrics(
2947 UserMapping::SystemNetHsmMetrics {
2948 nethsm_users: NetHsmMetricsUsers::new(
2949 SystemWideUserId::new("metrics".to_string())?,
2950 vec![
2951 UserId::new("operator".to_string())?,
2952 ],
2953 )?,
2954 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2955 system_user: "system-metrics".parse()?,
2956 },
2957 Vec::new(),
2958 )]
2959 #[case::backup(
2960 UserMapping::SystemNetHsmBackup {
2961 nethsm_user: "backup".parse()?,
2962 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2963 system_user: "system-backup".parse()?,
2964 },
2965 Vec::new(),
2966 )]
2967 #[case::system_wide_operator(
2968 UserMapping::SystemNetHsmOperatorSigning {
2969 nethsm_user: "operator".parse()?,
2970 key_id: "key1".parse()?,
2971 nethsm_key_setup: SigningKeySetup::new(
2972 "Curve25519".parse()?,
2973 vec!["EdDsaSignature".parse()?],
2974 None,
2975 "EdDsa".parse()?,
2976 CryptographicKeyContext::OpenPgp{
2977 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2978 version: "v4".parse()?,
2979 },
2980 )?,
2981 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
2982 system_user: "system-operator".parse()?,
2983 tag: "tag1".to_string(),
2984 },
2985 Vec::new(),
2986 )]
2987 #[case::namespace_operator(
2988 UserMapping::SystemNetHsmOperatorSigning {
2989 nethsm_user: "ns1~operator".parse()?,
2990 key_id: "key1".parse()?,
2991 nethsm_key_setup: SigningKeySetup::new(
2992 "Curve25519".parse()?,
2993 vec!["EdDsaSignature".parse()?],
2994 None,
2995 "EdDsa".parse()?,
2996 CryptographicKeyContext::OpenPgp{
2997 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
2998 version: "v4".parse()?,
2999 },
3000 )?,
3001 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3002 system_user: "system-operator".parse()?,
3003 tag: "tag1".to_string(),
3004 },
3005 vec!["ns1".parse()?],
3006 )]
3007 #[case::hermetic_system_metrics_filter_all(
3008 UserMapping::HermeticSystemNetHsmMetrics {
3009 nethsm_users: NetHsmMetricsUsers::new(
3010 "metrics".parse()?,
3011 vec!["operator".parse()?],
3012 )?,
3013 system_user: "system-metrics".parse()?,
3014 },
3015 Vec::new(),
3016 )]
3017 fn user_mapping_get_nethsm_namespaces(
3018 #[case] mapping: UserMapping,
3019 #[case] output: Vec<NamespaceId>,
3020 ) -> TestResult {
3021 assert_eq!(mapping.get_nethsm_namespaces(), output);
3022 Ok(())
3023 }
3024
3025 #[rstest]
3028 #[case::system_wide_admin(UserMapping::NetHsmOnlyAdmin("test".parse()?), false)]
3029 #[case::namespace_admin(UserMapping::NetHsmOnlyAdmin("ns1~test".parse()?), false)]
3030 #[case::metrics(
3031 UserMapping::SystemNetHsmMetrics {
3032 nethsm_users: NetHsmMetricsUsers::new(
3033 SystemWideUserId::new("metrics".to_string())?,
3034 vec![
3035 UserId::new("operator".to_string())?,
3036 ],
3037 )?,
3038 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3039 system_user: "system-metrics".parse()?,
3040 },
3041 true,
3042 )]
3043 #[case::backup(
3044 UserMapping::SystemNetHsmBackup {
3045 nethsm_user: "backup".parse()?,
3046 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3047 system_user: "system-backup".parse()?,
3048 },
3049 true,
3050 )]
3051 #[case::system_wide_operator(
3052 UserMapping::SystemNetHsmOperatorSigning {
3053 nethsm_user: "operator".parse()?,
3054 key_id: "key1".parse()?,
3055 nethsm_key_setup: SigningKeySetup::new(
3056 "Curve25519".parse()?,
3057 vec!["EdDsaSignature".parse()?],
3058 None,
3059 "EdDsa".parse()?,
3060 CryptographicKeyContext::OpenPgp{
3061 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
3062 version: "v4".parse()?,
3063 },
3064 )?,
3065 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3066 system_user: "system-operator".parse()?,
3067 tag: "tag1".to_string(),
3068 },
3069 true,
3070 )]
3071 #[case::namespace_operator(
3072 UserMapping::SystemNetHsmOperatorSigning {
3073 nethsm_user: "ns1~operator".parse()?,
3074 key_id: "key1".parse()?,
3075 nethsm_key_setup: SigningKeySetup::new(
3076 "Curve25519".parse()?,
3077 vec!["EdDsaSignature".parse()?],
3078 None,
3079 "EdDsa".parse()?,
3080 CryptographicKeyContext::OpenPgp{
3081 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
3082 version: "v4".parse()?,
3083 },
3084 )?,
3085 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3086 system_user: "system-operator".parse()?,
3087 tag: "tag1".to_string(),
3088 },
3089 true,
3090 )]
3091 #[case::hermetic_system_metrics_filter_all(
3092 UserMapping::HermeticSystemNetHsmMetrics {
3093 nethsm_users: NetHsmMetricsUsers::new(
3094 "metrics".parse()?,
3095 vec!["operator".parse()?],
3096 )?,
3097 system_user: "system-metrics".parse()?,
3098 },
3099 true,
3100 )]
3101 fn user_mapping_has_system_and_backend_user(
3102 #[case] mapping: UserMapping,
3103 #[case] output: bool,
3104 ) -> TestResult {
3105 assert_eq!(mapping.has_system_and_backend_user(), output);
3106 Ok(())
3107 }
3108 }
3109
3110 mod system {
3111 use super::*;
3112
3113 #[rstest]
3116 #[case::share_download(
3117 UserMapping::SystemOnlyShareDownload {
3118 system_user: "system-share".parse()?,
3119 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3120 },
3121 Some("system-share".parse()?),
3122 )]
3123 #[case::share_upload(
3124 UserMapping::SystemOnlyShareUpload {
3125 system_user: "system-share".parse()?,
3126 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3127 },
3128 Some("system-share".parse()?),
3129 )]
3130 #[case::wireguard_download(
3131 UserMapping::SystemOnlyWireGuardDownload {
3132 system_user: "system-wireguard".parse()?,
3133 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3134 },
3135 Some("system-wireguard".parse()?),
3136 )]
3137 fn user_mapping_get_system_user(
3138 #[case] mapping: UserMapping,
3139 #[case] result: Option<SystemUserId>,
3140 ) -> TestResult {
3141 assert_eq!(mapping.get_system_user(), result.as_ref());
3142 Ok(())
3143 }
3144
3145 #[rstest]
3148 #[case::share_download_filter_default(
3149 UserMapping::SystemOnlyShareDownload {
3150 system_user: "system-share".parse()?,
3151 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3152 },
3153 UserMappingFilter::default(),
3154 )]
3155 #[case::share_download_filter_admin(
3156 UserMapping::SystemOnlyShareDownload {
3157 system_user: "system-share".parse()?,
3158 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3159 },
3160 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
3161 )]
3162 #[case::share_upload_filter_default(
3163 UserMapping::SystemOnlyShareUpload {
3164 system_user: "system-share".parse()?,
3165 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3166 },
3167 UserMappingFilter::default(),
3168 )]
3169 #[case::share_upload_filter_admin(
3170 UserMapping::SystemOnlyShareUpload {
3171 system_user: "system-share".parse()?,
3172 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3173 },
3174 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
3175 )]
3176 #[case::wireguard_download_filter_default(
3177 UserMapping::SystemOnlyWireGuardDownload {
3178 system_user: "system-wireguard".parse()?,
3179 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3180 },
3181 UserMappingFilter::default(),
3182 )]
3183 #[case::wireguard_download_filter_admin(
3184 UserMapping::SystemOnlyWireGuardDownload {
3185 system_user: "system-wireguard".parse()?,
3186 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3187 },
3188 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
3189 )]
3190 fn user_mapping_backend_users(
3191 #[case] mapping: UserMapping,
3192 #[case] filter: UserMappingFilter,
3193 ) -> TestResult {
3194 assert_eq!(mapping.backend_users(filter).len(), 0);
3195 Ok(())
3196 }
3197
3198 #[rstest]
3201 #[case::share_download_filter_default(
3202 UserMapping::SystemOnlyShareDownload {
3203 system_user: "system-share".parse()?,
3204 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3205 },
3206 UserMappingFilter::default(),
3207 )]
3208 #[case::share_download_filter_admin(
3209 UserMapping::SystemOnlyShareDownload {
3210 system_user: "system-share".parse()?,
3211 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3212 },
3213 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
3214 )]
3215 #[case::share_upload_filter_default(
3216 UserMapping::SystemOnlyShareUpload {
3217 system_user: "system-share".parse()?,
3218 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3219 },
3220 UserMappingFilter::default(),
3221 )]
3222 #[case::share_upload_filter_admin(
3223 UserMapping::SystemOnlyShareUpload {
3224 system_user: "system-share".parse()?,
3225 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3226 },
3227 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
3228 )]
3229 #[case::wireguard_download_filter_default(
3230 UserMapping::SystemOnlyWireGuardDownload {
3231 system_user: "system-wireguard".parse()?,
3232 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3233 },
3234 UserMappingFilter::default(),
3235 )]
3236 #[case::wireguard_download_filter_admin(
3237 UserMapping::SystemOnlyWireGuardDownload {
3238 system_user: "system-wireguard".parse()?,
3239 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3240 },
3241 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
3242 )]
3243 fn user_mapping_backend_users_with_new_passphrase(
3244 #[case] mapping: UserMapping,
3245 #[case] filter: UserMappingFilter,
3246 ) -> TestResult {
3247 assert!(mapping.backend_users_with_new_passphrase(filter).is_empty());
3248 Ok(())
3249 }
3250
3251 #[rstest]
3254 #[case::share_download(
3255 UserMapping::SystemOnlyShareDownload {
3256 system_user: "system-share".parse()?,
3257 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3258 },
3259 Vec::new(),
3260 )]
3261 #[case::share_upload(
3262 UserMapping::SystemOnlyShareUpload {
3263 system_user: "system-share".parse()?,
3264 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3265 },
3266 Vec::new(),
3267 )]
3268 #[case::wireguard_download(
3269 UserMapping::SystemOnlyWireGuardDownload {
3270 system_user: "system-wireguard".parse()?,
3271 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3272 },
3273 Vec::new(),
3274 )]
3275 fn user_mapping_get_nethsm_users(
3276 #[case] mapping: UserMapping,
3277 #[case] expected: Vec<UserId>,
3278 ) -> TestResult {
3279 assert_eq!(mapping.get_nethsm_users(), expected);
3280 Ok(())
3281 }
3282
3283 #[rstest]
3286 #[case::share_download(
3287 UserMapping::SystemOnlyShareDownload {
3288 system_user: "system-share".parse()?,
3289 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3290 },
3291 )]
3292 #[case::share_upload(
3293 UserMapping::SystemOnlyShareUpload {
3294 system_user: "system-share".parse()?,
3295 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3296 },
3297 )]
3298 #[case::wireguard_download(
3299 UserMapping::SystemOnlyWireGuardDownload {
3300 system_user: "system-wireguard".parse()?,
3301 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3302 },
3303 )]
3304 fn usermapping_get_nethsm_users_and_roles(#[case] mapping: UserMapping) -> TestResult {
3305 let expected: Vec<(UserId, UserRole)> = Vec::new();
3306 assert_eq!(mapping.get_nethsm_users_and_roles(), expected);
3307 Ok(())
3308 }
3309
3310 #[rstest]
3313 #[case::share_download(
3314 UserMapping::SystemOnlyShareDownload {
3315 system_user: "system-share".parse()?,
3316 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3317 },
3318 FilterUserKeys::All,
3319 )]
3320 #[case::share_upload(
3321 UserMapping::SystemOnlyShareUpload {
3322 system_user: "system-share".parse()?,
3323 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3324 },
3325 FilterUserKeys::All,
3326 )]
3327 #[case::wireguard_download(
3328 UserMapping::SystemOnlyWireGuardDownload {
3329 system_user: "system-wireguard".parse()?,
3330 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3331 },
3332 FilterUserKeys::All,
3333 )]
3334 fn user_mapping_get_nethsm_user_key_and_tag(
3335 #[case] mapping: UserMapping,
3336 #[case] filter: FilterUserKeys,
3337 ) -> TestResult {
3338 let expected: Vec<(UserId, KeyId, SigningKeySetup, String)> = Vec::new();
3339 assert_eq!(mapping.get_nethsm_user_key_and_tag(filter), expected);
3340 Ok(())
3341 }
3342
3343 #[rstest]
3346 #[case::share_download(
3347 UserMapping::SystemOnlyShareDownload {
3348 system_user: "system-share".parse()?,
3349 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3350 },
3351 )]
3352 #[case::share_upload(
3353 UserMapping::SystemOnlyShareUpload {
3354 system_user: "system-share".parse()?,
3355 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3356 },
3357 )]
3358 #[case::wireguard_download(
3359 UserMapping::SystemOnlyWireGuardDownload {
3360 system_user: "system-wireguard".parse()?,
3361 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3362 },
3363 )]
3364 fn user_mapping_get_nethsm_user_role_and_tags(#[case] mapping: UserMapping) -> TestResult {
3365 let expected: Vec<(UserId, UserRole, Vec<String>)> = Vec::new();
3366 assert_eq!(mapping.get_nethsm_user_role_and_tags(), expected);
3367 Ok(())
3368 }
3369
3370 #[rstest]
3373 #[case::share_download(
3374 UserMapping::SystemOnlyShareDownload {
3375 system_user: "system-share".parse()?,
3376 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3377 },
3378 )]
3379 #[case::share_upload(
3380 UserMapping::SystemOnlyShareUpload {
3381 system_user: "system-share".parse()?,
3382 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3383 },
3384 )]
3385 #[case::wireguard_download(
3386 UserMapping::SystemOnlyWireGuardDownload {
3387 system_user: "system-wireguard".parse()?,
3388 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3389 },
3390 )]
3391 fn user_mapping_get_ssh_authorized_key(#[case] mapping: UserMapping) -> TestResult {
3392 let expected: Option<AuthorizedKeyEntry> = Some("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?);
3393 assert_eq!(mapping.get_ssh_authorized_key(), expected.as_ref());
3394 Ok(())
3395 }
3396
3397 #[rstest]
3400 #[case::share_download_target_system_wide(
3401 UserMapping::SystemOnlyShareDownload {
3402 system_user: "system-share".parse()?,
3403 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3404 },
3405 None,
3406 )]
3407 #[case::share_download_target_namespace(
3408 UserMapping::SystemOnlyShareDownload {
3409 system_user: "system-share".parse()?,
3410 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3411 },
3412 Some("ns1".parse()?),
3413 )]
3414 #[case::share_upload_target_system_wide(
3415 UserMapping::SystemOnlyShareUpload {
3416 system_user: "system-share".parse()?,
3417 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3418 },
3419 None,
3420 )]
3421 #[case::share_upload_target_namespace(
3422 UserMapping::SystemOnlyShareUpload {
3423 system_user: "system-share".parse()?,
3424 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3425 },
3426 Some("ns1".parse()?),
3427 )]
3428 #[case::wireguard_download_target_system_wide(
3429 UserMapping::SystemOnlyWireGuardDownload {
3430 system_user: "system-wireguard".parse()?,
3431 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3432 },
3433 None,
3434 )]
3435 #[case::wireguard_download_target_namespace(
3436 UserMapping::SystemOnlyWireGuardDownload {
3437 system_user: "system-wireguard".parse()?,
3438 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3439 },
3440 Some("ns1".parse()?),
3441 )]
3442 fn user_mapping_get_nethsm_key_ids(
3443 #[case] mapping: UserMapping,
3444 #[case] namespace: Option<NamespaceId>,
3445 ) -> TestResult {
3446 let expected: Vec<KeyId> = Vec::new();
3447 assert_eq!(mapping.get_nethsm_key_ids(namespace.as_ref()), expected);
3448 Ok(())
3449 }
3450
3451 #[rstest]
3454 #[case::share_download_target_system_wide(
3455 UserMapping::SystemOnlyShareDownload {
3456 system_user: "system-share".parse()?,
3457 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3458 },
3459 None,
3460 )]
3461 #[case::share_download_target_namespace(
3462 UserMapping::SystemOnlyShareDownload {
3463 system_user: "system-share".parse()?,
3464 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3465 },
3466 Some("ns1".parse()?),
3467 )]
3468 #[case::share_upload_target_system_wide(
3469 UserMapping::SystemOnlyShareUpload {
3470 system_user: "system-share".parse()?,
3471 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3472 },
3473 None,
3474 )]
3475 #[case::share_upload_target_namespace(
3476 UserMapping::SystemOnlyShareUpload {
3477 system_user: "system-share".parse()?,
3478 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3479 },
3480 Some("ns1".parse()?),
3481 )]
3482 #[case::wireguard_download_target_system_wide(
3483 UserMapping::SystemOnlyWireGuardDownload {
3484 system_user: "system-wireguard".parse()?,
3485 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3486 },
3487 None,
3488 )]
3489 #[case::wireguard_download_target_namespace(
3490 UserMapping::SystemOnlyWireGuardDownload {
3491 system_user: "system-wireguard".parse()?,
3492 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3493 },
3494 Some("ns1".parse()?),
3495 )]
3496 fn user_mapping_get_nethsm_tags(
3497 #[case] mapping: UserMapping,
3498 #[case] namespace: Option<NamespaceId>,
3499 ) -> TestResult {
3500 let expected: Vec<&str> = Vec::new();
3501 assert_eq!(mapping.get_nethsm_tags(namespace.as_ref()), expected);
3502 Ok(())
3503 }
3504
3505 #[rstest]
3508 #[case::share_download(
3509 UserMapping::SystemOnlyShareDownload {
3510 system_user: "system-share".parse()?,
3511 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3512 },
3513 Vec::new(),
3514 )]
3515 #[case::share_upload(
3516 UserMapping::SystemOnlyShareUpload {
3517 system_user: "system-share".parse()?,
3518 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3519 },
3520 Vec::new(),
3521 )]
3522 #[case::wireguard_download(
3523 UserMapping::SystemOnlyWireGuardDownload {
3524 system_user: "system-wireguard".parse()?,
3525 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3526 },
3527 Vec::new(),
3528 )]
3529 fn user_mapping_get_nethsm_namespaces(
3530 #[case] mapping: UserMapping,
3531 #[case] output: Vec<NamespaceId>,
3532 ) -> TestResult {
3533 assert_eq!(mapping.get_nethsm_namespaces(), output);
3534 Ok(())
3535 }
3536
3537 #[rstest]
3540 #[case::share_download(
3541 UserMapping::SystemOnlyShareDownload {
3542 system_user: "system-share".parse()?,
3543 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3544 },
3545 false,
3546 )]
3547 #[case::share_upload(
3548 UserMapping::SystemOnlyShareUpload {
3549 system_user: "system-share".parse()?,
3550 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3551 },
3552 false,
3553 )]
3554 #[case::wireguard_download(
3555 UserMapping::SystemOnlyWireGuardDownload {
3556 system_user: "system-wireguard".parse()?,
3557 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3558 },
3559 false,
3560 )]
3561 fn user_mapping_has_system_and_backend_user(
3562 #[case] mapping: UserMapping,
3563 #[case] output: bool,
3564 ) -> TestResult {
3565 assert_eq!(mapping.has_system_and_backend_user(), output);
3566 Ok(())
3567 }
3568 }
3569
3570 #[cfg(feature = "yubihsm2")]
3571 mod yubihsm {
3572 use super::*;
3573
3574 #[rstest]
3577 #[case::admin(UserMapping::YubiHsm2OnlyAdmin(1), None)]
3578 #[case::backup(
3579 UserMapping::SystemYubiHsm2Backup{
3580 authentication_key_id: 1,
3581 wrapping_key_id: 2,
3582 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3583 system_user: "backup".parse()?,
3584 },
3585 Some("backup".parse()?),
3586 )]
3587 #[case::metrics(
3588 UserMapping::SystemYubiHsm2Metrics {
3589 authentication_key_id: 1,
3590 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3591 system_user: "metrics".parse()?,
3592 },
3593 Some("metrics".parse()?),
3594 )]
3595 #[case::hermetic_metrics(
3596 UserMapping::HermeticSystemYubiHsm2Metrics {
3597 authentication_key_id: 1,
3598 system_user: "metrics".parse()?,
3599 },
3600 Some("metrics".parse()?),
3601 )]
3602 #[case::operator_signing(
3603 UserMapping::SystemYubiHsm2OperatorSigning {
3604 authentication_key_id: 1,
3605 backend_key_setup: SigningKeySetup::new(
3606 "Curve25519".parse()?,
3607 vec!["EdDsaSignature".parse()?],
3608 None,
3609 "EdDsa".parse()?,
3610 CryptographicKeyContext::OpenPgp{
3611 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
3612 version: "v4".parse()?,
3613 },
3614 )?,
3615 backend_key_id: 1, backend_key_domain: 1,
3616 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3617 system_user: "system-operator".parse()?,
3618 },
3619 Some("system-operator".parse()?),
3620 )]
3621 fn user_mapping_get_system_user(
3622 #[case] mapping: UserMapping,
3623 #[case] result: Option<SystemUserId>,
3624 ) -> TestResult {
3625 assert_eq!(mapping.get_system_user(), result.as_ref());
3626 Ok(())
3627 }
3628
3629 #[rstest]
3632 #[case::admin_filter_default(UserMapping::YubiHsm2OnlyAdmin(1), UserMappingFilter::default(), &[])]
3633 #[case::admin_filter_admin(UserMapping::YubiHsm2OnlyAdmin(1), UserMappingFilter{backend_user_kind: BackendUserKind::Admin}, &["1"])]
3634 #[case::backup_filter_default(
3635 UserMapping::SystemYubiHsm2Backup{
3636 authentication_key_id: 1,
3637 wrapping_key_id: 2,
3638 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3639 system_user: "backup".parse()?,
3640 },
3641 UserMappingFilter::default(),
3642 &["1"]
3643 )]
3644 #[case::backup_filter_admin(
3645 UserMapping::SystemYubiHsm2Backup{
3646 authentication_key_id: 1,
3647 wrapping_key_id: 2,
3648 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3649 system_user: "backup".parse()?,
3650 },
3651 UserMappingFilter{ backend_user_kind: BackendUserKind::Admin },
3652 &[]
3653 )]
3654 #[case::metrics_filter_default(
3655 UserMapping::SystemYubiHsm2Metrics {
3656 authentication_key_id: 1,
3657 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3658 system_user: "metrics".parse()?,
3659 },
3660 UserMappingFilter::default(),
3661 &["1"]
3662 )]
3663 #[case::metrics_filter_admin(
3664 UserMapping::SystemYubiHsm2Metrics {
3665 authentication_key_id: 1,
3666 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3667 system_user: "metrics".parse()?,
3668 },
3669 UserMappingFilter{ backend_user_kind: BackendUserKind::Admin },
3670 &[]
3671 )]
3672 #[case::hermetic_metrics_filter_default(
3673 UserMapping::HermeticSystemYubiHsm2Metrics {
3674 authentication_key_id: 1,
3675 system_user: "metrics".parse()?,
3676 },
3677 UserMappingFilter::default(),
3678 &["1"]
3679 )]
3680 #[case::hermetic_metrics_filter_admin(
3681 UserMapping::HermeticSystemYubiHsm2Metrics {
3682 authentication_key_id: 1,
3683 system_user: "metrics".parse()?,
3684 },
3685 UserMappingFilter{ backend_user_kind: BackendUserKind::Admin },
3686 &[]
3687 )]
3688 #[case::operator_filter_default(
3689 UserMapping::SystemYubiHsm2OperatorSigning {
3690 backend_key_id: 1,
3691 backend_key_setup: SigningKeySetup::new(
3692 "Curve25519".parse()?,
3693 vec!["EdDsaSignature".parse()?],
3694 None,
3695 "EdDsa".parse()?,
3696 CryptographicKeyContext::OpenPgp{
3697 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
3698 version: "v4".parse()?,
3699 },
3700 )?,
3701 authentication_key_id: 1,
3702 backend_key_domain: 1,
3703 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3704 system_user: "system-operator".parse()?,
3705 },
3706 UserMappingFilter::default(),
3707 &["1"]
3708 )]
3709 #[case::operator_filter_admin(
3710 UserMapping::SystemYubiHsm2OperatorSigning {
3711 backend_key_id: 1,
3712 backend_key_setup: SigningKeySetup::new(
3713 "Curve25519".parse()?,
3714 vec!["EdDsaSignature".parse()?],
3715 None,
3716 "EdDsa".parse()?,
3717 CryptographicKeyContext::OpenPgp{
3718 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
3719 version: "v4".parse()?,
3720 },
3721 )?,
3722 authentication_key_id: 1,
3723 backend_key_domain: 1,
3724 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3725 system_user: "system-operator".parse()?,
3726 },
3727 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
3728 &[]
3729 )]
3730 fn user_mapping_backend_users(
3731 #[case] mapping: UserMapping,
3732 #[case] filter: UserMappingFilter,
3733 #[case] expected_names: &[&str],
3734 ) -> TestResult {
3735 assert_eq!(mapping.backend_users(filter), expected_names);
3736 Ok(())
3737 }
3738
3739 #[rstest]
3742 #[case::admin_filter_default(
3743 UserMapping::YubiHsm2OnlyAdmin(1),
3744 UserMappingFilter::default(),
3745 0
3746 )]
3747 #[case::admin_filter_admin(
3748 UserMapping::YubiHsm2OnlyAdmin(1),
3749 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
3750 1
3751 )]
3752 #[case::backup_filter_default(
3753 UserMapping::SystemYubiHsm2Backup{
3754 authentication_key_id: 1,
3755 wrapping_key_id: 2,
3756 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3757 system_user: "backup".parse()?,
3758 },
3759 UserMappingFilter::default(),
3760 1
3761 )]
3762 #[case::backup_filter_admin(
3763 UserMapping::SystemYubiHsm2Backup{
3764 authentication_key_id: 1,
3765 wrapping_key_id: 2,
3766 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3767 system_user: "backup".parse()?,
3768 },
3769 UserMappingFilter{ backend_user_kind: BackendUserKind::Admin },
3770 0
3771 )]
3772 #[case::metrics_filter_default(
3773 UserMapping::SystemYubiHsm2Metrics {
3774 authentication_key_id: 1,
3775 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3776 system_user: "metrics".parse()?,
3777 },
3778 UserMappingFilter::default(),
3779 1
3780 )]
3781 #[case::metrics_filter_admin(
3782 UserMapping::SystemYubiHsm2Metrics {
3783 authentication_key_id: 1,
3784 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3785 system_user: "metrics".parse()?,
3786 },
3787 UserMappingFilter{ backend_user_kind: BackendUserKind::Admin },
3788 0
3789 )]
3790 #[case::hermetic_metrics_filter_default(
3791 UserMapping::HermeticSystemYubiHsm2Metrics {
3792 authentication_key_id: 1,
3793 system_user: "metrics".parse()?,
3794 },
3795 UserMappingFilter::default(),
3796 1
3797 )]
3798 #[case::hermetic_metrics_filter_admin(
3799 UserMapping::HermeticSystemYubiHsm2Metrics {
3800 authentication_key_id: 1,
3801 system_user: "metrics".parse()?,
3802 },
3803 UserMappingFilter{ backend_user_kind: BackendUserKind::Admin },
3804 0
3805 )]
3806 #[case::operator_filter_default(
3807 UserMapping::SystemYubiHsm2OperatorSigning {
3808 backend_key_id: 1,
3809 backend_key_setup: SigningKeySetup::new(
3810 "Curve25519".parse()?,
3811 vec!["EdDsaSignature".parse()?],
3812 None,
3813 "EdDsa".parse()?,
3814 CryptographicKeyContext::OpenPgp{
3815 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
3816 version: "v4".parse()?,
3817 },
3818 )?,
3819 authentication_key_id: 1,
3820 backend_key_domain: 1,
3821 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3822 system_user: "system-operator".parse()?,
3823 },
3824 UserMappingFilter::default(),
3825 1
3826 )]
3827 #[case::operator_filter_admin(
3828 UserMapping::SystemYubiHsm2OperatorSigning {
3829 backend_key_id: 1,
3830 backend_key_setup: SigningKeySetup::new(
3831 "Curve25519".parse()?,
3832 vec!["EdDsaSignature".parse()?],
3833 None,
3834 "EdDsa".parse()?,
3835 CryptographicKeyContext::OpenPgp{
3836 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
3837 version: "v4".parse()?,
3838 },
3839 )?,
3840 authentication_key_id: 1,
3841 backend_key_domain: 1,
3842 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3843 system_user: "system-operator".parse()?,
3844 },
3845 UserMappingFilter{backend_user_kind: BackendUserKind::Admin},
3846 0
3847 )]
3848 fn usermapping_yubihsm_backend_users_with_new_passphrase(
3849 #[case] mapping: UserMapping,
3850 #[case] filter: UserMappingFilter,
3851 #[case] expected_length: usize,
3852 ) -> TestResult {
3853 assert_eq!(
3854 mapping.backend_users_with_new_passphrase(filter).len(),
3855 expected_length
3856 );
3857 Ok(())
3858 }
3859
3860 #[rstest]
3863 #[case::admin(UserMapping::YubiHsm2OnlyAdmin(1))]
3864 #[case::backup(
3865 UserMapping::SystemYubiHsm2Backup{
3866 authentication_key_id: 1,
3867 wrapping_key_id: 2,
3868 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3869 system_user: "backup".parse()?,
3870 }
3871 )]
3872 #[case::metrics(
3873 UserMapping::SystemYubiHsm2Metrics {
3874 authentication_key_id: 1,
3875 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3876 system_user: "metrics".parse()?,
3877 },
3878 )]
3879 #[case::hermetic_metrics(
3880 UserMapping::HermeticSystemYubiHsm2Metrics {
3881 authentication_key_id: 1,
3882 system_user: "metrics".parse()?,
3883 },
3884 )]
3885 #[case::operator_signing(
3886 UserMapping::SystemYubiHsm2OperatorSigning {
3887 authentication_key_id: 1,
3888 backend_key_setup: SigningKeySetup::new(
3889 "Curve25519".parse()?,
3890 vec!["EdDsaSignature".parse()?],
3891 None,
3892 "EdDsa".parse()?,
3893 CryptographicKeyContext::OpenPgp{
3894 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
3895 version: "v4".parse()?,
3896 },
3897 )?,
3898 backend_key_id: 1, backend_key_domain: 1,
3899 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3900 system_user: "system-operator".parse()?,
3901 },
3902 )]
3903 fn user_mapping_get_nethsm_users(#[case] mapping: UserMapping) -> TestResult {
3904 let expected: Vec<UserId> = Vec::new();
3905 assert_eq!(mapping.get_nethsm_users(), expected);
3906 Ok(())
3907 }
3908
3909 #[rstest]
3912 #[case::admin(UserMapping::YubiHsm2OnlyAdmin(1))]
3913 #[case::backup(
3914 UserMapping::SystemYubiHsm2Backup{
3915 authentication_key_id: 1,
3916 wrapping_key_id: 2,
3917 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3918 system_user: "backup".parse()?,
3919 }
3920 )]
3921 #[case::metrics(
3922 UserMapping::SystemYubiHsm2Metrics {
3923 authentication_key_id: 1,
3924 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3925 system_user: "metrics".parse()?,
3926 },
3927 )]
3928 #[case::hermetic_metrics(
3929 UserMapping::HermeticSystemYubiHsm2Metrics {
3930 authentication_key_id: 1,
3931 system_user: "metrics".parse()?,
3932 },
3933 )]
3934 #[case::operator_signing(
3935 UserMapping::SystemYubiHsm2OperatorSigning {
3936 authentication_key_id: 1,
3937 backend_key_setup: SigningKeySetup::new(
3938 "Curve25519".parse()?,
3939 vec!["EdDsaSignature".parse()?],
3940 None,
3941 "EdDsa".parse()?,
3942 CryptographicKeyContext::OpenPgp{
3943 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
3944 version: "v4".parse()?,
3945 },
3946 )?,
3947 backend_key_id: 1, backend_key_domain: 1,
3948 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3949 system_user: "system-operator".parse()?,
3950 },
3951 )]
3952 fn usermapping_get_nethsm_users_and_roles(#[case] mapping: UserMapping) -> TestResult {
3953 let expected: Vec<(UserId, UserRole)> = Vec::new();
3954 assert_eq!(mapping.get_nethsm_users_and_roles(), expected);
3955 Ok(())
3956 }
3957
3958 #[rstest]
3961 #[case::admin(UserMapping::YubiHsm2OnlyAdmin(1), FilterUserKeys::All)]
3962 #[case::backup(
3963 UserMapping::SystemYubiHsm2Backup{
3964 authentication_key_id: 1,
3965 wrapping_key_id: 2,
3966 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3967 system_user: "backup".parse()?,
3968 },
3969 FilterUserKeys::All,
3970 )]
3971 #[case::metrics(
3972 UserMapping::SystemYubiHsm2Metrics {
3973 authentication_key_id: 1,
3974 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
3975 system_user: "metrics".parse()?,
3976 },
3977 FilterUserKeys::All,
3978 )]
3979 #[case::hermetic_metrics(
3980 UserMapping::HermeticSystemYubiHsm2Metrics {
3981 authentication_key_id: 1,
3982 system_user: "metrics".parse()?,
3983 },
3984 FilterUserKeys::All,
3985 )]
3986 #[case::operator_signing(
3987 UserMapping::SystemYubiHsm2OperatorSigning {
3988 authentication_key_id: 1,
3989 backend_key_setup: SigningKeySetup::new(
3990 "Curve25519".parse()?,
3991 vec!["EdDsaSignature".parse()?],
3992 None,
3993 "EdDsa".parse()?,
3994 CryptographicKeyContext::OpenPgp{
3995 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
3996 version: "v4".parse()?,
3997 },
3998 )?,
3999 backend_key_id: 1, backend_key_domain: 1,
4000 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4001 system_user: "system-operator".parse()?,
4002 },
4003 FilterUserKeys::All,
4004 )]
4005 fn user_mapping_get_nethsm_user_key_and_tag(
4006 #[case] mapping: UserMapping,
4007 #[case] filter: FilterUserKeys,
4008 ) -> TestResult {
4009 let expected: Vec<(UserId, KeyId, SigningKeySetup, String)> = Vec::new();
4010 assert_eq!(mapping.get_nethsm_user_key_and_tag(filter), expected);
4011 Ok(())
4012 }
4013
4014 #[rstest]
4017 #[case::admin(UserMapping::YubiHsm2OnlyAdmin(1))]
4018 #[case::backup(
4019 UserMapping::SystemYubiHsm2Backup{
4020 authentication_key_id: 1,
4021 wrapping_key_id: 2,
4022 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4023 system_user: "backup".parse()?,
4024 }
4025 )]
4026 #[case::metrics(
4027 UserMapping::SystemYubiHsm2Metrics {
4028 authentication_key_id: 1,
4029 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4030 system_user: "metrics".parse()?,
4031 },
4032 )]
4033 #[case::hermetic_metrics(
4034 UserMapping::HermeticSystemYubiHsm2Metrics {
4035 authentication_key_id: 1,
4036 system_user: "metrics".parse()?,
4037 },
4038 )]
4039 #[case::operator_signing(
4040 UserMapping::SystemYubiHsm2OperatorSigning {
4041 authentication_key_id: 1,
4042 backend_key_setup: SigningKeySetup::new(
4043 "Curve25519".parse()?,
4044 vec!["EdDsaSignature".parse()?],
4045 None,
4046 "EdDsa".parse()?,
4047 CryptographicKeyContext::OpenPgp{
4048 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
4049 version: "v4".parse()?,
4050 },
4051 )?,
4052 backend_key_id: 1, backend_key_domain: 1,
4053 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4054 system_user: "system-operator".parse()?,
4055 },
4056 )]
4057 fn user_mapping_get_nethsm_user_role_and_tags(#[case] mapping: UserMapping) -> TestResult {
4058 let expected: Vec<(UserId, UserRole, Vec<String>)> = Vec::new();
4059 assert_eq!(mapping.get_nethsm_user_role_and_tags(), expected);
4060 Ok(())
4061 }
4062
4063 #[rstest]
4066 #[case::admin(UserMapping::YubiHsm2OnlyAdmin(1), None)]
4067 #[case::backup(
4068 UserMapping::SystemYubiHsm2Backup{
4069 authentication_key_id: 1,
4070 wrapping_key_id: 2,
4071 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4072 system_user: "backup".parse()?,
4073 },
4074 Some("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?),
4075 )]
4076 #[case::metrics(
4077 UserMapping::SystemYubiHsm2Metrics {
4078 authentication_key_id: 1,
4079 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4080 system_user: "metrics".parse()?,
4081 },
4082 Some("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?),
4083 )]
4084 #[case::hermetic_metrics(
4085 UserMapping::HermeticSystemYubiHsm2Metrics {
4086 authentication_key_id: 1,
4087 system_user: "metrics".parse()?,
4088 },
4089 None,
4090 )]
4091 #[case::operator_signing(
4092 UserMapping::SystemYubiHsm2OperatorSigning {
4093 authentication_key_id: 1,
4094 backend_key_setup: SigningKeySetup::new(
4095 "Curve25519".parse()?,
4096 vec!["EdDsaSignature".parse()?],
4097 None,
4098 "EdDsa".parse()?,
4099 CryptographicKeyContext::OpenPgp{
4100 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
4101 version: "v4".parse()?,
4102 },
4103 )?,
4104 backend_key_id: 1, backend_key_domain: 1,
4105 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4106 system_user: "system-operator".parse()?,
4107 },
4108 Some("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?),
4109 )]
4110 fn user_mapping_get_ssh_authorized_key(
4111 #[case] mapping: UserMapping,
4112 #[case] output: Option<AuthorizedKeyEntry>,
4113 ) -> TestResult {
4114 assert_eq!(mapping.get_ssh_authorized_key(), output.as_ref());
4115 Ok(())
4116 }
4117
4118 #[rstest]
4121 #[case::admin_target_system_wide(UserMapping::YubiHsm2OnlyAdmin(1), None)]
4122 #[case::admin_target_namespace(UserMapping::YubiHsm2OnlyAdmin(1), Some("ns1".parse()?))]
4123 #[case::backup_target_system_wide(
4124 UserMapping::SystemYubiHsm2Backup{
4125 authentication_key_id: 1,
4126 wrapping_key_id: 2,
4127 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4128 system_user: "backup".parse()?,
4129 },
4130 None,
4131 )]
4132 #[case::backup_target_namespace(
4133 UserMapping::SystemYubiHsm2Backup{
4134 authentication_key_id: 1,
4135 wrapping_key_id: 2,
4136 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4137 system_user: "backup".parse()?,
4138 },
4139 Some("ns1".parse()?),
4140 )]
4141 #[case::metrics_target_system_wide(
4142 UserMapping::SystemYubiHsm2Metrics {
4143 authentication_key_id: 1,
4144 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4145 system_user: "metrics".parse()?,
4146 },
4147 None,
4148 )]
4149 #[case::metrics_target_namespace(
4150 UserMapping::SystemYubiHsm2Metrics {
4151 authentication_key_id: 1,
4152 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4153 system_user: "metrics".parse()?,
4154 },
4155 Some("ns1".parse()?),
4156 )]
4157 #[case::hermetic_metrics_target_system_wide(
4158 UserMapping::HermeticSystemYubiHsm2Metrics {
4159 authentication_key_id: 1,
4160 system_user: "metrics".parse()?,
4161 },
4162 None,
4163 )]
4164 #[case::hermetic_metrics_target_namespace(
4165 UserMapping::HermeticSystemYubiHsm2Metrics {
4166 authentication_key_id: 1,
4167 system_user: "metrics".parse()?,
4168 },
4169 Some("ns1".parse()?),
4170 )]
4171 #[case::operator_signing_target_system_wide(
4172 UserMapping::SystemYubiHsm2OperatorSigning {
4173 authentication_key_id: 1,
4174 backend_key_setup: SigningKeySetup::new(
4175 "Curve25519".parse()?,
4176 vec!["EdDsaSignature".parse()?],
4177 None,
4178 "EdDsa".parse()?,
4179 CryptographicKeyContext::OpenPgp{
4180 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
4181 version: "v4".parse()?,
4182 },
4183 )?,
4184 backend_key_id: 1, backend_key_domain: 1,
4185 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4186 system_user: "system-operator".parse()?,
4187 },
4188 None,
4189 )]
4190 #[case::operator_signing_target_namespace(
4191 UserMapping::SystemYubiHsm2OperatorSigning {
4192 authentication_key_id: 1,
4193 backend_key_setup: SigningKeySetup::new(
4194 "Curve25519".parse()?,
4195 vec!["EdDsaSignature".parse()?],
4196 None,
4197 "EdDsa".parse()?,
4198 CryptographicKeyContext::OpenPgp{
4199 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
4200 version: "v4".parse()?,
4201 },
4202 )?,
4203 backend_key_id: 1, backend_key_domain: 1,
4204 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4205 system_user: "system-operator".parse()?,
4206 },
4207 Some("ns1".parse()?),
4208 )]
4209 fn user_mapping_get_nethsm_key_ids(
4210 #[case] mapping: UserMapping,
4211 #[case] namespace: Option<NamespaceId>,
4212 ) -> TestResult {
4213 let expected: Vec<KeyId> = Vec::new();
4214 assert_eq!(mapping.get_nethsm_key_ids(namespace.as_ref()), expected);
4215 Ok(())
4216 }
4217
4218 #[rstest]
4221 #[case::admin_target_system_wide(UserMapping::YubiHsm2OnlyAdmin(1), None)]
4222 #[case::admin_target_namespace(UserMapping::YubiHsm2OnlyAdmin(1), Some("ns1".parse()?))]
4223 #[case::backup_target_system_wide(
4224 UserMapping::SystemYubiHsm2Backup{
4225 authentication_key_id: 1,
4226 wrapping_key_id: 2,
4227 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4228 system_user: "backup".parse()?,
4229 },
4230 None,
4231 )]
4232 #[case::backup_target_namespace(
4233 UserMapping::SystemYubiHsm2Backup{
4234 authentication_key_id: 1,
4235 wrapping_key_id: 2,
4236 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4237 system_user: "backup".parse()?,
4238 },
4239 Some("ns1".parse()?),
4240 )]
4241 #[case::metrics_target_system_wide(
4242 UserMapping::SystemYubiHsm2Metrics {
4243 authentication_key_id: 1,
4244 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4245 system_user: "metrics".parse()?,
4246 },
4247 None,
4248 )]
4249 #[case::metrics_target_namespace(
4250 UserMapping::SystemYubiHsm2Metrics {
4251 authentication_key_id: 1,
4252 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4253 system_user: "metrics".parse()?,
4254 },
4255 Some("ns1".parse()?),
4256 )]
4257 #[case::hermetic_metrics_target_system_wide(
4258 UserMapping::HermeticSystemYubiHsm2Metrics {
4259 authentication_key_id: 1,
4260 system_user: "metrics".parse()?,
4261 },
4262 None,
4263 )]
4264 #[case::hermetic_metrics_target_namespace(
4265 UserMapping::HermeticSystemYubiHsm2Metrics {
4266 authentication_key_id: 1,
4267 system_user: "metrics".parse()?,
4268 },
4269 Some("ns1".parse()?),
4270 )]
4271 #[case::operator_signing_target_system_wide(
4272 UserMapping::SystemYubiHsm2OperatorSigning {
4273 authentication_key_id: 1,
4274 backend_key_setup: SigningKeySetup::new(
4275 "Curve25519".parse()?,
4276 vec!["EdDsaSignature".parse()?],
4277 None,
4278 "EdDsa".parse()?,
4279 CryptographicKeyContext::OpenPgp{
4280 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
4281 version: "v4".parse()?,
4282 },
4283 )?,
4284 backend_key_id: 1, backend_key_domain: 1,
4285 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4286 system_user: "system-operator".parse()?,
4287 },
4288 None,
4289 )]
4290 #[case::operator_signing_target_namespace(
4291 UserMapping::SystemYubiHsm2OperatorSigning {
4292 authentication_key_id: 1,
4293 backend_key_setup: SigningKeySetup::new(
4294 "Curve25519".parse()?,
4295 vec!["EdDsaSignature".parse()?],
4296 None,
4297 "EdDsa".parse()?,
4298 CryptographicKeyContext::OpenPgp{
4299 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
4300 version: "v4".parse()?,
4301 },
4302 )?,
4303 backend_key_id: 1, backend_key_domain: 1,
4304 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4305 system_user: "system-operator".parse()?,
4306 },
4307 Some("ns1".parse()?),
4308 )]
4309 fn user_mapping_get_nethsm_tags(
4310 #[case] mapping: UserMapping,
4311 #[case] namespace: Option<NamespaceId>,
4312 ) -> TestResult {
4313 let expected: Vec<&str> = Vec::new();
4314 assert_eq!(mapping.get_nethsm_tags(namespace.as_ref()), expected);
4315 Ok(())
4316 }
4317
4318 #[rstest]
4321 #[case::admin(UserMapping::YubiHsm2OnlyAdmin(1))]
4322 #[case::backup(
4323 UserMapping::SystemYubiHsm2Backup{
4324 authentication_key_id: 1,
4325 wrapping_key_id: 2,
4326 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4327 system_user: "backup".parse()?,
4328 },
4329 )]
4330 #[case::metrics(
4331 UserMapping::SystemYubiHsm2Metrics {
4332 authentication_key_id: 1,
4333 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4334 system_user: "metrics".parse()?,
4335 },
4336 )]
4337 #[case::hermetic_metrics(
4338 UserMapping::HermeticSystemYubiHsm2Metrics {
4339 authentication_key_id: 1,
4340 system_user: "metrics".parse()?,
4341 },
4342 )]
4343 #[case::operator_signing(
4344 UserMapping::SystemYubiHsm2OperatorSigning {
4345 authentication_key_id: 1,
4346 backend_key_setup: SigningKeySetup::new(
4347 "Curve25519".parse()?,
4348 vec!["EdDsaSignature".parse()?],
4349 None,
4350 "EdDsa".parse()?,
4351 CryptographicKeyContext::OpenPgp{
4352 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
4353 version: "v4".parse()?,
4354 },
4355 )?,
4356 backend_key_id: 1, backend_key_domain: 1,
4357 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4358 system_user: "system-operator".parse()?,
4359 },
4360 )]
4361 fn user_mapping_get_nethsm_namespaces(#[case] mapping: UserMapping) -> TestResult {
4362 let expected: Vec<NamespaceId> = Vec::new();
4363 assert_eq!(mapping.get_nethsm_namespaces(), expected);
4364 Ok(())
4365 }
4366
4367 #[rstest]
4370 #[case::admin(UserMapping::YubiHsm2OnlyAdmin(1), false)]
4371 #[case::backup(
4372 UserMapping::SystemYubiHsm2Backup{
4373 authentication_key_id: 1,
4374 wrapping_key_id: 2,
4375 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4376 system_user: "backup".parse()?,
4377 },
4378 true
4379 )]
4380 #[case::metrics(
4381 UserMapping::SystemYubiHsm2Metrics {
4382 authentication_key_id: 1,
4383 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4384 system_user: "metrics".parse()?,
4385 },
4386 true
4387 )]
4388 #[case::hermetic_metrics(
4389 UserMapping::HermeticSystemYubiHsm2Metrics {
4390 authentication_key_id: 1,
4391 system_user: "metrics".parse()?,
4392 },
4393 true
4394 )]
4395 #[case::operator_signing(
4396 UserMapping::SystemYubiHsm2OperatorSigning {
4397 authentication_key_id: 1,
4398 backend_key_setup: SigningKeySetup::new(
4399 "Curve25519".parse()?,
4400 vec!["EdDsaSignature".parse()?],
4401 None,
4402 "EdDsa".parse()?,
4403 CryptographicKeyContext::OpenPgp{
4404 user_ids: OpenPgpUserIdList::new(vec!["John Doe <john@example.org>".parse()?])?,
4405 version: "v4".parse()?,
4406 },
4407 )?,
4408 backend_key_id: 1, backend_key_domain: 1,
4409 ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3NyNfSqtDxdnWwSVzulZi0k7Lyjw3vBEG+U8y6KsuW user@host".parse()?,
4410 system_user: "system-operator".parse()?,
4411 },
4412 true,
4413 )]
4414 fn user_mapping_has_system_and_backend_user(
4415 #[case] mapping: UserMapping,
4416 #[case] output: bool,
4417 ) -> TestResult {
4418 assert_eq!(mapping.has_system_and_backend_user(), output);
4419 Ok(())
4420 }
4421 }
4422
4423 #[test]
4426 fn check_secrets_file_succeeds() -> TestResult {
4427 setup_logging(LevelFilter::Debug)?;
4428
4429 let temp_file = NamedTempFile::new()?;
4430 let path = temp_file.path();
4431 set_permissions(path, Permissions::from_mode(SECRET_FILE_MODE))?;
4432 debug!(
4433 "Created {path:?} with mode {:o}",
4434 path.metadata()?.permissions().mode()
4435 );
4436
4437 check_secrets_file(path)?;
4438
4439 Ok(())
4440 }
4441
4442 #[test]
4444 fn check_secrets_file_fails_on_missing_file() -> TestResult {
4445 setup_logging(LevelFilter::Debug)?;
4446
4447 let temp_file = NamedTempFile::new()?;
4448 let path = temp_file.path().to_path_buf();
4449 temp_file.close()?;
4450
4451 if check_secrets_file(&path).is_ok() {
4452 panic!("The path {path:?} is missing and should not have passed as a secrets file.");
4453 }
4454
4455 Ok(())
4456 }
4457
4458 #[test]
4460 fn check_secrets_file_fails_on_dir() -> TestResult {
4461 setup_logging(LevelFilter::Debug)?;
4462
4463 let temp_file = TempDir::new()?;
4464 let path = temp_file.path();
4465 debug!(
4466 "Created {path:?} with mode {:o}",
4467 path.metadata()?.permissions().mode()
4468 );
4469
4470 if check_secrets_file(path).is_ok() {
4471 panic!("The dir {path:?} should not have passed as a secrets file.");
4472 }
4473
4474 Ok(())
4475 }
4476
4477 #[test]
4479 fn check_secrets_file_fails_on_invalid_permissions() -> TestResult {
4480 setup_logging(LevelFilter::Debug)?;
4481
4482 let temp_file = NamedTempFile::new()?;
4483 let path = temp_file.path();
4484 set_permissions(path, Permissions::from_mode(0o100644))?;
4485 debug!(
4486 "Created {path:?} with mode {:o}",
4487 path.metadata()?.permissions().mode()
4488 );
4489
4490 if check_secrets_file(path).is_ok() {
4491 panic!("The file at {path:?} should not have passed as a secrets file.");
4492 }
4493
4494 Ok(())
4495 }
4496}