Added GetNewMasterPass state and added restrictions on the master password

This commit is contained in:
StNicolay 2023-06-04 20:41:10 +03:00
parent 4d4cec1353
commit 9d0fa17a0e
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
7 changed files with 79 additions and 3 deletions

View File

@ -2,7 +2,7 @@
pub mod account; pub mod account;
pub mod master_pass; pub mod master_pass;
pub mod password_generation; pub mod passwords;
pub mod prelude; pub mod prelude;
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]

View File

@ -50,3 +50,28 @@ fn generate_password() -> ArrayString<32> {
pub fn generate_passwords() -> [ArrayString<32>; 10] { pub fn generate_passwords() -> [ArrayString<32>; 10] {
array::from_fn(|_| generate_password()) array::from_fn(|_| generate_password())
} }
#[inline]
pub fn check_master_pass(password: &str) -> bool {
if password.chars().count() < 8 {
return false;
}
let mut flags = PasswordFlags::empty();
for char in password.chars() {
if char.is_lowercase() {
flags |= PasswordFlags::LOWERCASE
} else if char.is_uppercase() {
flags |= PasswordFlags::UPPERCASE
} else if char.is_ascii_digit() {
flags |= PasswordFlags::NUMBER;
} else if char.is_ascii_punctuation() {
flags |= PasswordFlags::SPECIAL_CHARACTER
}
if flags.is_all() {
return true;
}
}
false
}

View File

@ -1,6 +1,6 @@
use crate::markups::deletion_markup; use crate::markups::deletion_markup;
use arrayvec::ArrayString; use arrayvec::ArrayString;
use cryptography::password_generation::generate_passwords; use cryptography::passwords::generate_passwords;
use std::fmt::Write; use std::fmt::Write;
use teloxide::{adaptors::Throttle, prelude::*, types::ParseMode}; use teloxide::{adaptors::Throttle, prelude::*, types::ParseMode};
use tokio::task::spawn_blocking; use tokio::task::spawn_blocking;

View File

@ -44,7 +44,10 @@ pub async fn set_master_pass(
.send_message(msg.chat.id, "Send new master password") .send_message(msg.chat.id, "Send new master password")
.await?; .await?;
dialogue dialogue
.update(State::GetPassword(Handler::new(get_master_pass, previous))) .update(State::GetNewMasterPass(Handler::new(
get_master_pass,
previous,
)))
.await?; .await?;
Ok(()) Ok(())
} }

View File

@ -50,6 +50,7 @@ pub fn get_dispatcher(
.branch(case![State::GetExistingName(next)].endpoint(state::get_existing_name)) .branch(case![State::GetExistingName(next)].endpoint(state::get_existing_name))
.branch(case![State::GetNewName(next)].endpoint(state::get_new_name)) .branch(case![State::GetNewName(next)].endpoint(state::get_new_name))
.branch(case![State::GetMasterPass(next)].endpoint(state::get_master_pass)) .branch(case![State::GetMasterPass(next)].endpoint(state::get_master_pass))
.branch(case![State::GetNewMasterPass(next)].endpoint(state::get_new_master_pass))
.branch(case![State::GetLogin(next)].endpoint(state::get_login)) .branch(case![State::GetLogin(next)].endpoint(state::get_login))
.branch(case![State::GetPassword(next)].endpoint(state::get_password)) .branch(case![State::GetPassword(next)].endpoint(state::get_password))
.branch(case![State::GetUser(next)].endpoint(state::get_user)) .branch(case![State::GetUser(next)].endpoint(state::get_user))

View File

@ -0,0 +1,44 @@
use crate::MainDialogue;
use cryptography::passwords::check_master_pass;
use sea_orm::DatabaseConnection;
use teloxide::{adaptors::Throttle, prelude::*};
const INVALID_MASTER_PASS_MESSAGE: &str = "Master password is invalid. It must be at least 8 characters long. \
It also has to contain at least one lowercase, one uppercase, one number and one punctuation character";
/// Checks that the account with that name exists
#[inline]
async fn check_new_master_pass(
bot: &Throttle<Bot>,
msg: &Message,
password: &str,
) -> crate::Result<Option<Message>> {
let is_valid = check_master_pass(password);
if !is_valid {
let msg = bot
.send_message(msg.chat.id, INVALID_MASTER_PASS_MESSAGE)
.await?;
return Ok(Some(msg));
}
Ok(None)
}
/// Handles GetNewMasterPass state
pub async fn get_new_master_pass(
bot: Throttle<Bot>,
msg: Message,
db: DatabaseConnection,
dialogue: MainDialogue,
next: super::PackagedHandler<String>,
) -> crate::Result<()> {
super::generic::generic(
bot,
msg,
db,
dialogue,
|bot, msg, _, password| Box::pin(check_new_master_pass(bot, msg, password)),
"Couldn't get the text of the message. Send the master password again",
next,
)
.await
}

View File

@ -4,6 +4,7 @@ mod generic;
mod get_existing_name; mod get_existing_name;
mod get_login; mod get_login;
mod get_master_pass; mod get_master_pass;
mod get_new_master_pass;
mod get_new_name; mod get_new_name;
mod get_password; mod get_password;
mod get_user; mod get_user;
@ -12,6 +13,7 @@ mod handler;
pub use get_existing_name::get_existing_name; pub use get_existing_name::get_existing_name;
pub use get_login::get_login; pub use get_login::get_login;
pub use get_master_pass::get_master_pass; pub use get_master_pass::get_master_pass;
pub use get_new_master_pass::get_new_master_pass;
pub use get_new_name::get_new_name; pub use get_new_name::get_new_name;
pub use get_password::get_password; pub use get_password::get_password;
pub use get_user::get_user; pub use get_user::get_user;
@ -27,6 +29,7 @@ pub enum State {
GetExistingName(PackagedHandler<String>), GetExistingName(PackagedHandler<String>),
GetNewName(PackagedHandler<String>), GetNewName(PackagedHandler<String>),
GetMasterPass(PackagedHandler<String>), GetMasterPass(PackagedHandler<String>),
GetNewMasterPass(PackagedHandler<String>),
GetLogin(PackagedHandler<String>), GetLogin(PackagedHandler<String>),
GetPassword(PackagedHandler<String>), GetPassword(PackagedHandler<String>),
GetUser(PackagedHandler<User>), GetUser(PackagedHandler<User>),