diff --git a/.gitignore b/.gitignore index 96ef6c0..315330e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /target Cargo.lock +.vscode/settings.json +cobertura.xml diff --git a/Cargo.toml b/Cargo.toml index c3cf279..9696ff3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "totp-rs" -version = "1.2.1" +version = "1.3.0" authors = ["Cleo Rebert "] edition = "2021" readme = "README.md" diff --git a/README.md b/README.md index 967f72f..fe0630c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ With optional feature "serde_support", library-defined types will be Deserialize Add it to your `Cargo.toml`: ```toml [dependencies] -totp-rs = "~1.2" +totp-rs = "~1.3" ``` You can then do something like: ```Rust @@ -31,12 +31,9 @@ let totp = TOTP::new( 30, "supersecret", ); -let time = SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH).unwrap() - .as_secs(); let url = totp.get_url("user@example.com", "my-org.com"); println!("{}", url); -let token = totp.generate(time); +let token = totp.generate_current().unwrap(); println!("{}", token); ``` @@ -45,7 +42,7 @@ println!("{}", token); Add it to your `Cargo.toml`: ```toml [dependencies.totp-rs] -version = "~1.2" +version = "~1.3" features = ["qr"] ``` You can then do something like: @@ -67,6 +64,6 @@ println!("{}", code); Add it to your `Cargo.toml`: ```toml [dependencies.totp-rs] -version = "~1.2" +version = "~1.3" features = ["serde_support"] ``` diff --git a/src/lib.rs b/src/lib.rs index be0d599..64ecda5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,12 +19,9 @@ //! 30, //! "supersecret", //! ); -//! let time = SystemTime::now() -//! .duration_since(SystemTime::UNIX_EPOCH).unwrap() -//! .as_secs(); //! let url = totp.get_url("user@example.com", "my-org.com"); //! println!("{}", url); -//! let token = totp.generate(time); +//! let token = totp.generate_current().unwrap(); //! println!("{}", token); //! ``` //! @@ -165,7 +162,7 @@ impl> TOTP { ) } - /// 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 { let result: &[u8] = &self.sign(time); let offset = (result.last().unwrap() & 15) as usize; @@ -183,7 +180,7 @@ impl> TOTP { 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 { let basestep = time / self.step - (self.skew as u64); for i in 0..self.skew * 2 + 1 { @@ -223,6 +220,8 @@ impl> TOTP { } /// 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 /// @@ -248,20 +247,8 @@ impl> TOTP { // Draw the border for x in 0..image_size { for y in 0..image_size { - if y < 8*4 || y >= image_size - 8*4 { - canvas.put_pixel( - x, - y, - Luma([255]), - ); - continue; - } - if x < 8*4 || x >= image_size - 8*4 { - canvas.put_pixel( - x, - y, - Luma([255]), - ); + if (y < 8*4 || y >= image_size - 8*4) || (x < 8*4 || x >= image_size - 8*4) { + canvas.put_pixel(x, y, Luma([255])); } } } @@ -378,11 +365,20 @@ mod tests { } #[test] - fn generates_token() { + fn generate_token() { let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecret"); 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] fn generates_token_sha256() { let totp = TOTP::new(Algorithm::SHA256, 6, 1, 1, "TestSecret"); @@ -404,6 +400,13 @@ mod tests { 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] fn checks_token_with_skew() { let totp = TOTP::new(Algorithm::SHA1, 6, 1, 1, "TestSecret");