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

mod.rs (5182B)


      1 pub mod accounts;
      2 mod ciphers;
      3 mod emergency_access;
      4 mod events;
      5 mod folders;
      6 mod organizations;
      7 mod public;
      8 mod sends;
      9 pub mod two_factor;
     10 use crate::config as config_file;
     11 use crate::error::Error;
     12 use crate::util;
     13 pub use ciphers::{CipherData, CipherSyncData, CipherSyncType};
     14 pub fn routes() -> Vec<Route> {
     15     let mut eq_domains_routes = routes![get_eq_domains, post_eq_domains, put_eq_domains];
     16     let mut hibp_routes = routes![hibp_breach];
     17     let mut meta_routes = routes![alive, config, now, version];
     18     let mut routes = Vec::new();
     19     routes.append(&mut accounts::routes());
     20     routes.append(&mut ciphers::routes());
     21     routes.append(&mut emergency_access::routes());
     22     routes.append(&mut eq_domains_routes);
     23     routes.append(&mut events::routes());
     24     routes.append(&mut folders::routes());
     25     routes.append(&mut hibp_routes);
     26     routes.append(&mut meta_routes);
     27     routes.append(&mut organizations::routes());
     28     routes.append(&mut public::routes());
     29     routes.append(&mut sends::routes());
     30     routes.append(&mut two_factor::routes());
     31     routes
     32 }
     33 
     34 pub fn events_routes() -> Vec<Route> {
     35     let mut routes = Vec::new();
     36     routes.append(&mut events::main_routes());
     37     routes
     38 }
     39 
     40 //
     41 // Move this somewhere else
     42 //
     43 use crate::{api::JsonResult, auth::Headers, db::DbConn};
     44 use rocket::{serde::json::Json, Catcher, Route};
     45 use serde_json::Value;
     46 
     47 #[derive(Serialize, Deserialize)]
     48 #[serde(rename_all = "camelCase")]
     49 struct GlobalDomain {
     50     r#type: i32,
     51     domains: Vec<String>,
     52     excluded: bool,
     53 }
     54 
     55 const GLOBAL_DOMAINS: &str = include_str!("../../static/global_domains.json");
     56 
     57 #[get("/settings/domains")]
     58 fn get_eq_domains(headers: Headers) -> Json<Value> {
     59     _get_eq_domains(headers, false)
     60 }
     61 
     62 fn _get_eq_domains(headers: Headers, no_excluded: bool) -> Json<Value> {
     63     let user = headers.user;
     64     use serde_json::from_str;
     65     let equivalent_domains: Vec<Vec<String>> = from_str(&user.equivalent_domains).unwrap();
     66     let excluded_globals: Vec<i32> = from_str(&user.excluded_globals).unwrap();
     67     let mut globals: Vec<GlobalDomain> = from_str(GLOBAL_DOMAINS).unwrap();
     68     for global in &mut globals {
     69         global.excluded = excluded_globals.contains(&global.r#type);
     70     }
     71     if no_excluded {
     72         globals.retain(|g| !g.excluded);
     73     }
     74     Json(json!({
     75         "equivalentDomains": equivalent_domains,
     76         "globalEquivalentDomains": globals,
     77         "object": "domains",
     78     }))
     79 }
     80 
     81 #[derive(Deserialize)]
     82 #[serde(rename_all = "camelCase")]
     83 struct EquivDomainData {
     84     excluded_global_equivalent_domains: Option<Vec<i32>>,
     85     equivalent_domains: Option<Vec<Vec<String>>>,
     86 }
     87 
     88 #[post("/settings/domains", data = "<data>")]
     89 async fn post_eq_domains(
     90     data: Json<EquivDomainData>,
     91     headers: Headers,
     92     conn: DbConn,
     93 ) -> JsonResult {
     94     let data: EquivDomainData = data.into_inner();
     95     let excluded_globals = data.excluded_global_equivalent_domains.unwrap_or_default();
     96     let equivalent_domains = data.equivalent_domains.unwrap_or_default();
     97     let mut user = headers.user;
     98     use serde_json::to_string;
     99     user.excluded_globals = to_string(&excluded_globals).unwrap_or_else(|_| "[]".to_owned());
    100     user.equivalent_domains = to_string(&equivalent_domains).unwrap_or_else(|_| "[]".to_owned());
    101     user.save(&conn).await?;
    102     Ok(Json(json!({})))
    103 }
    104 
    105 #[put("/settings/domains", data = "<data>")]
    106 async fn put_eq_domains(data: Json<EquivDomainData>, headers: Headers, conn: DbConn) -> JsonResult {
    107     post_eq_domains(data, headers, conn).await
    108 }
    109 #[allow(unused_variables)]
    110 #[get("/hibp/breach?<username>")]
    111 fn hibp_breach(username: &str) -> Error {
    112     Error::empty().with_code(404)
    113 }
    114 
    115 #[get("/alive")]
    116 fn alive() -> Json<String> {
    117     now()
    118 }
    119 
    120 #[get("/now")]
    121 pub fn now() -> Json<String> {
    122     Json(util::format_date(&chrono::Utc::now().naive_utc()))
    123 }
    124 
    125 #[get("/version")]
    126 const fn version() -> Json<&'static str> {
    127     Json(crate::VERSION)
    128 }
    129 
    130 #[get("/config")]
    131 fn config() -> Json<Value> {
    132     let domain = &config_file::get_config().domain_url();
    133     Json(json!({
    134         // Note: The clients use this version to handle backwards compatibility concerns
    135         // This means they expect a version that closely matches the Bitwarden server version
    136         // We should make sure that we keep this updated when we support the new server features
    137         "version": "2024.2.0",
    138         "gitHash": "",
    139         "server": {
    140           "name": "Vaultwarden",
    141           "url": "https://github.com/dani-garcia/vaultwarden",
    142         },
    143         "environment": {
    144           "vault": domain,
    145           "api": format!("{domain}/api"),
    146           "identity": format!("{domain}/identity"),
    147           "notifications": "",
    148           "sso": ""
    149         },
    150         "featureStates": {
    151           "flexible-collections-v-1": false,
    152           "key-rotation-improvements": true,
    153         },
    154         "object": "config",
    155     }))
    156 }
    157 
    158 pub fn catchers() -> Vec<Catcher> {
    159     catchers![api_not_found]
    160 }
    161 
    162 #[catch(404)]
    163 fn api_not_found() -> Json<Value> {
    164     Json(json!({
    165         "error": {
    166             "code": 404i32,
    167             "reason": "Not Found",
    168             "description": "The requested resource could not be found."
    169         }
    170     }))
    171 }