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