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', global = true, value_enum, default_value_t = Output::JSON)]
47    pub output: Output,
48
49    /// Color
50    #[arg(short = 'c', long, global = true, value_enum, default_value_t = Color::Auto)]
51    pub color: Color,
52
53    // TODO(CLI): Pretty/raw/response options
54    #[arg(
55        long,
56        global = true,
57        env = SESSION_ENV,
58        help = "The session key used to decrypt your vault data. Can be obtained with `bw login` or `bw unlock`."
59    )]
60    pub session: Option<String>,
61
62    #[arg(
63        long,
64        global = true,
65        alias = "cleanexit",
66        help = "Exit with a success exit code (0) unless an error is thrown."
67    )]
68    pub clean_exit: bool,
69
70    #[arg(
71        short = 'q',
72        long,
73        global = true,
74        help = "Don't return anything to stdout."
75    )]
76    pub quiet: bool,
77
78    #[arg(
79        long,
80        global = true,
81        alias = "nointeraction",
82        help = "Do not prompt for interactive user input."
83    )]
84    pub no_interaction: bool,
85
86    // Clap uses uppercase V for the short flag by default, but we want lowercase v
87    // for compatibility with the node CLI:
88    // https://github.com/clap-rs/clap/issues/138
89    #[arg(short = 'v', long, action = clap::builder::ArgAction::Version)]
90    pub version: (),
91}
92
93#[derive(Subcommand, Clone)]
94pub enum Commands {
95    // Auth commands
96    #[command(about = "Log into a user account.")]
97    Login(LoginArgs),
98
99    #[command(about = "Log out of the current user account.")]
100    Logout,
101
102    #[command(about = "Lock the vault and destroy active session keys.")]
103    Lock(LockArgs),
104
105    // KM commands
106    #[command(about = "Unlock the vault and return a session key.")]
107    Unlock(UnlockArgs),
108
109    // Platform commands
110    #[command(about = "Pull the latest vault data from server.")]
111    Sync(SyncArgs),
112
113    #[command(about = "Base 64 encode stdin.")]
114    Encode(EncodeArgs),
115
116    #[command(about = "Configure CLI settings.")]
117    Config {
118        #[command(subcommand)]
119        command: ConfigCommand,
120    },
121
122    #[command(about = "Check for updates.")]
123    Update {
124        #[arg(long, help = "Return only the download URL for the update.")]
125        raw: bool,
126    },
127
128    #[command(about = "Generate shell completions.")]
129    Completion(CompletionArgs),
130
131    Status(StatusArgs),
132
133    // These are the old style action-name commands, to be replaced by name-action commands in the
134    // future
135    #[command(about = "List an array of objects from the vault.")]
136    List {
137        #[command(subcommand)]
138        command: ListCommands,
139    },
140    #[command(about = "Get an object from the vault.")]
141    Get {
142        #[command(subcommand)]
143        command: GetCommands,
144    },
145    #[command(about = "Create an object in the vault.")]
146    Create {
147        #[command(subcommand)]
148        command: CreateCommands,
149    },
150    #[command(about = "Edit an object from the vault.")]
151    Edit {
152        #[command(subcommand)]
153        command: EditCommands,
154    },
155    #[command(about = "Delete an object from the vault.")]
156    Delete {
157        #[command(subcommand)]
158        command: DeleteCommands,
159    },
160    #[command(about = "Restores an object from the trash.")]
161    Restore(RestoreArgs),
162    #[command(about = "Move an item to an organization.")]
163    Move(MoveArgs),
164
165    // Admin console commands
166    #[command(about = "Confirm an object to the organization.")]
167    Confirm {
168        #[command(subcommand)]
169        command: ConfirmCommand,
170    },
171
172    // Tools commands
173    Generate(GenerateArgs),
174    #[command(about = "Import vault data from a file.")]
175    Import(ImportArgs),
176    #[command(about = "Export vault data to a CSV, JSON or ZIP file.")]
177    Export(ExportArgs),
178    #[command(
179        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."
180    )]
181    Send(SendArgs),
182    #[command(about = "Access a Bitwarden Send from a url.")]
183    Receive(ReceiveArgs),
184
185    // Device approval commands
186    #[command(
187        long_about = "Manage device approval requests sent to organizations that use SSO with trusted devices."
188    )]
189    DeviceApproval,
190
191    // Server commands
192    #[command(about = "Start a RESTful API webserver.")]
193    Serve(ServeArgs),
194}