mirror of
https://github.com/lldap/lldap.git
synced 2026-06-09 21:10:25 +00:00
fix: percent-decode user_id route params for users with spaces in ID (#585)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2743,6 +2743,7 @@ dependencies = [
|
|||||||
"lldap_auth",
|
"lldap_auth",
|
||||||
"lldap_frontend_options",
|
"lldap_frontend_options",
|
||||||
"lldap_validation",
|
"lldap_validation",
|
||||||
|
"percent-encoding",
|
||||||
"rand 0.8.6",
|
"rand 0.8.6",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ rand = { workspace = true }
|
|||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
strum = { workspace = true }
|
strum = { workspace = true }
|
||||||
|
percent-encoding = "2"
|
||||||
url-escape = "0.1.1"
|
url-escape = "0.1.1"
|
||||||
validator = "0.14"
|
validator = "0.14"
|
||||||
validator_derive = "0.14"
|
validator_derive = "0.14"
|
||||||
|
|||||||
@@ -183,6 +183,16 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Percent-decode a URL path segment into a user ID string.
|
||||||
|
/// Returns `None` if the decoded bytes are not valid UTF-8, so the caller
|
||||||
|
/// can redirect to a safe page rather than silently mangling the ID.
|
||||||
|
fn decode_user_id(raw: &str) -> Option<String> {
|
||||||
|
percent_encoding::percent_decode_str(raw)
|
||||||
|
.decode_utf8()
|
||||||
|
.ok()
|
||||||
|
.map(|s| s.into_owned())
|
||||||
|
}
|
||||||
|
|
||||||
fn dispatch_route(
|
fn dispatch_route(
|
||||||
switch: &AppRoute,
|
switch: &AppRoute,
|
||||||
link: &Scope<Self>,
|
link: &Scope<Self>,
|
||||||
@@ -248,11 +258,17 @@ impl App {
|
|||||||
AppRoute::GroupDetails { group_id } => html! {
|
AppRoute::GroupDetails { group_id } => html! {
|
||||||
<GroupDetails group_id={*group_id} is_admin={is_admin} />
|
<GroupDetails group_id={*group_id} is_admin={is_admin} />
|
||||||
},
|
},
|
||||||
AppRoute::UserDetails { user_id } => html! {
|
AppRoute::UserDetails { user_id } => match Self::decode_user_id(user_id) {
|
||||||
<UserDetails username={user_id.clone()} is_admin={is_admin} />
|
Some(decoded_id) => html! {
|
||||||
|
<UserDetails username={decoded_id} is_admin={is_admin} />
|
||||||
|
},
|
||||||
|
None => html! { <Redirect to={AppRoute::Login} /> },
|
||||||
},
|
},
|
||||||
AppRoute::ChangePassword { user_id } => html! {
|
AppRoute::ChangePassword { user_id } => match Self::decode_user_id(user_id) {
|
||||||
<ChangePasswordForm username={user_id.clone()} is_admin={is_admin} />
|
Some(decoded_id) => html! {
|
||||||
|
<ChangePasswordForm username={decoded_id} is_admin={is_admin} />
|
||||||
|
},
|
||||||
|
None => html! { <Redirect to={AppRoute::Login} /> },
|
||||||
},
|
},
|
||||||
AppRoute::StartResetPassword => match password_reset_enabled {
|
AppRoute::StartResetPassword => match password_reset_enabled {
|
||||||
Some(true) => html! { <ResetPasswordStep1Form /> },
|
Some(true) => html! { <ResetPasswordStep1Form /> },
|
||||||
|
|||||||
Reference in New Issue
Block a user