Add permission checks to p.prefix command

This commit is contained in:
2025-08-20 02:29:40 -03:00
parent 3cc37cfc0c
commit ee49b0a984
23 changed files with 296 additions and 766 deletions
+9
View File
@@ -8,7 +8,9 @@ use crate::{
Command, CommandError,
arguments::{Argument, GreedyString, ParseArguments},
context::CommandContext,
permissions::Permission,
},
groups::servers::permissions::{GuildOnlyPermission, ServerModeratorPermission},
state::State,
};
@@ -37,6 +39,13 @@ impl Command<State> for PrefixCommand {
}]
}
fn permissions(&self) -> Vec<Box<dyn Permission<State> + Send + Sync + 'static>> {
vec![
Box::new(GuildOnlyPermission),
Box::new(ServerModeratorPermission),
]
}
async fn execute(
&self,
ctx: CommandContext<'_, State>,
+42 -3
View File
@@ -1,4 +1,5 @@
use async_trait::async_trait;
use twilight_model::guild::Permissions;
use crate::{
framework::commands::{CommandError, context::CommandContext, permissions::Permission},
@@ -11,7 +12,15 @@ pub struct GuildOnlyPermission;
#[async_trait]
impl Permission<State> for GuildOnlyPermission {
async fn check(&self, ctx: &CommandContext<State>) -> Result<bool, CommandError> {
Ok(ctx.event.guild_id.is_none())
Ok(ctx.event.guild_id.is_some())
}
async fn on_handle_denied(&self, ctx: &CommandContext<State>) -> Result<(), CommandError> {
ctx.send()
.content("❌ This command can only be used in a server.")
.await?;
Ok(())
}
}
@@ -20,7 +29,37 @@ pub struct ServerModeratorPermission;
#[async_trait]
impl Permission<State> for ServerModeratorPermission {
async fn check(&self, _ctx: &CommandContext<State>) -> Result<bool, CommandError> {
Ok(true)
async fn check(&self, ctx: &CommandContext<State>) -> Result<bool, CommandError> {
if let Some(guild_id) = ctx.event.guild_id {
let permissions = ctx
.rt
.cache
.permissions()
.root(ctx.event.author.id, guild_id);
if let Ok(permissions) = permissions {
let guild = ctx
.rt
.cache
.guild(guild_id)
.ok_or(CommandError::CacheStateInconsistent)?;
Ok(permissions
.contains(Permissions::MANAGE_CHANNELS | Permissions::MANAGE_MESSAGES)
|| guild.owner_id() == ctx.event.author.id)
} else {
Err(CommandError::CacheStateInconsistent)
}
} else {
Ok(true)
}
}
async fn on_handle_denied(&self, ctx: &CommandContext<State>) -> Result<(), CommandError> {
ctx.send()
.content("❌ This command can only be run by a server moderator.\n-# 🛈 Moderators must have permission to manage messages and to manage channels.")
.await?;
Ok(())
}
}