summaryrefslogtreecommitdiff
path: root/src/totp.rs
blob: 09b45031a1126e3ddbfde38e3b4ae9bc1a1663f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use oath::totp_custom_time;
use oath::HashType;
use std::time::{UNIX_EPOCH, SystemTime};

pub fn verify(secret: &str, token: &str) -> Result<bool, &'static str> {
    let time_step = 30;
    let totp = |time| {
        totp_custom_time(secret, 6, 0, time_step, time, &HashType::SHA512)
            .map(|t| {
                debug!("Generated OTP for probing {} for key {}", t, secret);
                t
            })
            .map(|t| format!("{:06}", t) == *token)
    };
    let current_time: u64 = SystemTime::now().duration_since(UNIX_EPOCH)
        .expect("Earlier than 1970-01-01 00:00:00 UTC").as_secs();
    if current_time % time_step <= 5 && totp(current_time - 30)? {
        return Ok(true);
    }

    if current_time % time_step >= 25 && totp(current_time + 30)? {
        return Ok(true);
    }

    if totp(current_time)? {
        return Ok(true);
    }

    Ok(false)
}