From c2467efbc107b0f59eec1604874bdc0a47107915 Mon Sep 17 00:00:00 2001 From: Ludovic Mermod <ludovic.mermod@gmail.com> Date: Sat, 7 Sep 2024 22:31:00 +0200 Subject: [PATCH 1/4] feat: improve message when no command are authorized --- src/cmd_authentication.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/cmd_authentication.rs b/src/cmd_authentication.rs index e675e7c..c1ac3de 100644 --- a/src/cmd_authentication.rs +++ b/src/cmd_authentication.rs @@ -160,14 +160,18 @@ pub async fn authorizations(bot: Bot, msg: Message, db: Arc<SqlitePool>) -> Hand bot.send_message( msg.chat.id, - format!( - "Ce groupe peut utiliser les commandes suivantes:\n{}", - authorizations - .into_iter() - .map(|s| format!(" - {}", s.command)) - .collect::<Vec<_>>() - .join("\n") - ), + if authorizations.is_empty() { + "Ce groupe ne peut utiliser aucune commande".to_owned() + } else { + format!( + "Ce groupe peut utiliser les commandes suivantes:\n{}", + authorizations + .into_iter() + .map(|s| format!(" - {}", s.command)) + .collect::<Vec<_>>() + .join("\n") + ) + }, ) .await?; From d236fa940c303369b14cb49fd5ee60f000dbc1f7 Mon Sep 17 00:00:00 2001 From: Ludovic Mermod <ludovic.mermod@gmail.com> Date: Sat, 7 Sep 2024 22:31:35 +0200 Subject: [PATCH 2/4] fix: check that authorized command exists --- src/cmd_authentication.rs | 37 +++++++++++++++++++++++++++++-------- src/commands.rs | 8 +++----- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/cmd_authentication.rs b/src/cmd_authentication.rs index c1ac3de..74746c7 100644 --- a/src/cmd_authentication.rs +++ b/src/cmd_authentication.rs @@ -1,11 +1,8 @@ -use std::sync::Arc; - +use crate::{commands::RESTRICTED_COMMANDS, config::config, HandlerResult}; use sqlx::SqlitePool; +use std::sync::Arc; use teloxide::{requests::Requester, types::Message, Bot}; -use crate::{config::config, HandlerResult}; - - pub async fn authenticate( bot: Bot, msg: Message, @@ -52,7 +49,12 @@ pub async fn admin_list(bot: Bot, msg: Message, db: Arc<SqlitePool>) -> HandlerR Ok(()) } -pub async fn admin_remove(bot: Bot, msg: Message, name: String, db: Arc<SqlitePool>) -> HandlerResult { +pub async fn admin_remove( + bot: Bot, + msg: Message, + name: String, + db: Arc<SqlitePool>, +) -> HandlerResult { let mut tx = db.begin().await?; if sqlx::query!("SELECT COUNT(*) AS count FROM admins WHERE name = $1", name) @@ -77,7 +79,12 @@ pub async fn admin_remove(bot: Bot, msg: Message, name: String, db: Arc<SqlitePo Ok(()) } -pub async fn authorize(bot: Bot, msg: Message, command: String, db: Arc<SqlitePool>) -> HandlerResult { +pub async fn authorize( + bot: Bot, + msg: Message, + command: String, + db: Arc<SqlitePool>, +) -> HandlerResult { let mut tx = db.begin().await?; let chat_id_str = msg.chat.id.to_string(); @@ -89,7 +96,21 @@ pub async fn authorize(bot: Bot, msg: Message, command: String, db: Arc<SqlitePo .fetch_one(tx.as_mut()) .await?; - if already_authorized.count == 0 { + if RESTRICTED_COMMANDS + .iter() + .find(|c| c.shortand() == command) + .is_none() + { + bot.send_message(msg.chat.id, "Cette commande n'existe pas") + .await?; + return Ok(()); + } + + if already_authorized + .iter() + .find(|aa| aa.command == command) + .is_none() + { sqlx::query!( r#"INSERT INTO authorizations(command, chat_id) VALUES($1, $2)"#, command, diff --git a/src/commands.rs b/src/commands.rs index 953a02e..5214f24 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -2,11 +2,7 @@ use std::sync::Arc; use sqlx::SqlitePool; use teloxide::{ - dispatching::DpHandlerDescription, - prelude::*, - types::{Message, MessageCommon, MessageKind}, - utils::command::BotCommands, - Bot, + dispatching::DpHandlerDescription, prelude::*, types::Message, utils::command::BotCommands, Bot, }; use crate::{ @@ -141,6 +137,8 @@ pub enum Command { Stats, } +pub const RESTRICTED_COMMANDS: [Command; 3] = [Command::Bureau, Command::Poll, Command::Stats]; + impl Command { // Used as key for the access control map pub fn shortand(&self) -> &str { From 822e0c64bb41eebb3a8d58aaad35d72fc43b54e8 Mon Sep 17 00:00:00 2001 From: Ludovic Mermod <ludovic.mermod@epfl.ch> Date: Sun, 8 Sep 2024 11:28:59 +0200 Subject: [PATCH 3/4] feat: add log for unauthorized command use --- src/cmd_bureau.rs | 2 +- src/cmd_poll.rs | 11 +++-------- src/commands.rs | 8 +++++++- src/main.rs | 11 ++++++----- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/cmd_bureau.rs b/src/cmd_bureau.rs index ba2e7e4..f795561 100644 --- a/src/cmd_bureau.rs +++ b/src/cmd_bureau.rs @@ -18,4 +18,4 @@ pub async fn bureau(bot: Bot, msg: Message) -> HandlerResult { .is_anonymous(false) .await?; Ok(()) -} \ No newline at end of file +} diff --git a/src/cmd_poll.rs b/src/cmd_poll.rs index 4e4c238..53e4cfb 100644 --- a/src/cmd_poll.rs +++ b/src/cmd_poll.rs @@ -9,8 +9,7 @@ use teloxide::{ prelude::Dialogue, requests::Requester, types::{ - CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message, MessageId, - ReplyMarkup, + CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message, MessageId, ReplyMarkup, }, Bot, }; @@ -36,11 +35,7 @@ pub enum PollState { pub type PollDialogue = Dialogue<PollState, InMemStorage<PollState>>; /// Starts the /poll dialogue by sending a message with an inline keyboard to select the target of the /poll. -pub async fn start_poll_dialogue( - bot: Bot, - msg: Message, - dialogue: PollDialogue, -) -> HandlerResult { +pub async fn start_poll_dialogue(bot: Bot, msg: Message, dialogue: PollDialogue) -> HandlerResult { log::info!("Starting /poll dialogue"); log::debug!("Removing /poll message"); @@ -207,4 +202,4 @@ pub async fn stats(bot: Bot, msg: Message) -> HandlerResult { .await?; Ok(()) -} \ No newline at end of file +} diff --git a/src/commands.rs b/src/commands.rs index 5214f24..a3d1f53 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -64,7 +64,7 @@ fn require_authorization() -> Endpoint<'static, DependencyMap, HandlerResult, Dp |command: Command, msg: Message, pool: Arc<SqlitePool>| async move { let chat_id = msg.chat.id.to_string(); let shortand = command.shortand(); - match sqlx::query!( + let authorized = match sqlx::query!( r#"SELECT COUNT(*) AS count FROM authorizations WHERE chat_id = $1 AND command = $2"#, chat_id, shortand @@ -76,7 +76,13 @@ fn require_authorization() -> Endpoint<'static, DependencyMap, HandlerResult, Dp log::error!("Could not check authorization in database: {:?}", e); false }, + }; + + if !authorized { + log::warn!("Chat {} tried to use the commmand {}", msg.chat.id, command.shortand()) } + + authorized }, ) } diff --git a/src/main.rs b/src/main.rs index b63db1b..747ac97 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,17 +9,17 @@ use teloxide::{ }; use crate::{ + cmd_poll::PollState, commands::{command_callback_query_handler, command_message_handler, Command}, directus::{update_committee, Committee}, - cmd_poll::PollState }; +mod cmd_authentication; +mod cmd_bureau; +mod cmd_poll; mod commands; mod config; mod directus; -mod cmd_poll; -mod cmd_bureau; -mod cmd_authentication; pub type HandlerResult = Result<(), Box<dyn std::error::Error + Send + Sync>>; @@ -47,7 +47,8 @@ async fn main() { id: 1, name: "".into(), poll_count: 15, - }]).await; + }]) + .await; log::info!("Loading config files"); config::config(); From 9a35ac84c92aee79a7a0144b7faeae2fc699dc01 Mon Sep 17 00:00:00 2001 From: Ludovic Mermod <ludovic.mermod@epfl.ch> Date: Sun, 8 Sep 2024 13:54:20 +0200 Subject: [PATCH 4/4] fix: add missing sqlx queries --- ...d5160ac09ce56db5c7082865448411dc47cd0.json | 12 --------- ...abda876d7b70212da0fdf9d9331a621578f5a.json | 20 -------------- ...9efbd66b1754ffd957a23610b1323dbaa6f0d.json | 12 --------- ...cc30ce14f1ecfc988e92e837f778d0a67df03.json | 26 ------------------- ...6550b1fdbd9f32fb0e313964e5058dc1a10b8.json | 12 --------- src/cmd_authentication.rs | 23 ++++++---------- 6 files changed, 8 insertions(+), 97 deletions(-) delete mode 100644 .sqlx/query-5b090e1e68c28c448b51811b0f4d5160ac09ce56db5c7082865448411dc47cd0.json delete mode 100644 .sqlx/query-6f0ad1b206a91ecc03afc952e82abda876d7b70212da0fdf9d9331a621578f5a.json delete mode 100644 .sqlx/query-af4ddce9ab335303494ad6a0f7f9efbd66b1754ffd957a23610b1323dbaa6f0d.json delete mode 100644 .sqlx/query-d0c6ad43c92be65d1c600aee4fecc30ce14f1ecfc988e92e837f778d0a67df03.json delete mode 100644 .sqlx/query-d32dd5b9da3258a0f3d45565c7f6550b1fdbd9f32fb0e313964e5058dc1a10b8.json diff --git a/.sqlx/query-5b090e1e68c28c448b51811b0f4d5160ac09ce56db5c7082865448411dc47cd0.json b/.sqlx/query-5b090e1e68c28c448b51811b0f4d5160ac09ce56db5c7082865448411dc47cd0.json deleted file mode 100644 index cfbb153..0000000 --- a/.sqlx/query-5b090e1e68c28c448b51811b0f4d5160ac09ce56db5c7082865448411dc47cd0.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "UPDATE committee SET poll_count = poll_count + 1 WHERE name = $1", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "5b090e1e68c28c448b51811b0f4d5160ac09ce56db5c7082865448411dc47cd0" -} diff --git a/.sqlx/query-6f0ad1b206a91ecc03afc952e82abda876d7b70212da0fdf9d9331a621578f5a.json b/.sqlx/query-6f0ad1b206a91ecc03afc952e82abda876d7b70212da0fdf9d9331a621578f5a.json deleted file mode 100644 index 0b65b4b..0000000 --- a/.sqlx/query-6f0ad1b206a91ecc03afc952e82abda876d7b70212da0fdf9d9331a621578f5a.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT name FROM committee", - "describe": { - "columns": [ - { - "name": "name", - "ordinal": 0, - "type_info": "Text" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - true - ] - }, - "hash": "6f0ad1b206a91ecc03afc952e82abda876d7b70212da0fdf9d9331a621578f5a" -} diff --git a/.sqlx/query-af4ddce9ab335303494ad6a0f7f9efbd66b1754ffd957a23610b1323dbaa6f0d.json b/.sqlx/query-af4ddce9ab335303494ad6a0f7f9efbd66b1754ffd957a23610b1323dbaa6f0d.json deleted file mode 100644 index f89ded7..0000000 --- a/.sqlx/query-af4ddce9ab335303494ad6a0f7f9efbd66b1754ffd957a23610b1323dbaa6f0d.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "INSERT INTO committee(name) VALUES($1)", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "af4ddce9ab335303494ad6a0f7f9efbd66b1754ffd957a23610b1323dbaa6f0d" -} diff --git a/.sqlx/query-d0c6ad43c92be65d1c600aee4fecc30ce14f1ecfc988e92e837f778d0a67df03.json b/.sqlx/query-d0c6ad43c92be65d1c600aee4fecc30ce14f1ecfc988e92e837f778d0a67df03.json deleted file mode 100644 index afeb04e..0000000 --- a/.sqlx/query-d0c6ad43c92be65d1c600aee4fecc30ce14f1ecfc988e92e837f778d0a67df03.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT * FROM committee", - "describe": { - "columns": [ - { - "name": "name", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "poll_count", - "ordinal": 1, - "type_info": "Int64" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - true, - false - ] - }, - "hash": "d0c6ad43c92be65d1c600aee4fecc30ce14f1ecfc988e92e837f778d0a67df03" -} diff --git a/.sqlx/query-d32dd5b9da3258a0f3d45565c7f6550b1fdbd9f32fb0e313964e5058dc1a10b8.json b/.sqlx/query-d32dd5b9da3258a0f3d45565c7f6550b1fdbd9f32fb0e313964e5058dc1a10b8.json deleted file mode 100644 index b0ed104..0000000 --- a/.sqlx/query-d32dd5b9da3258a0f3d45565c7f6550b1fdbd9f32fb0e313964e5058dc1a10b8.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM committee WHERE name = $1", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "d32dd5b9da3258a0f3d45565c7f6550b1fdbd9f32fb0e313964e5058dc1a10b8" -} diff --git a/src/cmd_authentication.rs b/src/cmd_authentication.rs index 74746c7..71fe7eb 100644 --- a/src/cmd_authentication.rs +++ b/src/cmd_authentication.rs @@ -88,6 +88,13 @@ pub async fn authorize( let mut tx = db.begin().await?; let chat_id_str = msg.chat.id.to_string(); + + if !RESTRICTED_COMMANDS.iter().any(|c| c.shortand() == command) { + bot.send_message(msg.chat.id, "Cette commande n'existe pas") + .await?; + return Ok(()); + } + let already_authorized = sqlx::query!( r#"SELECT COUNT(*) AS count FROM authorizations WHERE chat_id = $1 AND command = $2"#, chat_id_str, @@ -96,21 +103,7 @@ pub async fn authorize( .fetch_one(tx.as_mut()) .await?; - if RESTRICTED_COMMANDS - .iter() - .find(|c| c.shortand() == command) - .is_none() - { - bot.send_message(msg.chat.id, "Cette commande n'existe pas") - .await?; - return Ok(()); - } - - if already_authorized - .iter() - .find(|aa| aa.command == command) - .is_none() - { + if already_authorized.count > 0 { sqlx::query!( r#"INSERT INTO authorizations(command, chat_id) VALUES($1, $2)"#, command,