|
|
@ -9,7 +9,6 @@ use rocket::{ |
|
|
|
}; |
|
|
|
use serde_json::Value; |
|
|
|
|
|
|
|
use crate::api::core::two_factor::webauthn::Webauthn2FaConfig; |
|
|
|
use crate::{ |
|
|
|
api::{ |
|
|
|
core::{ |
|
|
@ -49,7 +48,6 @@ async fn login( |
|
|
|
data: Form<ConnectData>, |
|
|
|
client_header: ClientHeaders, |
|
|
|
client_version: Option<ClientVersion>, |
|
|
|
webauthn: Webauthn2FaConfig<'_>, |
|
|
|
mut conn: DbConn, |
|
|
|
) -> JsonResult { |
|
|
|
let data: ConnectData = data.into_inner(); |
|
|
@ -72,7 +70,7 @@ async fn login( |
|
|
|
_check_is_some(&data.device_name, "device_name cannot be blank")?; |
|
|
|
_check_is_some(&data.device_type, "device_type cannot be blank")?; |
|
|
|
|
|
|
|
_password_login(data, &mut user_id, &mut conn, &client_header.ip, &client_version, webauthn).await |
|
|
|
_password_login(data, &mut user_id, &mut conn, &client_header.ip, &client_version).await |
|
|
|
} |
|
|
|
"client_credentials" => { |
|
|
|
_check_is_some(&data.client_id, "client_id cannot be blank")?; |
|
|
@ -93,7 +91,7 @@ async fn login( |
|
|
|
_check_is_some(&data.device_name, "device_name cannot be blank")?; |
|
|
|
_check_is_some(&data.device_type, "device_type cannot be blank")?; |
|
|
|
|
|
|
|
_sso_login(data, &mut user_id, &mut conn, &client_header.ip, &client_version, webauthn).await |
|
|
|
_sso_login(data, &mut user_id, &mut conn, &client_header.ip, &client_version).await |
|
|
|
} |
|
|
|
"authorization_code" => err!("SSO sign-in is not available"), |
|
|
|
t => err!("Invalid type", t), |
|
|
@ -171,7 +169,6 @@ async fn _sso_login( |
|
|
|
conn: &mut DbConn, |
|
|
|
ip: &ClientIp, |
|
|
|
client_version: &Option<ClientVersion>, |
|
|
|
webauthn: Webauthn2FaConfig<'_>, |
|
|
|
) -> JsonResult { |
|
|
|
AuthMethod::Sso.check_scope(data.scope.as_ref())?; |
|
|
|
|
|
|
@ -270,7 +267,7 @@ async fn _sso_login( |
|
|
|
} |
|
|
|
Some((mut user, sso_user)) => { |
|
|
|
let mut device = get_device(&data, conn, &user).await?; |
|
|
|
let twofactor_token = twofactor_auth(&user, &data, &mut device, ip, client_version, webauthn, conn).await?; |
|
|
|
let twofactor_token = twofactor_auth(&user, &data, &mut device, ip, client_version, conn).await?; |
|
|
|
|
|
|
|
if user.private_key.is_none() { |
|
|
|
// User was invited a stub was created
|
|
|
@ -325,7 +322,6 @@ async fn _password_login( |
|
|
|
conn: &mut DbConn, |
|
|
|
ip: &ClientIp, |
|
|
|
client_version: &Option<ClientVersion>, |
|
|
|
webauthn: Webauthn2FaConfig<'_>, |
|
|
|
) -> JsonResult { |
|
|
|
// Validate scope
|
|
|
|
AuthMethod::Password.check_scope(data.scope.as_ref())?; |
|
|
@ -435,7 +431,7 @@ async fn _password_login( |
|
|
|
|
|
|
|
let mut device = get_device(&data, conn, &user).await?; |
|
|
|
|
|
|
|
let twofactor_token = twofactor_auth(&user, &data, &mut device, ip, client_version, webauthn, conn).await?; |
|
|
|
let twofactor_token = twofactor_auth(&user, &data, &mut device, ip, client_version, conn).await?; |
|
|
|
|
|
|
|
let auth_tokens = auth::AuthTokens::new(&device, &user, AuthMethod::Password, data.client_id); |
|
|
|
|
|
|
@ -668,7 +664,6 @@ async fn twofactor_auth( |
|
|
|
device: &mut Device, |
|
|
|
ip: &ClientIp, |
|
|
|
client_version: &Option<ClientVersion>, |
|
|
|
webauthn: Webauthn2FaConfig<'_>, |
|
|
|
conn: &mut DbConn, |
|
|
|
) -> ApiResult<Option<String>> { |
|
|
|
let twofactors = TwoFactor::find_by_user(&user.uuid, conn).await; |
|
|
@ -688,7 +683,7 @@ async fn twofactor_auth( |
|
|
|
Some(ref code) => code, |
|
|
|
None => { |
|
|
|
err_json!( |
|
|
|
_json_err_twofactor(&twofactor_ids, &user.uuid, data, client_version, webauthn, conn).await?, |
|
|
|
_json_err_twofactor(&twofactor_ids, &user.uuid, data, client_version, conn).await?, |
|
|
|
"2FA token not provided" |
|
|
|
) |
|
|
|
} |
|
|
@ -705,9 +700,7 @@ async fn twofactor_auth( |
|
|
|
Some(TwoFactorType::Authenticator) => { |
|
|
|
authenticator::validate_totp_code_str(&user.uuid, twofactor_code, &selected_data?, ip, conn).await? |
|
|
|
} |
|
|
|
Some(TwoFactorType::Webauthn) => { |
|
|
|
webauthn::validate_webauthn_login(&user.uuid, twofactor_code, webauthn, conn).await? |
|
|
|
} |
|
|
|
Some(TwoFactorType::Webauthn) => webauthn::validate_webauthn_login(&user.uuid, twofactor_code, conn).await?, |
|
|
|
Some(TwoFactorType::YubiKey) => yubikey::validate_yubikey_login(twofactor_code, &selected_data?).await?, |
|
|
|
Some(TwoFactorType::Duo) => { |
|
|
|
match CONFIG.duo_use_iframe() { |
|
|
@ -739,7 +732,7 @@ async fn twofactor_auth( |
|
|
|
} |
|
|
|
_ => { |
|
|
|
err_json!( |
|
|
|
_json_err_twofactor(&twofactor_ids, &user.uuid, data, client_version, webauthn, conn).await?, |
|
|
|
_json_err_twofactor(&twofactor_ids, &user.uuid, data, client_version, conn).await?, |
|
|
|
"2FA Remember token not provided" |
|
|
|
) |
|
|
|
} |
|
|
@ -773,7 +766,6 @@ async fn _json_err_twofactor( |
|
|
|
user_id: &UserId, |
|
|
|
data: &ConnectData, |
|
|
|
client_version: &Option<ClientVersion>, |
|
|
|
webauthn: Webauthn2FaConfig<'_>, |
|
|
|
conn: &mut DbConn, |
|
|
|
) -> ApiResult<Value> { |
|
|
|
let mut result = json!({ |
|
|
@ -793,7 +785,7 @@ async fn _json_err_twofactor( |
|
|
|
Some(TwoFactorType::Authenticator) => { /* Nothing to do for TOTP */ } |
|
|
|
|
|
|
|
Some(TwoFactorType::Webauthn) if CONFIG.domain_set() => { |
|
|
|
let request = webauthn::generate_webauthn_login(user_id, webauthn, conn).await?; |
|
|
|
let request = webauthn::generate_webauthn_login(user_id, conn).await?; |
|
|
|
result["TwoFactorProviders2"][provider.to_string()] = request.0; |
|
|
|
} |
|
|
|
|
|
|
|