diff options
| author | Zeyla Hellyer <[email protected]> | 2018-01-06 15:02:05 -0800 |
|---|---|---|
| committer | Zeyla Hellyer <[email protected]> | 2018-01-06 15:02:05 -0800 |
| commit | 222382ca48cb9786aaf5d0b5fc16958e482e7c5f (patch) | |
| tree | 9607694a5ec604e4ff3b73938772093e4d90cba3 /src | |
| parent | Add Guild::greater_member_hierarchy (diff) | |
| download | serenity-222382ca48cb9786aaf5d0b5fc16958e482e7c5f.tar.xz serenity-222382ca48cb9786aaf5d0b5fc16958e482e7c5f.zip | |
Add some role position hierarchy checks
Diffstat (limited to 'src')
| -rw-r--r-- | src/model/error.rs | 9 | ||||
| -rw-r--r-- | src/model/guild/member.rs | 18 | ||||
| -rw-r--r-- | src/model/guild/mod.rs | 17 |
3 files changed, 36 insertions, 8 deletions
diff --git a/src/model/error.rs b/src/model/error.rs index 340bd18..a2b8325 100644 --- a/src/model/error.rs +++ b/src/model/error.rs @@ -86,6 +86,14 @@ pub enum Error { /// [`GuildId`]: ../model/struct.GuildId.html /// [`Cache`]: ../cache/struct.Cache.html GuildNotFound, + /// Indicates that there are hierarchy problems restricting an action. + /// + /// For example, when banning a user, if the other user has a role with an + /// equal to or higher position, then they can not be banned. + /// + /// When editing a role, if the role is higher in position than the current + /// user's highest role, then the role can not be edited. + Hierarchy, /// Indicates that you do not have the required permissions to perform an /// operation. /// @@ -126,6 +134,7 @@ impl StdError for Error { Error::DeleteMessageDaysAmount(_) => "Invalid delete message days", Error::EmbedTooLarge(_) => "Embed too large", Error::GuildNotFound => "Guild not found in the cache", + Error::Hierarchy => "Role hierarchy prevents this action", Error::InvalidPermissions(_) => "Invalid permissions", Error::InvalidUser => "The current user can not perform the action", Error::ItemMissing => "The required item is missing from the cache", diff --git a/src/model/guild/member.rs b/src/model/guild/member.rs index 3622489..b93349e 100644 --- a/src/model/guild/member.rs +++ b/src/model/guild/member.rs @@ -309,16 +309,18 @@ impl Member { pub fn kick(&self) -> Result<()> { #[cfg(feature = "cache")] { - let req = Permissions::KICK_MEMBERS; + let cache = CACHE.read(); - let has_perms = CACHE - .read() - .guilds - .get(&self.guild_id) - .map(|guild| guild.read().has_perms(req)); + if let Some(guild) = self.guilds.get(&self.guild_id) { + let reader = guild.read(); + + if !guild.has_perms(req) { + let req = Permissions::KICK_MEMBERS; + + return Err(Error::Model(ModelError::InvalidPermissions(req))); + } - if let Some(false) = has_perms { - return Err(Error::Model(ModelError::InvalidPermissions(req))); + guild.check_hierarchy(&self.user.read().id)?; } } diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs index f9eca59..c74b4b2 100644 --- a/src/model/guild/mod.rs +++ b/src/model/guild/mod.rs @@ -144,6 +144,19 @@ pub struct Guild { #[cfg(feature = "model")] impl Guild { + #[cfg(feature = "cache")] + fn check_hierarchy(&self, other_user: UserId) -> Result<()> { + let current_id = CACHE.read().user.id; + + if let Some(higher) = self.greater_member_hierarchy(user, current_id) { + if higher != current_id { + return Err(Error::Model(ModelError::Hierarchy)); + } + } + + Ok(()) + } + /// Returns the "default" channel of the guild for the passed user id. /// (This returns the first channel that can be read by the user, if there isn't one, /// returns `None`) @@ -215,6 +228,8 @@ impl Guild { /// [`User`]: struct.User.html /// [Ban Members]: permissions/constant.BAN_MEMBERS.html pub fn ban<U: Into<UserId>, BO: BanOptions>(&self, user: U, options: &BO) -> Result<()> { + let user = user.into(); + #[cfg(feature = "cache")] { let req = Permissions::BAN_MEMBERS; @@ -222,6 +237,8 @@ impl Guild { if !self.has_perms(req) { return Err(Error::Model(ModelError::InvalidPermissions(req))); } + + self.check_hierarchy(user)?; } self.id.ban(user, options) |