Skip to content

Commit

Permalink
Refactor captcha module to separate state handling from solution chec…
Browse files Browse the repository at this point in the history
…king

This PR refactors the captcha module to provide a separate function for
checking the supplied solution that is independent of how captcha state
handling works.
  • Loading branch information
frederikrothenberger committed Sep 24, 2024
1 parent 795451b commit 41d21d1
Showing 1 changed file with 22 additions and 16 deletions.
38 changes: 22 additions & 16 deletions src/internet_identity/src/anchor_management/registration/captcha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,29 @@ pub fn create_captcha<T: RngCore>(rng: T) -> (Base64, String) {

// Check whether the CAPTCHA challenge was solved
pub fn check_challenge(res: ChallengeAttempt) -> Result<(), ()> {
let Some(challenge) = state::inflight_challenges_mut(|inflight_challenges| {
prune_expired_challenges(inflight_challenges);
inflight_challenges.remove(&res.key)
}) else {
return Err(());
};

if let Some(value) = check_captcha_solution(res.chars, challenge.chars) {
return value;
}
Ok(())
}

/// Check whether the supplied CAPTCHA solution attempt matches the expected solution (after
/// normalizing ambiguous characters).
fn check_captcha_solution(solution_attempt: String, solution: String) -> Result<(), ()> {
// avoid processing too many characters
if res.chars.len() > CAPTCHA_LENGTH {
if solution_attempt.len() > CAPTCHA_LENGTH {
return Err(());
}
// Normalize challenge attempts by replacing characters that are not in the captcha character set
// with the respective replacement from CHAR_REPLACEMENTS.
let normalized_challenge_res: String = res
.chars
let normalized_challenge_res: String = solution_attempt
.chars()
.map(|c| {
// Apply all replacements
Expand All @@ -151,17 +166,8 @@ pub fn check_challenge(res: ChallengeAttempt) -> Result<(), ()> {
})
.collect();

state::inflight_challenges_mut(|inflight_challenges| {
prune_expired_challenges(inflight_challenges);

match inflight_challenges.remove(&res.key) {
Some(challenge) => {
if normalized_challenge_res != challenge.chars {
return Err(());
}
Ok(())
}
None => Err(()),
}
})
if normalized_challenge_res != solution {
return Err(());
}
Ok(())
}

0 comments on commit 41d21d1

Please sign in to comment.