Added GetNewMasterPass state and added restrictions on the master password
This commit is contained in:
		@@ -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)]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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))
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								src/state/get_new_master_pass.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/state/get_new_master_pass.rs
									
									
									
									
									
										Normal 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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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>),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user