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,