nethsm_cli/cli/
user.rs

1use clap::{Parser, Subcommand};
2use expression_format::ex_format;
3use nethsm::{
4    SystemState::Operational,
5    UserId,
6    UserRole::{self, Administrator, Operator},
7};
8use strum::IntoEnumIterator;
9
10use super::BIN_NAME;
11use crate::passphrase_file::PassphraseFile;
12
13#[derive(Debug, Subcommand)]
14#[command(
15    about = "Operate on users of a device",
16    long_about = ex_format!("Operate on users of a device
17
18Allows to add and remove users, retrieve information about them, set their passphrases and set or unset tags for them.
19
20Users may exist in specific scopes: system-wide or in namespaces (see \"{BIN_NAME} namespace\").
21The use of a namespace is indicated by a prefix in the user name (e.g. the user name \"namespace1~user1\" indicates that the user is in \"namespace1\").
22Users in a namespace can only be administrated by users in the \"{Administrator}\" role in that same namespace.
23System-wide users can only be administratred by system-wide users in the \"{Administrator}\" role.")
24)]
25pub enum UserCommand {
26    Add(UserAddCommand),
27    Get(UserGetCommand),
28    List(UserListCommand),
29    Passphrase(UserPassphraseCommand),
30    Remove(UserRemoveCommand),
31    Tag(UserTagCommand),
32    Untag(UserUntagCommand),
33}
34
35#[derive(Debug, Parser)]
36#[command(
37    about = "Add a user",
38    long_about = ex_format!("Add a user
39
40Adds a new user by providing a real name and a user role.
41If no user name is provided specifically, a random one is generated automatically by the target device.
42If no passphrase is provided, it is prompted for interactively.
43
44New users inherit the scope of the user that created them.
45If a system-wide user in the \"{Administrator}\" role creates a new user (e.g. \"user1\"), then that new user is also a system-wide user.
46As exception to this rule, a system-wide user in the \"{Administrator}\" role can create namespaced users by providing a user name specifically (e.g. \"namespace1~user1\"), but only if the targeted namespace (i.e. \"namespace1\") does not yet exist (see \"{BIN_NAME} namespace add\").
47If a namespaced user in the \"{Administrator}\" role creates a new user, then that new user is also a user in that namespace.
48If a namespaced user in the \"{Administrator}\" role (e.g. \"namespace1~admin1\") provides a specific user name, it must be in that same namespace (e.g. \"namespace1~user1\", not \"namespace2~user1\")!
49
50The device must be in state \"{Operational}\".
51
52Requires authentication of a user in the \"{Administrator}\" role."),
53)]
54pub struct UserAddCommand {
55    #[arg(
56        env = "NETHSM_REAL_NAME",
57        help = "The real name of the user that is created",
58        long_help = "The real name of the user that is created
59
60This name is only used for further identification, but not for authentication!"
61    )]
62    pub real_name: String,
63
64    #[arg(
65        env = "NETHSM_USER_ROLE",
66        help = "The role of the user that is created",
67        long_help = format!("The role of the user that is created
68
69One of {:?} (defaults to \"{:?}\").", UserRole::iter().map(Into::into).collect::<Vec<&'static str>>(), UserRole::default())
70    )]
71    pub role: Option<UserRole>,
72
73    #[arg(
74        env = "NETHSM_USER_NAME",
75        help = "A unique name for the user that is created",
76        long_help = "A unique name for the user that is created
77
78This name must be unique as it is used for authentication!"
79    )]
80    pub name: Option<UserId>,
81
82    #[arg(
83        env = "NETHSM_PASSPHRASE_FILE",
84        help = "The path to a file containing the new user's passphrase",
85        long_help = "The path to a file containing the new user's passphrase
86
87The passphrase must be >= 10 and <= 200 characters long.",
88        long,
89        short
90    )]
91    pub passphrase_file: Option<PassphraseFile>,
92}
93
94#[derive(Debug, Parser)]
95#[command(
96    about = "Get information about a user",
97    long_about = ex_format!("Get information about a user
98
99Retrieves the real name and role of a user.
100If the user is in the \"{Operator}\" role, also displays tags that are assigned to the user.
101
102System-wide users in the \"{Administrator}\" role have access to information of system-wide and namespaced users.
103Namespaced users in the \"{Administrator}\" role only have access to information of users in the same namespace.
104
105The device must be in state \"{Operational}\".
106
107Requires authentication of a user in the \"{Administrator}\" role."),
108)]
109pub struct UserGetCommand {
110    #[arg(
111        env = "NETHSM_USER_NAME",
112        help = "The unique name of a user on the target device"
113    )]
114    pub name: UserId,
115}
116
117#[derive(Debug, Parser)]
118#[command(
119    about = "List all user names",
120    long_about = ex_format!("List all user names
121
122System-wide users in the \"{Administrator}\" role can list system-wide and namespaced users.
123Namespaced users in the \"{Administrator}\" role can only list users in the same namespace.
124
125The device must be in state \"{Operational}\".
126
127Requires authentication of a user in the \"{Administrator}\" role."),
128)]
129pub struct UserListCommand {}
130
131#[derive(Debug, Parser)]
132#[command(
133    about = "Set the passphrase for a user",
134    long_about = ex_format!("Set the passphrase for a user
135
136If no passphrase is provided specifically, it is prompted for interactively.
137
138System-wide users in the \"{Administrator}\" role can only set the passphrase for system-wide users.
139Namespaced users in the \"{Administrator}\" role can only set the passphrase for users in the same namespace.
140
141The device must be in state \"{Operational}\".
142
143Requires authentication of a user in the \"{Administrator}\" role."),
144)]
145pub struct UserPassphraseCommand {
146    #[arg(
147        env = "NETHSM_USER_NAME",
148        help = "The name of the user on the target device"
149    )]
150    pub name: UserId,
151
152    #[arg(
153        env = "NETHSM_PASSPHRASE_FILE",
154        help = "The path to a file containing the user's new passphrase",
155        long_help = "The path to a file containing the user's new passphrase
156
157The passphrase must be >= 10 and <= 200 characters long.",
158        long,
159        short
160    )]
161    pub passphrase_file: Option<PassphraseFile>,
162}
163
164#[derive(Debug, Parser)]
165#[command(
166    about = "Remove a user",
167    long_about = ex_format!("Remove a user
168
169System-wide users in the \"{Administrator}\" role can only remove system-wide users.
170As an exception to this rule, system-wide users in the \"{Administrator}\" role can delete users in a namespace, if the namespace is removed first (see \"{BIN_NAME} namespace remove\").
171Namespaced users in the \"{Administrator}\" role can only remove users in the same namespace.
172
173The device must be in state \"{Operational}\".
174
175Requires authentication of a user in the \"{Administrator}\" role."),
176)]
177pub struct UserRemoveCommand {
178    #[arg(env = "NETHSM_USER_NAME", help = "The name of the user to remove")]
179    pub name: UserId,
180}
181
182#[derive(Debug, Parser)]
183#[command(
184    about = "Add a tag to a user",
185    long_about = ex_format!("Add a tag to a user
186
187Tags provide access to keys for users.
188Keys that carry identical tags to that of a user, are accessible for the user.
189Tags on a key must exist (see \"{BIN_NAME} key tag\") before an identical tag can be added to a user.
190
191System-wide users in the \"{Administrator}\" role can only add tags for system-wide users in the \"{Operator}\" role.
192Namespaced users in the \"{Administrator}\" role can only add tags for users in the \"{Operator}\" role in the same namespace.
193
194The device must be in state \"{Operational}\".
195
196Requires authentication of a user in the \"{Administrator}\" role."),
197)]
198pub struct UserTagCommand {
199    #[arg(
200        env = "NETHSM_USER_NAME",
201        help = "The name of the user for which to add a tag"
202    )]
203    pub name: UserId,
204
205    #[arg(env = "NETHSM_USER_TAG", help = "The tag to add for a user")]
206    pub tag: String,
207}
208
209#[derive(Debug, Parser)]
210#[command(
211    about = "Remove a tag from a user",
212    long_about = ex_format!("Remove a tag from a user
213
214Tags provide access to keys for users.
215Removing a tag from a user removes its access to keys that carry identical tags.
216
217System-wide users in the \"{Administrator}\" role can only remove tags for system-wide users in the \"{Operator}\" role.
218Namespaced users in the \"{Administrator}\" role can only remove tags for users in the \"{Operator}\" role in the same namespace.
219
220The device must be in state \"{Operational}\".
221
222Requires authentication of a user in the \"{Administrator}\" role."),
223)]
224pub struct UserUntagCommand {
225    #[arg(
226        env = "NETHSM_USER_NAME",
227        help = "The name of the user from which to remove a tag"
228    )]
229    pub name: UserId,
230
231    #[arg(env = "NETHSM_USER_TAG", help = "The tag to remove from a user")]
232    pub tag: String,
233}