Code cleanup

This commit is contained in:
2024-02-22 12:44:02 +03:00
parent 8979cc5b25
commit b526eb0c12
18 changed files with 124 additions and 148 deletions

View File

@ -1,8 +1,7 @@
use super::AlterableField::{self, Login, Name, Pass};
use crate::{change_state, prelude::*};
use cryptography::account::Cipher;
use futures::TryFutureExt;
use tokio::{task::spawn_blocking, try_join};
use tokio::task::spawn_blocking;
#[inline]
async fn update_account(
@ -81,13 +80,10 @@ pub async fn alter(
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
let Some(name) = Account::get_name_by_hash(user_id, &hash, &db).await? else {
try_join!(
bot.send_message(ids.0, "Account wasn't found")
.reply_markup(deletion_markup())
.send(),
bot.answer_callback_query(q.id).send()
)?;
bot.send_message(ids.0, "Account wasn't found")
.reply_markup(deletion_markup())
.await?;
bot.answer_callback_query(q.id).await?;
return Ok(());
};
@ -106,10 +102,8 @@ pub async fn alter(
}
};
try_join!(
ids.alter_message(&bot, text, None, None),
bot.answer_callback_query(q.id).send().err_into()
)?;
ids.alter_message(&bot, text, None, None).await?;
bot.answer_callback_query(q.id).await?;
Ok(())
}

View File

@ -1,6 +1,6 @@
use crate::{change_state, prelude::*};
use teloxide::types::ParseMode;
use tokio::{task::spawn_blocking, try_join};
use tokio::task::spawn_blocking;
#[inline]
async fn get_master_pass(
@ -53,13 +53,10 @@ pub async fn decrypt(
let user_id = q.from.id.0;
let Some(name) = Account::get_name_by_hash(user_id, &hash, &db).await? else {
try_join!(
bot.send_message(ids.0, "Account wasn't found")
.reply_markup(deletion_markup())
.send(),
bot.answer_callback_query(q.id).send()
)?;
bot.send_message(ids.0, "Account wasn't found")
.reply_markup(deletion_markup())
.await?;
bot.answer_callback_query(q.id).await?;
return Ok(());
};

View File

@ -1,6 +1,3 @@
use futures::TryFutureExt;
use tokio::try_join;
use crate::{change_state, prelude::*};
#[inline]
@ -37,35 +34,28 @@ pub async fn delete(
dialogue: MainDialogue,
(hash, is_command): (super::NameHash, bool),
) -> crate::Result<()> {
const TEXT: &str = "Send master password. \
Once you send the master password the account is unrecoverable";
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
let user_id = q.from.id.0;
let Some(name) = Account::get_name_by_hash(user_id, &hash, &db).await? else {
try_join!(
bot.send_message(ids.0, "Account wasn't found")
.reply_markup(deletion_markup())
.send(),
bot.answer_callback_query(q.id).send()
)?;
bot.send_message(ids.0, "Account wasn't found")
.reply_markup(deletion_markup())
.await?;
bot.answer_callback_query(q.id).await?;
return Ok(());
};
let response = async {
const TEXT: &str = "Send master password. \
Once you send the master password the account is unrecoverable";
if is_command {
ids.alter_message(&bot, TEXT, None, None).await?;
} else {
let msg = bot.send_message(ids.0, TEXT).await?;
ids = MessageIds::from(&msg);
};
Ok::<_, crate::Error>(())
if is_command {
ids.alter_message(&bot, TEXT, None, None).await?;
} else {
let msg = bot.send_message(ids.0, TEXT).await?;
ids = MessageIds::from(&msg);
};
try_join!(response, bot.answer_callback_query(q.id).send().err_into())?;
bot.answer_callback_query(q.id).await?;
change_state!(dialogue, ids, (name), State::GetMasterPass, get_master_pass);

View File

@ -1,5 +1,4 @@
use crate::prelude::*;
use futures::try_join;
use teloxide::types::ParseMode;
#[inline]
@ -13,12 +12,10 @@ pub async fn get(
let mut ids: MessageIds = q.message.as_ref().unwrap().into();
let Some(name) = Account::get_name_by_hash(user_id, &hash, &db).await? else {
try_join!(
bot.send_message(ids.0, "Account wasn't found")
.reply_markup(deletion_markup())
.send(),
bot.answer_callback_query(q.id).send()
)?;
bot.send_message(ids.0, "Account wasn't found")
.reply_markup(deletion_markup())
.await?;
bot.answer_callback_query(q.id).await?;
return Ok(());
};

View File

@ -1,20 +1,18 @@
use crate::prelude::*;
use tokio::task::spawn_blocking;
#[inline]
pub async fn delete(bot: Throttle<Bot>, msg: Message, db: Pool) -> crate::Result<()> {
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let names: Vec<String> = Account::get_names(user_id, &db).try_collect().await?;
let markup = menu_markup("get", user_id, &db).await?;
if names.is_empty() {
if markup.inline_keyboard.is_empty() {
bot.send_message(msg.chat.id, "You don't have any accounts")
.reply_markup(deletion_markup())
.await?;
return Ok(());
}
let markup = spawn_blocking(|| menu_markup_sync("delete1", names)).await?;
bot.send_message(msg.chat.id, "Choose the account to delete")
.reply_markup(markup)
.await?;

View File

@ -14,6 +14,7 @@ async fn get_master_pass(
) -> crate::Result<()> {
dialogue.exit().await?;
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let mut txn = db.begin().await?;
let result = (
Account::delete_all(user_id, &mut *txn).await,

View File

@ -1,20 +1,18 @@
use crate::prelude::*;
use tokio::task::spawn_blocking;
#[inline]
pub async fn get_account(bot: Throttle<Bot>, msg: Message, db: Pool) -> crate::Result<()> {
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let names: Vec<String> = Account::get_names(user_id, &db).try_collect().await?;
let markup = menu_markup("decrypt", user_id, &db).await?;
if names.is_empty() {
if markup.inline_keyboard.is_empty() {
bot.send_message(msg.chat.id, "You don't have any accounts")
.reply_markup(deletion_markup())
.await?;
return Ok(());
}
let markup = spawn_blocking(|| menu_markup_sync("decrypt", names)).await?;
bot.send_message(msg.chat.id, "Choose the account to get")
.reply_markup(markup)
.await?;

View File

@ -1,5 +1,4 @@
use crate::prelude::*;
use futures::future;
use std::fmt::Write;
use teloxide::types::ParseMode;
@ -18,13 +17,9 @@ pub async fn get_accounts(bot: Throttle<Bot>, msg: Message, db: Pool) -> crate::
return Ok(());
};
account_names
.map_err(crate::Error::from)
.try_for_each(|name| {
let result = write!(text, "\n`{name}`").map_err(Into::into);
future::ready(result)
})
.await?;
while let Some(name) = account_names.try_next().await? {
write!(text, "\n`{name}`")?;
}
bot.send_message(msg.chat.id, text)
.parse_mode(ParseMode::MarkdownV2)

View File

@ -1,20 +1,18 @@
use crate::prelude::*;
use tokio::task::spawn_blocking;
#[inline]
pub async fn menu(bot: Throttle<Bot>, msg: Message, db: Pool) -> crate::Result<()> {
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let names: Vec<String> = Account::get_names(user_id, &db).try_collect().await?;
let markup = menu_markup("get", user_id, &db).await?;
if names.is_empty() {
if markup.inline_keyboard.is_empty() {
bot.send_message(msg.chat.id, "You don't have any accounts")
.reply_markup(deletion_markup())
.await?;
return Ok(());
}
let markup = spawn_blocking(|| menu_markup_sync("get", names)).await?;
bot.send_message(msg.chat.id, "Choose your account")
.reply_markup(markup)
.await?;

View File

@ -40,7 +40,6 @@ async fn get_master_pass2(
Ok(())
}
/// Actually sets the master password
#[inline]
async fn get_master_pass(
bot: Throttle<Bot>,

View File

@ -6,7 +6,7 @@ pub async fn start(bot: Throttle<Bot>, msg: Message) -> crate::Result<()> {
bot.send_message(
msg.chat.id,
"Hi! This bot can be used to store the passwords securely. \
Use /help command to get the list of commands",
Use /help command to get the list of commands",
)
.await?;
Ok(())

View File

@ -11,7 +11,7 @@ type DynError = Arc<dyn std::error::Error + Send + Sync>;
///
/// # 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(DynError)) if an error occures.
/// The String represents the error that occured
#[inline]
async fn master_pass_exists(update: Update, db: Pool) -> Option<Option<DynError>> {

View File

@ -20,8 +20,8 @@ async fn check_master_pass(
let is_valid = {
let hash = HashedBytes::from(model);
let master_pass = master_pass.to_owned();
spawn_blocking(move || hash.verify(master_pass.as_bytes())).await?
let master_pass: Box<[u8]> = master_pass.as_bytes().into();
spawn_blocking(move || hash.verify(&master_pass)).await?
};
if !is_valid {

View File

@ -31,16 +31,14 @@ fn validate_document(document: Option<&Document>) -> Result<&Document, &'static
}
#[inline]
async fn download_file(bot: &Throttle<Bot>, file: &FileMeta) -> crate::Result<Vec<u8>> {
let path = bot.get_file(file.id.as_str()).await?.path;
async fn download_file(bot: &Throttle<Bot>, file: &FileMeta) -> crate::Result<Box<[u8]>> {
let path = bot.get_file(&file.id).await?.path;
let mut data = Vec::with_capacity(file.size as usize);
bot.download_file_stream(&path)
.try_for_each(|bytes| {
data.extend_from_slice(&bytes);
async { Ok(()) }
})
.await?;
Ok(data)
let mut stream = bot.download_file_stream(&path);
while let Some(bytes) = stream.try_next().await? {
data.extend_from_slice(&bytes);
}
Ok(data.into_boxed_slice())
}
#[inline]
@ -116,12 +114,12 @@ fn process_accounts(
}
#[inline]
fn user_from_vec(
vector: Vec<u8>,
fn user_from_bytes(
bytes: impl AsRef<[u8]>,
existing_names: ahash::HashSet<String>,
) -> crate::Result<Result<User, String>> {
let mut user: User = serde_json::from_slice(&vector)?;
drop(vector);
let mut user: User = serde_json::from_slice(bytes.as_ref())?;
drop(bytes);
match process_accounts(&mut user.accounts, existing_names)? {
Ok(()) => Ok(Ok(user)),
Err(error_text) => Ok(Err(error_text)),
@ -136,11 +134,7 @@ async fn user_from_document(
user_id: u64,
) -> Result<User, Cow<'static, str>> {
let (data, existing_names) = {
let file = match validate_document(document) {
Ok(document) => &document.file,
Err(text) => return Err(Cow::Borrowed(text)),
};
let file = &validate_document(document)?.file;
let data = download_file(bot, file).map_err(|_| "Error downloading the file. Try again");
let existing_names = Account::get_names(user_id, db)
@ -150,9 +144,8 @@ async fn user_from_document(
try_join!(data, existing_names)?
};
match spawn_blocking(|| user_from_vec(data, existing_names)).await {
Ok(Ok(Ok(user))) => Ok(user),
Ok(Ok(Err(error_text))) => Err(Cow::Owned(error_text)),
match spawn_blocking(|| user_from_bytes(data, existing_names)).await {
Ok(Ok(user)) => user.map_err(Cow::Owned),
_ => Err(Cow::Borrowed("Error parsing the json file. Try again")),
}
}