vw_small

Hardened fork of Vaultwarden (https://github.com/dani-garcia/vaultwarden) with fewer features.
git clone https://git.philomathiclife.com/repos/vw_small
Log | Files | Refs | README

main.rs (5411B)


      1 #![deny(
      2     unknown_lints,
      3     future_incompatible,
      4     let_underscore,
      5     nonstandard_style,
      6     refining_impl_trait,
      7     rust_2018_compatibility,
      8     rust_2018_idioms,
      9     rust_2021_compatibility,
     10     rust_2024_compatibility,
     11     unsafe_code,
     12     unused,
     13     warnings,
     14     clippy::all,
     15     clippy::cargo,
     16     clippy::complexity,
     17     clippy::correctness,
     18     clippy::nursery,
     19     clippy::pedantic,
     20     clippy::perf,
     21     clippy::restriction,
     22     clippy::style,
     23     clippy::suspicious
     24 )]
     25 #![allow(
     26     clippy::blanket_clippy_restriction_lints,
     27     clippy::doc_markdown,
     28     clippy::expect_used,
     29     clippy::if_then_some_else_none,
     30     clippy::implicit_return,
     31     clippy::indexing_slicing,
     32     clippy::items_after_statements,
     33     clippy::min_ident_chars,
     34     clippy::missing_docs_in_private_items,
     35     clippy::missing_errors_doc,
     36     clippy::missing_trait_methods,
     37     clippy::mod_module_files,
     38     clippy::module_name_repetitions,
     39     clippy::multiple_crate_versions,
     40     clippy::multiple_inherent_impl,
     41     clippy::multiple_unsafe_ops_per_block,
     42     clippy::no_effect_underscore_binding,
     43     clippy::panic,
     44     clippy::panic_in_result_fn,
     45     clippy::partial_pub_fields,
     46     clippy::pub_use,
     47     clippy::question_mark_used,
     48     clippy::redundant_type_annotations,
     49     clippy::ref_patterns,
     50     clippy::shadow_reuse,
     51     clippy::significant_drop_in_scrutinee,
     52     clippy::significant_drop_tightening,
     53     clippy::single_call_fn,
     54     clippy::single_char_lifetime_names,
     55     clippy::std_instead_of_alloc,
     56     clippy::std_instead_of_core,
     57     clippy::too_many_lines,
     58     clippy::unreachable,
     59     clippy::unseparated_literal_suffix,
     60     clippy::unwrap_in_result,
     61     clippy::unwrap_used,
     62     clippy::used_underscore_binding
     63 )]
     64 // The recursion_limit is mainly triggered by the json!() macro.
     65 // The more key/value pairs there are the more recursion occurs.
     66 // We want to keep this as low as possible, but not higher then 128.
     67 // If you go above 128 it will cause rust-analyzer to fail,
     68 #![recursion_limit = "206"]
     69 #[macro_use]
     70 extern crate diesel;
     71 #[macro_use]
     72 mod error;
     73 #[macro_use]
     74 extern crate rocket;
     75 #[macro_use]
     76 extern crate serde;
     77 #[macro_use]
     78 extern crate serde_json;
     79 mod api;
     80 mod auth;
     81 mod config;
     82 mod crypto;
     83 mod db;
     84 mod priv_sep;
     85 mod util;
     86 use config::Config;
     87 pub use error::{Error, MapResult};
     88 use std::env;
     89 use std::{path::Path, process};
     90 use tokio::runtime::Builder;
     91 use tokio::signal;
     92 pub const VERSION: &str = env!("CARGO_PKG_VERSION");
     93 
     94 fn main() -> Result<(), Error> {
     95     let mut promises = priv_sep::pledge_init()?;
     96     priv_sep::unveil_read(env::current_dir()?)?;
     97     static_init();
     98     check_data_folder();
     99     check_web_vault();
    100     Builder::new_multi_thread()
    101         .enable_all()
    102         .build()
    103         .map_or_else(
    104             |e| Err(Error::from(e)),
    105             |runtime| {
    106                 runtime.block_on(async {
    107                     config::get_config()
    108                         .rocket
    109                         .tls
    110                         .as_ref()
    111                         .map_or(Ok(()), |tls| {
    112                             tls.certs().left().map_or(Ok(()), |certs| {
    113                                 priv_sep::unveil_read(certs).and_then(|()| {
    114                                     tls.key().left().map_or(Ok(()), priv_sep::unveil_read)
    115                                 })
    116                             })
    117                         })?;
    118                     priv_sep::pledge_away_unveil(&mut promises)?;
    119                     launch_rocket(create_db_pool().await).await
    120                 })
    121             },
    122         )
    123 }
    124 #[inline]
    125 fn static_init() {
    126     config::init_config();
    127     priv_sep::unveil_create_read_write(Config::DATA_FOLDER).unwrap_or_else(|_| {
    128         panic!(
    129             "unable to unveil(2) {} with create, read, and write permissions",
    130             Config::DATA_FOLDER
    131         )
    132     });
    133     auth::init_values();
    134 }
    135 
    136 #[allow(clippy::exit)]
    137 fn check_data_folder() {
    138     if !Path::new(Config::DATA_FOLDER).is_dir() {
    139         process::exit(1);
    140     }
    141 }
    142 #[allow(clippy::exit)]
    143 fn check_web_vault() {
    144     if config::get_config().web_vault_enabled
    145         && !Path::new(Config::WEB_VAULT_FOLDER)
    146             .join("index.html")
    147             .exists()
    148     {
    149         process::exit(1);
    150     }
    151 }
    152 #[allow(clippy::exit)]
    153 async fn create_db_pool() -> db::DbPool {
    154     (util::retry_db(
    155         db::DbPool::from_config,
    156         u32::from(config::get_config().db_connection_retries.get()),
    157     )
    158     .await)
    159         .unwrap_or_else(|_| {
    160             process::exit(1);
    161         })
    162 }
    163 
    164 async fn launch_rocket(pool: db::DbPool) -> Result<(), Error> {
    165     let instance = rocket::custom(&config::get_config().rocket)
    166         .mount("/", api::web_routes())
    167         .mount("/admin", api::admin_routes())
    168         .mount("/api", api::core_routes())
    169         .mount("/events", api::core_events_routes())
    170         .mount("/icons", api::icons_routes())
    171         .mount("/identity", api::identity_routes())
    172         .register("/", api::web_catchers())
    173         .register("/admin", api::admin_catchers())
    174         .register("/api", api::core_catchers())
    175         .manage(pool)
    176         .attach(util::AppHeaders)
    177         .attach(util::Cors)
    178         .ignite()
    179         .await?;
    180     let shutdown = instance.shutdown();
    181     tokio::spawn(async move {
    182         signal::ctrl_c()
    183             .await
    184             .expect("Error setting Ctrl-C handler");
    185         shutdown.notify();
    186     });
    187     instance.launch().await?;
    188     Ok(())
    189 }