53 lines
1.5 KiB
Rust
53 lines
1.5 KiB
Rust
|
use base32::Alphabet;
|
||
|
use rand::Rng;
|
||
|
|
||
|
use crate::data::app_config::AppConfig;
|
||
|
use crate::data::user::User;
|
||
|
|
||
|
const BASE32_ALPHABET: Alphabet = Alphabet::RFC4648 { padding: true };
|
||
|
const NUM_DIGITS: i32 = 6;
|
||
|
const PERIOD: i32 = 30;
|
||
|
|
||
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||
|
pub struct TotpKey {
|
||
|
encoded: String,
|
||
|
}
|
||
|
|
||
|
impl TotpKey {
|
||
|
/// Generate a new TOTP key
|
||
|
pub fn new_random() -> Self {
|
||
|
let random_bytes = rand::thread_rng().gen::<[u8; 10]>();
|
||
|
TotpKey {
|
||
|
encoded: base32::encode(BASE32_ALPHABET, &random_bytes)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Get QrCode URL for user
|
||
|
///
|
||
|
/// Based on https://github.com/google/google-authenticator/wiki/Key-Uri-Format
|
||
|
pub fn url_for_user(&self, u: &User, conf: &AppConfig) -> String {
|
||
|
format!(
|
||
|
"otpauth://totp/{}:{}?secret={}&issuer={}&algorithm=SHA1&digits={}&period={}",
|
||
|
urlencoding::encode(&conf.domain_name()),
|
||
|
urlencoding::encode(&u.username),
|
||
|
self.encoded,
|
||
|
urlencoding::encode(&conf.domain_name()),
|
||
|
NUM_DIGITS,
|
||
|
PERIOD,
|
||
|
)
|
||
|
}
|
||
|
|
||
|
/// Get account name
|
||
|
pub fn account_name(&self, u: &User, conf: &AppConfig) -> String {
|
||
|
format!(
|
||
|
"{}:{}",
|
||
|
urlencoding::encode(conf.domain_name()),
|
||
|
urlencoding::encode(&u.username)
|
||
|
)
|
||
|
}
|
||
|
|
||
|
/// Get current secret in base32 format
|
||
|
pub fn get_secret(&self) -> String {
|
||
|
self.encoded.to_string()
|
||
|
}
|
||
|
}
|