1#![doc = include_str!("../README.md")]
2
3use base64::{Engine, engine::general_purpose::STANDARD};
4use bitwarden_cli::install_color_eyre;
5use clap::{CommandFactory, Parser};
6use clap_complete::Shell;
7use color_eyre::eyre::Result;
8use tracing_subscriber::{
9 EnvFilter, prelude::__tracing_subscriber_SubscriberExt as _, util::SubscriberInitExt as _,
10};
11
12use crate::{command::*, render::CommandResult};
13
14mod admin_console;
15mod auth;
16mod command;
17mod key_management;
18mod platform;
19mod render;
20mod tools;
21mod vault;
22
23#[tokio::main(flavor = "current_thread")]
24async fn main() -> Result<()> {
25 let filter = EnvFilter::builder()
30 .with_default_directive(
31 option_env!("RUST_LOG")
32 .unwrap_or("info")
33 .parse()
34 .expect("should provide valid log level at compile time."),
35 )
36 .from_env_lossy();
39
40 tracing_subscriber::registry()
41 .with(tracing_subscriber::fmt::layer().with_writer(std::io::stderr))
42 .with(filter)
43 .init();
44
45 let cli = Cli::parse();
46 install_color_eyre(cli.color)?;
47 let render_config = render::RenderConfig::new(&cli);
48
49 let Some(command) = cli.command else {
50 let mut cmd = Cli::command();
51 cmd.print_help()?;
52 return Ok(());
53 };
54
55 let result = process_commands(command, cli.session).await;
56
57 render_config.render_result(result)
59}
60
61async fn process_commands(command: Commands, _session: Option<String>) -> CommandResult {
62 let client = bitwarden_pm::PasswordManagerClient::new(None);
73
74 match command {
75 Commands::Login(args) => args.run().await,
77 Commands::Logout => todo!(),
78
79 Commands::Lock => todo!(),
81 Commands::Unlock(_args) => todo!(),
82
83 Commands::Sync { .. } => todo!(),
85
86 Commands::Encode => {
87 let input = std::io::read_to_string(std::io::stdin())?;
88 let encoded = STANDARD.encode(input);
89 Ok(encoded.into())
90 }
91
92 Commands::Config { command } => command.run().await,
93
94 Commands::Update { .. } => todo!(),
95
96 Commands::Completion { shell } => {
97 let Some(shell) = shell.or_else(Shell::from_env) else {
98 return Ok(
99 "Couldn't autodetect a valid shell. Run `bw completion --help` for more info."
100 .into(),
101 );
102 };
103
104 let mut cmd = Cli::command();
105 let name = cmd.get_name().to_string();
106 clap_complete::generate(shell, &mut cmd, name, &mut std::io::stdout());
107 Ok(().into())
108 }
109
110 Commands::Status => todo!(),
111
112 Commands::List(_args) => todo!(),
114 Commands::Get { command } => match command {
115 GetCommands::Template { command } => command.run(),
116 _ => todo!("Get command implementation with {:?}", command),
117 },
118 Commands::Create { .. } => todo!(),
119 Commands::Edit(_args) => todo!(),
120 Commands::Delete { .. } => todo!(),
121 Commands::Restore(_args) => todo!(),
122
123 Commands::Confirm { .. } => todo!(),
125 Commands::DeviceApproval => todo!(),
126 Commands::Move(_args) => todo!(),
127
128 Commands::Generate(arg) => arg.run(&client),
130 Commands::Import(_args) => todo!(),
131 Commands::Export(_args) => todo!(),
132 Commands::Send(_args) => todo!(),
133 Commands::Receive(_args) => todo!(),
134
135 Commands::Serve(_args) => todo!(),
137 }
138}