Skip to content

Commit

Permalink
GuildChannel.permissionsFor(role) (#2254)
Browse files Browse the repository at this point in the history
* GuildChannel.permissionsFor(role)

* 1Comp's requested changes
  • Loading branch information
bdistin authored and Lewdcario committed Jan 18, 2018
1 parent d5b0cf9 commit b846cbd
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 26 deletions.
77 changes: 54 additions & 23 deletions src/structures/GuildChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,31 +92,16 @@ class GuildChannel extends Channel {
}

/**
* Gets the overall set of permissions for a user in this channel, taking into account roles and permission
* overwrites.
* @param {GuildMemberResolvable} member The user that you want to obtain the overall permissions for
* Gets the overall set of permissions for a member or role in this channel, taking into account channel overwrites.
* @param {GuildMemberResolvable|RoleResolvable} memberOrRole The member or role to obtain the overall permissions for
* @returns {?Permissions}
*/
permissionsFor(member) {
member = this.guild.members.resolve(member);
if (!member) return null;
if (member.id === this.guild.ownerID) return new Permissions(Permissions.ALL).freeze();

const roles = member.roles;
const permissions = new Permissions(roles.map(role => role.permissions));

if (permissions.has(Permissions.FLAGS.ADMINISTRATOR)) return new Permissions(Permissions.ALL).freeze();

const overwrites = this.overwritesFor(member, true, roles);

return permissions
.remove(overwrites.everyone ? overwrites.everyone.denied : 0)
.add(overwrites.everyone ? overwrites.everyone.allowed : 0)
.remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.denied) : 0)
.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allowed) : 0)
.remove(overwrites.member ? overwrites.member.denied : 0)
.add(overwrites.member ? overwrites.member.allowed : 0)
.freeze();
permissionsFor(memberOrRole) {
const member = this.guild.members.resolve(memberOrRole);
if (member) return this.memberPermissions(member);
const role = this.guild.roles.resolve(memberOrRole);
if (role) return this.rolePermissions(role);
return null;
}

overwritesFor(member, verified = false, roles = null) {
Expand Down Expand Up @@ -145,6 +130,52 @@ class GuildChannel extends Channel {
};
}

/**
* Gets the overall set of permissions for a member in this channel, taking into account channel overwrites.
* @param {GuildMember} member The member to obtain the overall permissions for
* @returns {Permissions}
* @private
*/
memberPermissions(member) {
if (member.id === this.guild.ownerID) return new Permissions(Permissions.ALL).freeze();

const roles = member.roles;
const permissions = new Permissions(roles.map(role => role.permissions));

if (permissions.has(Permissions.FLAGS.ADMINISTRATOR)) return new Permissions(Permissions.ALL).freeze();

const overwrites = this.overwritesFor(member, true, roles);

return permissions
.remove(overwrites.everyone ? overwrites.everyone.denied : 0)
.add(overwrites.everyone ? overwrites.everyone.allowed : 0)
.remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.denied) : 0)
.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allowed) : 0)
.remove(overwrites.member ? overwrites.member.denied : 0)
.add(overwrites.member ? overwrites.member.allowed : 0)
.freeze();
}

/**
* Gets the overall set of permissions for a role in this channel, taking into account channel overwrites.
* @param {Role} role The role to obtain the overall permissions for
* @returns {Permissions}
* @private
*/
rolePermissions(role) {
if (role.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) return new Permissions(Permissions.ALL).freeze();

const everyoneOverwrites = this.permissionOverwrites.get(this.guild.id);
const roleOverwrites = this.permissionOverwrites.get(role.id);

return role.permissions
.remove(everyoneOverwrites ? everyoneOverwrites.denied : 0)
.add(everyoneOverwrites ? everyoneOverwrites.allowed : 0)
.remove(roleOverwrites ? roleOverwrites.denied : 0)
.add(roleOverwrites ? roleOverwrites.allowed : 0)
.freeze();
}

/**
* An object mapping permission flags to `true` (enabled), `null` (default) or `false` (disabled).
* ```js
Expand Down
6 changes: 3 additions & 3 deletions src/structures/GuildMember.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,9 @@ class GuildMember extends Base {
* @returns {?Permissions}
*/
permissionsIn(channel) {
channel = this.client.channels.resolve(channel);
if (!channel || !channel.guild) throw new Error('GUILD_CHANNEL_RESOLVE');
return channel.permissionsFor(this);
channel = this.guild.channels.resolve(channel);
if (!channel) throw new Error('GUILD_CHANNEL_RESOLVE');
return channel.memberPermissions(this);
}

/**
Expand Down
12 changes: 12 additions & 0 deletions src/structures/Role.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,18 @@ class Role extends Base {
});
}

/**
* Returns `channel.permissionsFor(role)`. Returns permissions for a role in a guild channel,
* taking into account permission overwrites.
* @param {ChannelResolvable} channel The guild channel to use as context
* @returns {?Permissions}
*/
permissionsIn(channel) {
channel = this.guild.channels.resolve(channel);
if (!channel) throw new Error('GUILD_CHANNEL_RESOLVE');
return channel.rolePermissions(this);
}

/**
* Sets a new name for the role.
* @param {string} name The new name of the role
Expand Down

0 comments on commit b846cbd

Please sign in to comment.