bw/
command.rs

1use bitwarden_cli::Color;
2use clap::{Args, Parser, Subcommand};
3
4use crate::{
5    admin_console::ConfirmCommand,
6    auth::{LoginArgs, RegisterArgs},
7    platform::ConfigCommand,
8    render::Output,
9    tools::GenerateArgs,
10    vault::{ItemCommands, TemplateCommands},
11};
12
13pub const SESSION_ENV: &str = "BW_SESSION";
14
15#[derive(Parser, Clone)]
16#[command(name = "Bitwarden CLI", version, about = "Bitwarden CLI", long_about = None, disable_version_flag = true)]
17pub struct Cli {
18    // Optional as a workaround for https://github.com/clap-rs/clap/issues/3572
19    #[command(subcommand)]
20    pub command: Option<Commands>,
21
22    #[arg(short = 'o', long, global = true, value_enum, default_value_t = Output::JSON)]
23    pub output: Output,
24
25    #[arg(short = 'c', long, global = true, value_enum, default_value_t = Color::Auto)]
26    pub color: Color,
27
28    // TODO(CLI): Pretty/raw/response options
29    #[arg(
30        long,
31        global = true,
32        env = SESSION_ENV,
33        help = "The session key used to decrypt your vault data. Can be obtained with `bw login` or `bw unlock`."
34    )]
35    pub session: Option<String>,
36
37    #[arg(
38        long,
39        global = true,
40        help = "Exit with a success exit code (0) unless an error is thrown."
41    )]
42    pub cleanexit: bool,
43
44    #[arg(
45        short = 'q',
46        long,
47        global = true,
48        help = "Don't return anything to stdout."
49    )]
50    pub quiet: bool,
51
52    #[arg(
53        long,
54        global = true,
55        help = "Do not prompt for interactive user input."
56    )]
57    pub nointeraction: bool,
58
59    // Clap uses uppercase V for the short flag by default, but we want lowercase v
60    // for compatibility with the node CLI:
61    // https://github.com/clap-rs/clap/issues/138
62    #[arg(short = 'v', long, action = clap::builder::ArgAction::Version)]
63    pub version: (),
64}
65
66#[derive(Subcommand, Clone)]
67pub enum Commands {
68    // Auth commands
69    #[command(long_about = "Log into a user account.")]
70    Login(LoginArgs),
71
72    #[command(long_about = "Log out of the current user account.")]
73    Logout,
74
75    #[command(long_about = "Register a new user account.")]
76    Register(RegisterArgs),
77
78    // KM commands
79    #[command(long_about = "Unlock the vault and return a session key.")]
80    Unlock(UnlockArgs),
81
82    // Platform commands
83    #[command(long_about = "Pull the latest vault data from server.")]
84    Sync {
85        #[arg(short = 'f', long, help = "Force a full sync.")]
86        force: bool,
87
88        #[arg(long, help = "Get the last sync date.")]
89        last: bool,
90    },
91
92    #[command(long_about = "Base 64 encode stdin.")]
93    Encode,
94
95    #[command(long_about = "Configure CLI settings.")]
96    Config {
97        #[command(subcommand)]
98        command: ConfigCommand,
99    },
100
101    #[command(long_about = "Check for updates.")]
102    Update {
103        #[arg(long, help = "Return only the download URL for the update.")]
104        raw: bool,
105    },
106
107    #[command(long_about = "Generate shell completions.")]
108    Completion {
109        #[arg(long, help = "The shell to generate completions for.")]
110        shell: Option<clap_complete::Shell>,
111    },
112
113    #[command(
114        long_about = "Show server, last sync, user information, and vault status.",
115        after_help = r#"Example return value:
116  {
117    "serverUrl": "https://bitwarden.example.com",
118    "lastSync": "2020-06-16T06:33:51.419Z",
119    "userEmail": "[email protected]",
120    "userId": "00000000-0000-0000-0000-000000000000",
121    "status": "locked"
122  }
123
124Notes:
125  `status` is one of:
126    - `unauthenticated` when you are not logged in
127    - `locked` when you are logged in and the vault is locked
128    - `unlocked` when you are logged in and the vault is unlocked
129"#
130    )]
131    Status,
132
133    // Vault commands
134    #[command(long_about = "Manage vault objects.")]
135    Item {
136        #[command(subcommand)]
137        command: ItemCommands,
138    },
139    #[command(long_about = "Get the available templates")]
140    Template {
141        #[command(subcommand)]
142        command: TemplateCommands,
143    },
144
145    // These are the old style action-name commands, to be replaced by name-action commands in the
146    // future
147    #[command(long_about = "List an array of objects from the vault.")]
148    List,
149    #[command(long_about = "Get an object from the vault.")]
150    Get,
151    #[command(long_about = "Create an object in the vault.")]
152    Create,
153    #[command(long_about = "Edit an object from the vault.")]
154    Edit,
155    #[command(long_about = "Delete an object from the vault.")]
156    Delete,
157    #[command(long_about = "Restores an object from the trash.")]
158    Restore,
159    #[command(long_about = "Move an item to an organization.")]
160    Move,
161
162    // Admin console commands
163    #[command(long_about = "Confirm an object to the organization.")]
164    Confirm {
165        #[command(subcommand)]
166        command: ConfirmCommand,
167    },
168
169    // Tools commands
170    #[command(long_about = "Generate a password/passphrase.")]
171    #[command(after_help = r#"Notes:
172    Default options are `-uln --length 14`.
173    Minimum `length` is 5.
174    Minimum `words` is 3.
175
176Examples:
177    bw generate
178    bw generate -u -l --length 18
179    bw generate -ulns --length 25
180    bw generate -ul
181    bw generate -p --separator _
182    bw generate -p --words 5 --separator space
183    bw generate -p --words 5 --separator empty
184    "#)]
185    Generate(GenerateArgs),
186    #[command(long_about = "Import vault data from a file.")]
187    Import,
188    #[command(long_about = "Export vault data to a CSV, JSON or ZIP file.")]
189    Export,
190    #[command(long_about = "--DEPRECATED-- Move an item to an organization.")]
191    Share,
192    #[command(
193        long_about = "Work with Bitwarden sends. A Send can be quickly created using this command or subcommands can be used to fine-tune the Send."
194    )]
195    Send,
196    #[command(long_about = "Access a Bitwarden Send from a url.")]
197    Receive,
198}
199
200#[derive(Args, Clone)]
201pub struct UnlockArgs {
202    pub password: Option<String>,
203
204    #[arg(long, help = "Environment variable storing your password.")]
205    pub passwordenv: Option<String>,
206
207    #[arg(
208        long,
209        help = "Path to a file containing your password as its first line."
210    )]
211    pub passwordfile: Option<String>,
212
213    #[arg(long, help = "Only return the session key.")]
214    pub raw: bool,
215}