mysqladm/client/commands/
create_user.rs1use clap::Parser;
2use dialoguer::Confirm;
3use futures_util::SinkExt;
4use tokio_stream::StreamExt;
5
6use crate::{
7 client::commands::{erroneous_server_response, read_password_from_stdin_with_double_check},
8 core::{
9 protocol::{
10 ClientToServerMessageStream, Request, Response, print_create_users_output_status,
11 print_create_users_output_status_json, print_set_password_output_status,
12 },
13 types::MySQLUser,
14 },
15};
16
17#[derive(Parser, Debug, Clone)]
18pub struct CreateUserArgs {
19 #[arg(num_args = 1..)]
20 username: Vec<MySQLUser>,
21
22 #[clap(long)]
24 no_password: bool,
25
26 #[arg(short, long)]
30 json: bool,
31}
32
33pub async fn create_users(
34 args: CreateUserArgs,
35 mut server_connection: ClientToServerMessageStream,
36) -> anyhow::Result<()> {
37 if args.username.is_empty() {
38 anyhow::bail!("No usernames provided");
39 }
40
41 let message = Request::CreateUsers(args.username.to_owned());
42 if let Err(err) = server_connection.send(message).await {
43 server_connection.close().await.ok();
44 anyhow::bail!(anyhow::Error::from(err).context("Failed to communicate with server"));
45 }
46
47 let result = match server_connection.next().await {
48 Some(Ok(Response::CreateUsers(result))) => result,
49 response => return erroneous_server_response(response),
50 };
51
52 if args.json {
53 print_create_users_output_status_json(&result);
54 } else {
55 print_create_users_output_status(&result);
56
57 let successfully_created_users = result
58 .iter()
59 .filter_map(|(username, result)| result.as_ref().ok().map(|_| username))
60 .collect::<Vec<_>>();
61
62 for username in successfully_created_users {
63 if !args.no_password
64 && Confirm::new()
65 .with_prompt(format!(
66 "Do you want to set a password for user '{}'?",
67 username
68 ))
69 .default(false)
70 .interact()?
71 {
72 let password = read_password_from_stdin_with_double_check(username)?;
73 let message = Request::PasswdUser((username.to_owned(), password));
74
75 if let Err(err) = server_connection.send(message).await {
76 server_connection.close().await.ok();
77 anyhow::bail!(err);
78 }
79
80 match server_connection.next().await {
81 Some(Ok(Response::SetUserPassword(result))) => {
82 print_set_password_output_status(&result, username)
83 }
84 response => return erroneous_server_response(response),
85 }
86
87 println!();
88 }
89 }
90 }
91
92 server_connection.send(Request::Exit).await?;
93
94 Ok(())
95}