|
|
@ -20,8 +20,6 @@ extern crate derive_more; |
|
|
|
#[macro_use] |
|
|
|
extern crate num_derive; |
|
|
|
|
|
|
|
use rocket::{fairing::AdHoc, Rocket}; |
|
|
|
|
|
|
|
use std::{ |
|
|
|
path::Path, |
|
|
|
process::{exit, Command}, |
|
|
@ -40,56 +38,9 @@ mod util; |
|
|
|
pub use config::CONFIG; |
|
|
|
pub use error::{Error, MapResult}; |
|
|
|
|
|
|
|
fn launch_rocket() { |
|
|
|
// Create Rocket object, this stores current log level and sets it's own
|
|
|
|
let rocket = rocket::ignite(); |
|
|
|
|
|
|
|
// If we aren't logging the mounts, we force the logging level down
|
|
|
|
if !CONFIG.log_mounts() { |
|
|
|
log::set_max_level(log::LevelFilter::Warn); |
|
|
|
} |
|
|
|
|
|
|
|
let rocket = rocket |
|
|
|
.mount("/", api::web_routes()) |
|
|
|
.mount("/api", api::core_routes()) |
|
|
|
.mount("/admin", api::admin_routes()) |
|
|
|
.mount("/identity", api::identity_routes()) |
|
|
|
.mount("/icons", api::icons_routes()) |
|
|
|
.mount("/notifications", api::notifications_routes()); |
|
|
|
|
|
|
|
// Force the level up for the fairings, managed state and lauch
|
|
|
|
if !CONFIG.log_mounts() { |
|
|
|
log::set_max_level(log::LevelFilter::max()); |
|
|
|
} |
|
|
|
|
|
|
|
let rocket = rocket |
|
|
|
.manage(db::init_pool()) |
|
|
|
.manage(api::start_notification_server()) |
|
|
|
.attach(util::AppHeaders()) |
|
|
|
.attach(AdHoc::on_launch("Launch Info", launch_info)); |
|
|
|
|
|
|
|
// Launch and print error if there is one
|
|
|
|
// The launch will restore the original logging level
|
|
|
|
error!("Launch error {:#?}", rocket.launch()); |
|
|
|
} |
|
|
|
|
|
|
|
// Embed the migrations from the migrations folder into the application
|
|
|
|
// This way, the program automatically migrates the database to the latest version
|
|
|
|
// https://docs.rs/diesel_migrations/*/diesel_migrations/macro.embed_migrations.html
|
|
|
|
#[allow(unused_imports)] |
|
|
|
mod migrations { |
|
|
|
embed_migrations!(); |
|
|
|
|
|
|
|
pub fn run_migrations() { |
|
|
|
// Make sure the database is up to date (create if it doesn't exist, or run the migrations)
|
|
|
|
let connection = crate::db::get_connection().expect("Can't conect to DB"); |
|
|
|
|
|
|
|
use std::io::stdout; |
|
|
|
embedded_migrations::run_with_output(&connection, &mut stdout()).expect("Can't run migrations"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn main() { |
|
|
|
launch_info(); |
|
|
|
|
|
|
|
if CONFIG.extended_logging() { |
|
|
|
init_logging().ok(); |
|
|
|
} |
|
|
@ -102,6 +53,21 @@ fn main() { |
|
|
|
launch_rocket(); |
|
|
|
} |
|
|
|
|
|
|
|
fn launch_info() { |
|
|
|
println!("/--------------------------------------------------------------------\\"); |
|
|
|
println!("| Starting Bitwarden_RS |"); |
|
|
|
|
|
|
|
if let Some(version) = option_env!("GIT_VERSION") { |
|
|
|
println!("|{:^68}|", format!("Version {}", version)); |
|
|
|
} |
|
|
|
|
|
|
|
println!("|--------------------------------------------------------------------|"); |
|
|
|
println!("| This is an *unofficial* Bitwarden implementation, DO NOT use the |"); |
|
|
|
println!("| official channels to report bugs/features, regardless of client. |"); |
|
|
|
println!("| Report URL: https://github.com/dani-garcia/bitwarden_rs/issues/new |"); |
|
|
|
println!("\\--------------------------------------------------------------------/\n"); |
|
|
|
} |
|
|
|
|
|
|
|
fn init_logging() -> Result<(), fern::InitError> { |
|
|
|
let mut logger = fern::Dispatch::new() |
|
|
|
.format(|out, message, record| { |
|
|
@ -182,49 +148,36 @@ fn check_rsa_keys() { |
|
|
|
if !util::file_exists(&CONFIG.private_rsa_key()) || !util::file_exists(&CONFIG.public_rsa_key()) { |
|
|
|
info!("JWT keys don't exist, checking if OpenSSL is available..."); |
|
|
|
|
|
|
|
Command::new("openssl").arg("version").output().unwrap_or_else(|_| { |
|
|
|
Command::new("openssl").arg("version").status().unwrap_or_else(|_| { |
|
|
|
info!("Can't create keys because OpenSSL is not available, make sure it's installed and available on the PATH"); |
|
|
|
exit(1); |
|
|
|
}); |
|
|
|
|
|
|
|
info!("OpenSSL detected, creating keys..."); |
|
|
|
|
|
|
|
let key = CONFIG.rsa_key_filename(); |
|
|
|
|
|
|
|
let pem = format!("{}.pem", key); |
|
|
|
let priv_der = format!("{}.der", key); |
|
|
|
let pub_der = format!("{}.pub.der", key); |
|
|
|
|
|
|
|
let mut success = Command::new("openssl") |
|
|
|
.arg("genrsa") |
|
|
|
.arg("-out") |
|
|
|
.arg(&CONFIG.private_rsa_key_pem()) |
|
|
|
.output() |
|
|
|
.args(&["genrsa", "-out", &pem]) |
|
|
|
.status() |
|
|
|
.expect("Failed to create private pem file") |
|
|
|
.status |
|
|
|
.success(); |
|
|
|
|
|
|
|
success &= Command::new("openssl") |
|
|
|
.arg("rsa") |
|
|
|
.arg("-in") |
|
|
|
.arg(&CONFIG.private_rsa_key_pem()) |
|
|
|
.arg("-outform") |
|
|
|
.arg("DER") |
|
|
|
.arg("-out") |
|
|
|
.arg(&CONFIG.private_rsa_key()) |
|
|
|
.output() |
|
|
|
.args(&["rsa", "-in", &pem, "-outform", "DER", "-out", &priv_der]) |
|
|
|
.status() |
|
|
|
.expect("Failed to create private der file") |
|
|
|
.status |
|
|
|
.success(); |
|
|
|
|
|
|
|
success &= Command::new("openssl") |
|
|
|
.arg("rsa") |
|
|
|
.arg("-in") |
|
|
|
.arg(&CONFIG.private_rsa_key()) |
|
|
|
.arg("-inform") |
|
|
|
.arg("DER") |
|
|
|
.arg("-RSAPublicKey_out") |
|
|
|
.arg("-outform") |
|
|
|
.arg("DER") |
|
|
|
.arg("-out") |
|
|
|
.arg(&CONFIG.public_rsa_key()) |
|
|
|
.output() |
|
|
|
.args(&["rsa", "-in", &priv_der, "-inform", "DER"]) |
|
|
|
.args(&["-RSAPublicKey_out", "-outform", "DER", "-out", &pub_der]) |
|
|
|
.status() |
|
|
|
.expect("Failed to create public der file") |
|
|
|
.status |
|
|
|
.success(); |
|
|
|
|
|
|
|
if success { |
|
|
@ -249,20 +202,50 @@ fn check_web_vault() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn launch_info(_: &Rocket) { |
|
|
|
// Remove the target to keep the message more centered
|
|
|
|
macro_rules! w {( $l:literal $(,$e:expr)* ) => {warn!(target: "", $l, $($e),* )}} |
|
|
|
// Embed the migrations from the migrations folder into the application
|
|
|
|
// This way, the program automatically migrates the database to the latest version
|
|
|
|
// https://docs.rs/diesel_migrations/*/diesel_migrations/macro.embed_migrations.html
|
|
|
|
#[allow(unused_imports)] |
|
|
|
mod migrations { |
|
|
|
embed_migrations!(); |
|
|
|
|
|
|
|
w!("/--------------------------------------------------------------------\\"); |
|
|
|
w!("| Starting Bitwarden_RS |"); |
|
|
|
pub fn run_migrations() { |
|
|
|
// Make sure the database is up to date (create if it doesn't exist, or run the migrations)
|
|
|
|
let connection = crate::db::get_connection().expect("Can't conect to DB"); |
|
|
|
|
|
|
|
if let Some(version) = option_env!("GIT_VERSION") { |
|
|
|
w!("|{:^68}|", format!("Version {}", version)); |
|
|
|
use std::io::stdout; |
|
|
|
embedded_migrations::run_with_output(&connection, &mut stdout()).expect("Can't run migrations"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn launch_rocket() { |
|
|
|
// Create Rocket object, this stores current log level and sets it's own
|
|
|
|
let rocket = rocket::ignite(); |
|
|
|
|
|
|
|
w!("|--------------------------------------------------------------------|"); |
|
|
|
w!("| This is an *unofficial* Bitwarden implementation, DO NOT use the |"); |
|
|
|
w!("| official channels to report bugs/features, regardless of client. |"); |
|
|
|
w!("| Report URL: https://github.com/dani-garcia/bitwarden_rs/issues/new |"); |
|
|
|
w!("\\--------------------------------------------------------------------/"); |
|
|
|
// If we aren't logging the mounts, we force the logging level down
|
|
|
|
if !CONFIG.log_mounts() { |
|
|
|
log::set_max_level(log::LevelFilter::Warn); |
|
|
|
} |
|
|
|
|
|
|
|
let rocket = rocket |
|
|
|
.mount("/", api::web_routes()) |
|
|
|
.mount("/api", api::core_routes()) |
|
|
|
.mount("/admin", api::admin_routes()) |
|
|
|
.mount("/identity", api::identity_routes()) |
|
|
|
.mount("/icons", api::icons_routes()) |
|
|
|
.mount("/notifications", api::notifications_routes()); |
|
|
|
|
|
|
|
// Force the level up for the fairings, managed state and lauch
|
|
|
|
if !CONFIG.log_mounts() { |
|
|
|
log::set_max_level(log::LevelFilter::max()); |
|
|
|
} |
|
|
|
|
|
|
|
let rocket = rocket |
|
|
|
.manage(db::init_pool()) |
|
|
|
.manage(api::start_notification_server()) |
|
|
|
.attach(util::AppHeaders()); |
|
|
|
|
|
|
|
// Launch and print error if there is one
|
|
|
|
// The launch will restore the original logging level
|
|
|
|
error!("Launch error {:#?}", rocket.launch()); |
|
|
|
} |
|
|
|