fix: address argus review on matrix admin-room reset — ascii lowercase, tighter markers, unit tests
This commit is contained in:
parent
b2913bc656
commit
97a78cc5d6
1 changed files with 56 additions and 3 deletions
|
|
@ -354,14 +354,20 @@ async fn discover_admin_room_id(
|
|||
/// Try to parse the new password from an admin-room bot response.
|
||||
/// Conduwuit/tuwunel responds with a message like:
|
||||
/// "Done: Password of user @user:server has been reset. The new password is: <password>"
|
||||
///
|
||||
/// Uses [`str::to_ascii_lowercase`] for case folding — unlike `to_lowercase`,
|
||||
/// ASCII lowercasing is guaranteed to produce a same-byte-length string, so the
|
||||
/// byte offset from `find` is always a valid index into the original `bot_message`
|
||||
/// and we never slice at a non-char boundary.
|
||||
fn extract_new_password(bot_message: &str) -> Option<String> {
|
||||
// Look for "new password is:" (case-insensitive) followed by whitespace + the password.
|
||||
let lower = bot_message.to_lowercase();
|
||||
// ASCII lowercase: same byte length as the original, so positions from
|
||||
// `lower.find(marker)` are valid byte indices into `bot_message`.
|
||||
let lower = bot_message.to_ascii_lowercase();
|
||||
for marker in &[
|
||||
"new password is: ",
|
||||
"new password is:",
|
||||
"password is: ",
|
||||
"password: ",
|
||||
"password is:",
|
||||
] {
|
||||
if let Some(pos) = lower.find(marker) {
|
||||
let rest = &bot_message[pos + marker.len()..];
|
||||
|
|
@ -378,6 +384,53 @@ fn extract_new_password(bot_message: &str) -> Option<String> {
|
|||
None
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod extract_new_password_tests {
|
||||
use super::extract_new_password;
|
||||
|
||||
#[test]
|
||||
fn tuwunel_style_response() {
|
||||
let msg = "Done: Password of user @atlas:pr1ma.darkest.space has been reset. The new password is: abc123XYZ!";
|
||||
assert_eq!(extract_new_password(msg).as_deref(), Some("abc123XYZ!"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case_insensitive_marker() {
|
||||
let msg = "Password reset complete. New Password Is: S3cr3tP@ss";
|
||||
assert_eq!(extract_new_password(msg).as_deref(), Some("S3cr3tP@ss"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn marker_without_trailing_space() {
|
||||
let msg = "new password is:hunter2";
|
||||
assert_eq!(extract_new_password(msg).as_deref(), Some("hunter2"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shorter_marker_variant() {
|
||||
let msg = "Your password is: Tr0ub4dor&3";
|
||||
assert_eq!(extract_new_password(msg).as_deref(), Some("Tr0ub4dor&3"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match_returns_none() {
|
||||
let msg = "Command not recognised. Please try again.";
|
||||
assert_eq!(extract_new_password(msg), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_after_marker_returns_none() {
|
||||
let msg = "new password is: ";
|
||||
assert_eq!(extract_new_password(msg), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn password_stops_at_whitespace() {
|
||||
let msg = "New password is: abc123 (save it now)";
|
||||
assert_eq!(extract_new_password(msg).as_deref(), Some("abc123"));
|
||||
}
|
||||
}
|
||||
|
||||
/// Reset a user's password via the Matrix admin room as a fallback for
|
||||
/// homeservers that do not implement the Synapse admin REST API (e.g.
|
||||
/// tuwunel 1.6.x). Sends `reset-password @<localpart>:<server>` to
|
||||
|
|
|
|||
Loading…
Reference in a new issue