Enabled clippy warnings and fixed them
This commit is contained in:
parent
f0116b3207
commit
6ae745fcd4
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -1909,9 +1909,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.21.8"
|
version = "0.21.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c"
|
checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ring",
|
"ring",
|
||||||
@ -3336,6 +3336,6 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.6.1"
|
version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12a3946ecfc929b583800f4629b6c25b88ac6e92a40ea5670f77112a85d40a8b"
|
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
|
||||||
|
@ -12,7 +12,7 @@ bitflags::bitflags! {
|
|||||||
const SPECIAL_CHARACTER = 0b1000;
|
const SPECIAL_CHARACTER = 0b1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||||
pub struct PasswordValidity: u8 {
|
pub struct PasswordValidity: u8 {
|
||||||
const NO_LOWERCASE = 0b00001;
|
const NO_LOWERCASE = 0b00001;
|
||||||
const NO_UPPERCASE = 0b00010;
|
const NO_UPPERCASE = 0b00010;
|
||||||
|
@ -9,7 +9,7 @@ use teloxide::types::CallbackQuery;
|
|||||||
|
|
||||||
type NameHash = Vec<u8>;
|
type NameHash = Vec<u8>;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum AlterableField {
|
pub enum AlterableField {
|
||||||
Name,
|
Name,
|
||||||
Login,
|
Login,
|
||||||
@ -38,37 +38,36 @@ impl FromStr for CallbackCommand {
|
|||||||
type Err = crate::errors::InvalidCommand;
|
type Err = crate::errors::InvalidCommand;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
use AlterableField::*;
|
|
||||||
use CallbackCommand::*;
|
|
||||||
|
|
||||||
match s {
|
match s {
|
||||||
"delete_message" => return Ok(DeleteMessage),
|
"delete_message" => return Ok(Self::DeleteMessage),
|
||||||
"get_menu" => return Ok(GetMenu),
|
"get_menu" => return Ok(Self::GetMenu),
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut substrings = s.split(' ');
|
let mut substrings = s.split(' ');
|
||||||
let (command, name) = match (substrings.next(), substrings.next(), substrings.next()) {
|
let (Some(command), Some(name), None) =
|
||||||
(Some(command), Some(name), None) => (command, name),
|
(substrings.next(), substrings.next(), substrings.next())
|
||||||
_ => return Err(InvalidCommand::InvalidParams),
|
else {
|
||||||
|
return Err(InvalidCommand::InvalidParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
let name_hash = B64_ENGINE.decode(name)?;
|
let name_hash = B64_ENGINE.decode(name)?;
|
||||||
if name_hash.len() != 32 {
|
if name_hash.len() != 32 {
|
||||||
return Err(InvalidCommand::InvalidOutputLength);
|
return Err(InvalidCommand::InvalidOutputLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
match command {
|
match command {
|
||||||
"get" => Ok(Get(name_hash)),
|
"get" => Ok(Self::Get(name_hash)),
|
||||||
"decrypt" => Ok(Decrypt(name_hash)),
|
"decrypt" => Ok(Self::Decrypt(name_hash)),
|
||||||
"hide" => Ok(Hide(name_hash)),
|
"hide" => Ok(Self::Hide(name_hash)),
|
||||||
"an" => Ok(Alter(name_hash, Name)),
|
"an" => Ok(Self::Alter(name_hash, AlterableField::Name)),
|
||||||
"al" => Ok(Alter(name_hash, Login)),
|
"al" => Ok(Self::Alter(name_hash, AlterableField::Login)),
|
||||||
"ap" => Ok(Alter(name_hash, Pass)),
|
"ap" => Ok(Self::Alter(name_hash, AlterableField::Pass)),
|
||||||
"delete0" => Ok(DeleteAccount {
|
"delete0" => Ok(Self::DeleteAccount {
|
||||||
name: name_hash,
|
name: name_hash,
|
||||||
is_command: false,
|
is_command: false,
|
||||||
}),
|
}),
|
||||||
"delete1" => Ok(DeleteAccount {
|
"delete1" => Ok(Self::DeleteAccount {
|
||||||
name: name_hash,
|
name: name_hash,
|
||||||
is_command: true,
|
is_command: true,
|
||||||
}),
|
}),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::AlterableField::{self, *};
|
use super::AlterableField::{self, Login, Name, Pass};
|
||||||
use crate::{change_state, prelude::*};
|
use crate::{change_state, prelude::*};
|
||||||
use account::ActiveModel;
|
use account::ActiveModel;
|
||||||
use futures::TryFutureExt;
|
use futures::TryFutureExt;
|
||||||
@ -14,7 +14,7 @@ async fn update_account(
|
|||||||
field_value: String,
|
field_value: String,
|
||||||
master_pass: String,
|
master_pass: String,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
if let Name = field {
|
if field == Name {
|
||||||
Account::update_name(user_id, name, field_value, db).await?;
|
Account::update_name(user_id, name, field_value, db).await?;
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -37,7 +37,7 @@ async fn update_account(
|
|||||||
match field {
|
match field {
|
||||||
Login => model.enc_login = Set(field_value),
|
Login => model.enc_login = Set(field_value),
|
||||||
Pass => model.enc_password = Set(field_value),
|
Pass => model.enc_password = Set(field_value),
|
||||||
_ => unreachable!(),
|
Name => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
model.update(db).await?;
|
model.update(db).await?;
|
||||||
@ -87,18 +87,15 @@ pub async fn alter(
|
|||||||
let user_id = q.from.id.0;
|
let user_id = q.from.id.0;
|
||||||
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
|
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
|
||||||
|
|
||||||
let name = match name_from_hash(&db, user_id, &hash).await? {
|
let Some(name) = name_from_hash(&db, user_id, &hash).await? else {
|
||||||
Some(name) => name,
|
try_join!(
|
||||||
None => {
|
bot.send_message(ids.0, "Account wasn't found")
|
||||||
try_join!(
|
.reply_markup(deletion_markup())
|
||||||
bot.send_message(ids.0, "Account wasn't found")
|
.send(),
|
||||||
.reply_markup(deletion_markup())
|
bot.answer_callback_query(q.id).send()
|
||||||
.send(),
|
)?;
|
||||||
bot.answer_callback_query(q.id).send()
|
|
||||||
)?;
|
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let text = match field {
|
let text = match field {
|
||||||
|
@ -16,14 +16,11 @@ async fn get_master_pass(
|
|||||||
|
|
||||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||||
|
|
||||||
let account = match Account::get(user_id, &name, &db).await? {
|
let Some(account) = Account::get(user_id, &name, &db).await? else {
|
||||||
Some(account) => account,
|
bot.send_message(msg.chat.id, "Account not found")
|
||||||
None => {
|
.reply_markup(deletion_markup())
|
||||||
bot.send_message(msg.chat.id, "Account not found")
|
.await?;
|
||||||
.reply_markup(deletion_markup())
|
return Ok(());
|
||||||
.await?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (login, password) = spawn_blocking(move || account.decrypt(&master_pass)).await??;
|
let (login, password) = spawn_blocking(move || account.decrypt(&master_pass)).await??;
|
||||||
@ -50,18 +47,15 @@ pub async fn decrypt(
|
|||||||
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
|
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
|
||||||
let user_id = q.from.id.0;
|
let user_id = q.from.id.0;
|
||||||
|
|
||||||
let name = match name_from_hash(&db, user_id, &hash).await? {
|
let Some(name) = name_from_hash(&db, user_id, &hash).await? else {
|
||||||
Some(name) => name,
|
try_join!(
|
||||||
None => {
|
bot.send_message(ids.0, "Account wasn't found")
|
||||||
try_join!(
|
.reply_markup(deletion_markup())
|
||||||
bot.send_message(ids.0, "Account wasn't found")
|
.send(),
|
||||||
.reply_markup(deletion_markup())
|
bot.answer_callback_query(q.id).send()
|
||||||
.send(),
|
)?;
|
||||||
bot.answer_callback_query(q.id).send()
|
|
||||||
)?;
|
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ids.alter_message(&bot, "Send master password", None, None)
|
ids.alter_message(&bot, "Send master password", None, None)
|
||||||
|
@ -40,18 +40,15 @@ pub async fn delete(
|
|||||||
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
|
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
|
||||||
let user_id = q.from.id.0;
|
let user_id = q.from.id.0;
|
||||||
|
|
||||||
let name = match name_from_hash(&db, user_id, &hash).await? {
|
let Some(name) = name_from_hash(&db, user_id, &hash).await? else {
|
||||||
Some(name) => name,
|
try_join!(
|
||||||
None => {
|
bot.send_message(ids.0, "Account wasn't found")
|
||||||
try_join!(
|
.reply_markup(deletion_markup())
|
||||||
bot.send_message(ids.0, "Account wasn't found")
|
.send(),
|
||||||
.reply_markup(deletion_markup())
|
bot.answer_callback_query(q.id).send()
|
||||||
.send(),
|
)?;
|
||||||
bot.answer_callback_query(q.id).send()
|
|
||||||
)?;
|
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = async {
|
let response = async {
|
||||||
@ -59,10 +56,10 @@ pub async fn delete(
|
|||||||
Once you send the master password the account is unrecoverable";
|
Once you send the master password the account is unrecoverable";
|
||||||
|
|
||||||
if is_command {
|
if is_command {
|
||||||
ids.alter_message(&bot, TEXT, None, None).await?
|
ids.alter_message(&bot, TEXT, None, None).await?;
|
||||||
} else {
|
} else {
|
||||||
let msg = bot.send_message(ids.0, TEXT).await?;
|
let msg = bot.send_message(ids.0, TEXT).await?;
|
||||||
ids = MessageIds::from(&msg)
|
ids = MessageIds::from(&msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok::<_, crate::Error>(())
|
Ok::<_, crate::Error>(())
|
||||||
|
@ -12,17 +12,14 @@ pub async fn get(
|
|||||||
let user_id = q.from.id.0;
|
let user_id = q.from.id.0;
|
||||||
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
|
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
|
||||||
|
|
||||||
let name = match name_from_hash(&db, user_id, &hash).await? {
|
let Some(name) = name_from_hash(&db, user_id, &hash).await? else {
|
||||||
Some(name) => name,
|
try_join!(
|
||||||
None => {
|
bot.send_message(ids.0, "Account wasn't found")
|
||||||
try_join!(
|
.reply_markup(deletion_markup())
|
||||||
bot.send_message(ids.0, "Account wasn't found")
|
.send(),
|
||||||
.reply_markup(deletion_markup())
|
bot.answer_callback_query(q.id).send()
|
||||||
.send(),
|
)?;
|
||||||
bot.answer_callback_query(q.id).send()
|
return Ok(());
|
||||||
)?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let text = format!("Name:\n`{name}`\nLogin:\n\\*\\*\\*\nPassword:\n\\*\\*\\*");
|
let text = format!("Name:\n`{name}`\nLogin:\n\\*\\*\\*\nPassword:\n\\*\\*\\*");
|
||||||
|
@ -13,7 +13,7 @@ type PasswordArray = [ArrayString<PASSWORD_LENGTH>; AMOUNT_OF_PASSWORDS];
|
|||||||
const BUFFER_LENGTH: usize =
|
const BUFFER_LENGTH: usize =
|
||||||
MESSAGE_HEADER.len() + (PASSWORD_LENGTH + PASSWORD_PADDING_LENGTH) * AMOUNT_OF_PASSWORDS;
|
MESSAGE_HEADER.len() + (PASSWORD_LENGTH + PASSWORD_PADDING_LENGTH) * AMOUNT_OF_PASSWORDS;
|
||||||
|
|
||||||
/// Handles /gen_password command by generating 10 copyable passwords and sending them to the user
|
/// Handles /`gen_password` command by generating 10 copyable passwords and sending them to the user
|
||||||
#[inline]
|
#[inline]
|
||||||
pub async fn gen_password(bot: Throttle<Bot>, msg: Message) -> crate::Result<()> {
|
pub async fn gen_password(bot: Throttle<Bot>, msg: Message) -> crate::Result<()> {
|
||||||
let mut message: ArrayString<BUFFER_LENGTH> = MESSAGE_HEADER.try_into().unwrap();
|
let mut message: ArrayString<BUFFER_LENGTH> = MESSAGE_HEADER.try_into().unwrap();
|
||||||
|
@ -3,7 +3,7 @@ use futures::future;
|
|||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use teloxide::types::ParseMode;
|
use teloxide::types::ParseMode;
|
||||||
|
|
||||||
/// Handles /get_accounts command by sending the list of copyable account names to the user
|
/// Handles /`get_accounts` command by sending the list of copyable account names to the user
|
||||||
#[inline]
|
#[inline]
|
||||||
pub async fn get_accounts(
|
pub async fn get_accounts(
|
||||||
bot: Throttle<Bot>,
|
bot: Throttle<Bot>,
|
||||||
|
@ -66,7 +66,7 @@ async fn get_master_pass(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles /set_master_pass command
|
/// Handles /`set_master_pass` command
|
||||||
#[inline]
|
#[inline]
|
||||||
pub async fn set_master_pass(
|
pub async fn set_master_pass(
|
||||||
bot: Throttle<Bot>,
|
bot: Throttle<Bot>,
|
||||||
|
@ -2,37 +2,38 @@ use crate::prelude::*;
|
|||||||
use teloxide::{dispatching::DpHandlerDescription, dptree::Handler};
|
use teloxide::{dispatching::DpHandlerDescription, dptree::Handler};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
fn has_no_user_info(msg: Message) -> bool {
|
fn has_no_user_info(msg: Message) -> bool {
|
||||||
msg.from().is_none()
|
msg.from().is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[allow(clippy::significant_drop_tightening)]
|
||||||
async fn notify_about_no_user_info(
|
async fn notify_about_no_user_info(
|
||||||
bot: Throttle<Bot>,
|
bot: Throttle<Bot>,
|
||||||
msg: Message,
|
msg: Message,
|
||||||
state: State,
|
state: State,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
use State::*;
|
|
||||||
const TEXT: &str = "Invalid message. Couldn't get the user information. Send the message again";
|
const TEXT: &str = "Invalid message. Couldn't get the user information. Send the message again";
|
||||||
|
|
||||||
match state {
|
match state {
|
||||||
Start => {
|
State::Start => {
|
||||||
bot.send_message(msg.chat.id, TEXT)
|
bot.send_message(msg.chat.id, TEXT)
|
||||||
.reply_markup(deletion_markup())
|
.reply_markup(deletion_markup())
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
GetNewName(handler)
|
State::GetNewName(handler)
|
||||||
| GetMasterPass(handler)
|
| State::GetMasterPass(handler)
|
||||||
| GetNewMasterPass(handler)
|
| State::GetNewMasterPass(handler)
|
||||||
| GetLogin(handler)
|
| State::GetLogin(handler)
|
||||||
| GetPassword(handler) => {
|
| State::GetPassword(handler) => {
|
||||||
let mut handler = handler.lock().await;
|
let mut handler = handler.lock().await;
|
||||||
handler
|
handler
|
||||||
.previous
|
.previous
|
||||||
.alter_message(&bot, TEXT, None, None)
|
.alter_message(&bot, TEXT, None, None)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
GetUser(handler) => {
|
State::GetUser(handler) => {
|
||||||
let mut handler = handler.lock().await;
|
let mut handler = handler.lock().await;
|
||||||
handler
|
handler
|
||||||
.previous
|
.previous
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
#![warn(clippy::pedantic, clippy::all, clippy::nursery)]
|
||||||
|
#![allow(clippy::single_match_else)]
|
||||||
|
|
||||||
mod callbacks;
|
mod callbacks;
|
||||||
mod commands;
|
mod commands;
|
||||||
mod default;
|
mod default;
|
||||||
@ -36,7 +39,7 @@ fn get_dispatcher(
|
|||||||
.branch(case![Command::GenPassword].endpoint(commands::gen_password))
|
.branch(case![Command::GenPassword].endpoint(commands::gen_password))
|
||||||
.branch(case![Command::Cancel].endpoint(commands::cancel))
|
.branch(case![Command::Cancel].endpoint(commands::cancel))
|
||||||
// This branch filters out the users that don't have a master password set
|
// This branch filters out the users that don't have a master password set
|
||||||
.branch(master_password_check::get_handler::<Message>())
|
.branch(master_password_check::get_handler())
|
||||||
.branch(case![Command::Menu].endpoint(commands::menu))
|
.branch(case![Command::Menu].endpoint(commands::menu))
|
||||||
.branch(case![Command::AddAccount].endpoint(commands::add_account))
|
.branch(case![Command::AddAccount].endpoint(commands::add_account))
|
||||||
.branch(case![Command::GetAccount].endpoint(commands::get_account))
|
.branch(case![Command::GetAccount].endpoint(commands::get_account))
|
||||||
@ -62,7 +65,7 @@ fn get_dispatcher(
|
|||||||
let callback_handler = Update::filter_callback_query()
|
let callback_handler = Update::filter_callback_query()
|
||||||
.filter_map(CallbackCommand::from_query)
|
.filter_map(CallbackCommand::from_query)
|
||||||
.branch(case![CallbackCommand::DeleteMessage].endpoint(callbacks::delete_message))
|
.branch(case![CallbackCommand::DeleteMessage].endpoint(callbacks::delete_message))
|
||||||
.branch(master_password_check::get_handler::<CallbackQuery>())
|
.branch(master_password_check::get_handler())
|
||||||
.branch(case![CallbackCommand::GetMenu].endpoint(callbacks::get_menu))
|
.branch(case![CallbackCommand::GetMenu].endpoint(callbacks::get_menu))
|
||||||
.branch(case![CallbackCommand::Get(hash)].endpoint(callbacks::get))
|
.branch(case![CallbackCommand::Get(hash)].endpoint(callbacks::get))
|
||||||
.branch(case![CallbackCommand::Decrypt(hash)].endpoint(callbacks::decrypt))
|
.branch(case![CallbackCommand::Decrypt(hash)].endpoint(callbacks::decrypt))
|
||||||
|
@ -27,7 +27,7 @@ pub fn menu_markup_sync(
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub async fn menu_markup(
|
pub async fn menu_markup(
|
||||||
command: impl Into<String>,
|
command: impl Into<String> + Send,
|
||||||
user_id: u64,
|
user_id: u64,
|
||||||
db: &DatabaseConnection,
|
db: &DatabaseConnection,
|
||||||
) -> crate::Result<InlineKeyboardMarkup> {
|
) -> crate::Result<InlineKeyboardMarkup> {
|
||||||
|
@ -3,39 +3,19 @@ use std::sync::Arc;
|
|||||||
use teloxide::{
|
use teloxide::{
|
||||||
dispatching::{dialogue::GetChatId, DpHandlerDescription},
|
dispatching::{dialogue::GetChatId, DpHandlerDescription},
|
||||||
dptree::Handler,
|
dptree::Handler,
|
||||||
types::User,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait GetUserInfo: GetChatId + Clone + Send + Sync + 'static {
|
type DynError = Arc<dyn std::error::Error + Send + Sync>;
|
||||||
fn user(&self) -> Option<&User>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetUserInfo for Message {
|
/// Filters out the messages from users without master passwords
|
||||||
fn user(&self) -> Option<&User> {
|
|
||||||
self.from()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetUserInfo for CallbackQuery {
|
|
||||||
fn user(&self) -> Option<&User> {
|
|
||||||
Some(&self.from)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A wierd filter that checks for the existance of a master password.
|
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// Returns None if account exists, Some(None) if there's an account and Some(Some(String)) if an error occures.
|
/// Returns None if account exists, Some(None) if there's an account and Some(Some(String)) if an error occures.
|
||||||
/// The String represents the error that occured
|
/// The String represents the error that occured
|
||||||
#[inline]
|
#[inline]
|
||||||
async fn master_pass_exists<T: GetUserInfo>(
|
async fn master_pass_exists(update: Update, db: DatabaseConnection) -> Option<Option<DynError>> {
|
||||||
msg: T,
|
let user_id = match update.user() {
|
||||||
db: DatabaseConnection,
|
|
||||||
) -> Option<Option<Arc<dyn std::error::Error + Send + Sync>>> {
|
|
||||||
msg.chat_id()?;
|
|
||||||
|
|
||||||
let user_id = match msg.user() {
|
|
||||||
Some(user) => user.id.0,
|
Some(user) => user.id.0,
|
||||||
None => return Some(Some(Arc::new(NoUserInfo))),
|
None => return Some(Some(Arc::new(NoUserInfo))),
|
||||||
};
|
};
|
||||||
@ -47,16 +27,16 @@ async fn master_pass_exists<T: GetUserInfo>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
async fn notify_about_no_master_pass<T: GetChatId>(
|
async fn notify_about_no_master_pass(
|
||||||
bot: Throttle<Bot>,
|
bot: Throttle<Bot>,
|
||||||
result: Option<Arc<dyn std::error::Error + Send + Sync>>,
|
result: Option<DynError>,
|
||||||
msg: T,
|
update: Update,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
if let Some(error) = result {
|
if let Some(error) = result {
|
||||||
return Err(error.into());
|
return Err(error.into());
|
||||||
}
|
}
|
||||||
bot.send_message(
|
bot.send_message(
|
||||||
msg.chat_id().unwrap(),
|
update.chat_id().unwrap(),
|
||||||
"No master password set. Use /set_master_pass to set it",
|
"No master password set. Use /set_master_pass to set it",
|
||||||
)
|
)
|
||||||
.reply_markup(deletion_markup())
|
.reply_markup(deletion_markup())
|
||||||
@ -66,7 +46,6 @@ async fn notify_about_no_master_pass<T: GetChatId>(
|
|||||||
|
|
||||||
/// Gets a handler that filters out the messages of users that don't have a master password set
|
/// Gets a handler that filters out the messages of users that don't have a master password set
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_handler<T: GetUserInfo>(
|
pub fn get_handler() -> Handler<'static, DependencyMap, crate::Result<()>, DpHandlerDescription> {
|
||||||
) -> Handler<'static, DependencyMap, crate::Result<()>, DpHandlerDescription> {
|
dptree::filter_map_async(master_pass_exists).endpoint(notify_about_no_master_pass)
|
||||||
dptree::filter_map_async(master_pass_exists::<T>).endpoint(notify_about_no_master_pass::<T>)
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ pub struct DecryptedAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DecryptedAccount {
|
impl DecryptedAccount {
|
||||||
/// Constructs DecryptedAccount by decrypting the provided account
|
/// Constructs `DecryptedAccount` by decrypting the provided account
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_account(account: account::Model, master_pass: &str) -> crate::Result<Self> {
|
pub fn from_account(account: account::Model, master_pass: &str) -> crate::Result<Self> {
|
||||||
let (login, password) = account.decrypt(master_pass)?;
|
let (login, password) = account.decrypt(master_pass)?;
|
||||||
@ -22,7 +22,7 @@ impl DecryptedAccount {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs ActiveModel with eath field Set by encrypting `self`
|
/// Constructs `ActiveModel` with eath field Set by encrypting `self`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_account(
|
pub fn into_account(
|
||||||
self,
|
self,
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
pub(crate) use crate::{
|
pub use crate::{
|
||||||
commands::Command,
|
commands::Command,
|
||||||
errors::*,
|
errors::*,
|
||||||
first_handler, handler,
|
first_handler, handler,
|
||||||
markups::*,
|
markups::*,
|
||||||
models::*,
|
models::*,
|
||||||
state::State,
|
state::{Handler, MainDialogue, MessageIds, PackagedHandler, State},
|
||||||
state::{Handler, MainDialogue, MessageIds, PackagedHandler},
|
|
||||||
utils::*,
|
utils::*,
|
||||||
};
|
};
|
||||||
pub(crate) use cryptography::prelude::*;
|
pub use cryptography::prelude::*;
|
||||||
pub(crate) use entity::prelude::*;
|
pub use entity::prelude::*;
|
||||||
pub(crate) use futures::{StreamExt, TryStreamExt};
|
pub use futures::{StreamExt, TryStreamExt};
|
||||||
pub(crate) use sea_orm::prelude::*;
|
pub use sea_orm::prelude::*;
|
||||||
pub(crate) use teloxide::{adaptors::Throttle, prelude::*};
|
pub use teloxide::{adaptors::Throttle, prelude::*};
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
mod generic;
|
mod generic;
|
||||||
mod handler;
|
mod handler;
|
||||||
|
|
||||||
pub use handler::{Handler, MessageIds, PackagedHandler};
|
pub use handler::{Handler, MessageIds, Packaged as PackagedHandler};
|
||||||
|
|
||||||
crate::export_handlers!(
|
crate::export_handlers!(
|
||||||
get_login,
|
get_login,
|
||||||
|
@ -9,17 +9,18 @@ pub async fn generic<F>(
|
|||||||
db: DatabaseConnection,
|
db: DatabaseConnection,
|
||||||
dialogue: MainDialogue,
|
dialogue: MainDialogue,
|
||||||
check: F,
|
check: F,
|
||||||
no_text_message: impl Into<String>,
|
no_text_message: impl Into<String> + Send,
|
||||||
next: PackagedHandler<String>,
|
handler: PackagedHandler<String>,
|
||||||
) -> crate::Result<()>
|
) -> crate::Result<()>
|
||||||
where
|
where
|
||||||
for<'a> F: FnOnce(
|
for<'a> F: FnOnce(
|
||||||
&'a Message,
|
&'a Message,
|
||||||
&'a DatabaseConnection,
|
&'a DatabaseConnection,
|
||||||
&'a str,
|
&'a str,
|
||||||
) -> BoxFuture<'a, crate::Result<Option<String>>>,
|
) -> BoxFuture<'a, crate::Result<Option<String>>>
|
||||||
|
+ Send,
|
||||||
{
|
{
|
||||||
let mut handler = next.lock().await;
|
let mut handler = handler.lock().await;
|
||||||
if handler.func.is_none() {
|
if handler.func.is_none() {
|
||||||
let _ = dialogue.exit().await;
|
let _ = dialogue.exit().await;
|
||||||
return Err(HandlerUsed.into());
|
return Err(HandlerUsed.into());
|
||||||
|
@ -10,19 +10,19 @@ fn process_validity(validity: PasswordValidity) -> Result<(), String> {
|
|||||||
let mut error_text = "Your master password is invalid:\n".to_owned();
|
let mut error_text = "Your master password is invalid:\n".to_owned();
|
||||||
|
|
||||||
if validity.contains(PasswordValidity::NO_LOWERCASE) {
|
if validity.contains(PasswordValidity::NO_LOWERCASE) {
|
||||||
error_text.push_str("\n* It doesn't have any lowercase characters")
|
error_text.push_str("\n* It doesn't have any lowercase characters");
|
||||||
}
|
}
|
||||||
if validity.contains(PasswordValidity::NO_UPPERCASE) {
|
if validity.contains(PasswordValidity::NO_UPPERCASE) {
|
||||||
error_text.push_str("\n* It doesn't have any uppercase characters")
|
error_text.push_str("\n* It doesn't have any uppercase characters");
|
||||||
}
|
}
|
||||||
if validity.contains(PasswordValidity::NO_NUMBER) {
|
if validity.contains(PasswordValidity::NO_NUMBER) {
|
||||||
error_text.push_str("\n* It doesn't have any numbers")
|
error_text.push_str("\n* It doesn't have any numbers");
|
||||||
}
|
}
|
||||||
if validity.contains(PasswordValidity::NO_SPECIAL_CHARACTER) {
|
if validity.contains(PasswordValidity::NO_SPECIAL_CHARACTER) {
|
||||||
error_text.push_str("\n* It doesn't have any special characters")
|
error_text.push_str("\n* It doesn't have any special characters");
|
||||||
}
|
}
|
||||||
if validity.contains(PasswordValidity::TOO_SHORT) {
|
if validity.contains(PasswordValidity::TOO_SHORT) {
|
||||||
error_text.push_str("\n* It is shorter than 8 characters")
|
error_text.push_str("\n* It is shorter than 8 characters");
|
||||||
}
|
}
|
||||||
|
|
||||||
error_text.push_str("\n\nModify your password and send it again");
|
error_text.push_str("\n\nModify your password and send it again");
|
||||||
|
@ -10,9 +10,8 @@ use trim_in_place::TrimInPlace;
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn validate_document(document: Option<&Document>) -> Result<&Document, &'static str> {
|
fn validate_document(document: Option<&Document>) -> Result<&Document, &'static str> {
|
||||||
let document = match document {
|
let Some(document) = document else {
|
||||||
Some(document) => document,
|
return Err("You didn't send a file. Try again");
|
||||||
None => return Err("You didn't send a file. Try again"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if document.file.size > 1024 * 1024 * 200 {
|
if document.file.size > 1024 * 1024 * 200 {
|
||||||
@ -70,7 +69,7 @@ fn process_accounts(
|
|||||||
duplicates.push(account.name.as_str());
|
duplicates.push(account.name.as_str());
|
||||||
}
|
}
|
||||||
if exists {
|
if exists {
|
||||||
existing.push(account.name.as_str())
|
existing.push(account.name.as_str());
|
||||||
}
|
}
|
||||||
// If it already exists or if it is a duplicate there's no need to check the account's validity
|
// If it already exists or if it is a duplicate there's no need to check the account's validity
|
||||||
if !duplicate && !exists && !account.validate() {
|
if !duplicate && !exists && !account.validate() {
|
||||||
@ -91,7 +90,7 @@ fn process_accounts(
|
|||||||
error_text,
|
error_text,
|
||||||
"\n\nDuplicate names:\n{:?}",
|
"\n\nDuplicate names:\n{:?}",
|
||||||
duplicates.into_iter().format("\n")
|
duplicates.into_iter().format("\n")
|
||||||
)?
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !existing.is_empty() {
|
if !existing.is_empty() {
|
||||||
@ -99,7 +98,7 @@ fn process_accounts(
|
|||||||
error_text,
|
error_text,
|
||||||
"\n\nAccounts with these names already exist in the database:\n{:?}",
|
"\n\nAccounts with these names already exist in the database:\n{:?}",
|
||||||
existing.into_iter().format("\n")
|
existing.into_iter().format("\n")
|
||||||
)?
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !invalid.is_empty() {
|
if !invalid.is_empty() {
|
||||||
@ -107,7 +106,7 @@ fn process_accounts(
|
|||||||
error_text,
|
error_text,
|
||||||
"\n\nInvalid account fields:\n{:?}",
|
"\n\nInvalid account fields:\n{:?}",
|
||||||
invalid.into_iter().format("\n")
|
invalid.into_iter().format("\n")
|
||||||
)?
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_text.push_str("\n\nFix these problems and send the file again");
|
error_text.push_str("\n\nFix these problems and send the file again");
|
||||||
@ -128,23 +127,23 @@ fn user_from_vec(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Function to handle GetUser state. It doesn't actually validate anything
|
/// Function to handle `GetUser` state. It doesn't actually validate anything
|
||||||
pub async fn get_user(
|
pub async fn get_user(
|
||||||
bot: Throttle<Bot>,
|
bot: Throttle<Bot>,
|
||||||
msg: Message,
|
msg: Message,
|
||||||
db: DatabaseConnection,
|
db: DatabaseConnection,
|
||||||
dialogue: MainDialogue,
|
dialogue: MainDialogue,
|
||||||
next: PackagedHandler<User>,
|
handler: PackagedHandler<User>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||||
|
|
||||||
let mut handler = next.lock().await;
|
let mut handler = handler.lock().await;
|
||||||
if handler.func.is_none() {
|
if handler.func.is_none() {
|
||||||
let _ = dialogue.exit().await;
|
let _ = dialogue.exit().await;
|
||||||
return Err(HandlerUsed.into());
|
return Err(HandlerUsed.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some("/cancel") = msg.text().map(str::trim) {
|
if msg.text().map(str::trim) == Some("/cancel") {
|
||||||
dialogue.exit().await?;
|
dialogue.exit().await?;
|
||||||
handler
|
handler
|
||||||
.previous
|
.previous
|
||||||
|
@ -26,9 +26,9 @@ impl MessageIds {
|
|||||||
pub async fn alter_message(
|
pub async fn alter_message(
|
||||||
&mut self,
|
&mut self,
|
||||||
bot: &Throttle<Bot>,
|
bot: &Throttle<Bot>,
|
||||||
text: impl Into<String>,
|
text: impl Into<String> + Send,
|
||||||
markup: impl Into<Option<InlineKeyboardMarkup>>,
|
markup: impl Into<Option<InlineKeyboardMarkup>> + Send,
|
||||||
parse_mode: impl Into<Option<ParseMode>>,
|
parse_mode: impl Into<Option<ParseMode>> + Send,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let mut edit = bot.edit_message_text(self.0, self.1, text);
|
let mut edit = bot.edit_message_text(self.0, self.1, text);
|
||||||
edit.parse_mode = parse_mode.into();
|
edit.parse_mode = parse_mode.into();
|
||||||
@ -76,10 +76,10 @@ pub struct Handler<T: ?Sized> {
|
|||||||
pub previous: MessageIds,
|
pub previous: MessageIds,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PackagedHandler<T> = Arc<Mutex<Handler<T>>>;
|
pub type Packaged<T> = Arc<Mutex<Handler<T>>>;
|
||||||
|
|
||||||
impl<T> Handler<T> {
|
impl<T> Handler<T> {
|
||||||
/// Convinience method to convert a simple async function and a previous message into PackagedHandler
|
/// Convinience method to convert a simple async function and a previous message into `PackagedHandler`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<H>(f: H, previous: impl Into<MessageIds>) -> PackagedHandler<T>
|
pub fn new<H>(f: H, previous: impl Into<MessageIds>) -> PackagedHandler<T>
|
||||||
where
|
where
|
||||||
|
Loading…
Reference in New Issue
Block a user