Skip to content

Commit

Permalink
backport: GuildChannel#permissionsFor(role)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lewdcario committed Aug 9, 2018
1 parent c76f304 commit 1e5b5b8
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 30 deletions.
67 changes: 43 additions & 24 deletions src/structures/GuildChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,44 +74,63 @@ class GuildChannel extends Channel {
}

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

let permissions = 0;
if (member.id === this.guild.ownerID) return new Permissions(member, Permissions.ALL);

const roles = member.roles;
for (const role of roles.values()) permissions |= role.permissions;
const permissions = new Permissions(roles.map(role => role.permissions));

const admin = Boolean(permissions & Permissions.FLAGS.ADMINISTRATOR);
if (admin) return new Permissions(Permissions.ALL);
if (permissions.has(Permissions.FLAGS.ADMINISTRATOR)) return new Permissions(Permissions.ALL).freeze();

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

if (overwrites.everyone) {
permissions &= ~overwrites.everyone.deny;
permissions |= overwrites.everyone.allow;
}

let allow = 0;
for (const overwrite of overwrites.roles) {
permissions &= ~overwrite.deny;
allow |= overwrite.allow;
}
permissions |= allow;
return permissions
.remove(overwrites.everyone ? overwrites.everyone.deny : 0)
.add(overwrites.everyone ? overwrites.everyone.allow : 0)
.remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.deny) : 0)
.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allow) : 0)
.remove(overwrites.member ? overwrites.member.deny : 0)
.add(overwrites.member ? overwrites.member.allow : 0)
.freeze();
}

if (overwrites.member) {
permissions &= ~overwrites.member.deny;
permissions |= overwrites.member.allow;
}
/**
* Gets the overall set of permissions for a role in this channel, taking into account channel overwrites.
* @param {RoleResolvable} role The role that you want to obtain the overall permissions for
* @returns {?Permissions}
*/
rolePermissions(role) {
if (role.permissions & 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 new Permissions(role.permissions)
.remove(everyoneOverwrites ? everyoneOverwrites.deny : 0)
.add(everyoneOverwrites ? everyoneOverwrites.allow : 0)
.remove(roleOverwrites ? roleOverwrites.deny : 0)
.add(roleOverwrites ? roleOverwrites.allow : 0)
.freeze();
}

return new Permissions(member, permissions);
/**
* Get 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(memberOrRole) {
const member = this.guild.member(memberOrRole);
if (member) return this.memberPermissions(member);
const role = this.client.resolver.resolveRole(this.guild, memberOrRole);
if (role) return this.rolePermissions(role);
return null;
}

overwritesFor(member, verified = false, roles = null) {
Expand Down
16 changes: 10 additions & 6 deletions src/util/Permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,13 @@ class Permissions {
*/
add(...permissions) {
let total = 0;
for (let p = 0; p < permissions.length; p++) {
for (let p = permissions.length - 1; p >= 0; p--) {
const perm = this.constructor.resolve(permissions[p]);
if ((this.bitfield & perm) !== perm) total |= perm;
total |= perm;
}
return new this.constructor(this.member, this.bitfield | total);
if (Object.isFrozen(this)) return new this.constructor(this.bitfield | total);
this.bitfield |= total;
return this;
}

/**
Expand All @@ -96,11 +98,13 @@ class Permissions {
*/
remove(...permissions) {
let total = 0;
for (let p = 0; p < permissions.length; p++) {
for (let p = permissions.length - 1; p >= 0; p--) {
const perm = this.constructor.resolve(permissions[p]);
if ((this.bitfield & perm) === perm) total |= perm;
total |= perm;
}
return new this.constructor(this.member, this.bitfield & ~total);
if (Object.isFrozen(this)) return new this.constructor(this.bitfield & ~total);
this.bitfield &= ~total;
return this;
}

/**
Expand Down

0 comments on commit 1e5b5b8

Please # to comment.