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 }