|
1 | 1 | use crate::commands::status::BotStatus; |
2 | 2 | use crate::commands::{BoxFuture, RegistrableCommand}; |
3 | 3 | use crate::config::Config; |
4 | | -use crate::errors::ModmailResult; |
| 4 | +use crate::errors::{CommandError, ModmailError, ModmailResult}; |
5 | 5 | use crate::handlers::InteractionHandler; |
6 | 6 | use crate::i18n::get_translated_message; |
7 | 7 | use crate::utils::{MessageBuilder, defer_response}; |
8 | 8 | use serenity::FutureExt; |
9 | 9 | use serenity::all::{ |
10 | 10 | ActivityData, CommandDataOptionValue, CommandInteraction, CommandOptionType, Context, |
11 | | - CreateCommand, CreateCommandOption, ResolvedOption, |
| 11 | + CreateCommand, CreateCommandOption, Permissions, ResolvedOption, |
12 | 12 | }; |
13 | 13 | use std::str::FromStr; |
14 | 14 | use std::sync::Arc; |
15 | 15 | use std::sync::atomic::Ordering; |
16 | 16 |
|
| 17 | +async fn is_interaction_user_admin_or_super_admin( |
| 18 | + ctx: &Context, |
| 19 | + command: &CommandInteraction, |
| 20 | + config: &Config, |
| 21 | +) -> bool { |
| 22 | + let user_id = command.user.id.get(); |
| 23 | + |
| 24 | + if config.bot.panel_super_admin_users.contains(&user_id) { |
| 25 | + return true; |
| 26 | + } |
| 27 | + |
| 28 | + let guild_id = match command.guild_id { |
| 29 | + Some(id) => id, |
| 30 | + None => return false, |
| 31 | + }; |
| 32 | + |
| 33 | + let member = match guild_id.member(&ctx.http, command.user.id).await { |
| 34 | + Ok(m) => m, |
| 35 | + Err(_) => return false, |
| 36 | + }; |
| 37 | + |
| 38 | + if !config.bot.panel_super_admin_roles.is_empty() { |
| 39 | + for role_id in &member.roles { |
| 40 | + if config.bot.panel_super_admin_roles.contains(&role_id.get()) { |
| 41 | + return true; |
| 42 | + } |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + let guild = match guild_id.to_partial_guild(&ctx.http).await { |
| 47 | + Ok(g) => g, |
| 48 | + Err(_) => return false, |
| 49 | + }; |
| 50 | + |
| 51 | + if guild.owner_id == command.user.id { |
| 52 | + return true; |
| 53 | + } |
| 54 | + |
| 55 | + member.roles.iter().any(|role_id| { |
| 56 | + guild |
| 57 | + .roles |
| 58 | + .get(role_id) |
| 59 | + .map(|role| role.permissions.contains(Permissions::ADMINISTRATOR)) |
| 60 | + .unwrap_or(false) |
| 61 | + }) |
| 62 | +} |
| 63 | + |
17 | 64 | pub struct StatusCommand; |
18 | 65 |
|
19 | 66 | impl RegistrableCommand for StatusCommand { |
@@ -136,6 +183,16 @@ impl RegistrableCommand for StatusCommand { |
136 | 183 | Err(_) => return Ok(()), |
137 | 184 | }; |
138 | 185 |
|
| 186 | + if bot_status == BotStatus::Maintenance { |
| 187 | + let is_allowed = |
| 188 | + is_interaction_user_admin_or_super_admin(&ctx, &command, &config).await; |
| 189 | + if !is_allowed { |
| 190 | + return Err(ModmailError::Command( |
| 191 | + CommandError::MaintenanceModeNotAllowed, |
| 192 | + )); |
| 193 | + } |
| 194 | + } |
| 195 | + |
139 | 196 | let message_key = match bot_status { |
140 | 197 | BotStatus::Online => { |
141 | 198 | handler.maintenance_mode.store(false, Ordering::Relaxed); |
|
0 commit comments