130 lines
4.4 KiB
Rust
130 lines
4.4 KiB
Rust
mod callbacks;
|
|
mod commands;
|
|
mod markups;
|
|
mod master_password_check;
|
|
mod state;
|
|
mod utils;
|
|
|
|
use sea_orm::prelude::*;
|
|
use std::sync::Arc;
|
|
use teloxide::{
|
|
adaptors::{throttle::Limits, Throttle},
|
|
dispatching::dialogue::InMemStorage,
|
|
filter_command,
|
|
prelude::*,
|
|
utils::command::BotCommands,
|
|
};
|
|
use tokio::sync::Mutex;
|
|
|
|
type MainDialogue = Dialogue<State, InMemStorage<State>>;
|
|
|
|
#[allow(clippy::type_complexity)]
|
|
pub struct Handler<T> {
|
|
pub handler: Box<
|
|
dyn FnOnce(
|
|
Throttle<Bot>,
|
|
Message,
|
|
DatabaseConnection,
|
|
MainDialogue,
|
|
T,
|
|
) -> crate::PinnedFuture<'static, crate::Result<()>>
|
|
+ Send
|
|
+ Sync,
|
|
>,
|
|
|
|
pub previous: Option<Message>,
|
|
}
|
|
|
|
type PackagedHandler<T> = Arc<Mutex<Option<Handler<T>>>>;
|
|
|
|
#[derive(BotCommands, Clone, Copy)]
|
|
#[command(
|
|
rename_rule = "snake_case",
|
|
description = "These commands are supported:"
|
|
)]
|
|
enum Command {
|
|
#[command(description = "displays the welcome message")]
|
|
Start,
|
|
#[command(description = "displays this text")]
|
|
Help,
|
|
#[command(description = "sets the master password")]
|
|
SetMasterPass,
|
|
#[command(description = "adds the account")]
|
|
AddAccount,
|
|
#[command(description = "gets the account")]
|
|
GetAccount,
|
|
#[command(description = "gets a list of accounts")]
|
|
GetAccounts,
|
|
#[command(description = "deletes the account")]
|
|
Delete,
|
|
#[command(description = "deletes all the accounts and the master password")]
|
|
DeleteAll,
|
|
#[command(description = "exports all the accounts in a json file")]
|
|
Export,
|
|
#[command(description = "loads the accounts from a json file")]
|
|
Import,
|
|
#[command(description = "generates 10 secure passwords")]
|
|
GenPassword,
|
|
#[command(description = "cancels the current action")]
|
|
Cancel,
|
|
}
|
|
|
|
#[derive(Default, Clone)]
|
|
pub enum State {
|
|
#[default]
|
|
Start,
|
|
GetAccountName(PackagedHandler<String>),
|
|
GetMasterPass(PackagedHandler<String>),
|
|
GetLogin(PackagedHandler<String>),
|
|
GetPassword(PackagedHandler<String>),
|
|
GetDocument(PackagedHandler<()>),
|
|
}
|
|
|
|
pub fn get_dispatcher(
|
|
token: String,
|
|
db: DatabaseConnection,
|
|
) -> Dispatcher<Throttle<Bot>, crate::Error, teloxide::dispatching::DefaultKey> {
|
|
use dptree::{case, deps, endpoint};
|
|
|
|
let bot = Bot::new(token).throttle(Limits::default());
|
|
|
|
let command_handler = filter_command::<Command, _>()
|
|
.branch(case![Command::Start].endpoint(commands::start))
|
|
.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(case![Command::Cancel].endpoint(commands::cancel))
|
|
// This branch filters out the users that don't have a master password set
|
|
.branch(master_password_check::get_handler())
|
|
.branch(case![Command::AddAccount].endpoint(commands::add_account))
|
|
.branch(case![Command::GetAccount].endpoint(commands::get_account))
|
|
.branch(case![Command::GetAccounts].endpoint(commands::get_accounts))
|
|
.branch(case![Command::Delete].endpoint(commands::delete))
|
|
.branch(case![Command::DeleteAll].endpoint(commands::delete_all))
|
|
.branch(case![Command::Export].endpoint(commands::export))
|
|
.branch(case![Command::Import].endpoint(commands::import));
|
|
|
|
let message_handler = Update::filter_message()
|
|
.map_async(utils::delete_message)
|
|
.enter_dialogue::<Update, InMemStorage<State>, State>()
|
|
.branch(case![State::GetAccountName(next)].endpoint(state::get_account_name))
|
|
.branch(case![State::GetMasterPass(next)].endpoint(state::get_master_pass))
|
|
.branch(case![State::GetLogin(next)].endpoint(state::get_login))
|
|
.branch(case![State::GetPassword(next)].endpoint(state::get_password))
|
|
.branch(case![State::GetDocument(next)].endpoint(state::get_document))
|
|
.branch(command_handler)
|
|
.branch(endpoint(commands::default));
|
|
|
|
let callback_handler =
|
|
Update::filter_callback_query().chain(callbacks::delete_message::get_handler());
|
|
|
|
let handler = dptree::entry()
|
|
.branch(message_handler)
|
|
.branch(callback_handler);
|
|
|
|
Dispatcher::builder(bot, handler)
|
|
.dependencies(deps![db, InMemStorage::<State>::new()])
|
|
.enable_ctrlc_handler()
|
|
.build()
|
|
}
|