Skip to content

Commit ff8cb14

Browse files
authored
Rename user_permissions_in and add member_permissions_guild_level (#3116)
`user_permissions_in` was renamed because it was an outlier, the previously removed `member_permissions` has come back under a new name.
1 parent 22eb841 commit ff8cb14

File tree

5 files changed

+128
-12
lines changed

5 files changed

+128
-12
lines changed

src/model/channel/guild_channel.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ impl GuildChannel {
406406
.members
407407
.iter()
408408
.filter(|member| {
409-
guild.user_permissions_in(self, member).contains(Permissions::VIEW_CHANNEL)
409+
guild.member_permissions_in(self, member).contains(Permissions::VIEW_CHANNEL)
410410
})
411411
.cloned()
412412
.collect::<Vec<Member>>()),

src/model/channel/message.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ impl Message {
217217
let mut permissions = if let Some(member) = &self.member {
218218
guild.partial_member_permissions_in(channel, self.author.id, member)
219219
} else {
220-
guild.user_permissions_in(channel, guild.members.get(&self.author.id)?)
220+
guild.member_permissions_in(channel, guild.members.get(&self.author.id)?)
221221
};
222222

223223
if is_thread {

src/model/guild/member.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ impl Member {
175175

176176
for channel in &guild.channels {
177177
if channel.kind != ChannelType::Category
178-
&& guild.user_permissions_in(channel, member).view_channel()
178+
&& guild.member_permissions_in(channel, member).view_channel()
179179
{
180180
return Some(channel.clone());
181181
}

src/model/guild/mod.rs

+82-6
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ impl Guild {
270270
let member = self.members.get(&uid)?;
271271
self.channels.iter().find(|&channel| {
272272
channel.kind != ChannelType::Category
273-
&& self.user_permissions_in(channel, member).view_channel()
273+
&& self.member_permissions_in(channel, member).view_channel()
274274
})
275275
}
276276

@@ -285,7 +285,7 @@ impl Guild {
285285
&& self
286286
.members
287287
.iter()
288-
.map(|member| self.user_permissions_in(channel, member))
288+
.map(|member| self.member_permissions_in(channel, member))
289289
.all(Permissions::view_channel)
290290
})
291291
}
@@ -804,8 +804,8 @@ impl Guild {
804804

805805
/// Calculate a [`Member`]'s permissions in a given channel in the guild.
806806
#[must_use]
807-
pub fn user_permissions_in(&self, channel: &GuildChannel, member: &Member) -> Permissions {
808-
Self::user_permissions_in_(
807+
pub fn member_permissions_in(&self, channel: &GuildChannel, member: &Member) -> Permissions {
808+
Self::member_permissions_in_(
809809
channel,
810810
member.user.id,
811811
&member.roles,
@@ -831,7 +831,7 @@ impl Guild {
831831
assert_eq!(user.id, member_id, "User::id does not match provided PartialMember");
832832
}
833833

834-
Self::user_permissions_in_(
834+
Self::member_permissions_in_(
835835
channel,
836836
member_id,
837837
&member.roles,
@@ -841,8 +841,84 @@ impl Guild {
841841
)
842842
}
843843

844+
/// Calculate a [`Member`]'s permissions in the guild.
845+
///
846+
/// **Note**: This method calculates the permissions granted to the member across the entire
847+
/// guild, excluding any channel-specific overrides. If you are not checking permissions that
848+
/// do not apply on the channel level, like `Permissions::BAN_MEMBERS`, use
849+
/// member_permissions_in instead.
850+
#[must_use]
851+
pub fn member_permissions_guild_level(&self, member: &Member) -> Permissions {
852+
Self::member_permissions_guild_level_(
853+
member.user.id,
854+
&member.roles,
855+
self.id,
856+
self.owner_id,
857+
&self.roles,
858+
)
859+
}
860+
861+
/// Calculate a [`PartialMember`]'s permissions in the guild.
862+
///
863+
/// See `Self::member_permissions_guild_level` for note on usage.
864+
///
865+
/// # Panics
866+
///
867+
/// Panics if the passed [`UserId`] does not match the [`PartialMember`] id, if user is Some.
868+
#[must_use]
869+
pub fn partial_member_permissions_guild_level(
870+
&self,
871+
member_id: UserId,
872+
member: &PartialMember,
873+
) -> Permissions {
874+
if let Some(user) = &member.user {
875+
assert_eq!(user.id, member_id, "User::id does not match provided PartialMember");
876+
}
877+
878+
Self::member_permissions_guild_level_(
879+
member_id,
880+
&member.roles,
881+
self.id,
882+
self.owner_id,
883+
&self.roles,
884+
)
885+
}
886+
887+
/// Helper function that can also be used from [`PartialGuild`].
888+
pub(crate) fn member_permissions_guild_level_(
889+
user_id: UserId,
890+
member_roles: &[RoleId],
891+
guild_id: GuildId,
892+
guild_owner_id: UserId,
893+
guild_roles: &ExtractMap<RoleId, Role>,
894+
) -> Permissions {
895+
if user_id == guild_owner_id {
896+
return Permissions::all();
897+
}
898+
899+
//// Get @everyone permissions first.
900+
let mut permissions = if let Some(role) = guild_roles.get(&RoleId::new(guild_id.get())) {
901+
role.permissions
902+
} else {
903+
error!("@everyone role missing in {}", guild_id);
904+
Permissions::empty()
905+
};
906+
907+
for role_id in member_roles {
908+
if let Some(role) = guild_roles.get(role_id) {
909+
permissions |= role.permissions;
910+
}
911+
}
912+
913+
if permissions.contains(Permissions::ADMINISTRATOR) {
914+
return Permissions::all();
915+
}
916+
917+
permissions
918+
}
919+
844920
/// Helper function that can also be used from [`PartialGuild`].
845-
pub(crate) fn user_permissions_in_(
921+
pub(crate) fn member_permissions_in_(
846922
channel: &GuildChannel,
847923
member_user_id: UserId,
848924
member_roles: &[RoleId],

src/model/guild/partial_guild.rs

+43-3
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ impl PartialGuild {
225225
assert_eq!(user.id, member_id, "User::id does not match provided PartialMember");
226226
}
227227

228-
Guild::user_permissions_in_(
228+
Guild::member_permissions_in_(
229229
channel,
230230
member_id,
231231
&member.roles,
@@ -235,6 +235,46 @@ impl PartialGuild {
235235
)
236236
}
237237

238+
/// Calculate a [`Member`]'s permissions in the guild.
239+
///
240+
/// See `Guild::member_permissions_guild_level` for note on usage.
241+
#[must_use]
242+
pub fn member_permissions_guild_level(&self, member: &Member) -> Permissions {
243+
Guild::member_permissions_guild_level_(
244+
member.user.id,
245+
&member.roles,
246+
self.id,
247+
self.owner_id,
248+
&self.roles,
249+
)
250+
}
251+
252+
/// Calculate a [`PartialMember`]'s permissions in the guild.
253+
///
254+
/// See `Guild::member_permissions_guild_level` for note on usage.
255+
///
256+
/// # Panics
257+
///
258+
/// Panics if the passed [`UserId`] does not match the [`PartialMember`] id, if user is Some.
259+
#[must_use]
260+
pub fn partial_member_permissions_guild_level(
261+
&self,
262+
member_id: UserId,
263+
member: &PartialMember,
264+
) -> Permissions {
265+
if let Some(user) = &member.user {
266+
assert_eq!(user.id, member_id, "User::id does not match provided PartialMember");
267+
}
268+
269+
Guild::member_permissions_guild_level_(
270+
member_id,
271+
&member.roles,
272+
self.id,
273+
self.owner_id,
274+
&self.roles,
275+
)
276+
}
277+
238278
/// Returns a formatted URL of the guild's icon, if the guild has an icon.
239279
#[must_use]
240280
pub fn icon_url(&self) -> Option<String> {
@@ -249,8 +289,8 @@ impl PartialGuild {
249289

250290
/// Calculate a [`Member`]'s permissions in a given channel in the guild.
251291
#[must_use]
252-
pub fn user_permissions_in(&self, channel: &GuildChannel, member: &Member) -> Permissions {
253-
Guild::user_permissions_in_(
292+
pub fn member_permissions_in(&self, channel: &GuildChannel, member: &Member) -> Permissions {
293+
Guild::member_permissions_in_(
254294
channel,
255295
member.user.id,
256296
&member.roles,

0 commit comments

Comments
 (0)