Skip to content

Commit

Permalink
Do permission checks for all parent commands too
Browse files Browse the repository at this point in the history
  • Loading branch information
kangalio committed Nov 1, 2022
1 parent ebb72a2 commit cceac77
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 12 deletions.
29 changes: 26 additions & 3 deletions examples/testing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,39 @@ type Context<'a> = poise::Context<'a, Data, Error>;
// User data, which is stored and accessible in all command invocations
struct Data {}

#[poise::command(slash_command, prefix_command)]
async fn child2_check(_ctx: Context<'_>) -> Result<bool, Error> {
println!("Child2 check executed!");
Ok(true)
}
async fn child1_check(_ctx: Context<'_>) -> Result<bool, Error> {
println!("Child1 check executed!");
Ok(true)
}
async fn parent_check(_ctx: Context<'_>) -> Result<bool, Error> {
println!("Parent check executed!");
Ok(true)
}

#[poise::command(slash_command, prefix_command, check = "child2_check")]
async fn child2(ctx: Context<'_>, _b: bool, _s: String, _i: u32) -> Result<(), Error> {
ctx.say(ctx.invocation_string()).await?;
Ok(())
}
#[poise::command(slash_command, prefix_command, subcommands("child2"))]
#[poise::command(
slash_command,
prefix_command,
subcommands("child2"),
check = "child1_check"
)]
async fn child1(_ctx: Context<'_>) -> Result<(), Error> {
Ok(())
}
#[poise::command(slash_command, prefix_command, subcommands("child1"))]
#[poise::command(
slash_command,
prefix_command,
subcommands("child1"),
check = "parent_check"
)]
async fn parent(_ctx: Context<'_>) -> Result<(), Error> {
Ok(())
}
Expand Down
28 changes: 19 additions & 9 deletions src/dispatch/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,10 @@ async fn missing_permissions<U, E>(
Some(required_permissions - permissions?)
}

/// Checks if the invoker is allowed to execute this command at this point in time
///
/// Doesn't actually start the cooldown timer! This should be done by the caller later, after
/// argument parsing.
/// (A command that didn't even get past argument parsing shouldn't trigger cooldowns)
#[allow(clippy::needless_lifetimes)] // false positive (clippy issue 7271)
pub async fn check_permissions_and_cooldown<'a, U, E>(
async fn check_permissions_and_cooldown_single<'a, U, E>(
ctx: crate::Context<'a, U, E>,
cmd: &'a crate::Command<U, E>,
) -> Result<(), crate::FrameworkError<'a, U, E>> {
let cmd = ctx.command();

if cmd.owners_only && !ctx.framework().options().owners.contains(&ctx.author().id) {
return Err(crate::FrameworkError::NotAnOwner { ctx });
}
Expand Down Expand Up @@ -183,3 +176,20 @@ pub async fn check_permissions_and_cooldown<'a, U, E>(

Ok(())
}

/// Checks if the invoker is allowed to execute this command at this point in time
///
/// Doesn't actually start the cooldown timer! This should be done by the caller later, after
/// argument parsing.
/// (A command that didn't even get past argument parsing shouldn't trigger cooldowns)
#[allow(clippy::needless_lifetimes)] // false positive (clippy issue 7271)
pub async fn check_permissions_and_cooldown<'a, U, E>(
ctx: crate::Context<'a, U, E>,
) -> Result<(), crate::FrameworkError<'a, U, E>> {
for parent_command in ctx.parent_commands() {
check_permissions_and_cooldown_single(ctx, parent_command).await?;
}
check_permissions_and_cooldown_single(ctx, ctx.command()).await?;

Ok(())
}

0 comments on commit cceac77

Please sign in to comment.