]>
Commit | Line | Data |
---|---|---|
6fa39e53 DM |
1 | use anyhow::Error; |
2 | use serde_json::Value; | |
3 | ||
4615325f FG |
4 | use std::collections::HashMap; |
5 | ||
6fa39e53 DM |
6 | use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler}; |
7 | ||
8 | use proxmox_backup::config; | |
6fa39e53 | 9 | use proxmox_backup::api2; |
4615325f | 10 | use proxmox_backup::api2::types::{ACL_PATH_SCHEMA, Authid, Userid}; |
6fa39e53 | 11 | |
1a0b4105 TL |
12 | fn render_expire(value: &Value, _record: &Value) -> Result<String, Error> { |
13 | let never = String::from("never"); | |
14 | if value.is_null() { return Ok(never); } | |
15 | let text = match value.as_i64() { | |
16 | Some(epoch) if epoch == 0 => never, | |
17 | Some(epoch) => { | |
18 | if let Ok(epoch_string) = proxmox::tools::time::strftime_local("%c", epoch as i64) { | |
19 | epoch_string | |
20 | } else { | |
21 | epoch.to_string() | |
22 | } | |
23 | }, | |
24 | None => value.to_string(), | |
25 | }; | |
26 | Ok(text) | |
27 | } | |
28 | ||
6fa39e53 DM |
29 | #[api( |
30 | input: { | |
31 | properties: { | |
32 | "output-format": { | |
33 | schema: OUTPUT_FORMAT, | |
34 | optional: true, | |
35 | }, | |
36 | } | |
37 | } | |
38 | )] | |
39 | /// List configured users. | |
40 | fn list_users(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Error> { | |
41 | ||
42 | let output_format = get_output_format(¶m); | |
43 | ||
44 | let info = &api2::access::user::API_METHOD_LIST_USERS; | |
45 | let mut data = match info.handler { | |
46 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, | |
47 | _ => unreachable!(), | |
48 | }; | |
49 | ||
50 | let options = default_table_format_options() | |
51 | .column(ColumnConfig::new("userid")) | |
52 | .column( | |
53 | ColumnConfig::new("enable") | |
770a36e5 | 54 | .renderer(pbs_tools::format::render_bool_with_default_true) |
6fa39e53 DM |
55 | ) |
56 | .column( | |
57 | ColumnConfig::new("expire") | |
1a0b4105 | 58 | .renderer(render_expire) |
6fa39e53 DM |
59 | ) |
60 | .column(ColumnConfig::new("firstname")) | |
61 | .column(ColumnConfig::new("lastname")) | |
62 | .column(ColumnConfig::new("email")) | |
63 | .column(ColumnConfig::new("comment")); | |
64 | ||
b2362a12 | 65 | format_and_print_result_full(&mut data, &info.returns, &output_format, &options); |
6fa39e53 DM |
66 | |
67 | Ok(Value::Null) | |
68 | } | |
69 | ||
2156dec5 FG |
70 | #[api( |
71 | input: { | |
72 | properties: { | |
73 | "output-format": { | |
74 | schema: OUTPUT_FORMAT, | |
75 | optional: true, | |
76 | }, | |
77 | userid: { | |
78 | type: Userid, | |
79 | } | |
80 | } | |
81 | } | |
82 | )] | |
83 | /// List tokens associated with user. | |
84 | fn list_tokens(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Error> { | |
85 | ||
86 | let output_format = get_output_format(¶m); | |
87 | ||
88 | let info = &api2::access::user::API_METHOD_LIST_TOKENS; | |
89 | let mut data = match info.handler { | |
90 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, | |
91 | _ => unreachable!(), | |
92 | }; | |
93 | ||
94 | let options = default_table_format_options() | |
95 | .column(ColumnConfig::new("tokenid")) | |
96 | .column( | |
97 | ColumnConfig::new("enable") | |
770a36e5 | 98 | .renderer(pbs_tools::format::render_bool_with_default_true) |
2156dec5 FG |
99 | ) |
100 | .column( | |
101 | ColumnConfig::new("expire") | |
1a0b4105 | 102 | .renderer(render_expire) |
2156dec5 FG |
103 | ) |
104 | .column(ColumnConfig::new("comment")); | |
105 | ||
b2362a12 | 106 | format_and_print_result_full(&mut data, &info.returns, &output_format, &options); |
2156dec5 FG |
107 | |
108 | Ok(Value::Null) | |
109 | } | |
110 | ||
111 | ||
4615325f FG |
112 | #[api( |
113 | input: { | |
114 | properties: { | |
115 | "output-format": { | |
116 | schema: OUTPUT_FORMAT, | |
117 | optional: true, | |
118 | }, | |
8b600f99 | 119 | "auth-id": { |
4615325f FG |
120 | type: Authid, |
121 | }, | |
122 | path: { | |
123 | schema: ACL_PATH_SCHEMA, | |
124 | optional: true, | |
125 | }, | |
126 | } | |
127 | } | |
128 | )] | |
129 | /// List permissions of user/token. | |
130 | fn list_permissions(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Error> { | |
131 | ||
132 | let output_format = get_output_format(¶m); | |
133 | ||
134 | let info = &api2::access::API_METHOD_LIST_PERMISSIONS; | |
4d104cd4 | 135 | let data = match info.handler { |
4615325f FG |
136 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, |
137 | _ => unreachable!(), | |
138 | }; | |
139 | ||
140 | if output_format == "text" { | |
141 | println!("Privileges with (*) have the propagate flag set\n"); | |
142 | let data:HashMap<String, HashMap<String, bool>> = serde_json::from_value(data)?; | |
143 | let mut paths:Vec<String> = data.keys().cloned().collect(); | |
144 | paths.sort_unstable(); | |
145 | for path in paths { | |
146 | println!("Path: {}", path); | |
147 | let priv_map = data.get(&path).unwrap(); | |
148 | let mut privs:Vec<String> = priv_map.keys().cloned().collect(); | |
149 | if privs.is_empty() { | |
150 | println!("- NoAccess"); | |
151 | } else { | |
152 | privs.sort_unstable(); | |
153 | for privilege in privs { | |
154 | if *priv_map.get(&privilege).unwrap() { | |
155 | println!("- {} (*)", privilege); | |
156 | } else { | |
157 | println!("- {}", privilege); | |
158 | } | |
159 | } | |
160 | } | |
161 | } | |
162 | } else { | |
4d104cd4 | 163 | format_and_print_result(&data, &output_format); |
4615325f FG |
164 | } |
165 | ||
166 | Ok(Value::Null) | |
167 | } | |
168 | ||
169 | ||
6fa39e53 DM |
170 | pub fn user_commands() -> CommandLineInterface { |
171 | ||
172 | let cmd_def = CliCommandMap::new() | |
173 | .insert("list", CliCommand::new(&&API_METHOD_LIST_USERS)) | |
174 | .insert( | |
175 | "create", | |
176 | // fixme: howto handle password parameter? | |
177 | CliCommand::new(&api2::access::user::API_METHOD_CREATE_USER) | |
178 | .arg_param(&["userid"]) | |
179 | ) | |
180 | .insert( | |
181 | "update", | |
182 | CliCommand::new(&api2::access::user::API_METHOD_UPDATE_USER) | |
183 | .arg_param(&["userid"]) | |
ba3d7e19 | 184 | .completion_cb("userid", pbs_config::user::complete_userid) |
6fa39e53 DM |
185 | ) |
186 | .insert( | |
187 | "remove", | |
188 | CliCommand::new(&api2::access::user::API_METHOD_DELETE_USER) | |
189 | .arg_param(&["userid"]) | |
ba3d7e19 | 190 | .completion_cb("userid", pbs_config::user::complete_userid) |
2156dec5 FG |
191 | ) |
192 | .insert( | |
193 | "list-tokens", | |
194 | CliCommand::new(&&API_METHOD_LIST_TOKENS) | |
195 | .arg_param(&["userid"]) | |
ba3d7e19 | 196 | .completion_cb("userid", pbs_config::user::complete_userid) |
2156dec5 FG |
197 | ) |
198 | .insert( | |
199 | "generate-token", | |
200 | CliCommand::new(&api2::access::user::API_METHOD_GENERATE_TOKEN) | |
201 | .arg_param(&["userid", "tokenname"]) | |
ba3d7e19 | 202 | .completion_cb("userid", pbs_config::user::complete_userid) |
2156dec5 FG |
203 | ) |
204 | .insert( | |
205 | "delete-token", | |
206 | CliCommand::new(&api2::access::user::API_METHOD_DELETE_TOKEN) | |
207 | .arg_param(&["userid", "tokenname"]) | |
ba3d7e19 DM |
208 | .completion_cb("userid", pbs_config::user::complete_userid) |
209 | .completion_cb("tokenname", pbs_config::user::complete_token_name) | |
4615325f FG |
210 | ) |
211 | .insert( | |
212 | "permissions", | |
213 | CliCommand::new(&&API_METHOD_LIST_PERMISSIONS) | |
8b600f99 | 214 | .arg_param(&["auth-id"]) |
ba3d7e19 | 215 | .completion_cb("auth-id", pbs_config::user::complete_authid) |
4615325f | 216 | .completion_cb("path", config::datastore::complete_acl_path) |
6fa39e53 DM |
217 | ); |
218 | ||
219 | cmd_def.into() | |
220 | } |