Spiegel von
https://github.com/dani-garcia/vaultwarden.git
synchronisiert 2024-09-28 21:53:55 +02:00
remove redundant explicit returns, rustfmt
Dieser Commit ist enthalten in:
Ursprung
33c7053b4f
Commit
768d6a1f49
4 geänderte Dateien mit 47 neuen und 44 gelöschten Zeilen
|
@ -6,21 +6,18 @@ use ring::digest::{digest, Digest, SHA512_256};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use url::Url;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{core::two_factor::duo::get_duo_keys_email, EmptyResult},
|
api::{core::two_factor::duo::get_duo_keys_email, EmptyResult},
|
||||||
crypto,
|
crypto,
|
||||||
db::{models::{
|
db::{
|
||||||
EventType,
|
models::{EventType, TwoFactorDuoContext},
|
||||||
TwoFactorDuoContext,
|
DbConn, DbPool,
|
||||||
},
|
|
||||||
DbConn,
|
|
||||||
DbPool,
|
|
||||||
},
|
},
|
||||||
error::Error,
|
error::Error,
|
||||||
util::get_reqwest_client,
|
util::get_reqwest_client,
|
||||||
CONFIG,
|
CONFIG,
|
||||||
};
|
};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
// State length must be at least 16 characters and at most 1024 characters.
|
// State length must be at least 16 characters and at most 1024 characters.
|
||||||
const STATE_LENGTH: usize = 64;
|
const STATE_LENGTH: usize = 64;
|
||||||
|
@ -128,10 +125,9 @@ struct DuoClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DuoClient {
|
impl DuoClient {
|
||||||
|
|
||||||
// Construct a new DuoClient
|
// Construct a new DuoClient
|
||||||
fn new(client_id: String, client_secret: String, api_host: String, redirect_uri: String) -> DuoClient {
|
fn new(client_id: String, client_secret: String, api_host: String, redirect_uri: String) -> DuoClient {
|
||||||
return DuoClient {
|
DuoClient {
|
||||||
client_id,
|
client_id,
|
||||||
client_secret,
|
client_secret,
|
||||||
api_host,
|
api_host,
|
||||||
|
@ -254,7 +250,7 @@ impl DuoClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
let final_auth_url = auth_url.to_string();
|
let final_auth_url = auth_url.to_string();
|
||||||
return Ok(final_auth_url);
|
Ok(final_auth_url)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exchange the authorization code obtained from an access token provided by the user
|
// Exchange the authorization code obtained from an access token provided by the user
|
||||||
|
@ -345,12 +341,12 @@ struct DuoAuthContext {
|
||||||
async fn extract_context(state: &str, conn: &mut DbConn) -> Option<DuoAuthContext> {
|
async fn extract_context(state: &str, conn: &mut DbConn) -> Option<DuoAuthContext> {
|
||||||
let ctx: TwoFactorDuoContext = match TwoFactorDuoContext::find_by_state(state, conn).await {
|
let ctx: TwoFactorDuoContext = match TwoFactorDuoContext::find_by_state(state, conn).await {
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
None => return None
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if ctx.exp < Utc::now().timestamp() {
|
if ctx.exp < Utc::now().timestamp() {
|
||||||
ctx.delete(conn).await.ok();
|
ctx.delete(conn).await.ok();
|
||||||
return None
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the context data, so that we can delete the context from
|
// Copy the context data, so that we can delete the context from
|
||||||
|
@ -363,7 +359,7 @@ async fn extract_context(state: &str, conn: &mut DbConn) -> Option<DuoAuthContex
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.delete(conn).await.ok();
|
ctx.delete(conn).await.ok();
|
||||||
return Some(ret_ctx)
|
Some(ret_ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Task to clean up expired Duo authentication contexts that may have accumulated in the database.
|
// Task to clean up expired Duo authentication contexts that may have accumulated in the database.
|
||||||
|
@ -400,15 +396,17 @@ fn make_callback_url(client_name: &str) -> Result<String, Error> {
|
||||||
let mut query_params = callback.query_pairs_mut();
|
let mut query_params = callback.query_pairs_mut();
|
||||||
query_params.append_pair("client", client_name);
|
query_params.append_pair("client", client_name);
|
||||||
}
|
}
|
||||||
return Ok(callback.to_string());
|
Ok(callback.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-redirect first stage of the Duo WebSDKv4 authentication flow.
|
// Pre-redirect first stage of the Duo WebSDKv4 authentication flow.
|
||||||
// Returns the "AuthUrl" that should be returned to clients for MFA.
|
// Returns the "AuthUrl" that should be returned to clients for MFA.
|
||||||
pub async fn get_duo_auth_url(email: &str,
|
pub async fn get_duo_auth_url(
|
||||||
|
email: &str,
|
||||||
client_id: &String,
|
client_id: &String,
|
||||||
device_identifier: &String,
|
device_identifier: &String,
|
||||||
conn: &mut DbConn) -> Result<String, Error> {
|
conn: &mut DbConn,
|
||||||
|
) -> Result<String, Error> {
|
||||||
let (ik, sk, _, host) = get_duo_keys_email(email, conn).await?;
|
let (ik, sk, _, host) = get_duo_keys_email(email, conn).await?;
|
||||||
|
|
||||||
let callback_url = match make_callback_url(client_id.as_str()) {
|
let callback_url = match make_callback_url(client_id.as_str()) {
|
||||||
|
@ -434,7 +432,7 @@ pub async fn get_duo_auth_url(email: &str,
|
||||||
|
|
||||||
match TwoFactorDuoContext::save(state.as_str(), email, nonce.as_str(), CTX_VALIDITY_SECS, conn).await {
|
match TwoFactorDuoContext::save(state.as_str(), email, nonce.as_str(), CTX_VALIDITY_SECS, conn).await {
|
||||||
Ok(()) => client.make_authz_req_url(email, state, hash),
|
Ok(()) => client.make_authz_req_url(email, state, hash),
|
||||||
Err(e) => err!(format!("Error saving Duo authentication context: {e:?}"))
|
Err(e) => err!(format!("Error saving Duo authentication context: {e:?}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -502,7 +502,9 @@ async fn twofactor_auth(
|
||||||
|
|
||||||
let twofactor_code = match data.two_factor_token {
|
let twofactor_code = match data.two_factor_token {
|
||||||
Some(ref code) => code,
|
Some(ref code) => code,
|
||||||
None => err_json!(_json_err_twofactor(&twofactor_ids, &user.uuid, &data, conn).await?, "2FA token not provided"),
|
None => {
|
||||||
|
err_json!(_json_err_twofactor(&twofactor_ids, &user.uuid, &data, conn).await?, "2FA token not provided")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let selected_twofactor = twofactors.into_iter().find(|tf| tf.atype == selected_id && tf.enabled);
|
let selected_twofactor = twofactors.into_iter().find(|tf| tf.atype == selected_id && tf.enabled);
|
||||||
|
@ -526,11 +528,14 @@ async fn twofactor_auth(
|
||||||
}
|
}
|
||||||
false => {
|
false => {
|
||||||
// OIDC based flow
|
// OIDC based flow
|
||||||
duo_oidc::validate_duo_login(data.username.as_ref().unwrap().trim(),
|
duo_oidc::validate_duo_login(
|
||||||
|
data.username.as_ref().unwrap().trim(),
|
||||||
twofactor_code,
|
twofactor_code,
|
||||||
data.client_id.as_ref().unwrap(),
|
data.client_id.as_ref().unwrap(),
|
||||||
data.device_identifier.as_ref().unwrap(),
|
data.device_identifier.as_ref().unwrap(),
|
||||||
conn).await?
|
conn,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -573,7 +578,12 @@ fn _selected_data(tf: Option<TwoFactor>) -> ApiResult<String> {
|
||||||
tf.map(|t| t.data).map_res("Two factor doesn't exist")
|
tf.map(|t| t.data).map_res("Two factor doesn't exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn _json_err_twofactor(providers: &[i32], user_uuid: &str, data: &ConnectData, conn: &mut DbConn) -> ApiResult<Value> {
|
async fn _json_err_twofactor(
|
||||||
|
providers: &[i32],
|
||||||
|
user_uuid: &str,
|
||||||
|
data: &ConnectData,
|
||||||
|
conn: &mut DbConn,
|
||||||
|
) -> ApiResult<Value> {
|
||||||
let mut result = json!({
|
let mut result = json!({
|
||||||
"error" : "invalid_grant",
|
"error" : "invalid_grant",
|
||||||
"error_description" : "Two factor required.",
|
"error_description" : "Two factor required.",
|
||||||
|
@ -609,10 +619,13 @@ async fn _json_err_twofactor(providers: &[i32], user_uuid: &str, data: &ConnectD
|
||||||
}
|
}
|
||||||
false => {
|
false => {
|
||||||
// OIDC based flow
|
// OIDC based flow
|
||||||
let auth_url = duo_oidc::get_duo_auth_url(&email,
|
let auth_url = duo_oidc::get_duo_auth_url(
|
||||||
|
&email,
|
||||||
data.client_id.as_ref().unwrap(),
|
data.client_id.as_ref().unwrap(),
|
||||||
data.device_identifier.as_ref().unwrap(),
|
data.device_identifier.as_ref().unwrap(),
|
||||||
conn).await?;
|
conn,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
result["TwoFactorProviders2"][provider.to_string()] = json!({
|
result["TwoFactorProviders2"][provider.to_string()] = json!({
|
||||||
"AuthUrl": auth_url,
|
"AuthUrl": auth_url,
|
||||||
|
|
|
@ -27,17 +27,11 @@ impl TwoFactorDuoContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn save(
|
pub async fn save(state: &str, user_email: &str, nonce: &str, ttl: i64, conn: &mut DbConn) -> EmptyResult {
|
||||||
state: &str,
|
|
||||||
user_email: &str,
|
|
||||||
nonce: &str,
|
|
||||||
ttl: i64,
|
|
||||||
conn: &mut DbConn,
|
|
||||||
) -> EmptyResult {
|
|
||||||
// A saved context should never be changed, only created or deleted.
|
// A saved context should never be changed, only created or deleted.
|
||||||
let exists = Self::find_by_state(state, conn).await;
|
let exists = Self::find_by_state(state, conn).await;
|
||||||
if exists.is_some() {
|
if exists.is_some() {
|
||||||
return Ok(())
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
let exp = Utc::now().timestamp() + ttl;
|
let exp = Utc::now().timestamp() + ttl;
|
||||||
|
|
|
@ -51,6 +51,7 @@ mod mail;
|
||||||
mod ratelimit;
|
mod ratelimit;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
use crate::api::core::two_factor::duo_oidc::purge_duo_contexts;
|
||||||
use crate::api::purge_auth_requests;
|
use crate::api::purge_auth_requests;
|
||||||
use crate::api::{WS_ANONYMOUS_SUBSCRIPTIONS, WS_USERS};
|
use crate::api::{WS_ANONYMOUS_SUBSCRIPTIONS, WS_USERS};
|
||||||
pub use config::CONFIG;
|
pub use config::CONFIG;
|
||||||
|
@ -58,7 +59,6 @@ pub use error::{Error, MapResult};
|
||||||
use rocket::data::{Limits, ToByteUnit};
|
use rocket::data::{Limits, ToByteUnit};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
pub use util::is_running_in_container;
|
pub use util::is_running_in_container;
|
||||||
use crate::api::core::two_factor::duo_oidc::purge_duo_contexts;
|
|
||||||
|
|
||||||
#[rocket::main]
|
#[rocket::main]
|
||||||
async fn main() -> Result<(), Error> {
|
async fn main() -> Result<(), Error> {
|
||||||
|
@ -586,9 +586,7 @@ fn schedule_jobs(pool: db::DbPool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean unused, expired Duo authentication contexts.
|
// Clean unused, expired Duo authentication contexts.
|
||||||
if !CONFIG.duo_context_purge_schedule().is_empty()
|
if !CONFIG.duo_context_purge_schedule().is_empty() && CONFIG._enable_duo() && !CONFIG.duo_use_iframe() {
|
||||||
&& CONFIG._enable_duo()
|
|
||||||
&& !CONFIG.duo_use_iframe() {
|
|
||||||
sched.add(Job::new(CONFIG.duo_context_purge_schedule().parse().unwrap(), || {
|
sched.add(Job::new(CONFIG.duo_context_purge_schedule().parse().unwrap(), || {
|
||||||
runtime.spawn(purge_duo_contexts(pool.clone()));
|
runtime.spawn(purge_duo_contexts(pool.clone()));
|
||||||
}));
|
}));
|
||||||
|
|
Laden …
In neuem Issue referenzieren