Use typed parameters instead of a hashmap

This commit is contained in:
Greg Burri 2025-05-21 20:18:31 +02:00
parent 084f7ef445
commit 817ef3d727
2 changed files with 129 additions and 150 deletions

View file

@ -110,7 +110,6 @@ pub async fn dev_panel(
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct LogsParams { pub struct LogsParams {
#[serde(default)]
pub log_file: String, pub log_file: String,
} }

View file

@ -31,6 +31,11 @@ use crate::{
const VALIDATION_TOKEN_KEY: &str = "validation_token"; const VALIDATION_TOKEN_KEY: &str = "validation_token";
#[derive(Deserialize)]
pub struct ValidationTokenParams {
validation_token: String,
}
/// SIGN UP /// /// SIGN UP ///
#[debug_handler] #[debug_handler]
@ -205,7 +210,7 @@ pub async fn sign_up_validation(
State(connection): State<db::Connection>, State(connection): State<db::Connection>,
Extension(context): Extension<Context>, Extension(context): Extension<Context>,
ConnectInfo(addr): ConnectInfo<SocketAddr>, ConnectInfo(addr): ConnectInfo<SocketAddr>,
Query(query): Query<HashMap<String, String>>, Query(params): Query<ValidationTokenParams>,
headers: HeaderMap, headers: HeaderMap,
) -> Result<(CookieJar, impl IntoResponse)> { ) -> Result<(CookieJar, impl IntoResponse)> {
let mut jar = CookieJar::from_headers(&headers); let mut jar = CookieJar::from_headers(&headers);
@ -223,12 +228,10 @@ pub async fn sign_up_validation(
)); ));
} }
let (client_ip, client_user_agent) = utils::get_ip_and_user_agent(&headers, addr); let (client_ip, client_user_agent) = utils::get_ip_and_user_agent(&headers, addr);
match query.get(VALIDATION_TOKEN_KEY) {
// 'validation_token' exists only when a user tries to validate a new account.
Some(token) => {
match connection match connection
.validation( .validation(
token, &params.validation_token,
Duration::seconds(consts::VALIDATION_TOKEN_DURATION), Duration::seconds(consts::VALIDATION_TOKEN_DURATION),
&client_ip, &client_ip,
&client_user_agent, &client_user_agent,
@ -253,20 +256,23 @@ pub async fn sign_up_validation(
)) ))
} }
db::user::ValidationResult::ValidationExpired => { db::user::ValidationResult::ValidationExpired => {
warn!("Unable to validate: validation expired. Token: {}", token); warn!(
"Unable to validate: validation expired. Token: {}",
&params.validation_token
);
Ok(( Ok((
jar, jar,
Html( Html(
MessageTemplate::new( MessageTemplate::new(context.tr.t(Sentence::SignUpValidationExpired), context)
context.tr.t(Sentence::SignUpValidationExpired),
context,
)
.render()?, .render()?,
), ),
)) ))
} }
db::user::ValidationResult::UnknownUser => { db::user::ValidationResult::UnknownUser => {
warn!("Unable to validate: unknown user. Token: {}", token); warn!(
"Unable to validate: unknown user. Token: {}",
&params.validation_token
);
Ok(( Ok((
jar, jar,
Html( Html(
@ -279,18 +285,6 @@ pub async fn sign_up_validation(
)) ))
} }
} }
}
None => {
warn!("Unable to validate: no token provided");
Ok((
jar,
Html(
MessageTemplate::new(context.tr.t(Sentence::ValidationError), context)
.render()?,
),
))
}
}
} }
/// SIGN IN /// /// SIGN IN ///
@ -560,17 +554,21 @@ pub async fn ask_reset_password_post(
} }
} }
#[derive(Deserialize)]
pub struct ResetPasswordGetParams {
reset_token: String,
}
#[debug_handler] #[debug_handler]
pub async fn reset_password_get( pub async fn reset_password_get(
State(connection): State<db::Connection>, State(connection): State<db::Connection>,
Extension(context): Extension<Context>, Extension(context): Extension<Context>,
Query(query): Query<HashMap<String, String>>, Query(params): Query<ResetPasswordGetParams>,
) -> Result<Response> { ) -> Result<Response> {
if let Some(reset_token) = query.get("reset_token") {
// Check if the token is valid. // Check if the token is valid.
if connection if connection
.is_reset_password_token_valid( .is_reset_password_token_valid(
reset_token, &params.reset_token,
Duration::seconds(consts::VALIDATION_PASSWORD_RESET_TOKEN_DURATION), Duration::seconds(consts::VALIDATION_PASSWORD_RESET_TOKEN_DURATION),
) )
.await? .await?
@ -578,20 +576,13 @@ pub async fn reset_password_get(
Ok(Html( Ok(Html(
ResetPasswordTemplate { ResetPasswordTemplate {
context, context,
reset_token, reset_token: &params.reset_token,
message: "", message: "",
message_password: "", message_password: "",
} }
.render()?, .render()?,
) )
.into_response()) .into_response())
} else {
Ok(Html(
MessageTemplate::new(context.tr.t(Sentence::AskResetTokenMissing), context)
.render()?,
)
.into_response())
}
} else { } else {
Ok(Html( Ok(Html(
MessageTemplate::new(context.tr.t(Sentence::AskResetTokenMissing), context).render()?, MessageTemplate::new(context.tr.t(Sentence::AskResetTokenMissing), context).render()?,
@ -948,7 +939,7 @@ pub async fn email_revalidation(
State(connection): State<db::Connection>, State(connection): State<db::Connection>,
Extension(context): Extension<Context>, Extension(context): Extension<Context>,
ConnectInfo(addr): ConnectInfo<SocketAddr>, ConnectInfo(addr): ConnectInfo<SocketAddr>,
Query(query): Query<HashMap<String, String>>, Query(params): Query<ValidationTokenParams>,
headers: HeaderMap, headers: HeaderMap,
) -> Result<(CookieJar, impl IntoResponse)> { ) -> Result<(CookieJar, impl IntoResponse)> {
let mut jar = CookieJar::from_headers(&headers); let mut jar = CookieJar::from_headers(&headers);
@ -962,12 +953,10 @@ pub async fn email_revalidation(
)); ));
} }
let (client_ip, client_user_agent) = utils::get_ip_and_user_agent(&headers, addr); let (client_ip, client_user_agent) = utils::get_ip_and_user_agent(&headers, addr);
match query.get(VALIDATION_TOKEN_KEY) {
// 'validation_token' exists only when a user must validate a new email.
Some(token) => {
match connection match connection
.validation( .validation(
token, &params.validation_token,
Duration::seconds(consts::VALIDATION_TOKEN_DURATION), Duration::seconds(consts::VALIDATION_TOKEN_DURATION),
&client_ip, &client_ip,
&client_user_agent, &client_user_agent,
@ -992,20 +981,17 @@ pub async fn email_revalidation(
)) ))
} }
error @ db::user::ValidationResult::ValidationExpired => { error @ db::user::ValidationResult::ValidationExpired => {
error!("Token: {}: {}", token, error); error!("Token: {}: {}", &params.validation_token, error);
Ok(( Ok((
jar, jar,
Html( Html(
MessageTemplate::new( MessageTemplate::new(context.tr.t(Sentence::ValidationExpired), context)
context.tr.t(Sentence::ValidationExpired),
context,
)
.render()?, .render()?,
), ),
)) ))
} }
error @ db::user::ValidationResult::UnknownUser => { error @ db::user::ValidationResult::UnknownUser => {
error!("(email={}): {}", token, error); error!("(email={}): {}", &params.validation_token, error);
Ok(( Ok((
jar, jar,
Html( Html(
@ -1018,10 +1004,4 @@ pub async fn email_revalidation(
)) ))
} }
} }
}
None => Ok((
jar,
Html(MessageTemplate::new(context.tr.t(Sentence::ValidationError), context).render()?),
)),
}
} }