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