Skip to main content

bw/command/
mod.rs

1//! CLI command definitions and argument parsing for the Bitwarden CLI (`bw`).
2//!
3//! This module defines the top-level [`Cli`] struct and the [`Commands`] enum that together
4//! describe every subcommand accepted by the CLI. Parsing is handled by
5//! [clap](https://docs.rs/clap) using its derive API.
6//!
7//! Subcommand that have an explicit owner lives under the team's corresponding module, such as the
8//! `sync` subcommand living under the `platform` module. Subcommands that don't have a clear owner,
9//! such as `get item`, live in this module. Each subcommand has a `run` method that executes the
10//! command's logic and returns a [`crate::render::CommandOutput`].
11
12use bitwarden_cli::Color;
13use clap::{Parser, Subcommand};
14
15use crate::{
16    admin_console::{ConfirmCommand, MoveArgs},
17    auth::LoginArgs,
18    key_management::{LockArgs, UnlockArgs},
19    platform::{CompletionArgs, ConfigCommand, EncodeArgs, ServeArgs, StatusArgs, SyncArgs},
20    render::Output,
21    tools::{ExportArgs, GenerateArgs, ImportArgs, ReceiveArgs, SendArgs},
22    vault::RestoreArgs,
23};
24
25mod create;
26mod delete;
27mod edit;
28mod get;
29mod list;
30
31pub(crate) use create::CreateCommands;
32pub(crate) use delete::DeleteCommands;
33pub(crate) use edit::EditCommands;
34pub(crate) use get::GetCommands;
35pub(crate) use list::ListCommands;
36
37pub const SESSION_ENV: &str = "BW_SESSION";
38
39#[derive(Parser, Clone)]
40#[command(name = "Bitwarden CLI", version, about = "Bitwarden CLI", long_about = None, disable_version_flag = true)]
41pub struct Cli {
42    // Optional as a workaround for https://github.com/clap-rs/clap/issues/3572
43    #[command(subcommand)]
44    pub command: Option<Commands>,
45
46    #[arg(short = 'o', long, global = true, value_enum, default_value_t = Output::JSON)]
47    pub output: Output,
48
49    #[arg(short = 'c', long, global = true, value_enum, default_value_t = Color::Auto)]
50    pub color: Color,
51
52    // TODO(CLI): Pretty/raw/response options
53    #[arg(
54        long,
55        global = true,
56        env = SESSION_ENV,
57        help = "The session key used to decrypt your vault data. Can be obtained with `bw login` or `bw unlock`."
58    )]
59    pub session: Option<String>,
60
61    #[arg(
62        long,
63        global = true,
64        alias = "cleanexit",
65        help = "Exit with a success exit code (0) unless an error is thrown."
66    )]
67    pub clean_exit: bool,
68
69    #[arg(
70        short = 'q',
71        long,
72        global = true,
73        help = "Don't return anything to stdout."
74    )]
75    pub quiet: bool,
76
77    #[arg(
78        long,
79        global = true,
80        alias = "nointeraction",
81        help = "Do not prompt for interactive user input."
82    )]
83    pub no_interaction: bool,
84
85    // Clap uses uppercase V for the short flag by default, but we want lowercase v
86    // for compatibility with the node CLI:
87    // https://github.com/clap-rs/clap/issues/138
88    #[arg(short = 'v', long, action = clap::builder::ArgAction::Version)]
89    pub version: (),
90}
91
92#[derive(Subcommand, Clone)]
93pub enum Commands {
94    // Auth commands
95    #[command(about = "Log into a user account.")]
96    Login(LoginArgs),
97
98    #[command(about = "Log out of the current user account.")]
99    Logout,
100
101    #[command(about = "Lock the vault and destroy active session keys.")]
102    Lock(LockArgs),
103
104    // KM commands
105    #[command(about = "Unlock the vault and return a session key.")]
106    Unlock(UnlockArgs),
107
108    // Platform commands
109    #[command(about = "Pull the latest vault data from server.")]
110    Sync(SyncArgs),
111
112    #[command(about = "Base 64 encode stdin.")]
113    Encode(EncodeArgs),
114
115    #[command(about = "Configure CLI settings.")]
116    Config {
117        #[command(subcommand)]
118        command: ConfigCommand,
119    },
120
121    #[command(about = "Check for updates.")]
122    Update {
123        #[arg(long, help = "Return only the download URL for the update.")]
124        raw: bool,
125    },
126
127    #[command(about = "Generate shell completions.")]
128    Completion(CompletionArgs),
129
130    Status(StatusArgs),
131
132    // These are the old style action-name commands, to be replaced by name-action commands in the
133    // future
134    #[command(about = "List an array of objects from the vault.")]
135    List {
136        #[command(subcommand)]
137        command: ListCommands,
138    },
139    #[command(about = "Get an object from the vault.")]
140    Get {
141        #[command(subcommand)]
142        command: GetCommands,
143    },
144    #[command(about = "Create an object in the vault.")]
145    Create {
146        #[command(subcommand)]
147        command: CreateCommands,
148    },
149    #[command(about = "Edit an object from the vault.")]
150    Edit {
151        #[command(subcommand)]
152        command: EditCommands,
153    },
154    #[command(about = "Delete an object from the vault.")]
155    Delete {
156        #[command(subcommand)]
157        command: DeleteCommands,
158    },
159    #[command(about = "Restores an object from the trash.")]
160    Restore(RestoreArgs),
161    #[command(about = "Move an item to an organization.")]
162    Move(MoveArgs),
163
164    // Admin console commands
165    #[command(about = "Confirm an object to the organization.")]
166    Confirm {
167        #[command(subcommand)]
168        command: ConfirmCommand,
169    },
170
171    // Tools commands
172    Generate(GenerateArgs),
173    #[command(about = "Import vault data from a file.")]
174    Import(ImportArgs),
175    #[command(about = "Export vault data to a CSV, JSON or ZIP file.")]
176    Export(ExportArgs),
177    #[command(
178        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."
179    )]
180    Send(SendArgs),
181    #[command(about = "Access a Bitwarden Send from a url.")]
182    Receive(ReceiveArgs),
183
184    // Device approval commands
185    #[command(
186        long_about = "Manage device approval requests sent to organizations that use SSO with trusted devices."
187    )]
188    DeviceApproval,
189
190    // Server commands
191    #[command(about = "Start a RESTful API webserver.")]
192    Serve(ServeArgs),
193}