mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
Added Permission evaluation for channels and EvaluatedPermissions class.
This commit is contained in:
@@ -6,6 +6,7 @@ const Constants = require('../util/Constants');
|
||||
const RESTManager = require('./rest/RestManager');
|
||||
const ClientDataStore = require('../structures/DataStore/ClientDataStore');
|
||||
const ClientManager = require('./ClientManager');
|
||||
const ClientDataResolver = require('./ClientDataResolver');
|
||||
const WebSocketManager = require('./websocket/WebSocketManager');
|
||||
|
||||
class Client extends EventEmitter{
|
||||
@@ -17,6 +18,7 @@ class Client extends EventEmitter{
|
||||
this.store = new ClientDataStore(this);
|
||||
this.manager = new ClientManager(this);
|
||||
this.ws = new WebSocketManager(this);
|
||||
this.resolver = new ClientDataResolver(this);
|
||||
}
|
||||
|
||||
login(email, password) {
|
||||
|
||||
59
src/client/ClientDataResolver.js
Normal file
59
src/client/ClientDataResolver.js
Normal file
@@ -0,0 +1,59 @@
|
||||
'use strict';
|
||||
|
||||
const Structure = name => require(`../structures/${name}`);
|
||||
|
||||
const User = Structure('User');
|
||||
const Message = Structure('Message');
|
||||
const Guild = Structure('Guild');
|
||||
const ServerChannel = Structure('ServerChannel');
|
||||
const TextChannel = Structure('TextChannel');
|
||||
const VoiceChannel = Structure('VoiceChannel');
|
||||
const GuildMember = Structure('GuildMember');
|
||||
|
||||
function $string(obj) {
|
||||
return (typeof obj === 'string' || obj instanceof String);
|
||||
}
|
||||
|
||||
class ClientDataResolver {
|
||||
|
||||
constructor(client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
ResolveUser(user) {
|
||||
if (user instanceof User) {
|
||||
return user;
|
||||
}else if ($string(user)) {
|
||||
return this.client.store.get('users', user);
|
||||
}else if (user instanceof Message) {
|
||||
return user.author;
|
||||
}else if (user instanceof Guild) {
|
||||
return user.owner;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
ResolveGuild(guild) {
|
||||
if (guild instanceof Guild) {
|
||||
return guild;
|
||||
}
|
||||
}
|
||||
|
||||
ResolveGuildMember(guild, user) {
|
||||
if (user instanceof GuildMember) {
|
||||
return user;
|
||||
}
|
||||
|
||||
guild = this.ResolveGuild(guild);
|
||||
user = this.ResolveUser(user);
|
||||
|
||||
if (!guild || !user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return guild.store.get('members', user.id);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ClientDataResolver;
|
||||
39
src/structures/EvaluatedPermissions.js
Normal file
39
src/structures/EvaluatedPermissions.js
Normal file
@@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
const Constants = require('../Util/Constants');
|
||||
|
||||
class EvaluatedPermissions {
|
||||
constructor(member, permissions) {
|
||||
this.member = member;
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
serialize() {
|
||||
let serializedPermissions = {};
|
||||
for (let permissionName in Constants.PermissionFlags) {
|
||||
serializedPermissions[permissionName] = this.hasPermission(permissionName);
|
||||
}
|
||||
|
||||
return serializedPermissions;
|
||||
}
|
||||
|
||||
hasPermission(permission, explicit) {
|
||||
if (permission instanceof String || typeof permission === 'string') {
|
||||
permission = Constants.PermissionFlags[permission];
|
||||
}
|
||||
|
||||
if (!permission) {
|
||||
throw Constants.Errors.NOT_A_PERMISSION;
|
||||
}
|
||||
|
||||
if (!explicit) {
|
||||
if ((this.permissions & Constants.PermissionFlags.MANAGE_ROLES) > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return ((this.permissions & permission) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = EvaluatedPermissions;
|
||||
@@ -60,12 +60,15 @@ class Guild {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
member(user) {
|
||||
return this.client.resolver.ResolveGuildMember(this, user);
|
||||
}
|
||||
|
||||
setup(data) {
|
||||
this.id = data.id;
|
||||
this.available = !data.unavailable;
|
||||
this.splash = data.splash;
|
||||
this.region = data.region;
|
||||
this.ownerID = data.owner_id;
|
||||
this.name = data.name;
|
||||
this.memberCount = data.member_count;
|
||||
this.large = data.large;
|
||||
@@ -87,6 +90,8 @@ class Guild {
|
||||
}
|
||||
}
|
||||
|
||||
this.owner = this.store.get('members', data.owner_id);
|
||||
|
||||
if (data.channels) {
|
||||
this.store.clear('channels');
|
||||
for (let channel of data.channels) {
|
||||
@@ -125,6 +130,18 @@ class Guild {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get channels() { return this.store.getAsArray('channels'); }
|
||||
|
||||
get $channels() { return this.store.data.channels; }
|
||||
|
||||
get roles() { return this.store.getAsArray('roles'); }
|
||||
|
||||
get $roles() { return this.store.data.roles; }
|
||||
|
||||
get members() { return this.store.getAsArray('members'); }
|
||||
|
||||
get $members() { return this.store.data.members; }
|
||||
}
|
||||
|
||||
module.exports = Guild;
|
||||
|
||||
@@ -25,6 +25,12 @@ class GuildMember {
|
||||
|
||||
get roles() {
|
||||
let list = [];
|
||||
let everyoneRole = this.guild.store.get('roles', this.guild.id);
|
||||
|
||||
if (everyoneRole) {
|
||||
list.push(everyoneRole);
|
||||
}
|
||||
|
||||
for (let roleID of this._roles) {
|
||||
let role = this.guild.store.get('roles', roleID);
|
||||
if (role) {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
const Channel = require('./Channel');
|
||||
const PermissionOverwrites = require('./PermissionOverwrites');
|
||||
const EvaluatedPermissions = require('./EvaluatedPermissions');
|
||||
const Constants = require('../util/Constants');
|
||||
|
||||
class ServerChannel extends Channel{
|
||||
constructor(guild, data) {
|
||||
@@ -15,7 +17,7 @@ class ServerChannel extends Channel{
|
||||
this.position = data.position;
|
||||
this.name = data.name;
|
||||
this.lastMessageID = data.last_message_id;
|
||||
|
||||
this.ow = data.permission_overwrites;
|
||||
if (data.permission_overwrites) {
|
||||
this.permissionOverwrites = [];
|
||||
for (let overwrite of data.permission_overwrites) {
|
||||
@@ -24,6 +26,62 @@ class ServerChannel extends Channel{
|
||||
}
|
||||
}
|
||||
|
||||
permissionsFor(member) {
|
||||
member = this.client.resolver.ResolveGuildMember(this.guild, member);
|
||||
if (member) {
|
||||
if (this.guild.owner.id === member.id) {
|
||||
return new EvaluatedPermissions(member, Constants.ALL_PERMISSIONS);
|
||||
}
|
||||
|
||||
let roles = member.roles;
|
||||
let permissions = 0;
|
||||
let overwrites = this.overwritesFor(member, true);
|
||||
|
||||
for (let role of roles) {
|
||||
permissions |= role.permissions;
|
||||
}
|
||||
|
||||
for (let overwrite of overwrites.role.concat(overwrites.member)) {
|
||||
permissions = permissions & ~overwrite.denyData;
|
||||
permissions = permissions | overwrite.allowData;
|
||||
}
|
||||
|
||||
if (!!(permissions & (Constants.PermissionFlags.MANAGE_ROLES))) {
|
||||
permissions = Constants.ALL_PERMISSIONS;
|
||||
}
|
||||
|
||||
return new EvaluatedPermissions(member, permissions);
|
||||
}
|
||||
}
|
||||
|
||||
overwritesFor(member, verified) {
|
||||
// for speed
|
||||
if (!verified)
|
||||
member = this.client.resolver.ResolveGuildMember(this.guild, member);
|
||||
if (member) {
|
||||
let found = [];
|
||||
let memberRoles = member._roles;
|
||||
|
||||
let roleOverwrites = [];
|
||||
let memberOverwrites = [];
|
||||
|
||||
for (let overwrite of this.permissionOverwrites) {
|
||||
if (overwrite.id === member.id) {
|
||||
memberOverwrites.push(overwrite);
|
||||
} else if (memberRoles.indexOf(overwrite.id) > -1) {
|
||||
roleOverwrites.push(overwrite);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
role: roleOverwrites,
|
||||
member: memberOverwrites,
|
||||
};
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const DefaultOptions = exports.DefaultOptions = {
|
||||
ws: {
|
||||
large_threshold: 250,
|
||||
@@ -157,4 +159,12 @@ const PermissionFlags = exports.PermissionFlags = {
|
||||
USE_VAD: 1 << 25,
|
||||
};
|
||||
|
||||
let _ALL_PERMISSIONS = 0;
|
||||
|
||||
for (let key in PermissionFlags) {
|
||||
_ALL_PERMISSIONS |= PermissionFlags[key];
|
||||
}
|
||||
|
||||
const ALL_PERMISSIONS = exports.ALL_PERMISSIONS = _ALL_PERMISSIONS;
|
||||
|
||||
const DEFAULT_PERMISSIONS = exports.DEFAULT_PERMISSIONS = 36953089;
|
||||
|
||||
@@ -80,3 +80,10 @@ client.on('messageUpdate', (old, message) => {
|
||||
if (message.author.username === 'hydrabolt')
|
||||
console.log('Message updated from', old.content, 'to', message.content);
|
||||
});
|
||||
|
||||
client.on('message', message => {
|
||||
if (message.content === '?perms?') {
|
||||
console.log(message.author.username, 'asked for perms in', message.channel.name, ':');
|
||||
console.log(message.channel.permissionsFor(message.author).serialize());
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user