Merge pull request #39 from constantoine/add_test_coverage

Add coverage for rfc.rs
This commit is contained in:
Cléo Rebert 2022-10-10 11:20:01 +02:00 committed by GitHub
commit c36b3a9507
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 161 additions and 5 deletions

View File

@ -15,7 +15,7 @@ categories = ["authentication", "web-programming"]
features = [ "qr", "serde_support", "otpauth" ]
[features]
default = []
default = ["qr", "gen_secret"]
otpauth = ["url", "urlencoding"]
qr = ["qrcodegen", "image", "base64", "otpauth"]
serde_support = ["serde"]

View File

@ -750,6 +750,31 @@ mod tests {
assert_eq!(url.as_str(), "otpauth://totp/Github:constantoine%40github.com?issuer=Github&secret=KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ&digits=6&algorithm=SHA512");
}
#[test]
#[cfg(all(feature = "otpauth", feature = "gen_secret"))]
fn ttl() {
let secret = Secret::default();
let totp_rfc = Rfc6238::with_defaults(secret.to_bytes().unwrap()).unwrap();
let totp = TOTP::from_rfc6238(totp_rfc);
assert!(totp.is_ok());
}
#[test]
#[cfg(feature = "otpauth")]
fn ttl_ok() {
let totp = TOTP::new(
Algorithm::SHA512,
6,
1,
1,
"TestSecretSuperSecret",
Some("Github".to_string()),
"constantoine@github.com".to_string(),
)
.unwrap();
assert!(totp.ttl().is_ok());
}
#[test]
#[cfg(not(feature = "otpauth"))]
fn returns_base32() {
@ -889,6 +914,24 @@ mod tests {
assert_eq!(totp.step, 60);
}
#[test]
#[cfg(feature = "otpauth")]
fn from_url_query_sha512() {
let totp = TOTP::<Vec<u8>>::from_url("otpauth://totp/GitHub:test?secret=KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ&digits=8&period=60&algorithm=SHA512").unwrap();
assert_eq!(
totp.secret,
base32::decode(
base32::Alphabet::RFC4648 { padding: false },
"KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ"
)
.unwrap()
);
assert_eq!(totp.algorithm, Algorithm::SHA512);
assert_eq!(totp.digits, 8);
assert_eq!(totp.skew, 1);
assert_eq!(totp.step, 60);
}
#[test]
#[cfg(feature = "otpauth")]
fn from_url_to_url() {
@ -906,6 +949,24 @@ mod tests {
assert_eq!(totp.get_url(), totp_bis.get_url());
}
#[test]
#[cfg(feature = "otpauth")]
fn from_url_unknown_param() {
let totp = TOTP::<Vec<u8>>::from_url("otpauth://totp/GitHub:test?secret=KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ&digits=8&period=60&algorithm=SHA256&foo=bar").unwrap();
assert_eq!(
totp.secret,
base32::decode(
base32::Alphabet::RFC4648 { padding: false },
"KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ"
)
.unwrap()
);
assert_eq!(totp.algorithm, Algorithm::SHA256);
assert_eq!(totp.digits, 8);
assert_eq!(totp.skew, 1);
assert_eq!(totp.step, 60);
}
#[test]
#[cfg(feature = "otpauth")]
fn from_url_issuer_special() {
@ -943,6 +1004,24 @@ mod tests {
assert_eq!(totp.issuer.unwrap(), "GitHub");
}
#[test]
#[cfg(feature = "otpauth")]
fn from_url_wrong_scheme() {
let totp = TOTP::<Vec<u8>>::from_url("http://totp/GitHub:test?issuer=GitHub&secret=KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ&digits=8&period=60&algorithm=SHA256");
assert!(totp.is_err());
let err = totp.unwrap_err();
assert!(matches!(err, TotpUrlError::Scheme(_)));
}
#[test]
#[cfg(feature = "otpauth")]
fn from_url_wrong_algo() {
let totp = TOTP::<Vec<u8>>::from_url("otpauth://totp/GitHub:test?issuer=GitHub&secret=KRSXG5CTMVRXEZLUKN2XAZLSKNSWG4TFOQ&digits=8&period=60&algorithm=MD5");
assert!(totp.is_err());
let err = totp.unwrap_err();
assert!(matches!(err, TotpUrlError::Algorithm(_)));
}
#[test]
#[cfg(feature = "otpauth")]
fn from_url_query_different_issuers() {
@ -981,4 +1060,21 @@ mod tests {
"025809c9db9c2c918930e018549c90929a083ee757156737812bad40ded64312c1526c73d8f2f59d5c203b97141ddfc331b1192e234f4f43257f50a6d05e382f"
);
}
#[test]
#[cfg(feature = "qr")]
fn generates_qr_ok() {
let totp = TOTP::new(
Algorithm::SHA1,
6,
1,
1,
"TestSecretSuperSecret",
Some("Github".to_string()),
"constantoine@github.com".to_string(),
)
.unwrap();
let qr = totp.get_qr();
assert!(qr.is_ok());
}
}

View File

@ -313,6 +313,21 @@ mod tests {
assert!(totp.is_ok());
}
#[test]
#[cfg(feature = "otpauth")]
fn rfc_with_default_set_values() {
let mut rfc = Rfc6238::with_defaults(GOOD_SECRET.to_string()).unwrap();
let ok = rfc.digits(8);
assert!(ok.is_ok());
assert_eq!(rfc.account_name, "");
assert_eq!(rfc.issuer, Some("".to_string()));
rfc.issuer("Github".to_string());
rfc.account_name("constantoine".to_string());
assert_eq!(rfc.account_name, "constantoine");
assert_eq!(rfc.issuer, Some("Github".to_string()));
assert_eq!(rfc.digits, 8)
}
#[test]
#[cfg(not(feature = "otpauth"))]
fn rfc_with_default_set_values() {
@ -325,4 +340,25 @@ mod tests {
assert!(ok.is_ok());
assert_eq!(rfc.digits, 8)
}
#[test]
#[cfg(not(feature = "otpauth"))]
fn digits_error() {
let error = crate::Rfc6238Error::InvalidDigits(9);
assert_eq!(
error.to_string(),
"Implementations MUST extract a 6-digit code at a minimum and possibly 7 and 8-digit code. 9 digits is not allowed".to_string()
)
}
#[test]
#[cfg(not(feature = "otpauth"))]
fn secret_length_error() {
let error = Rfc6238Error::SecretTooSmall(120);
assert_eq!(
error.to_string(),
"The length of the shared secret MUST be at least 128 bits. 120 bits is not enough"
.to_string()
)
}
}

View File

@ -237,9 +237,33 @@ mod tests {
#[test]
#[cfg(feature = "gen_secret")]
fn secret_gen_secret() {
match Secret::generate_secret() {
Secret::Raw(secret) => assert_eq!(secret.len(), 20),
Secret::Encoded(_) => panic!("should be raw"),
}
let sec = Secret::generate_secret();
assert!(matches!(sec, Secret::Raw(_)));
assert_eq!(sec.to_bytes().unwrap().len(), 20);
}
#[test]
#[cfg(feature = "gen_secret")]
fn secret_gen_default() {
let sec = Secret::default();
assert!(matches!(sec, Secret::Raw(_)));
assert_eq!(sec.to_bytes().unwrap().len(), 20);
}
#[test]
#[cfg(feature = "gen_secret")]
fn secret_empty() {
let non_ascii = vec![240, 159, 146, 150];
let sec = Secret::Encoded(std::str::from_utf8(&non_ascii).unwrap().to_owned());
let to_r = sec.to_raw();
assert!(to_r.is_err());
let to_b = sec.to_bytes();
assert!(to_b.is_err());
}
}