Drop generic support
This commit is contained in:
parent
608b6f2896
commit
cf6029aaf3
|
@ -17,7 +17,7 @@ fn main() {
|
||||||
|
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut rfc = Rfc6238::with_defaults("totp-sercret-123").unwrap();
|
let mut rfc = Rfc6238::with_defaults("totp-sercret-123".into()).unwrap();
|
||||||
|
|
||||||
// optional, set digits, issuer, account_name
|
// optional, set digits, issuer, account_name
|
||||||
rfc.digits(8).unwrap();
|
rfc.digits(8).unwrap();
|
||||||
|
|
56
src/lib.rs
56
src/lib.rs
|
@ -298,8 +298,8 @@ impl TOTP {
|
||||||
digits: usize,
|
digits: usize,
|
||||||
skew: u8,
|
skew: u8,
|
||||||
step: u64,
|
step: u64,
|
||||||
secret: T,
|
secret: Vec<u8>,
|
||||||
) -> Result<TOTP<T>, TotpUrlError> {
|
) -> Result<TOTP, TotpUrlError> {
|
||||||
crate::rfc::assert_digits(&digits)?;
|
crate::rfc::assert_digits(&digits)?;
|
||||||
crate::rfc::assert_secret_length(secret.as_ref())?;
|
crate::rfc::assert_secret_length(secret.as_ref())?;
|
||||||
Ok(TOTP {
|
Ok(TOTP {
|
||||||
|
@ -686,40 +686,45 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn comparison_different_algo() {
|
fn comparison_different_algo() {
|
||||||
let reference = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let reference =
|
||||||
let test = TOTP::new(Algorithm::SHA256, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
|
let test = TOTP::new(Algorithm::SHA256, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert_ne!(reference, test);
|
assert_ne!(reference, test);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn comparison_different_digits() {
|
fn comparison_different_digits() {
|
||||||
let reference = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let reference =
|
||||||
let test = TOTP::new(Algorithm::SHA1, 8, 1, 1, "TestSecretSuperSecret").unwrap();
|
TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
|
let test = TOTP::new(Algorithm::SHA1, 8, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert_ne!(reference, test);
|
assert_ne!(reference, test);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn comparison_different_skew() {
|
fn comparison_different_skew() {
|
||||||
let reference = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let reference =
|
||||||
let test = TOTP::new(Algorithm::SHA1, 6, 0, 1, "TestSecretSuperSecret").unwrap();
|
TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
|
let test = TOTP::new(Algorithm::SHA1, 6, 0, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert_ne!(reference, test);
|
assert_ne!(reference, test);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn comparison_different_step() {
|
fn comparison_different_step() {
|
||||||
let reference = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let reference =
|
||||||
let test = TOTP::new(Algorithm::SHA1, 6, 1, 30, "TestSecretSuperSecret").unwrap();
|
TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
|
let test = TOTP::new(Algorithm::SHA1, 6, 1, 30, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert_ne!(reference, test);
|
assert_ne!(reference, test);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn comparison_different_secret() {
|
fn comparison_different_secret() {
|
||||||
let reference = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let reference =
|
||||||
let test = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretDifferentSecret").unwrap();
|
TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
|
let test = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretDifferentSecret".into()).unwrap();
|
||||||
assert_ne!(reference, test);
|
assert_ne!(reference, test);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,7 +824,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn returns_base32() {
|
fn returns_base32() {
|
||||||
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
totp.get_secret_base32().as_str(),
|
totp.get_secret_base32().as_str(),
|
||||||
"KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ"
|
"KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ"
|
||||||
|
@ -829,14 +834,14 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn generate_token() {
|
fn generate_token() {
|
||||||
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert_eq!(totp.generate(1000).as_str(), "659761");
|
assert_eq!(totp.generate(1000).as_str(), "659761");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn generate_token_current() {
|
fn generate_token_current() {
|
||||||
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
let time = SystemTime::now()
|
let time = SystemTime::now()
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -850,28 +855,28 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn generates_token_sha256() {
|
fn generates_token_sha256() {
|
||||||
let totp = TOTP::new(Algorithm::SHA256, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let totp = TOTP::new(Algorithm::SHA256, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert_eq!(totp.generate(1000).as_str(), "076417");
|
assert_eq!(totp.generate(1000).as_str(), "076417");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn generates_token_sha512() {
|
fn generates_token_sha512() {
|
||||||
let totp = TOTP::new(Algorithm::SHA512, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let totp = TOTP::new(Algorithm::SHA512, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert_eq!(totp.generate(1000).as_str(), "473536");
|
assert_eq!(totp.generate(1000).as_str(), "473536");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn checks_token() {
|
fn checks_token() {
|
||||||
let totp = TOTP::new(Algorithm::SHA1, 6, 0, 1, "TestSecretSuperSecret").unwrap();
|
let totp = TOTP::new(Algorithm::SHA1, 6, 0, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert!(totp.check("659761", 1000));
|
assert!(totp.check("659761", 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn checks_token_current() {
|
fn checks_token_current() {
|
||||||
let totp = TOTP::new(Algorithm::SHA1, 6, 0, 1, "TestSecretSuperSecret").unwrap();
|
let totp = TOTP::new(Algorithm::SHA1, 6, 0, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert!(totp
|
assert!(totp
|
||||||
.check_current(&totp.generate_current().unwrap())
|
.check_current(&totp.generate_current().unwrap())
|
||||||
.unwrap());
|
.unwrap());
|
||||||
|
@ -881,7 +886,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn checks_token_with_skew() {
|
fn checks_token_with_skew() {
|
||||||
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret").unwrap();
|
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert!(
|
assert!(
|
||||||
totp.check("174269", 1000) && totp.check("659761", 1000) && totp.check("260393", 1000)
|
totp.check("174269", 1000) && totp.check("659761", 1000) && totp.check("260393", 1000)
|
||||||
);
|
);
|
||||||
|
@ -890,7 +895,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn next_step() {
|
fn next_step() {
|
||||||
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 30, "TestSecretSuperSecret").unwrap();
|
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 30, "TestSecretSuperSecret".into()).unwrap();
|
||||||
assert!(totp.next_step(0) == 30);
|
assert!(totp.next_step(0) == 30);
|
||||||
assert!(totp.next_step(29) == 30);
|
assert!(totp.next_step(29) == 30);
|
||||||
assert!(totp.next_step(30) == 60);
|
assert!(totp.next_step(30) == 60);
|
||||||
|
@ -899,7 +904,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn next_step_current() {
|
fn next_step_current() {
|
||||||
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 30, "TestSecretSuperSecret").unwrap();
|
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 30, "TestSecretSuperSecret".into()).unwrap();
|
||||||
let t = system_time().unwrap();
|
let t = system_time().unwrap();
|
||||||
assert!(totp.next_step_current().unwrap() == totp.next_step(t));
|
assert!(totp.next_step_current().unwrap() == totp.next_step(t));
|
||||||
}
|
}
|
||||||
|
@ -919,10 +924,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "otpauth")]
|
#[cfg(feature = "otpauth")]
|
||||||
fn from_url_default() {
|
fn from_url_default() {
|
||||||
let totp = TOTP::from_url(
|
let totp =
|
||||||
"otpauth://totp/GitHub:test?secret=KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ",
|
TOTP::from_url("otpauth://totp/GitHub:test?secret=KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ")
|
||||||
)
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
totp.secret,
|
totp.secret,
|
||||||
base32::decode(
|
base32::decode(
|
||||||
|
|
18
src/rfc.rs
18
src/rfc.rs
|
@ -117,7 +117,7 @@ impl Rfc6238 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
pub fn new(digits: usize, secret: T) -> Result<Rfc6238<T>, Rfc6238Error> {
|
pub fn new(digits: usize, secret: Vec<u8>) -> Result<Rfc6238, Rfc6238Error> {
|
||||||
assert_digits(&digits)?;
|
assert_digits(&digits)?;
|
||||||
assert_secret_length(secret.as_ref())?;
|
assert_secret_length(secret.as_ref())?;
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ impl Rfc6238 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
pub fn with_defaults(secret: T) -> Result<Rfc6238<T>, Rfc6238Error> {
|
pub fn with_defaults(secret: Vec<u8>) -> Result<Rfc6238, Rfc6238Error> {
|
||||||
Rfc6238::new(6, secret)
|
Rfc6238::new(6, secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,11 +169,11 @@ impl Rfc6238 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
impl<T: AsRef<[u8]>> TryFrom<Rfc6238<T>> for TOTP<T> {
|
impl TryFrom<Rfc6238> for TOTP {
|
||||||
type Error = TotpUrlError;
|
type Error = TotpUrlError;
|
||||||
|
|
||||||
/// Try to create a [TOTP](struct.TOTP.html) from a [Rfc6238](struct.Rfc6238.html) config
|
/// Try to create a [TOTP](struct.TOTP.html) from a [Rfc6238](struct.Rfc6238.html) config
|
||||||
fn try_from(rfc: Rfc6238<T>) -> Result<Self, Self::Error> {
|
fn try_from(rfc: Rfc6238) -> Result<Self, Self::Error> {
|
||||||
TOTP::new(rfc.algorithm, rfc.digits, rfc.skew, rfc.step, rfc.secret)
|
TOTP::new(rfc.algorithm, rfc.digits, rfc.skew, rfc.step, rfc.secret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ mod tests {
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn new_rfc_digits() {
|
fn new_rfc_digits() {
|
||||||
for x in 0..=20 {
|
for x in 0..=20 {
|
||||||
let rfc = Rfc6238::new(x, GOOD_SECRET.to_string());
|
let rfc = Rfc6238::new(x, GOOD_SECRET.into());
|
||||||
if !(6..=8).contains(&x) {
|
if !(6..=8).contains(&x) {
|
||||||
assert!(rfc.is_err());
|
assert!(rfc.is_err());
|
||||||
assert!(matches!(rfc.unwrap_err(), Rfc6238Error::InvalidDigits(_)));
|
assert!(matches!(rfc.unwrap_err(), Rfc6238Error::InvalidDigits(_)));
|
||||||
|
@ -237,8 +237,8 @@ mod tests {
|
||||||
let mut secret = String::from("");
|
let mut secret = String::from("");
|
||||||
for _ in 0..=20 {
|
for _ in 0..=20 {
|
||||||
secret = format!("{}{}", secret, "0");
|
secret = format!("{}{}", secret, "0");
|
||||||
let rfc = Rfc6238::new(6, secret.clone());
|
let rfc = Rfc6238::new(6, secret.as_bytes().to_vec());
|
||||||
let rfc_default = Rfc6238::with_defaults(secret.clone());
|
let rfc_default = Rfc6238::with_defaults(secret.as_bytes().to_vec());
|
||||||
if secret.len() < 16 {
|
if secret.len() < 16 {
|
||||||
assert!(rfc.is_err());
|
assert!(rfc.is_err());
|
||||||
assert!(matches!(rfc.unwrap_err(), Rfc6238Error::SecretTooSmall(_)));
|
assert!(matches!(rfc.unwrap_err(), Rfc6238Error::SecretTooSmall(_)));
|
||||||
|
@ -257,11 +257,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "otpauth"))]
|
#[cfg(not(feature = "otpauth"))]
|
||||||
fn rfc_to_totp_ok() {
|
fn rfc_to_totp_ok() {
|
||||||
let rfc = Rfc6238::new(8, GOOD_SECRET.to_string()).unwrap();
|
let rfc = Rfc6238::new(8, GOOD_SECRET.into()).unwrap();
|
||||||
let totp = TOTP::try_from(rfc);
|
let totp = TOTP::try_from(rfc);
|
||||||
assert!(totp.is_ok());
|
assert!(totp.is_ok());
|
||||||
let otp = totp.unwrap();
|
let otp = totp.unwrap();
|
||||||
assert_eq!(&otp.secret, GOOD_SECRET);
|
assert_eq!(&otp.secret, GOOD_SECRET.as_bytes());
|
||||||
assert_eq!(otp.algorithm, crate::Algorithm::SHA1);
|
assert_eq!(otp.algorithm, crate::Algorithm::SHA1);
|
||||||
assert_eq!(otp.digits, 8);
|
assert_eq!(otp.digits, 8);
|
||||||
assert_eq!(otp.skew, 1);
|
assert_eq!(otp.skew, 1);
|
||||||
|
|
Loading…
Reference in New Issue