diff options
| author | Zeyla Hellyer <[email protected]> | 2018-01-05 22:26:47 -0800 |
|---|---|---|
| committer | Zeyla Hellyer <[email protected]> | 2018-01-05 22:27:28 -0800 |
| commit | 7566f32c194bc4e62e89adc57bfb6104cc99458e (patch) | |
| tree | 2caf37e1fbe2343752943969f5b26eacff63b131 /src | |
| parent | Fix help-commands' `plain` (diff) | |
| download | serenity-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.rs | 12 |
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 { |