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 (4194B)


      1 use crate::{
      2     api::{JsonResult, PasswordOrOtpData},
      3     auth::{ClientHeaders, Headers},
      4     db::{
      5         models::{OrgPolicyType, TwoFactorType, UserOrgType, UserOrganization},
      6         DbConn,
      7     },
      8     util::NumberOrString,
      9 };
     10 pub mod authenticator;
     11 mod duo;
     12 mod email;
     13 mod protected_actions;
     14 use rocket::serde::json::Json;
     15 use rocket::Route;
     16 use serde_json::Value;
     17 pub mod webauthn;
     18 mod yubikey;
     19 
     20 pub fn routes() -> Vec<Route> {
     21     let mut routes = routes![
     22         disable_twofactor,
     23         disable_twofactor_put,
     24         get_device_verification_settings,
     25         get_recover,
     26         get_twofactor,
     27         recover,
     28     ];
     29     routes.append(&mut authenticator::routes());
     30     routes.append(&mut duo::routes());
     31     routes.append(&mut email::routes());
     32     routes.append(&mut protected_actions::routes());
     33     routes.append(&mut webauthn::routes());
     34     routes.append(&mut yubikey::routes());
     35     routes
     36 }
     37 
     38 #[get("/two-factor")]
     39 async fn get_twofactor(headers: Headers, conn: DbConn) -> Json<Value> {
     40     Json(json!({
     41         "data": TwoFactorType::get_factors(&headers.user.uuid, &conn).await.expect("unable to get two factors"),
     42         "object": "list",
     43         "continuationToken": null,
     44     }))
     45 }
     46 
     47 #[allow(unused_variables, clippy::needless_pass_by_value)]
     48 #[post("/two-factor/get-recover", data = "<data>")]
     49 fn get_recover(data: Json<PasswordOrOtpData>, _headers: Headers) -> JsonResult {
     50     err!("recovery codes are disabled")
     51 }
     52 
     53 #[derive(Deserialize)]
     54 #[serde(rename_all = "camelCase")]
     55 struct RecoverTwoFactor {
     56     #[allow(dead_code)]
     57     master_password_hash: String,
     58     #[allow(dead_code)]
     59     email: String,
     60     #[allow(dead_code)]
     61     recovery_code: String,
     62 }
     63 
     64 #[allow(unused_variables, clippy::needless_pass_by_value)]
     65 #[post("/two-factor/recover", data = "<data>")]
     66 fn recover(data: Json<RecoverTwoFactor>, _client_headers: ClientHeaders) -> JsonResult {
     67     err!("recovery codes are disabled")
     68 }
     69 
     70 #[derive(Deserialize)]
     71 #[serde(rename_all = "camelCase")]
     72 struct DisableTwoFactorData {
     73     master_password_hash: Option<String>,
     74     otp: Option<String>,
     75     r#type: NumberOrString,
     76 }
     77 
     78 #[post("/two-factor/disable", data = "<data>")]
     79 async fn disable_twofactor(
     80     data: Json<DisableTwoFactorData>,
     81     headers: Headers,
     82     conn: DbConn,
     83 ) -> JsonResult {
     84     let data: DisableTwoFactorData = data.into_inner();
     85     let user = headers.user;
     86     // Delete directly after a valid token has been provided
     87     PasswordOrOtpData {
     88         master_password_hash: data.master_password_hash,
     89         otp: data.otp,
     90     }
     91     .validate(&user)?;
     92     let type_ = data.r#type.into_i32()?;
     93     TwoFactorType::try_from(type_)?
     94         .delete_by_user(&user.uuid, &conn)
     95         .await?;
     96     if !TwoFactorType::has_twofactor(&user.uuid, &conn).await? {
     97         for user_org in UserOrganization::find_by_user_and_policy(
     98             &user.uuid,
     99             OrgPolicyType::TwoFactorAuthentication,
    100             &conn,
    101         )
    102         .await
    103         {
    104             if user_org.atype < UserOrgType::Admin {
    105                 user_org.delete(&conn).await?;
    106             }
    107         }
    108     }
    109     Ok(Json(json!({
    110         "enabled": false,
    111         "type": type_,
    112         "object": "twoFactorProvider"
    113     })))
    114 }
    115 
    116 #[put("/two-factor/disable", data = "<data>")]
    117 async fn disable_twofactor_put(
    118     data: Json<DisableTwoFactorData>,
    119     headers: Headers,
    120     conn: DbConn,
    121 ) -> JsonResult {
    122     disable_twofactor(data, headers, conn).await
    123 }
    124 
    125 // This function currently is just a dummy and the actual part is not implemented yet.
    126 // This also prevents 404 errors.
    127 //
    128 // See the following Bitwarden PR's regarding this feature.
    129 // https://github.com/bitwarden/clients/pull/2843
    130 // https://github.com/bitwarden/clients/pull/2839
    131 // https://github.com/bitwarden/server/pull/2016
    132 //
    133 // The HTML part is hidden via the CSS patches done via the bw_web_build repo
    134 #[allow(clippy::needless_pass_by_value)]
    135 #[get("/two-factor/get-device-verification-settings")]
    136 fn get_device_verification_settings(_headers: Headers) -> Json<Value> {
    137     Json(json!({
    138         "isDeviceVerificationSectionEnabled":false,
    139         "unknownDeviceVerificationEnabled":false,
    140         "object":"deviceVerificationSettings"
    141     }))
    142 }