From c259a0e3e23800347ed90b4a192b44798c3513fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Tue, 15 Jan 2019 21:38:21 +0100 Subject: [PATCH] Save recovery code when using yubikey and stop repeating headers.user everywhere --- src/api/core/two_factor.rs | 58 ++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/src/api/core/two_factor.rs b/src/api/core/two_factor.rs index 5aeb1b16..15dcac8a 100644 --- a/src/api/core/two_factor.rs +++ b/src/api/core/two_factor.rs @@ -50,13 +50,14 @@ fn get_twofactor(headers: Headers, conn: DbConn) -> JsonResult { #[post("/two-factor/get-recover", data = "")] fn get_recover(data: JsonUpcase, headers: Headers) -> JsonResult { let data: PasswordData = data.into_inner().data; + let user = headers.user; - if !headers.user.check_valid_password(&data.MasterPasswordHash) { + if !user.check_valid_password(&data.MasterPasswordHash) { err!("Invalid password"); } Ok(Json(json!({ - "Code": headers.user.totp_recover, + "Code": user.totp_recover, "Object": "twoFactorRecover" }))) } @@ -113,14 +114,15 @@ struct DisableTwoFactorData { fn disable_twofactor(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { let data: DisableTwoFactorData = data.into_inner().data; let password_hash = data.MasterPasswordHash; + let user = headers.user; - if !headers.user.check_valid_password(&password_hash) { + if !user.check_valid_password(&password_hash) { err!("Invalid password"); } let type_ = data.Type.into_i32().expect("Invalid type"); - if let Some(twofactor) = TwoFactor::find_by_user_and_type(&headers.user.uuid, type_, &conn) { + if let Some(twofactor) = TwoFactor::find_by_user_and_type(&user.uuid, type_, &conn) { twofactor.delete(&conn).expect("Error deleting twofactor"); } @@ -139,13 +141,14 @@ fn disable_twofactor_put(data: JsonUpcase, headers: Header #[post("/two-factor/get-authenticator", data = "")] fn generate_authenticator(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { let data: PasswordData = data.into_inner().data; + let user = headers.user; - if !headers.user.check_valid_password(&data.MasterPasswordHash) { + if !user.check_valid_password(&data.MasterPasswordHash) { err!("Invalid password"); } let type_ = TwoFactorType::Authenticator as i32; - let twofactor = TwoFactor::find_by_user_and_type(&headers.user.uuid, type_, &conn); + let twofactor = TwoFactor::find_by_user_and_type(&user.uuid, type_, &conn); let (enabled, key) = match twofactor { Some(tf) => (true, tf.data), @@ -176,8 +179,10 @@ fn activate_authenticator(data: JsonUpcase, headers: He Some(n) => n as u64, None => err!("Malformed token"), }; + + let mut user = headers.user; - if !headers.user.check_valid_password(&password_hash) { + if !user.check_valid_password(&password_hash) { err!("Invalid password"); } @@ -192,14 +197,13 @@ fn activate_authenticator(data: JsonUpcase, headers: He } let type_ = TwoFactorType::Authenticator; - let twofactor = TwoFactor::new(headers.user.uuid.clone(), type_, key.to_uppercase()); + let twofactor = TwoFactor::new(user.uuid.clone(), type_, key.to_uppercase()); // Validate the token provided with the key if !twofactor.check_totp_code(token) { err!("Invalid totp code") } - let mut user = headers.user; _generate_recover_code(&mut user, &conn); twofactor.save(&conn).expect("Error saving twofactor"); @@ -243,15 +247,14 @@ fn generate_u2f(data: JsonUpcase, headers: Headers, conn: DbConn) } let data: PasswordData = data.into_inner().data; + let user = headers.user; - if !headers.user.check_valid_password(&data.MasterPasswordHash) { + if !user.check_valid_password(&data.MasterPasswordHash) { err!("Invalid password"); } - let user_uuid = &headers.user.uuid; - let u2f_type = TwoFactorType::U2f as i32; - let enabled = TwoFactor::find_by_user_and_type(user_uuid, u2f_type, &conn).is_some(); + let enabled = TwoFactor::find_by_user_and_type(&user.uuid, u2f_type, &conn).is_some(); Ok(Json(json!({ "Enabled": enabled, @@ -262,17 +265,18 @@ fn generate_u2f(data: JsonUpcase, headers: Headers, conn: DbConn) #[post("/two-factor/get-u2f-challenge", data = "")] fn generate_u2f_challenge(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { let data: PasswordData = data.into_inner().data; + let user = headers.user; - if !headers.user.check_valid_password(&data.MasterPasswordHash) { + if !user.check_valid_password(&data.MasterPasswordHash) { err!("Invalid password"); } - let user_uuid = &headers.user.uuid; + let user_uuid = &user.uuid; let challenge = _create_u2f_challenge(user_uuid, TwoFactorType::U2fRegisterChallenge, &conn).challenge; Ok(Json(json!({ - "UserId": headers.user.uuid, + "UserId": user.uuid, "AppId": APP_ID.to_string(), "Challenge": challenge, "Version": U2F_VERSION, @@ -311,13 +315,14 @@ impl RegisterResponseCopy { #[post("/two-factor/u2f", data = "")] fn activate_u2f(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { let data: EnableU2FData = data.into_inner().data; + let mut user = headers.user; - if !headers.user.check_valid_password(&data.MasterPasswordHash) { + if !user.check_valid_password(&data.MasterPasswordHash) { err!("Invalid password"); } let tf_challenge = - TwoFactor::find_by_user_and_type(&headers.user.uuid, TwoFactorType::U2fRegisterChallenge as i32, &conn); + TwoFactor::find_by_user_and_type(&user.uuid, TwoFactorType::U2fRegisterChallenge as i32, &conn); if let Some(tf_challenge) = tf_challenge { let challenge: Challenge = serde_json::from_str(&tf_challenge.data)?; @@ -343,13 +348,12 @@ fn activate_u2f(data: JsonUpcase, headers: Headers, conn: DbConn) registrations.push(registration); let tf_registration = TwoFactor::new( - headers.user.uuid.clone(), + user.uuid.clone(), TwoFactorType::U2f, serde_json::to_string(®istrations).unwrap(), ); tf_registration.save(&conn)?; - let mut user = headers.user; _generate_recover_code(&mut user, &conn); Ok(Json(json!({ @@ -552,12 +556,13 @@ fn generate_yubikey(data: JsonUpcase, headers: Headers, conn: DbCo } let data: PasswordData = data.into_inner().data; + let user = headers.user; - if !headers.user.check_valid_password(&data.MasterPasswordHash) { + if !user.check_valid_password(&data.MasterPasswordHash) { err!("Invalid password"); } - let user_uuid = &headers.user.uuid; + let user_uuid = &user.uuid; let yubikey_type = TwoFactorType::YubiKey as i32; let r = TwoFactor::find_by_user_and_type(user_uuid, yubikey_type, &conn); @@ -583,13 +588,14 @@ fn generate_yubikey(data: JsonUpcase, headers: Headers, conn: DbCo #[post("/two-factor/yubikey", data = "")] fn activate_yubikey(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { let data: EnableYubikeyData = data.into_inner().data; + let mut user = headers.user; - if !headers.user.check_valid_password(&data.MasterPasswordHash) { + if !user.check_valid_password(&data.MasterPasswordHash) { err!("Invalid password"); } // Check if we already have some data - let yubikey_data = TwoFactor::find_by_user_and_type(&headers.user.uuid, TwoFactorType::YubiKey as i32, &conn); + let yubikey_data = TwoFactor::find_by_user_and_type(&user.uuid, TwoFactorType::YubiKey as i32, &conn); if let Some(yubikey_data) = yubikey_data { yubikey_data.delete(&conn)?; @@ -626,11 +632,13 @@ fn activate_yubikey(data: JsonUpcase, headers: Headers, conn: }; let yubikey_registration = TwoFactor::new( - headers.user.uuid.clone(), + user.uuid.clone(), TwoFactorType::YubiKey, serde_json::to_string(&yubikey_metadata).unwrap(), ); yubikey_registration.save(&conn)?; + + _generate_recover_code(&mut user, &conn); let mut result = jsonify_yubikeys(yubikey_metadata.Keys);