Pierre Hubert e80edcdfb3
All checks were successful
continuous-integration/drone/push Build is passing
Update Rust crate base32 to 0.5.0 (#24)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [base32](https://github.com/andreasots/base32) | dependencies | minor | `0.4.0` -> `0.5.0` |

---

### Release Notes

<details>
<summary>andreasots/base32 (base32)</summary>

### [`v0.5.0`](https://github.com/andreasots/base32/compare/v0.4.0...v0.5.0)

[Compare Source](https://github.com/andreasots/base32/compare/v0.4.0...v0.5.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNjguMCIsInVwZGF0ZWRJblZlciI6IjM3LjM2OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: #24
2024-05-23 09:34:15 +00:00

101 lines
2.7 KiB
Rust

use std::time::{SystemTime, UNIX_EPOCH};
use base32::Alphabet;
use clap::{Parser, Subcommand};
use totp_rfc6238::{HashAlgorithm, TotpGenerator};
/// Get the current time since epoch
pub fn time() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
}
/// TOTP - One Time Password generator
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
#[clap(subcommand)]
command: SubCommands,
}
#[derive(Subcommand, Debug)]
enum SubCommands {
/// Setup configuration
Setup,
/// Get a TOTP code
#[clap(arg_required_else_help = true)]
Code {
/// The secret to use
#[clap(short, long)]
secret: String,
/// Interval between two numbers generation
#[clap(short, long, default_value_t = 30)]
topt_step: u64,
/// Size of generated secret
#[clap(short, long, default_value_t = 6)]
len: usize,
},
}
fn main() {
let args: Args = Args::parse();
match args.command {
SubCommands::Setup => {
println!("To configure TOPT :");
println!("1. Please open https://mysignins.microsoft.com/security-info");
println!("2. Click on \"Add method\"");
println!(
"3. On the popup that appears, choose \"Authenticator app\" and click \"Add\"."
);
println!(
"4. Click on \"I want to use a different authenticator app\" and click \"Next\""
);
println!("5. Click on \"Can't save image ?\" and copy the \"Secret key\"");
println!(
"6. Re-run this program running {} code --secret <SECRET>",
std::env::args().next().unwrap()
);
println!("7. Back on the browser, click Next and paste copied code");
}
SubCommands::Code {
secret,
topt_step,
len,
} => {
let totp_generator = TotpGenerator::new()
.set_digit(len)
.unwrap()
.set_step(topt_step)
.unwrap()
.set_hash_algorithm(HashAlgorithm::SHA1)
.build();
let key = base32::decode(Alphabet::Rfc4648 { padding: true }, &secret).unwrap();
let code = totp_generator.get_code(&key);
let next_update = totp_generator.get_next_update_time().unwrap();
println!("Secret = {}", code);
println!("Next update = {} seconds", next_update - time());
}
}
}
#[cfg(test)]
mod test {
use crate::Args;
#[test]
fn verify_cli() {
use clap::CommandFactory;
Args::command().debug_assert()
}
}