nethsm/cli/config/
prompt.rs1use rpassword::prompt_password;
2use rprompt::prompt_reply;
3
4use crate::{Passphrase, UserId, UserRole};
5
6#[derive(Debug, thiserror::Error)]
7pub enum Error {
8 #[error("Unable to get backup passphrase")]
10 Backup,
11
12 #[error("Unable to get current backup passphrase")]
14 CurrentBackup,
15
16 #[error("Unable to get current unlock passphrase")]
18 CurrentUnlock,
19
20 #[error("Unable to get new backup passphrase")]
22 NewBackup,
23
24 #[error("Unable to get new unlock passphrase")]
26 NewUnlock,
27
28 #[error("Unable to get new passphrase for user {0}")]
30 NewUser(String),
31
32 #[error("Unable to get unlock passphrase")]
34 Unlock,
35
36 #[error("Unable to get passphrase for user {user_id:?} ({real_name:?}) ")]
38 User {
39 user_id: Option<UserId>,
40 real_name: Option<String>,
41 },
42
43 #[error("Unable to get username")]
45 UserName,
46
47 #[error("User data is invalid: {0}")]
49 NetHsmUser(#[from] crate::UserError),
50}
51
52#[derive(Debug)]
54pub enum PassphrasePrompt {
55 Backup,
57 CurrentBackup,
59 CurrentUnlock,
61 NewBackup,
63 NewUnlock,
65 NewUser(UserId),
67 Unlock,
69 User {
71 user_id: Option<UserId>,
73 real_name: Option<String>,
75 },
76}
77
78impl PassphrasePrompt {
79 pub fn prompt(&self) -> Result<Passphrase, Error> {
81 let reason = match self {
82 Self::Backup => "Backup passphrase: ".to_string(),
83 Self::CurrentBackup => "Current backup passphrase: ".to_string(),
84 Self::CurrentUnlock => "Current unlock passphrase: ".to_string(),
85 Self::NewBackup => "New backup passphrase: ".to_string(),
86 Self::NewUnlock => "New unlock passphrase: ".to_string(),
87 Self::NewUser(user) => format!("New passphrase for user \"{user}\": "),
88 Self::Unlock => "Unlock passphrase: ".to_string(),
89 Self::User { user_id, real_name } => match (user_id, real_name) {
90 (Some(user_id), Some(real_name)) => {
91 format!("Passphrase for user \"{user_id}\" (\"{real_name}\"): ")
92 }
93 (None, Some(real_name)) => format!("Passphrase for user \"{real_name}\": "),
94 (None, None) => "Passphrase for unknown user: ".to_string(),
95 (Some(user_id), None) => format!("Passphrase for unknown user \"{user_id}\": "),
96 },
97 };
98
99 Ok(Passphrase::new(prompt_password(reason).map_err(
100 |_| match self {
101 Self::Backup => Error::Backup,
102 Self::CurrentBackup => Error::CurrentBackup,
103 Self::CurrentUnlock => Error::CurrentUnlock,
104 Self::NewBackup => Error::NewBackup,
105 Self::NewUnlock => Error::NewUnlock,
106 Self::NewUser(user) => Error::NewUser(user.to_string()),
107 Self::Unlock => Error::Unlock,
108 Self::User { user_id, real_name } => Error::User {
109 user_id: user_id.to_owned(),
110 real_name: real_name.to_owned(),
111 },
112 },
113 )?))
114 }
115}
116
117#[derive(Debug)]
119pub struct UserPrompt(UserRole);
120
121impl UserPrompt {
122 pub fn new(role: UserRole) -> Self {
124 Self(role)
125 }
126
127 pub fn prompt(&self) -> Result<UserId, Error> {
129 let reason = match self.0 {
130 UserRole::Administrator => "Name of a user in the \"Administrator\" role: ".to_string(),
131 UserRole::Backup => "Name of a user in the \"Backup\" role: ".to_string(),
132 UserRole::Metrics => "Name of a user in the \"Metrics\" role: ".to_string(),
133 UserRole::Operator => "Name of a user in the \"Operator\" role: ".to_string(),
134 };
135
136 let name = UserId::new(prompt_reply(reason).map_err(|_| Error::UserName)?)?;
137 Ok(name)
138 }
139}