bw/auth/
mod.rs

1use bitwarden_cli::text_prompt_when_none;
2use bitwarden_core::ClientSettings;
3use clap::{Args, Subcommand};
4
5mod login;
6use inquire::Password;
7
8use crate::render::CommandResult;
9
10// TODO(CLI): This is incompatible with the current node CLI
11#[derive(Args, Clone)]
12pub struct LoginArgs {
13    #[command(subcommand)]
14    pub command: LoginCommands,
15
16    #[arg(short = 's', long, global = true, help = "Server URL")]
17    pub server: Option<String>,
18}
19
20#[derive(Subcommand, Clone)]
21pub enum LoginCommands {
22    Password {
23        #[arg(short = 'e', long, help = "Email address")]
24        email: Option<String>,
25    },
26    ApiKey {
27        client_id: Option<String>,
28        client_secret: Option<String>,
29    },
30    Device {
31        #[arg(short = 'e', long, help = "Email address")]
32        email: Option<String>,
33        device_identifier: Option<String>,
34    },
35}
36
37impl LoginArgs {
38    pub async fn run(self) -> CommandResult {
39        let settings = self.server.map(|server| ClientSettings {
40            api_url: format!("{server}/api"),
41            identity_url: format!("{server}/identity"),
42            ..Default::default()
43        });
44        let client = bitwarden_core::Client::new(settings);
45
46        match self.command {
47            // FIXME: Rust CLI will not support password login!
48            LoginCommands::Password { email } => {
49                login::login_password(client, email).await?;
50            }
51            LoginCommands::ApiKey {
52                client_id,
53                client_secret,
54            } => login::login_api_key(client, client_id, client_secret).await?,
55            LoginCommands::Device {
56                email,
57                device_identifier,
58            } => {
59                login::login_device(client, email, device_identifier).await?;
60            }
61        }
62        Ok("Successfully logged in!".into())
63    }
64}
65
66#[derive(Args, Clone)]
67pub struct RegisterArgs {
68    #[arg(short = 'e', long, help = "Email address")]
69    email: Option<String>,
70
71    name: Option<String>,
72
73    password_hint: Option<String>,
74
75    #[arg(short = 's', long, global = true, help = "Server URL")]
76    server: Option<String>,
77}
78
79impl RegisterArgs {
80    #[allow(unused_variables, clippy::unused_async)]
81    pub async fn run(self) -> CommandResult {
82        let settings = self.server.map(|server| ClientSettings {
83            api_url: format!("{server}/api"),
84            identity_url: format!("{server}/identity"),
85            ..Default::default()
86        });
87        let client = bitwarden_core::Client::new(settings);
88
89        let email = text_prompt_when_none("Email", self.email)?;
90        let password = Password::new("Password").prompt()?;
91
92        unimplemented!("Registration is not yet implemented");
93    }
94}