blue_build/commands/
login.rs

1use std::io::{self, Read};
2
3use blue_build_process_management::drivers::{BuildDriver, Driver, DriverArgs, SigningDriver};
4use blue_build_utils::credentials::{Credentials, CredentialsArgs};
5use clap::Args;
6use miette::{IntoDiagnostic, Result, bail};
7use requestty::questions;
8
9use super::BlueBuildCommand;
10
11#[derive(Debug, Clone, Args)]
12pub struct LoginCommand {
13    /// The server to login to.
14    server: String,
15
16    /// The password to login with.
17    ///
18    /// Cannont be used with `--password-stdin`.
19    #[arg(group = "pass", long, short)]
20    password: Option<String>,
21
22    /// Read password from stdin,
23    ///
24    /// Cannot be used with `--password/-p`
25    #[arg(group = "pass", long)]
26    password_stdin: bool,
27
28    /// The username to login with
29    #[arg(long, short)]
30    username: Option<String>,
31
32    #[clap(flatten)]
33    drivers: DriverArgs,
34}
35
36impl BlueBuildCommand for LoginCommand {
37    fn try_run(&mut self) -> miette::Result<()> {
38        Driver::init(self.drivers);
39
40        Credentials::init(
41            CredentialsArgs::builder()
42                .registry(&self.server)
43                .username(self.get_username()?)
44                .password(self.get_password()?)
45                .build(),
46        );
47
48        Driver::login()?;
49        Driver::signing_login()?;
50
51        Ok(())
52    }
53}
54
55impl LoginCommand {
56    fn get_username(&self) -> Result<String> {
57        Ok(if let Some(ref username) = self.username {
58            username.clone()
59        } else if !self.password_stdin {
60            let questions = questions! [ inline
61                Input {
62                    name: "username",
63                },
64            ];
65
66            requestty::prompt(questions)
67                .into_diagnostic()?
68                .get("username")
69                .unwrap()
70                .as_string()
71                .unwrap()
72                .to_string()
73        } else {
74            bail!("Cannot prompt for username when using `--password-stdin`");
75        })
76    }
77
78    fn get_password(&self) -> Result<String> {
79        Ok(if let Some(ref password) = self.password {
80            password.clone()
81        } else if self.password_stdin {
82            let mut password = String::new();
83            io::stdin()
84                .read_to_string(&mut password)
85                .into_diagnostic()?;
86            password
87        } else {
88            let questions = questions! [ inline
89                Password {
90                    name: "password",
91                }
92            ];
93
94            requestty::prompt(questions)
95                .into_diagnostic()?
96                .get("password")
97                .unwrap()
98                .as_string()
99                .unwrap()
100                .to_string()
101        })
102    }
103}