Added gen password command

This commit is contained in:
StNicolay 2023-05-07 18:07:48 +03:00
parent ef3a188120
commit 072e030e32
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
5 changed files with 67 additions and 0 deletions

1
Cargo.lock generated
View File

@ -1318,6 +1318,7 @@ name = "pass_manager"
version = "0.1.0"
dependencies = [
"anyhow",
"arrayvec",
"chacha20poly1305",
"dotenv",
"futures",

View File

@ -13,6 +13,7 @@ members = [".", "migration"]
[dependencies]
anyhow = "1.0.70"
arrayvec = "0.7.2"
chacha20poly1305 = { version = "0.10.1", features = ["std"] }
dotenv = "0.15.0"
futures = "0.3.28"

View File

@ -0,0 +1,60 @@
use arrayvec::{ArrayString, ArrayVec};
use rand::{rngs::OsRng, seq::SliceRandom};
use std::{iter, str::from_utf8_unchecked};
use teloxide::{adaptors::Throttle, prelude::*, types::ParseMode};
use tokio::task::JoinSet;
use crate::handlers::markups::deletion_markup;
const CHARS: &'static [u8] = br##"!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~"##;
#[inline]
fn check_generated_password(password: &[u8]) -> bool {
let mut flags: u8 = 0;
for &byte in password {
match byte {
b'a'..=b'z' => flags |= 0b1,
b'A'..=b'Z' => flags |= 0b10,
b'0'..=b'9' => flags |= 0b100,
b'!'..=b'/' | b':'..=b'@' | b'['..=b'`' | b'{'..=b'~' => flags |= 0b1000,
_ => (),
}
if flags == 0b1111 {
return true;
}
}
false
}
fn generete_password() -> ArrayString<34> {
loop {
let password: ArrayVec<u8, 32> = iter::repeat_with(|| *CHARS.choose(&mut OsRng).unwrap())
.take(32)
.collect();
if check_generated_password(&password) {
let mut string = ArrayString::<34>::new_const();
string.push('`');
unsafe { string.push_str(from_utf8_unchecked(&password)) };
string.push('`');
return string;
}
}
}
pub async fn gen_password(bot: Throttle<Bot>, msg: Message) -> crate::Result<()> {
let mut message = ArrayString::<{ 11 + 35 * 10 }>::new();
message.push_str("Passwords:\n");
let mut join_set = JoinSet::new();
for _ in 0..10 {
join_set.spawn_blocking(|| generete_password());
}
while let Some(password) = join_set.join_next().await {
message.push_str(password?.as_str());
message.push('\n')
}
bot.send_message(msg.chat.id, message.as_str())
.parse_mode(ParseMode::MarkdownV2)
.reply_markup(deletion_markup())
.await?;
Ok(())
}

View File

@ -3,6 +3,7 @@ mod default;
mod delete;
mod delete_all;
mod export;
mod gen_password;
mod get_account;
mod get_accounts;
mod help;
@ -14,6 +15,7 @@ pub use default::default;
pub use delete::delete;
pub use delete_all::delete_all;
pub use export::export;
pub use gen_password::gen_password;
pub use get_account::get_account;
pub use get_accounts::get_accounts;
pub use help::help;

View File

@ -61,6 +61,8 @@ enum Command {
Export,
#[command(description = "loads the accounts from a json file")]
Import,
#[command(description = "generates 10 secure passwords")]
GenPassword,
}
#[derive(Default, Clone)]
@ -85,6 +87,7 @@ pub fn get_dispatcher(
let command_handler = filter_command::<Command, _>()
.branch(case![Command::Help].endpoint(commands::help))
.branch(case![Command::SetMasterPass].endpoint(commands::set_master_pass))
.branch(case![Command::GenPassword].endpoint(commands::gen_password))
.branch(master_password_check::get_handler())
.branch(case![Command::AddAccount].endpoint(commands::add_account))
.branch(case![Command::GetAccount].endpoint(commands::get_account))