Skip to content

Commit

Permalink
Fix discordjs#1253: Permission Overwrites Resolution (discordjs#1255)
Browse files Browse the repository at this point in the history
* Fix discordjs#1253

* apparently @ everyone role can be undefined

* Fix oops

* Fixes possible mutiple roles named '@​everyone'

* Clean up order/logic
  • Loading branch information
bdistin authored and iCrawl committed Mar 15, 2017
1 parent 79c243f commit e99f88e
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 29 deletions.
8 changes: 4 additions & 4 deletions src/client/rest/APIRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ const request = require('superagent');
const Constants = require('../../util/Constants');

class APIRequest {
constructor(rest, method, url, auth, data, file) {
constructor(rest, method, url, auth, data, files) {
this.rest = rest;
this.method = method;
this.url = url;
this.auth = auth;
this.data = data;
this.file = file;
this.files = files;
this.route = this.getRoute(this.url);
}

Expand All @@ -34,8 +34,8 @@ class APIRequest {
gen() {
const apiRequest = request[this.method](this.url);
if (this.auth) apiRequest.set('authorization', this.getAuth());
if (this.file && this.file.file) {
apiRequest.attach('file', this.file.file, this.file.name);
if (this.files) {
for (const file of this.files) if (file && file.file) apiRequest.attach(file.name, file.file, file.name);
this.data = this.data || {};
apiRequest.field('payload_json', JSON.stringify(this.data));
} else if (this.data) {
Expand Down
6 changes: 3 additions & 3 deletions src/client/rest/RESTMethods.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class RESTMethods {
});
}

sendMessage(channel, content, { tts, nonce, embed, disableEveryone, split, code, reply } = {}, file = null) {
sendMessage(channel, content, { tts, nonce, embed, disableEveryone, split, code, reply } = {}, files = null) {
return new Promise((resolve, reject) => { // eslint-disable-line complexity
if (typeof content !== 'undefined') content = this.client.resolver.resolveString(content);

Expand Down Expand Up @@ -99,7 +99,7 @@ class RESTMethods {
const messages = [];
(function sendChunk(list, index) {
const options = index === list.length ? { tts, embed } : { tts };
chan.send(list[index], options, index === list.length ? file : null).then(message => {
chan.send(list[index], options, index === list.length ? files : null).then(message => {
messages.push(message);
if (index >= list.length - 1) return resolve(messages);
return sendChunk(list, ++index);
Expand All @@ -108,7 +108,7 @@ class RESTMethods {
} else {
this.rest.makeRequest('post', Constants.Endpoints.channelMessages(chan.id), true, {
content, tts, nonce, embed,
}, file).then(data => resolve(this.client.actions.MessageCreate.handle(data).message), reject);
}, files).then(data => resolve(this.client.actions.MessageCreate.handle(data).message), reject);
}
};

Expand Down
25 changes: 20 additions & 5 deletions src/structures/GuildChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,24 @@ class GuildChannel extends Channel {
for (const role of roles.values()) permissions |= role.permissions;

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.role.concat(overwrites.member)) {
for (const overwrite of overwrites.roles) {
permissions &= ~overwrite.deny;
allow |= overwrite.allow;
}
permissions |= allow;

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

const admin = Boolean(permissions & Permissions.FLAGS.ADMINISTRATOR);
if (admin) permissions = Permissions.ALL;

Expand All @@ -82,18 +93,22 @@ class GuildChannel extends Channel {

roles = roles || member.roles;
const roleOverwrites = [];
const memberOverwrites = [];
let memberOverwrites;
let everyoneOverwrites;

for (const overwrite of this.permissionOverwrites.values()) {
if (overwrite.id === member.id) {
memberOverwrites.push(overwrite);
if (overwrite.id === this.guild.id) {
everyoneOverwrites = overwrite;
} else if (roles.has(overwrite.id)) {
roleOverwrites.push(overwrite);
} else if (overwrite.id === member.id) {
memberOverwrites = overwrite;
}
}

return {
role: roleOverwrites,
everyone: everyoneOverwrites,
roles: roleOverwrites,
member: memberOverwrites,
};
}
Expand Down
54 changes: 37 additions & 17 deletions src/structures/interface/TextBasedChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class TextBasedChannel {
* (see [here](https://discordapp.com/developers/docs/resources/channel#embed-object) for more details)
* @property {boolean} [disableEveryone=this.client.options.disableEveryone] Whether or not @everyone and @here
* should be replaced with plain-text
* @property {FileOptions|string} [file] A file to send with the message
* @property {FileOptions|string} [file] A file to send with the message **(deprecated)**
* @property {FileOptions[]|string[]} [files] Files to send with the message
* @property {string|boolean} [code] Language for optional codeblock formatting to apply
* @property {boolean|SplitOptions} [split=false] Whether or not the message should be split into multiple messages if
* it exceeds the character limit. If an object is provided, these are the options for splitting the message.
Expand Down Expand Up @@ -78,26 +79,34 @@ class TextBasedChannel {
options = {};
}

if (options.embed && options.embed.file) options.file = options.embed.file;

// backward compat
if (options.file) {
if (typeof options.file === 'string') options.file = { attachment: options.file };
if (!options.file.name) {
if (typeof options.file.attachment === 'string') {
options.file.name = path.basename(options.file.attachment);
} else if (options.file.attachment && options.file.attachment.path) {
options.file.name = path.basename(options.file.attachment.path);
} else {
options.file.name = 'file.jpg';
if (options.files) options.files.push(options.file);
else options.files = [options.file];
}

if (options.files) {
for (const i in options.files) {
let file = options.files[i];
if (typeof file === 'string') file = { attachment: file };
if (!file.name) {
if (typeof file.attachment === 'string') {
file.name = path.basename(file.attachment);
} else if (file.attachment && file.attachment.path) {
file.name = path.basename(file.attachment.path);
} else {
file.name = 'file.jpg';
}
}
options.files[i] = file;
}

return this.client.resolver.resolveBuffer(options.file.attachment).then(file =>
this.client.rest.methods.sendMessage(this, content, options, {
file,
name: options.file.name,
return Promise.all(options.files.map(file =>
this.client.resolver.resolveBuffer(file.attachment).then(buffer => {
file.file = buffer;
return file;
})
);
)).then(files => this.client.rest.methods.sendMessage(this, content, options, files));
}

return this.client.rest.methods.sendMessage(this, content, options);
Expand Down Expand Up @@ -135,6 +144,17 @@ class TextBasedChannel {
return this.send(content, Object.assign(options, { embed }));
}

/**
* Send files to this channel
* @param {FileOptions[]|string[]} files Files to send with the message
* @param {StringResolvable} [content] Text for the message
* @param {MessageOptions} [options] Options for the message
* @returns {Promise<Message>}
*/
sendFiles(files, content, options) {
return this.send(content, Object.assign(options, { files }));
}

/**
* Send a file to this channel
* @param {BufferResolvable} attachment File to send
Expand All @@ -144,7 +164,7 @@ class TextBasedChannel {
* @returns {Promise<Message>}
*/
sendFile(attachment, name, content, options = {}) {
return this.send(content, Object.assign(options, { file: { attachment, name } }));
return this.sendFiles([{ attachment, name }], content, options);
}

/**
Expand Down

0 comments on commit e99f88e

Please sign in to comment.