mod response_state;
pub mod yubico_client;
const OTP_MIN_LENGTH: usize = 32;
const OTP_MAX_LENGTH: usize = 48;
pub fn is_valid_otp(otp: &str) -> bool {
if (otp.len() < OTP_MIN_LENGTH) || (otp.len() > OTP_MAX_LENGTH) {
return false;
}
return otp
.chars()
.map(|c| c as u32)
.all(|c| (0x20..=0x7E).contains(&c));
}
pub fn get_public_id(otp: &str) -> Result<&str, &str> {
if !is_valid_otp(otp) {
return Err("OTP is invalid");
}
Ok(otp.split_at(otp.len() - 32).0)
}
#[cfg(test)]
mod tests {
use crate::response_state::State;
use crate::yubico_client::YubicoClient;
use super::*;
#[test]
fn test_opt_validator() {
let valid_otp = is_valid_otp("cccjgjgkhcbbcvchfkfhiiuunbtnvgihdfiktncvlhck");
let another_valid_otp = is_valid_otp("cccjgjgkhcbbgefdkbbditfjrlniggevfhenublfnrev");
let invalid_otp_char = is_valid_otp("cccjgjgkhcbbcvchfkツhiiuunbtnvgihdfiktncvlhck");
let invalid_otp_length = is_valid_otp("gefdkbbditfjrlniggevfh");
assert!(valid_otp);
assert!(another_valid_otp);
assert_eq!(invalid_otp_char, false);
assert_eq!(invalid_otp_length, false);
}
#[test]
fn test_get_public_id() {
let valid_otp = get_public_id("cccjgjgkhcbbcvchfkfhiiuunbtnvgihdfiktncvlhck");
let another_valid_otp = get_public_id("cccjgjgkhcbbgefdkbbditfjrlniggevfhenublfnrev");
let invalid_otp = get_public_id("gefdkbbditfjrlniggevfh");
assert_eq!(valid_otp.ok().unwrap(), "cccjgjgkhcbb");
assert_eq!(another_valid_otp.ok().unwrap(), "cccjgjgkhcbb");
assert!(invalid_otp.err().is_some());
}
#[test]
fn test_yubico_client() {
let client = YubicoClient::new(1, None);
let x = client
.verify("vvungrrdhvtklknvrtvuvbbkeidikkvgglrvdgrfcdft")
.unwrap();
assert_eq!(x.state, State::ReplayedOtp)
}
}