Merge pull request #18 from constantoine/add_tests
Add tests for generate_current and check_current
This commit is contained in:
commit
733c27970e
|
@ -1,2 +1,4 @@
|
||||||
/target
|
/target
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
.vscode/settings.json
|
||||||
|
cobertura.xml
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "totp-rs"
|
name = "totp-rs"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
authors = ["Cleo Rebert <cleo.rebert@gmail.com>"]
|
authors = ["Cleo Rebert <cleo.rebert@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
11
README.md
11
README.md
|
@ -17,7 +17,7 @@ With optional feature "serde_support", library-defined types will be Deserialize
|
||||||
Add it to your `Cargo.toml`:
|
Add it to your `Cargo.toml`:
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
totp-rs = "~1.2"
|
totp-rs = "~1.3"
|
||||||
```
|
```
|
||||||
You can then do something like:
|
You can then do something like:
|
||||||
```Rust
|
```Rust
|
||||||
|
@ -31,12 +31,9 @@ let totp = TOTP::new(
|
||||||
30,
|
30,
|
||||||
"supersecret",
|
"supersecret",
|
||||||
);
|
);
|
||||||
let time = SystemTime::now()
|
|
||||||
.duration_since(SystemTime::UNIX_EPOCH).unwrap()
|
|
||||||
.as_secs();
|
|
||||||
let url = totp.get_url("user@example.com", "my-org.com");
|
let url = totp.get_url("user@example.com", "my-org.com");
|
||||||
println!("{}", url);
|
println!("{}", url);
|
||||||
let token = totp.generate(time);
|
let token = totp.generate_current().unwrap();
|
||||||
println!("{}", token);
|
println!("{}", token);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -45,7 +42,7 @@ println!("{}", token);
|
||||||
Add it to your `Cargo.toml`:
|
Add it to your `Cargo.toml`:
|
||||||
```toml
|
```toml
|
||||||
[dependencies.totp-rs]
|
[dependencies.totp-rs]
|
||||||
version = "~1.2"
|
version = "~1.3"
|
||||||
features = ["qr"]
|
features = ["qr"]
|
||||||
```
|
```
|
||||||
You can then do something like:
|
You can then do something like:
|
||||||
|
@ -67,6 +64,6 @@ println!("{}", code);
|
||||||
Add it to your `Cargo.toml`:
|
Add it to your `Cargo.toml`:
|
||||||
```toml
|
```toml
|
||||||
[dependencies.totp-rs]
|
[dependencies.totp-rs]
|
||||||
version = "~1.2"
|
version = "~1.3"
|
||||||
features = ["serde_support"]
|
features = ["serde_support"]
|
||||||
```
|
```
|
||||||
|
|
45
src/lib.rs
45
src/lib.rs
|
@ -19,12 +19,9 @@
|
||||||
//! 30,
|
//! 30,
|
||||||
//! "supersecret",
|
//! "supersecret",
|
||||||
//! );
|
//! );
|
||||||
//! let time = SystemTime::now()
|
|
||||||
//! .duration_since(SystemTime::UNIX_EPOCH).unwrap()
|
|
||||||
//! .as_secs();
|
|
||||||
//! let url = totp.get_url("user@example.com", "my-org.com");
|
//! let url = totp.get_url("user@example.com", "my-org.com");
|
||||||
//! println!("{}", url);
|
//! println!("{}", url);
|
||||||
//! let token = totp.generate(time);
|
//! let token = totp.generate_current().unwrap();
|
||||||
//! println!("{}", token);
|
//! println!("{}", token);
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
@ -165,7 +162,7 @@ impl<T: AsRef<[u8]>> TOTP<T> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Will generate a token according to the provided timestamp in seconds
|
/// Will generate a token given the provided timestamp in seconds
|
||||||
pub fn generate(&self, time: u64) -> String {
|
pub fn generate(&self, time: u64) -> String {
|
||||||
let result: &[u8] = &self.sign(time);
|
let result: &[u8] = &self.sign(time);
|
||||||
let offset = (result.last().unwrap() & 15) as usize;
|
let offset = (result.last().unwrap() & 15) as usize;
|
||||||
|
@ -183,7 +180,7 @@ impl<T: AsRef<[u8]>> TOTP<T> {
|
||||||
Ok(self.generate(t))
|
Ok(self.generate(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Will check if token is valid by current time, accounting [skew](struct.TOTP.html#structfield.skew)
|
/// Will check if token is valid given the provided timestamp in seconds, accounting [skew](struct.TOTP.html#structfield.skew)
|
||||||
pub fn check(&self, token: &str, time: u64) -> bool {
|
pub fn check(&self, token: &str, time: u64) -> bool {
|
||||||
let basestep = time / self.step - (self.skew as u64);
|
let basestep = time / self.step - (self.skew as u64);
|
||||||
for i in 0..self.skew * 2 + 1 {
|
for i in 0..self.skew * 2 + 1 {
|
||||||
|
@ -223,6 +220,8 @@ impl<T: AsRef<[u8]>> TOTP<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Will return a qrcode to automatically add a TOTP as a base64 string. Needs feature `qr` to be enabled!
|
/// Will return a qrcode to automatically add a TOTP as a base64 string. Needs feature `qr` to be enabled!
|
||||||
|
/// Result will be in the form of a string containing a base64-encoded png, which you can embed in HTML without needing
|
||||||
|
/// To store the png as a file.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
|
@ -248,20 +247,8 @@ impl<T: AsRef<[u8]>> TOTP<T> {
|
||||||
// Draw the border
|
// Draw the border
|
||||||
for x in 0..image_size {
|
for x in 0..image_size {
|
||||||
for y in 0..image_size {
|
for y in 0..image_size {
|
||||||
if y < 8*4 || y >= image_size - 8*4 {
|
if (y < 8*4 || y >= image_size - 8*4) || (x < 8*4 || x >= image_size - 8*4) {
|
||||||
canvas.put_pixel(
|
canvas.put_pixel(x, y, Luma([255]));
|
||||||
x,
|
|
||||||
y,
|
|
||||||
Luma([255]),
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if x < 8*4 || x >= image_size - 8*4 {
|
|
||||||
canvas.put_pixel(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
Luma([255]),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -378,11 +365,20 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generates_token() {
|
fn generate_token() {
|
||||||
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecret");
|
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecret");
|
||||||
assert_eq!(totp.generate(1000).as_str(), "718996");
|
assert_eq!(totp.generate(1000).as_str(), "718996");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn generate_token_current() {
|
||||||
|
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecret");
|
||||||
|
let time = SystemTime::now()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH).unwrap()
|
||||||
|
.as_secs();
|
||||||
|
assert_eq!(totp.generate(time).as_str(), totp.generate_current().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generates_token_sha256() {
|
fn generates_token_sha256() {
|
||||||
let totp = TOTP::new(Algorithm::SHA256, 6, 1, 1, "TestSecret");
|
let totp = TOTP::new(Algorithm::SHA256, 6, 1, 1, "TestSecret");
|
||||||
|
@ -404,6 +400,13 @@ mod tests {
|
||||||
assert!(!totp.check("714250", 2000));
|
assert!(!totp.check("714250", 2000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn checks_token_current() {
|
||||||
|
let totp = TOTP::new(Algorithm::SHA1, 6, 0, 1, "TestSecret");
|
||||||
|
assert!(totp.check_current(&totp.generate_current().unwrap()).unwrap());
|
||||||
|
assert!(!totp.check_current("bogus").unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn checks_token_with_skew() {
|
fn checks_token_with_skew() {
|
||||||
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecret");
|
let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecret");
|
||||||
|
|
Loading…
Reference in New Issue