From b2a74be0f904748a1a7c4f58e5ac0fb9246b419e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 1 Nov 2015 17:46:24 +0000 Subject: [PATCH] Added permissions --- lib/Structures/ChannelPermissions.js | 75 ++++++++++++++++++++++++++++ lib/Structures/Role.js | 2 +- lib/Structures/Server.js | 13 +++++ lib/Structures/ServerChannel.js | 71 ++++++++++++++++++++++++++ lib/index.js | 8 +-- src/Structures/ChannelPermissions.js | 63 +++++++++++++++++++++++ src/Structures/Role.js | 2 +- src/Structures/Server.js | 13 +++++ src/Structures/ServerChannel.js | 43 ++++++++++++++++ src/index.js | 13 +++-- 10 files changed, 293 insertions(+), 10 deletions(-) create mode 100644 lib/Structures/ChannelPermissions.js create mode 100644 src/Structures/ChannelPermissions.js diff --git a/lib/Structures/ChannelPermissions.js b/lib/Structures/ChannelPermissions.js new file mode 100644 index 000000000..fe7a039fd --- /dev/null +++ b/lib/Structures/ChannelPermissions.js @@ -0,0 +1,75 @@ +"use strict"; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Permissions = require("../Constants.js").Permissions; + +var ChannelPermissions = (function () { + function ChannelPermissions(permissions) { + _classCallCheck(this, ChannelPermissions); + + this.permissions = permissions; + } + + ChannelPermissions.prototype.serialise = function serialise(explicit) { + var _this = this; + + var hp = function hp(perm) { + return _this.hasPermission(perm, explicit); + }; + + return { + // general + createInstantInvite: hp(Permissions.createInstantInvite), + kickMembers: hp(Permissions.kickMembers), + banMembers: hp(Permissions.banMembers), + managePermissions: hp(Permissions.managePermissions), + manageChannel: hp(Permissions.manageChannel), + manageServer: hp(Permissions.manageServer), + // text + readMessages: hp(Permissions.readMessages), + sendMessages: hp(Permissions.sendMessages), + sendTTSMessages: hp(Permissions.sendTTSMessages), + manageMessages: hp(Permissions.manageMessages), + embedLinks: hp(Permissions.embedLinks), + attachFiles: hp(Permissions.attachFiles), + readMessageHistory: hp(Permissions.readMessageHistory), + mentionEveryone: hp(Permissions.mentionEveryone), + // voice + voiceConnect: hp(Permissions.voiceConnect), + voiceSpeak: hp(Permissions.voiceSpeak), + voiceMuteMembers: hp(Permissions.voiceMuteMembers), + voiceDeafenMembers: hp(Permissions.voiceDeafenMembers), + voiceMoveMembers: hp(Permissions.voiceMoveMembers), + voiceUseVAD: hp(Permissions.voiceUseVAD) + }; + }; + + ChannelPermissions.prototype.serialize = function serialize() { + // ;n; + return this.serialise(); + }; + + ChannelPermissions.prototype.hasPermission = function hasPermission(perm) { + var explicit = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; + + if (perm instanceof String || typeof perm === "string") { + perm = Permissions[perm]; + } + if (!perm) { + return false; + } + if (!explicit) { + // implicit permissions allowed + if (!!(this.permissions & Permissions.manageRoles)) { + // manageRoles allowed, they have all permissions + return true; + } + } + return !!(this.permissions & perm); + }; + + return ChannelPermissions; +})(); + +module.exports = ChannelPermissions; \ No newline at end of file diff --git a/lib/Structures/Role.js b/lib/Structures/Role.js index afa63c629..048c183cb 100644 --- a/lib/Structures/Role.js +++ b/lib/Structures/Role.js @@ -25,7 +25,7 @@ var Role = (function () { _classCallCheck(this, Role); this.position = data.position || -1; - this.permissions = data.permissions || DefaultRole; + this.permissions = data.permissions || (data.name === "@everyone" ? DefaultRole : 0); this.name = data.name || "@everyone"; this.managed = data.managed || false; this.id = data.id; diff --git a/lib/Structures/Server.js b/lib/Structures/Server.js index 7d3a24f9a..b9d7f36c3 100644 --- a/lib/Structures/Server.js +++ b/lib/Structures/Server.js @@ -71,6 +71,19 @@ var Server = (function (_Equality) { }); } + Server.prototype.rolesOfUser = function rolesOfUser(user) { + user = this.client.internal.resolver.resolveUser(user); + if (user) { + return this.memberMap[user.id] ? this.memberMap[user.id].roles : []; + } else { + return null; + } + }; + + Server.prototype.rolesOf = function rolesOf(user) { + return this.rolesOfUser(user); + }; + Server.prototype.toString = function toString() { return this.name; }; diff --git a/lib/Structures/ServerChannel.js b/lib/Structures/ServerChannel.js index fe4f9653b..215c31232 100644 --- a/lib/Structures/ServerChannel.js +++ b/lib/Structures/ServerChannel.js @@ -7,6 +7,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var Channel = require("./Channel.js"); var Cache = require("../Util/Cache.js"); var PermissionOverwrite = require("./PermissionOverwrite.js"); +var ChannelPermissions = require("./ChannelPermissions.js"); var ServerChannel = (function (_Channel) { _inherits(ServerChannel, _Channel); @@ -26,6 +27,76 @@ var ServerChannel = (function (_Channel) { }); } + ServerChannel.prototype.permissionsOf = function permissionsOf(user) { + user = this.client.internal.resolver.resolveUser(user); + if (user) { + if (this.server.owner.equals(user)) { + return new ChannelPermissions(4294967295); + } + var everyoneRole = this.server.roles.get("name", "@everyone"); + + var userRoles = [everyoneRole].concat(this.server.rolesOf(user) || []); + var userRolesID = userRoles.map(function (v) { + return v.id; + }); + var roleOverwrites = [], + memberOverwrites = []; + + this.permissionOverwrites.forEach(function (overwrite) { + if (overwrite.type === "member" && overwrite.id === user.id) { + memberOverwrites.push(overwrite); + } else if (overwrite.type === "role" && overwrite.id in userRolesID) { + roleOverwrites.push(overwrite); + } + }); + + var permissions = 0; + + for (var _iterator = userRoles, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref; + + if (_isArray) { + if (_i >= _iterator.length) break; + _ref = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref = _i.value; + } + + var serverRole = _ref; + + permissions |= serverRole.permissions; + } + + for (var _iterator2 = roleOverwrites.concat(memberOverwrites), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref2; + + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref2 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref2 = _i2.value; + } + + var overwrite = _ref2; + + permissions = permissions & ~overwrite.deny; + permissions = permissions | overwrite.allow; + } + + return new ChannelPermissions(permissions); + } else { + return null; + } + }; + + ServerChannel.prototype.permsOf = function permsOf(user) { + return this.permissionsOf(user); + }; + ServerChannel.prototype.toString = function toString() { return this.name; }; diff --git a/lib/index.js b/lib/index.js index 206b55820..8c2c2df59 100644 --- a/lib/index.js +++ b/lib/index.js @@ -13,10 +13,10 @@ a.on("warn", function (m) { }); a.on("message", function (m) { - if (m.content === "$$$") a.internal.createServer("H a h").then(function (srv) { - console.log(srv); - a.reply(m, srv); - }); + if (m.content === "$$$") a.reply(m, "you have the roles:\n" + m.channel.server.rolesOfUser(m.author).map(function (v) { + return "**" + v.name + "** " + v.id + "\n"; + })); + if (m.content === "$$") a.reply(m, JSON.stringify(m.channel.permissionsOf(m.author).serialise(), null, 4).replace(/true/g, "**true**")); }); a.on("serverMemberRemoved", function (r, s) { console.log(r, s); diff --git a/src/Structures/ChannelPermissions.js b/src/Structures/ChannelPermissions.js new file mode 100644 index 000000000..9ae1894a1 --- /dev/null +++ b/src/Structures/ChannelPermissions.js @@ -0,0 +1,63 @@ +"use strict"; + +var Permissions = require("../Constants.js").Permissions; + +class ChannelPermissions{ + constructor(permissions){ + this.permissions = permissions; + } + + serialise(explicit){ + + var hp = (perm) => this.hasPermission(perm, explicit); + + return { + // general + createInstantInvite : hp( Permissions.createInstantInvite ), + kickMembers : hp( Permissions.kickMembers ), + banMembers : hp( Permissions.banMembers ), + managePermissions : hp ( Permissions.managePermissions ), + manageChannel : hp( Permissions.manageChannel ), + manageServer : hp( Permissions.manageServer ), + // text + readMessages : hp( Permissions.readMessages ), + sendMessages : hp( Permissions.sendMessages ), + sendTTSMessages : hp( Permissions.sendTTSMessages ), + manageMessages : hp( Permissions.manageMessages ), + embedLinks : hp( Permissions.embedLinks ), + attachFiles : hp( Permissions.attachFiles ), + readMessageHistory : hp( Permissions.readMessageHistory ), + mentionEveryone : hp( Permissions.mentionEveryone ), + // voice + voiceConnect : hp( Permissions.voiceConnect ), + voiceSpeak : hp( Permissions.voiceSpeak ), + voiceMuteMembers : hp( Permissions.voiceMuteMembers ), + voiceDeafenMembers : hp( Permissions.voiceDeafenMembers ), + voiceMoveMembers : hp( Permissions.voiceMoveMembers ), + voiceUseVAD : hp( Permissions.voiceUseVAD ) + }; + } + + serialize(){ + // ;n; + return this.serialise(); + } + + hasPermission(perm, explicit=false){ + if( perm instanceof String || typeof perm === "string" ){ + perm = Permissions[perm]; + } + if(!perm){ + return false; + } + if(!explicit){ // implicit permissions allowed + if( !!(this.permissions & Permissions.manageRoles) ){ + // manageRoles allowed, they have all permissions + return true; + } + } + return !!(this.permissions & perm); + } +} + +module.exports = ChannelPermissions; \ No newline at end of file diff --git a/src/Structures/Role.js b/src/Structures/Role.js index 9493bacdf..c2c7b3f6d 100644 --- a/src/Structures/Role.js +++ b/src/Structures/Role.js @@ -31,7 +31,7 @@ const DefaultRole = [ class Role{ constructor(data, server, client){ this.position = data.position || -1; - this.permissions = data.permissions || DefaultRole; + this.permissions = data.permissions || (data.name === "@everyone" ? DefaultRole : 0 ); this.name = data.name || "@everyone"; this.managed = data.managed || false; this.id = data.id; diff --git a/src/Structures/Server.js b/src/Structures/Server.js index e8036cb14..a1084fb8b 100644 --- a/src/Structures/Server.js +++ b/src/Structures/Server.js @@ -59,6 +59,19 @@ class Server extends Equality { } } ); } + + rolesOfUser(user){ + user = this.client.internal.resolver.resolveUser(user); + if(user){ + return (this.memberMap[user.id] ? this.memberMap[user.id].roles : []); + }else{ + return null; + } + } + + rolesOf(user){ + return this.rolesOfUser(user); + } get iconURL() { if (!this.icon) { diff --git a/src/Structures/ServerChannel.js b/src/Structures/ServerChannel.js index aee047600..83aa1f3e0 100644 --- a/src/Structures/ServerChannel.js +++ b/src/Structures/ServerChannel.js @@ -3,6 +3,7 @@ var Channel = require("./Channel.js"); var Cache = require("../Util/Cache.js"); var PermissionOverwrite = require("./PermissionOverwrite.js"); +var ChannelPermissions = require("./ChannelPermissions.js"); class ServerChannel extends Channel{ constructor(data, client, server){ @@ -16,6 +17,48 @@ class ServerChannel extends Channel{ }); } + permissionsOf(user){ + user = this.client.internal.resolver.resolveUser(user); + if(user){ + if(this.server.owner.equals(user)){ + return new ChannelPermissions(4294967295); + } + var everyoneRole = this.server.roles.get("name", "@everyone"); + + var userRoles = [everyoneRole].concat(this.server.rolesOf(user) || []); + var userRolesID = userRoles.map((v) => v.id); + var roleOverwrites = [], memberOverwrites = []; + + this.permissionOverwrites.forEach((overwrite) => { + if(overwrite.type === "member" && overwrite.id === user.id){ + memberOverwrites.push(overwrite); + }else if(overwrite.type === "role" && overwrite.id in userRolesID){ + roleOverwrites.push(overwrite); + } + }); + + var permissions = 0; + + for(var serverRole of userRoles){ + permissions |= serverRole.permissions; + } + + for(var overwrite of roleOverwrites.concat(memberOverwrites)){ + permissions = permissions & ~overwrite.deny; + permissions = permissions | overwrite.allow; + } + + return new ChannelPermissions(permissions); + + }else{ + return null; + } + } + + permsOf(user){ + return this.permissionsOf(user); + } + toString(){ return this.name; } diff --git a/src/index.js b/src/index.js index 2fed235f8..033f20990 100644 --- a/src/index.js +++ b/src/index.js @@ -8,10 +8,15 @@ a.on("warn", (m) => console.log("[warn]", m)); a.on("message", m => { if(m.content === "$$$") - a.internal.createServer("H a h").then(srv => { - console.log(srv); - a.reply(m, srv); - }); + a.reply(m, + "you have the roles:\n" + m.channel.server.rolesOfUser(m.author) + .map(v => "**"+v.name+"** "+v.id+"\n") + ); + if(m.content === "$$") + a.reply(m, JSON.stringify( + m.channel.permissionsOf(m.author).serialise() + , null, 4 + ).replace(/true/g, "**true**")) }); a.on("serverMemberRemoved", (r, s) => { console.log(r, s);