Merge ClientIp with Headers.

Since we now use the `ClientIp` Guard on a lot more places, it also
increases the size of binary, and the macro generated code because of
this extra Guard. By merging the `ClientIp` Guard with the several
`Header` guards we have it reduces the amount of code generated
(including LLVM IR), but also a small speedup in build time.

I also spotted some small `json!()` optimizations which also reduced the
amount of code generated.
This commit is contained in:
BlackDex
2023-03-09 16:31:28 +01:00
parent f21089900e
commit 9e5b94924f
17 changed files with 256 additions and 422 deletions

View File

@@ -57,7 +57,6 @@ struct EnableAuthenticatorData {
async fn activate_authenticator(
data: JsonUpcase<EnableAuthenticatorData>,
headers: Headers,
ip: ClientIp,
mut conn: DbConn,
) -> JsonResult {
let data: EnableAuthenticatorData = data.into_inner().data;
@@ -82,11 +81,11 @@ async fn activate_authenticator(
}
// Validate the token provided with the key, and save new twofactor
validate_totp_code(&user.uuid, &token, &key.to_uppercase(), &ip, &mut conn).await?;
validate_totp_code(&user.uuid, &token, &key.to_uppercase(), &headers.ip, &mut conn).await?;
_generate_recover_code(&mut user, &mut conn).await;
log_user_event(EventType::UserUpdated2fa as i32, &user.uuid, headers.device.atype, &ip.ip, &mut conn).await;
log_user_event(EventType::UserUpdated2fa as i32, &user.uuid, headers.device.atype, &headers.ip.ip, &mut conn).await;
Ok(Json(json!({
"Enabled": true,
@@ -99,10 +98,9 @@ async fn activate_authenticator(
async fn activate_authenticator_put(
data: JsonUpcase<EnableAuthenticatorData>,
headers: Headers,
ip: ClientIp,
conn: DbConn,
) -> JsonResult {
activate_authenticator(data, headers, ip, conn).await
activate_authenticator(data, headers, conn).await
}
pub async fn validate_totp_code_str(

View File

@@ -8,7 +8,7 @@ use crate::{
core::log_user_event, core::two_factor::_generate_recover_code, ApiResult, EmptyResult, JsonResult, JsonUpcase,
PasswordData,
},
auth::{ClientIp, Headers},
auth::Headers,
crypto,
db::{
models::{EventType, TwoFactor, TwoFactorType, User},
@@ -155,7 +155,7 @@ fn check_duo_fields_custom(data: &EnableDuoData) -> bool {
}
#[post("/two-factor/duo", data = "<data>")]
async fn activate_duo(data: JsonUpcase<EnableDuoData>, headers: Headers, mut conn: DbConn, ip: ClientIp) -> JsonResult {
async fn activate_duo(data: JsonUpcase<EnableDuoData>, headers: Headers, mut conn: DbConn) -> JsonResult {
let data: EnableDuoData = data.into_inner().data;
let mut user = headers.user;
@@ -178,7 +178,7 @@ async fn activate_duo(data: JsonUpcase<EnableDuoData>, headers: Headers, mut con
_generate_recover_code(&mut user, &mut conn).await;
log_user_event(EventType::UserUpdated2fa as i32, &user.uuid, headers.device.atype, &ip.ip, &mut conn).await;
log_user_event(EventType::UserUpdated2fa as i32, &user.uuid, headers.device.atype, &headers.ip.ip, &mut conn).await;
Ok(Json(json!({
"Enabled": true,
@@ -190,8 +190,8 @@ async fn activate_duo(data: JsonUpcase<EnableDuoData>, headers: Headers, mut con
}
#[put("/two-factor/duo", data = "<data>")]
async fn activate_duo_put(data: JsonUpcase<EnableDuoData>, headers: Headers, conn: DbConn, ip: ClientIp) -> JsonResult {
activate_duo(data, headers, conn, ip).await
async fn activate_duo_put(data: JsonUpcase<EnableDuoData>, headers: Headers, conn: DbConn) -> JsonResult {
activate_duo(data, headers, conn).await
}
async fn duo_api_request(method: &str, path: &str, params: &str, data: &DuoData) -> EmptyResult {

View File

@@ -7,7 +7,7 @@ use crate::{
core::{log_user_event, two_factor::_generate_recover_code},
EmptyResult, JsonResult, JsonUpcase, PasswordData,
},
auth::{ClientIp, Headers},
auth::Headers,
crypto,
db::{
models::{EventType, TwoFactor, TwoFactorType},
@@ -90,7 +90,7 @@ async fn get_email(data: JsonUpcase<PasswordData>, headers: Headers, mut conn: D
let twofactor_data = EmailTokenData::from_json(&x.data)?;
(true, json!(twofactor_data.email))
}
_ => (false, json!(null)),
_ => (false, serde_json::value::Value::Null),
};
Ok(Json(json!({
@@ -150,7 +150,7 @@ struct EmailData {
/// Verify email belongs to user and can be used for 2FA email codes.
#[put("/two-factor/email", data = "<data>")]
async fn email(data: JsonUpcase<EmailData>, headers: Headers, mut conn: DbConn, ip: ClientIp) -> JsonResult {
async fn email(data: JsonUpcase<EmailData>, headers: Headers, mut conn: DbConn) -> JsonResult {
let data: EmailData = data.into_inner().data;
let mut user = headers.user;
@@ -180,7 +180,7 @@ async fn email(data: JsonUpcase<EmailData>, headers: Headers, mut conn: DbConn,
_generate_recover_code(&mut user, &mut conn).await;
log_user_event(EventType::UserUpdated2fa as i32, &user.uuid, headers.device.atype, &ip.ip, &mut conn).await;
log_user_event(EventType::UserUpdated2fa as i32, &user.uuid, headers.device.atype, &headers.ip.ip, &mut conn).await;
Ok(Json(json!({
"Email": email_data.email,

View File

@@ -6,7 +6,7 @@ use serde_json::Value;
use crate::{
api::{core::log_user_event, JsonResult, JsonUpcase, NumberOrString, PasswordData},
auth::{ClientHeaders, ClientIp, Headers},
auth::{ClientHeaders, Headers},
crypto,
db::{models::*, DbConn, DbPool},
mail, CONFIG,
@@ -73,12 +73,7 @@ struct RecoverTwoFactor {
}
#[post("/two-factor/recover", data = "<data>")]
async fn recover(
data: JsonUpcase<RecoverTwoFactor>,
client_headers: ClientHeaders,
mut conn: DbConn,
ip: ClientIp,
) -> JsonResult {
async fn recover(data: JsonUpcase<RecoverTwoFactor>, client_headers: ClientHeaders, mut conn: DbConn) -> JsonResult {
let data: RecoverTwoFactor = data.into_inner().data;
use crate::db::models::User;
@@ -102,12 +97,19 @@ async fn recover(
// Remove all twofactors from the user
TwoFactor::delete_all_by_user(&user.uuid, &mut conn).await?;
log_user_event(EventType::UserRecovered2fa as i32, &user.uuid, client_headers.device_type, &ip.ip, &mut conn).await;
log_user_event(
EventType::UserRecovered2fa as i32,
&user.uuid,
client_headers.device_type,
&client_headers.ip.ip,
&mut conn,
)
.await;
// Remove the recovery code, not needed without twofactors
user.totp_recover = None;
user.save(&mut conn).await?;
Ok(Json(json!({})))
Ok(Json(Value::Object(serde_json::Map::new())))
}
async fn _generate_recover_code(user: &mut User, conn: &mut DbConn) {
@@ -126,12 +128,7 @@ struct DisableTwoFactorData {
}
#[post("/two-factor/disable", data = "<data>")]
async fn disable_twofactor(
data: JsonUpcase<DisableTwoFactorData>,
headers: Headers,
mut conn: DbConn,
ip: ClientIp,
) -> JsonResult {
async fn disable_twofactor(data: JsonUpcase<DisableTwoFactorData>, headers: Headers, mut conn: DbConn) -> JsonResult {
let data: DisableTwoFactorData = data.into_inner().data;
let password_hash = data.MasterPasswordHash;
let user = headers.user;
@@ -144,7 +141,8 @@ async fn disable_twofactor(
if let Some(twofactor) = TwoFactor::find_by_user_and_type(&user.uuid, type_, &mut conn).await {
twofactor.delete(&mut conn).await?;
log_user_event(EventType::UserDisabled2fa as i32, &user.uuid, headers.device.atype, &ip.ip, &mut conn).await;
log_user_event(EventType::UserDisabled2fa as i32, &user.uuid, headers.device.atype, &headers.ip.ip, &mut conn)
.await;
}
let twofactor_disabled = TwoFactor::find_by_user(&user.uuid, &mut conn).await.is_empty();
@@ -173,13 +171,8 @@ async fn disable_twofactor(
}
#[put("/two-factor/disable", data = "<data>")]
async fn disable_twofactor_put(
data: JsonUpcase<DisableTwoFactorData>,
headers: Headers,
conn: DbConn,
ip: ClientIp,
) -> JsonResult {
disable_twofactor(data, headers, conn, ip).await
async fn disable_twofactor_put(data: JsonUpcase<DisableTwoFactorData>, headers: Headers, conn: DbConn) -> JsonResult {
disable_twofactor(data, headers, conn).await
}
pub async fn send_incomplete_2fa_notifications(pool: DbPool) {

View File

@@ -9,7 +9,7 @@ use crate::{
core::{log_user_event, two_factor::_generate_recover_code},
EmptyResult, JsonResult, JsonUpcase, NumberOrString, PasswordData,
},
auth::{ClientIp, Headers},
auth::Headers,
db::{
models::{EventType, TwoFactor, TwoFactorType},
DbConn,
@@ -242,12 +242,7 @@ impl From<PublicKeyCredentialCopy> for PublicKeyCredential {
}
#[post("/two-factor/webauthn", data = "<data>")]
async fn activate_webauthn(
data: JsonUpcase<EnableWebauthnData>,
headers: Headers,
mut conn: DbConn,
ip: ClientIp,
) -> JsonResult {
async fn activate_webauthn(data: JsonUpcase<EnableWebauthnData>, headers: Headers, mut conn: DbConn) -> JsonResult {
let data: EnableWebauthnData = data.into_inner().data;
let mut user = headers.user;
@@ -286,7 +281,7 @@ async fn activate_webauthn(
.await?;
_generate_recover_code(&mut user, &mut conn).await;
log_user_event(EventType::UserUpdated2fa as i32, &user.uuid, headers.device.atype, &ip.ip, &mut conn).await;
log_user_event(EventType::UserUpdated2fa as i32, &user.uuid, headers.device.atype, &headers.ip.ip, &mut conn).await;
let keys_json: Vec<Value> = registrations.iter().map(WebauthnRegistration::to_json).collect();
Ok(Json(json!({
@@ -297,13 +292,8 @@ async fn activate_webauthn(
}
#[put("/two-factor/webauthn", data = "<data>")]
async fn activate_webauthn_put(
data: JsonUpcase<EnableWebauthnData>,
headers: Headers,
conn: DbConn,
ip: ClientIp,
) -> JsonResult {
activate_webauthn(data, headers, conn, ip).await
async fn activate_webauthn_put(data: JsonUpcase<EnableWebauthnData>, headers: Headers, conn: DbConn) -> JsonResult {
activate_webauthn(data, headers, conn).await
}
#[derive(Deserialize, Debug)]

View File

@@ -8,7 +8,7 @@ use crate::{
core::{log_user_event, two_factor::_generate_recover_code},
EmptyResult, JsonResult, JsonUpcase, PasswordData,
},
auth::{ClientIp, Headers},
auth::Headers,
db::{
models::{EventType, TwoFactor, TwoFactorType},
DbConn,
@@ -47,7 +47,7 @@ fn parse_yubikeys(data: &EnableYubikeyData) -> Vec<String> {
}
fn jsonify_yubikeys(yubikeys: Vec<String>) -> serde_json::Value {
let mut result = json!({});
let mut result = Value::Object(serde_json::Map::new());
for (i, key) in yubikeys.into_iter().enumerate() {
result[format!("Key{}", i + 1)] = Value::String(key);
@@ -118,12 +118,7 @@ async fn generate_yubikey(data: JsonUpcase<PasswordData>, headers: Headers, mut
}
#[post("/two-factor/yubikey", data = "<data>")]
async fn activate_yubikey(
data: JsonUpcase<EnableYubikeyData>,
headers: Headers,
mut conn: DbConn,
ip: ClientIp,
) -> JsonResult {
async fn activate_yubikey(data: JsonUpcase<EnableYubikeyData>, headers: Headers, mut conn: DbConn) -> JsonResult {
let data: EnableYubikeyData = data.into_inner().data;
let mut user = headers.user;
@@ -169,7 +164,7 @@ async fn activate_yubikey(
_generate_recover_code(&mut user, &mut conn).await;
log_user_event(EventType::UserUpdated2fa as i32, &user.uuid, headers.device.atype, &ip.ip, &mut conn).await;
log_user_event(EventType::UserUpdated2fa as i32, &user.uuid, headers.device.atype, &headers.ip.ip, &mut conn).await;
let mut result = jsonify_yubikeys(yubikey_metadata.Keys);
@@ -181,13 +176,8 @@ async fn activate_yubikey(
}
#[put("/two-factor/yubikey", data = "<data>")]
async fn activate_yubikey_put(
data: JsonUpcase<EnableYubikeyData>,
headers: Headers,
conn: DbConn,
ip: ClientIp,
) -> JsonResult {
activate_yubikey(data, headers, conn, ip).await
async fn activate_yubikey_put(data: JsonUpcase<EnableYubikeyData>, headers: Headers, conn: DbConn) -> JsonResult {
activate_yubikey(data, headers, conn).await
}
pub async fn validate_yubikey_login(response: &str, twofactor_data: &str) -> EmptyResult {