Skip to content

Commit c16bf12

Browse files
authored
Authorizations check (#8)
* feat: improve message when no command are authorized * fix: check that authorized command exists * feat: add log for unauthorized command use * fix: add missing sqlx queries
1 parent efa43d8 commit c16bf12

10 files changed

+54
-118
lines changed

.sqlx/query-5b090e1e68c28c448b51811b0f4d5160ac09ce56db5c7082865448411dc47cd0.json

-12
This file was deleted.

.sqlx/query-6f0ad1b206a91ecc03afc952e82abda876d7b70212da0fdf9d9331a621578f5a.json

-20
This file was deleted.

.sqlx/query-af4ddce9ab335303494ad6a0f7f9efbd66b1754ffd957a23610b1323dbaa6f0d.json

-12
This file was deleted.

.sqlx/query-d0c6ad43c92be65d1c600aee4fecc30ce14f1ecfc988e92e837f778d0a67df03.json

-26
This file was deleted.

.sqlx/query-d32dd5b9da3258a0f3d45565c7f6550b1fdbd9f32fb0e313964e5058dc1a10b8.json

-12
This file was deleted.

src/cmd_authentication.rs

+34-16
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
use std::sync::Arc;
2-
1+
use crate::{commands::RESTRICTED_COMMANDS, config::config, HandlerResult};
32
use sqlx::SqlitePool;
3+
use std::sync::Arc;
44
use teloxide::{requests::Requester, types::Message, Bot};
55

6-
use crate::{config::config, HandlerResult};
7-
8-
96
pub async fn authenticate(
107
bot: Bot,
118
msg: Message,
@@ -52,7 +49,12 @@ pub async fn admin_list(bot: Bot, msg: Message, db: Arc<SqlitePool>) -> HandlerR
5249
Ok(())
5350
}
5451

55-
pub async fn admin_remove(bot: Bot, msg: Message, name: String, db: Arc<SqlitePool>) -> HandlerResult {
52+
pub async fn admin_remove(
53+
bot: Bot,
54+
msg: Message,
55+
name: String,
56+
db: Arc<SqlitePool>,
57+
) -> HandlerResult {
5658
let mut tx = db.begin().await?;
5759

5860
if sqlx::query!("SELECT COUNT(*) AS count FROM admins WHERE name = $1", name)
@@ -77,10 +79,22 @@ pub async fn admin_remove(bot: Bot, msg: Message, name: String, db: Arc<SqlitePo
7779
Ok(())
7880
}
7981

80-
pub async fn authorize(bot: Bot, msg: Message, command: String, db: Arc<SqlitePool>) -> HandlerResult {
82+
pub async fn authorize(
83+
bot: Bot,
84+
msg: Message,
85+
command: String,
86+
db: Arc<SqlitePool>,
87+
) -> HandlerResult {
8188
let mut tx = db.begin().await?;
8289

8390
let chat_id_str = msg.chat.id.to_string();
91+
92+
if !RESTRICTED_COMMANDS.iter().any(|c| c.shortand() == command) {
93+
bot.send_message(msg.chat.id, "Cette commande n'existe pas")
94+
.await?;
95+
return Ok(());
96+
}
97+
8498
let already_authorized = sqlx::query!(
8599
r#"SELECT COUNT(*) AS count FROM authorizations WHERE chat_id = $1 AND command = $2"#,
86100
chat_id_str,
@@ -89,7 +103,7 @@ pub async fn authorize(bot: Bot, msg: Message, command: String, db: Arc<SqlitePo
89103
.fetch_one(tx.as_mut())
90104
.await?;
91105

92-
if already_authorized.count == 0 {
106+
if already_authorized.count > 0 {
93107
sqlx::query!(
94108
r#"INSERT INTO authorizations(command, chat_id) VALUES($1, $2)"#,
95109
command,
@@ -160,14 +174,18 @@ pub async fn authorizations(bot: Bot, msg: Message, db: Arc<SqlitePool>) -> Hand
160174

161175
bot.send_message(
162176
msg.chat.id,
163-
format!(
164-
"Ce groupe peut utiliser les commandes suivantes:\n{}",
165-
authorizations
166-
.into_iter()
167-
.map(|s| format!(" - {}", s.command))
168-
.collect::<Vec<_>>()
169-
.join("\n")
170-
),
177+
if authorizations.is_empty() {
178+
"Ce groupe ne peut utiliser aucune commande".to_owned()
179+
} else {
180+
format!(
181+
"Ce groupe peut utiliser les commandes suivantes:\n{}",
182+
authorizations
183+
.into_iter()
184+
.map(|s| format!(" - {}", s.command))
185+
.collect::<Vec<_>>()
186+
.join("\n")
187+
)
188+
},
171189
)
172190
.await?;
173191

src/cmd_bureau.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ pub async fn bureau(bot: Bot, msg: Message) -> HandlerResult {
1818
.is_anonymous(false)
1919
.await?;
2020
Ok(())
21-
}
21+
}

src/cmd_poll.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ use teloxide::{
99
prelude::Dialogue,
1010
requests::Requester,
1111
types::{
12-
CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message, MessageId,
13-
ReplyMarkup,
12+
CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message, MessageId, ReplyMarkup,
1413
},
1514
Bot,
1615
};
@@ -36,11 +35,7 @@ pub enum PollState {
3635
pub type PollDialogue = Dialogue<PollState, InMemStorage<PollState>>;
3736

3837
/// Starts the /poll dialogue by sending a message with an inline keyboard to select the target of the /poll.
39-
pub async fn start_poll_dialogue(
40-
bot: Bot,
41-
msg: Message,
42-
dialogue: PollDialogue,
43-
) -> HandlerResult {
38+
pub async fn start_poll_dialogue(bot: Bot, msg: Message, dialogue: PollDialogue) -> HandlerResult {
4439
log::info!("Starting /poll dialogue");
4540

4641
log::debug!("Removing /poll message");
@@ -207,4 +202,4 @@ pub async fn stats(bot: Bot, msg: Message) -> HandlerResult {
207202
.await?;
208203

209204
Ok(())
210-
}
205+
}

src/commands.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ use std::sync::Arc;
22

33
use sqlx::SqlitePool;
44
use teloxide::{
5-
dispatching::DpHandlerDescription,
6-
prelude::*,
7-
types::{Message, MessageCommon, MessageKind},
8-
utils::command::BotCommands,
9-
Bot,
5+
dispatching::DpHandlerDescription, prelude::*, types::Message, utils::command::BotCommands, Bot,
106
};
117

128
use crate::{
@@ -68,7 +64,7 @@ fn require_authorization() -> Endpoint<'static, DependencyMap, HandlerResult, Dp
6864
|command: Command, msg: Message, pool: Arc<SqlitePool>| async move {
6965
let chat_id = msg.chat.id.to_string();
7066
let shortand = command.shortand();
71-
match sqlx::query!(
67+
let authorized = match sqlx::query!(
7268
r#"SELECT COUNT(*) AS count FROM authorizations WHERE chat_id = $1 AND command = $2"#,
7369
chat_id,
7470
shortand
@@ -80,7 +76,13 @@ fn require_authorization() -> Endpoint<'static, DependencyMap, HandlerResult, Dp
8076
log::error!("Could not check authorization in database: {:?}", e);
8177
false
8278
},
79+
};
80+
81+
if !authorized {
82+
log::warn!("Chat {} tried to use the commmand {}", msg.chat.id, command.shortand())
8383
}
84+
85+
authorized
8486
},
8587
)
8688
}
@@ -141,6 +143,8 @@ pub enum Command {
141143
Stats,
142144
}
143145

146+
pub const RESTRICTED_COMMANDS: [Command; 3] = [Command::Bureau, Command::Poll, Command::Stats];
147+
144148
impl Command {
145149
// Used as key for the access control map
146150
pub fn shortand(&self) -> &str {

src/main.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ use teloxide::{
99
};
1010

1111
use crate::{
12+
cmd_poll::PollState,
1213
commands::{command_callback_query_handler, command_message_handler, Command},
1314
directus::{update_committee, Committee},
14-
cmd_poll::PollState
1515
};
1616

17+
mod cmd_authentication;
18+
mod cmd_bureau;
19+
mod cmd_poll;
1720
mod commands;
1821
mod config;
1922
mod directus;
20-
mod cmd_poll;
21-
mod cmd_bureau;
22-
mod cmd_authentication;
2323

2424
pub type HandlerResult = Result<(), Box<dyn std::error::Error + Send + Sync>>;
2525

@@ -47,7 +47,8 @@ async fn main() {
4747
id: 1,
4848
name: "".into(),
4949
poll_count: 15,
50-
}]).await;
50+
}])
51+
.await;
5152

5253
log::info!("Loading config files");
5354
config::config();

0 commit comments

Comments
 (0)