aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZeyla Hellyer <[email protected]>2018-01-05 22:26:47 -0800
committerZeyla Hellyer <[email protected]>2018-01-05 22:27:28 -0800
commit7566f32c194bc4e62e89adc57bfb6104cc99458e (patch)
tree2caf37e1fbe2343752943969f5b26eacff63b131 /src
parentFix help-commands' `plain` (diff)
downloadserenity-7566f32c194bc4e62e89adc57bfb6104cc99458e.tar.xz
serenity-7566f32c194bc4e62e89adc57bfb6104cc99458e.zip
Fix permission overwrites in permission building
While building permissions in the `Guild::permissions_in` function - which is relied upon by most model functions to check CurrentUser permissions - the channel overwrites of the given channel were iterated over incorrectly. The channel overwrites were iterated over in a non-specified order, resulting in overwrites being applied in a random order. However, Discord operates by applying permissions from a down-top order: role ID 0 is below role ID 1, which is below role ID 2, etc. This means that prior to applying permissions we must first sort by position so that lower positioned roles are iterated over first.
Diffstat (limited to 'src')
-rw-r--r--src/model/guild/mod.rs12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs
index bc97ba8..3226067 100644
--- a/src/model/guild/mod.rs
+++ b/src/model/guild/mod.rs
@@ -1167,6 +1167,8 @@ impl Guild {
// First apply the denied permission overwrites for each, then apply
// the allowed.
+ let mut data = Vec::with_capacity(member.roles.len());
+
// Roles
for overwrite in &channel.permission_overwrites {
if let PermissionOverwriteType::Role(role) = overwrite.kind {
@@ -1174,10 +1176,18 @@ impl Guild {
continue;
}
- permissions = (permissions & !overwrite.deny) | overwrite.allow;
+ if let Some(role) = self.roles.get(&role) {
+ data.push((role.position, overwrite.deny, overwrite.allow));
+ }
}
}
+ data.sort_by(|a, b| a.0.cmp(&b.0));
+
+ for overwrite in data {
+ permissions = (permissions & !overwrite.1) | overwrite.2;
+ }
+
// Member
for overwrite in &channel.permission_overwrites {
if PermissionOverwriteType::Member(user_id) != overwrite.kind {