Skip to content

Commit

Permalink
Remove permission checks (serenity-rs#2855)
Browse files Browse the repository at this point in the history
Users should realistically be checking the permissions themselves, or
handling the HTTP error from Discord.

This removes any cases where permission checking inside the library is
broken because of Discord's changes or due to oversights.

This also changes the documentation on the prune functionality, this was
recently changed to also require `MANAGE_GUILDS` as well as
`KICK_MEMBERS`.
  • Loading branch information
jamesbt365 authored and mkrasnitski committed Jul 28, 2024
1 parent f4499cc commit ae0d4b3
Show file tree
Hide file tree
Showing 34 changed files with 271 additions and 910 deletions.
28 changes: 15 additions & 13 deletions examples/e09_collectors/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,26 @@ impl EventHandler for Handler {

async fn message(&self, ctx: Context, msg: Message) {
let mut score = 0u32;
let _ = msg.reply(&ctx, "How was that crusty crab called again? 10 seconds time!").await;
let _ =
msg.reply(&ctx.http, "How was that crusty crab called again? 10 seconds time!").await;

// There is a method implemented for some models to conveniently collect replies. They
// return a builder that can be turned into a Stream, or here, where we can await a
// single reply
let collector = msg.author.await_reply(ctx.shard.clone()).timeout(Duration::from_secs(10));
if let Some(answer) = collector.await {
if answer.content.to_lowercase() == "ferris" {
let _ = answer.reply(&ctx, "That's correct!").await;
let _ = answer.reply(&ctx.http, "That's correct!").await;
score += 1;
} else {
let _ = answer.reply(&ctx, "Wrong, it's Ferris!").await;
let _ = answer.reply(&ctx.http, "Wrong, it's Ferris!").await;
}
} else {
let _ = msg.reply(&ctx, "No answer within 10 seconds.").await;
let _ = msg.reply(&ctx.http, "No answer within 10 seconds.").await;
};

let react_msg = msg
.reply(&ctx, "React with the reaction representing 1, you got 10 seconds!")
.reply(&ctx.http, "React with the reaction representing 1, you got 10 seconds!")
.await
.unwrap();

Expand All @@ -52,15 +53,15 @@ impl EventHandler for Handler {
if let Some(reaction) = collector.await {
let _ = if reaction.emoji.as_data() == "1️⃣" {
score += 1;
msg.reply(&ctx, "That's correct!").await
msg.reply(&ctx.http, "That's correct!").await
} else {
msg.reply(&ctx, "Wrong!").await
msg.reply(&ctx.http, "Wrong!").await
};
} else {
let _ = msg.reply(&ctx, "No reaction within 10 seconds.").await;
let _ = msg.reply(&ctx.http, "No reaction within 10 seconds.").await;
};

let _ = msg.reply(&ctx, "Write 5 messages in 10 seconds").await;
let _ = msg.reply(&ctx.http, "Write 5 messages in 10 seconds").await;

// We can create a collector from scratch too using this builder future.
let collector = MessageCollector::new(ctx.shard.clone())
Expand Down Expand Up @@ -107,7 +108,7 @@ impl EventHandler for Handler {
})
.take_until(Box::pin(tokio::time::sleep(Duration::from_secs(20))));

let _ = msg.reply(&ctx, "Edit each of those 5 messages in 20 seconds").await;
let _ = msg.reply(&ctx.http, "Edit each of those 5 messages in 20 seconds").await;
let mut edited = HashSet::new();
while let Some(edited_message_id) = collector.next().await {
edited.insert(edited_message_id);
Expand All @@ -118,13 +119,14 @@ impl EventHandler for Handler {

if edited.len() >= 5 {
score += 1;
let _ = msg.reply(&ctx, "Great! You edited 5 out of 5").await;
let _ = msg.reply(&ctx.http, "Great! You edited 5 out of 5").await;
} else {
let _ = msg.reply(&ctx, format!("You only edited {} out of 5", edited.len())).await;
let _ =
msg.reply(&ctx.http, format!("You only edited {} out of 5", edited.len())).await;
}

let _ = msg
.reply(ctx, format!("TIME'S UP! You completed {score} out of 4 tasks correctly!"))
.reply(&ctx.http, format!("TIME'S UP! You completed {score} out of 4 tasks correctly!"))
.await;
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/e11_global_data/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl EventHandler for Handler {
Cow::Owned(format!("OWO Has been said {owo_count} times!"))
};

if let Err(err) = msg.reply(ctx, response).await {
if let Err(err) = msg.reply(&ctx.http, response).await {
eprintln!("Error sending response: {err:?}")
};
}
Expand Down
2 changes: 1 addition & 1 deletion examples/e12_parallel_loops/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ async fn log_system_load(ctx: &Context) {
false,
);
let builder = CreateMessage::new().embed(embed);
let message = ChannelId::new(381926291785383946).send_message(&ctx, builder).await;
let message = ChannelId::new(381926291785383946).send_message(&ctx.http, builder).await;
if let Err(why) = message {
eprintln!("Error sending message: {why:?}");
};
Expand Down
6 changes: 3 additions & 3 deletions examples/e13_sqlite_database/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl EventHandler for Bot {
.unwrap();

let response = format!("Successfully added `{task_description}` to your todo list");
msg.channel_id.say(&ctx, response).await.unwrap();
msg.channel_id.say(&ctx.http, response).await.unwrap();
} else if let Some(task_index) = msg.content.strip_prefix("~todo remove") {
let task_index = task_index.trim().parse::<i64>().unwrap() - 1;

Expand All @@ -51,7 +51,7 @@ impl EventHandler for Bot {
.unwrap();

let response = format!("Successfully completed `{}`!", entry.task);
msg.channel_id.say(&ctx, response).await.unwrap();
msg.channel_id.say(&ctx.http, response).await.unwrap();
} else if msg.content.trim() == "~todo list" {
// "SELECT" will return the task of all rows where user_Id column = user_id in todo.
let todos = sqlx::query!("SELECT task FROM todo WHERE user_id = ? ORDER BY rowid", user_id)
Expand All @@ -64,7 +64,7 @@ impl EventHandler for Bot {
writeln!(response, "{}. {}", i + 1, todo.task).unwrap();
}

msg.channel_id.say(&ctx, response).await.unwrap();
msg.channel_id.say(&ctx.http, response).await.unwrap();
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions examples/e14_message_components/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl EventHandler for Handler {
let m = msg
.channel_id
.send_message(
&ctx,
&ctx.http,
CreateMessage::new().content("Please select your favorite animal").select_menu(
CreateSelectMenu::new("animal_select", CreateSelectMenuKind::String {
options: Cow::Borrowed(&[
Expand Down Expand Up @@ -65,7 +65,7 @@ impl EventHandler for Handler {
{
Some(x) => x,
None => {
m.reply(&ctx, "Timed out").await.unwrap();
m.reply(&ctx.http, "Timed out").await.unwrap();
return;
},
};
Expand Down Expand Up @@ -131,7 +131,7 @@ impl EventHandler for Handler {

// Delete the orig message or there will be dangling components (components that still
// exist, but no collector is running so any user who presses them sees an error)
m.delete(&ctx, None).await.unwrap()
m.delete(&ctx.http, None).await.unwrap()
}
}

Expand Down
33 changes: 18 additions & 15 deletions examples/testing/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,21 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
} else if msg.content == "edit" {
let mut msg = channel_id
.send_message(
&ctx,
&ctx.http,
CreateMessage::new()
.add_file(CreateAttachment::url(&ctx.http, IMAGE_URL, "testing.png").await?),
)
.await?;
// Pre-PR, this falsely triggered a MODEL_TYPE_CONVERT Discord error
msg.edit(&ctx, EditMessage::new().attachments(EditAttachments::keep_all(&msg))).await?;
} else if msg.content == "unifiedattachments" {
let mut msg = channel_id.send_message(ctx, CreateMessage::new().content("works")).await?;
let mut msg =
channel_id.send_message(&ctx.http, CreateMessage::new().content("works")).await?;
msg.edit(ctx, EditMessage::new().content("works still")).await?;

let mut msg = channel_id
.send_message(
ctx,
&ctx.http,
CreateMessage::new()
.add_file(CreateAttachment::url(&ctx.http, IMAGE_URL, "testing.png").await?),
)
Expand All @@ -86,14 +87,14 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
// Test special characters in audit log reason
msg.channel_id
.edit(
ctx,
&ctx.http,
EditChannel::new().name("new-channel-name").audit_log_reason("hello\nworld\n🙂"),
)
.await?;
} else if msg.content == "actionrow" {
channel_id
.send_message(
ctx,
&ctx.http,
CreateMessage::new()
.button(CreateButton::new("0").label("Foo"))
.button(CreateButton::new("1").emoji('🤗').style(ButtonStyle::Secondary))
Expand All @@ -113,7 +114,7 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
loop {
let msg = channel_id
.send_message(
ctx,
&ctx.http,
CreateMessage::new()
.button(CreateButton::new(custom_id.clone()).label(custom_id)),
)
Expand All @@ -131,8 +132,8 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
}
} else if msg.content == "reactionremoveemoji" {
// Test new ReactionRemoveEmoji gateway event: https://github.com/serenity-rs/serenity/issues/2248
msg.react(ctx, '👍').await?;
msg.delete_reaction_emoji(ctx, '👍').await?;
msg.react(&ctx.http, '👍').await?;
msg.delete_reaction_emoji(&ctx.http, '👍').await?;
} else if msg.content == "testautomodregex" {
guild_id
.create_automod_rule(
Expand All @@ -152,7 +153,7 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
} else if msg.content == "createtags" {
channel_id
.edit(
&ctx,
&ctx.http,
EditChannel::new().available_tags(vec![
CreateForumTag::new("tag1 :)").emoji('👍'),
CreateForumTag::new("tag2 (:").moderated(true),
Expand All @@ -174,7 +175,7 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
use tokio::time::Duration;

let mut msg = channel_id
.say(ctx, format!("https://codereview.stackexchange.com/questions/260653/very-slow-discord-bot-to-play-music{}", msg.id))
.say(&ctx.http, format!("https://codereview.stackexchange.com/questions/260653/very-slow-discord-bot-to-play-music{}", msg.id))
.await?;

let msg_id = msg.id;
Expand All @@ -197,15 +198,15 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
let mut channel =
channel.trim().parse::<ChannelId>().unwrap().to_channel(ctx).await?.guild().unwrap();
let parent_id = channel.parent_id.unwrap();
channel.edit(ctx, EditChannel::new().category(None)).await?;
channel.edit(ctx, EditChannel::new().category(Some(parent_id))).await?;
channel.edit(&ctx.http, EditChannel::new().category(None)).await?;
channel.edit(&ctx.http, EditChannel::new().category(Some(parent_id))).await?;
} else if msg.content == "channelperms" {
let guild = guild_id.to_guild_cached(&ctx.cache).unwrap().clone();
let perms = guild.user_permissions_in(
&channel_id.to_channel(ctx).await?.guild().unwrap(),
&*guild.member(&ctx.http, msg.author.id).await?,
);
channel_id.say(ctx, format!("{:?}", perms)).await?;
channel_id.say(&ctx.http, format!("{:?}", perms)).await?;
} else if let Some(forum_channel_id) = msg.content.strip_prefix("createforumpostin ") {
forum_channel_id
.parse::<ChannelId>()
Expand All @@ -222,14 +223,16 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
} else if let Some(forum_post_url) = msg.content.strip_prefix("deleteforumpost ") {
let (_guild_id, channel_id, _message_id) =
serenity::utils::parse_message_url(forum_post_url).unwrap();
msg.channel_id.say(ctx, format!("Deleting <#{}> in 10 seconds...", channel_id)).await?;
msg.channel_id
.say(&ctx.http, format!("Deleting <#{}> in 10 seconds...", channel_id))
.await?;
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
channel_id.delete(&ctx.http, None).await?;
} else {
return Ok(());
}

msg.react(&ctx, '✅').await?;
msg.react(&ctx.http, '✅').await?;
Ok(())
}

Expand Down
5 changes: 0 additions & 5 deletions src/builder/create_attachment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,6 @@ impl<'a> EditAttachments<'a> {
}
files
}

#[cfg(feature = "cache")]
pub(crate) fn is_empty(&self) -> bool {
self.new_and_existing_attachments.is_empty()
}
}

impl<'a> Serialize for EditAttachments<'a> {
Expand Down
16 changes: 4 additions & 12 deletions src/builder/create_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::borrow::Cow;
use nonmax::NonMaxU16;

#[cfg(feature = "http")]
use crate::http::CacheHttp;
use crate::http::Http;
#[cfg(feature = "http")]
use crate::internal::prelude::*;
use crate::model::prelude::*;
Expand Down Expand Up @@ -261,19 +261,11 @@ impl<'a> CreateChannel<'a> {
///
/// # Errors
///
/// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
/// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
/// Returns [`Error::Http`] if the current user lacks permission or if invalid data is given.
///
/// [Manage Channels]: Permissions::MANAGE_CHANNELS
#[cfg(feature = "http")]
pub async fn execute(
self,
cache_http: impl CacheHttp,
guild_id: GuildId,
) -> Result<GuildChannel> {
#[cfg(feature = "cache")]
crate::utils::user_has_guild_perms(&cache_http, guild_id, Permissions::MANAGE_CHANNELS)?;

cache_http.http().create_channel(guild_id, &self, self.audit_log_reason).await
pub async fn execute(self, http: &Http, guild_id: GuildId) -> Result<GuildChannel> {
http.create_channel(guild_id, &self, self.audit_log_reason).await
}
}
Loading

0 comments on commit ae0d4b3

Please sign in to comment.