From 091e4798e4c289476877766c0a07942f714a47ae Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Fri, 8 Nov 2019 23:32:18 +0000 Subject: [PATCH] remove comments meant for logging, implement moderator removal, cleanup --- .../moderation/dialect.loki_moderation.js | 7 +- .../moderation/dialect_moderation_handlers.js | 17 +--- .../moderation/dialect_moderation_helpers.js | 11 +-- dialects/token/dialect_tokens_handlers.js | 10 --- dialects/token/dialect_tokens_helpers.js | 13 --- lib.overlay.js | 6 +- logic.js | 20 ++--- logic/permissions.js | 24 ++---- models/role_permissions.js | 44 +++++++--- overlay_server.js | 6 +- storage.js | 83 ++++++++----------- 11 files changed, 101 insertions(+), 140 deletions(-) diff --git a/dialects/moderation/dialect.loki_moderation.js b/dialects/moderation/dialect.loki_moderation.js index 3e5c48a..a1e6c61 100644 --- a/dialects/moderation/dialect.loki_moderation.js +++ b/dialects/moderation/dialect.loki_moderation.js @@ -2,10 +2,6 @@ const overlay = require('../../lib.overlay'); const handlers = require('./dialect_moderation_handlers'); -// -// helpers -// - module.exports = (app, prefix) => { // set cache based on dispatcher object cache = app.dispatcher.cache; @@ -31,9 +27,12 @@ module.exports = (app, prefix) => { // single mod delete, deprecated app.delete(prefix + '/loki/v1/moderation/messages', handlers.modDeleteMultipleHandler); + // create moderator app.post(prefix + '/loki/v1/moderators/:id', handlers.addGlobalModerator); + // remove moderator app.delete(prefix + '/loki/v1/moderators/:id', handlers.removeGlobalModerator); + // blacklist userid app.post(prefix + '/loki/v1/moderation/blacklist/:id', handlers.blacklistUserFromServerHandler); } diff --git a/dialects/moderation/dialect_moderation_handlers.js b/dialects/moderation/dialect_moderation_handlers.js index ad73b4b..7539078 100644 --- a/dialects/moderation/dialect_moderation_handlers.js +++ b/dialects/moderation/dialect_moderation_handlers.js @@ -36,7 +36,6 @@ const getChannelModeratorsHandler = async (req, res) => { const getDeletesHandler = (req, res) => { const numId = parseInt(req.params.id); - //console.log('numId', numId) cache.getChannelDeletions(numId, req.apiParams, (interactions, err, meta) => { const items = interactions.map(interaction => ({ delete_at: interaction.datetime, @@ -52,9 +51,8 @@ const getDeletesHandler = (req, res) => { }; const deleteMultipleHandler = (req, res) => { - //console.log('dialect_moderation_handler::deleteMultipleHandler - ids', req.query.ids); if (!req.query.ids) { - console.log('moderation message mass delete ids empty'); + console.warn('user message mass delete ids empty'); res.status(422).type('application/json').end(JSON.stringify({ error: 'ids missing', })); @@ -68,16 +66,14 @@ const deleteMultipleHandler = (req, res) => { ids = [ ids ]; } if (ids.length > 200) { - console.log('moderation message mass delete too many ids, 200<', ids.length); + console.warn('user message mass delete too many ids, 200<', ids.length); res.status(422).type('application/json').end(JSON.stringify({ error: 'too many ids', })); return; } dialect.validUser(req.token, res, async usertoken => { - //console.log('dialect_moderation_handler::deleteMultipleHandler - validUser'); const [ code, err, messages ] = await helpers.getMessages(ids); - //console.log('dialect_moderation_handler::deleteMultipleHandler - getMessages', code); if (err) { console.error('dialect_moderation_handler::deleteMultipleHandler - getMessages err', err) const resObj = { @@ -120,13 +116,12 @@ const deleteMultipleHandler = (req, res) => { datas.push(msg); return; } - //console.log('dialect_moderation_handler::deleteMultipleHandler - nuking', msg.id); + // we're allowed to nuke it & carry out deletion const resObj = await helpers.deleteMessage(msg); metas.push(resObj.meta); datas.push(resObj.data); })); - //console.log('dialect_moderation_handler::deleteMultipleHandler - calling back'); resObj = { meta: { code: code, @@ -142,9 +137,7 @@ const deleteMultipleHandler = (req, res) => { const modDeleteSingleHandler = (req, res) => { helpers.validGlobal(req.token, res, async (usertoken, access_list) => { const numId = parseInt(req.params.id); - //console.log('dialect_moderation_handlers::modDeleteSingleHandler - modTryDeleteMessages'); resObj = await helpers.modTryDeleteMessages([numId], access_list); - //console.log('dialect_moderation_handlers::modDeleteSingleHandler - Sending response'); dialect.sendResponse(resObj, res); }); }; @@ -217,7 +210,7 @@ const removeGlobalModerator = (req, res) => { data: [] } helpers.validGlobal(req.token, res, async (usertoken, access_list) => { - // + res.data = await storage.removeServerModerator(usertoken.userid); dialect.sendResponse(resObj, res); }); }; @@ -236,9 +229,7 @@ const blacklistUserFromServerHandler = (req, res) => { data: [] } helpers.validGlobal(req.token, res, async (usertoken, access_list) => { - //console.log('blacklistUserFromServerHandler validGlobal') const result = await logic.blacklistUserFromServer(req.params.id); - //console.log('blacklistUserFromServerHandler result', result) dialect.sendResponse(resObj, res); }); } diff --git a/dialects/moderation/dialect_moderation_helpers.js b/dialects/moderation/dialect_moderation_helpers.js index 4fb0ed7..003d476 100644 --- a/dialects/moderation/dialect_moderation_helpers.js +++ b/dialects/moderation/dialect_moderation_helpers.js @@ -6,10 +6,10 @@ const setup = (utilties) => { ({ config, cache, dispatcher, dialect } = utilties); }; +// not currently used const getUser = (userid) => { return new Promise((res, rej) => { cache.getUser(userid, (user, err) => { - //console.log('getUser', user) if (user) { res(user); } else { @@ -27,16 +27,15 @@ const getUsers = (userids) => { let next200 = userids.splice(0, 200); while(next200.length) { requests++; + // allow them to overlap cache.getUsers(next200, {}, (users, err) => { if (err) { return rej(err); } - // console.log('getUsers', users) results = results.concat(users); responses++; if (requests === responses) { - // console.log('results', results); return res(results); } }); @@ -46,15 +45,12 @@ const getUsers = (userids) => { }; const validGlobal = (token, res, cb) => { - //console.log('dialect_moderation_helpers::validGlobal', token) dialect.validUser(token, res, async (usertoken) => { if (usertoken === undefined) { // should have already been handled by dialect.validUser return; } - //console.log('usertoken', usertoken); const list = await config.getUserAccess(usertoken.userid); - //console.log('list', list); if (!list) { // not even on the list const resObj={ @@ -101,9 +97,7 @@ const deleteMessage = (msg) => { const getMessages = (ids) => { return new Promise(function(resolve, rej) { - //console.log('dialect_moderation_helpers::getMessage starting', ids) cache.getMessage(ids, (messages, getErr) => { - //console.log('dialect_moderation_helpers::getMessage returned') // handle errors if (getErr) { console.error('getMessage err', getErr); @@ -163,7 +157,6 @@ const modTryDeleteMessages = async (ids, access_list) => { return resObj; } } - //console.log('tryDeleteMessage message', message) // carry out deletion const resObj = await deleteMessage(message); diff --git a/dialects/token/dialect_tokens_handlers.js b/dialects/token/dialect_tokens_handlers.js index 40bfdd6..5d7f7a2 100644 --- a/dialects/token/dialect_tokens_handlers.js +++ b/dialects/token/dialect_tokens_handlers.js @@ -11,7 +11,6 @@ const setup = (utilties) => { const getChallengeHandler = async (req, res) => { const { pubKey } = req.query; - //console.log('dialect_tokens_handler::getChallengeHandler', pubKey) if (!pubKey) { console.log('get_challenge pubKey missing'); res.status(422).type('application/json').end(JSON.stringify({ @@ -41,7 +40,6 @@ const getChallengeHandler = async (req, res) => { const submitChallengeHandler = async (req, res) => { const { pubKey, token } = req.body; - //console.log('dialect_tokens_handler::submitChallengeHandler', pubKey) if (!pubKey) { console.log('submit_challenge pubKey missing'); res.status(422).type('application/json').end(JSON.stringify({ @@ -79,21 +77,13 @@ const submitChallengeHandler = async (req, res) => { }; const getTokenInfoHandler = async (req, res) => { - // console.log('dialect_tokens_handler::getTokenInfoHandler') const usertoken = await dialect.validUser(req.token, res); if (usertoken === undefined) { // should have already been handled by dialect.validUser return; } - //console.log('usertoken', JSON.stringify(usertoken)) let resObj = {} try { - //console.log('dialect_tokens_handler::getTokenInfoHandler - getperms', usertoken.userid) - // do we want server permissions? - // or do we want a list of channel permissions? - //const [err, perms] = await logic.getAllPermissionsByUserId(usertoken.userid); - //console.log('dialect_tokens_handler::getTokenInfoHandler - got perms') - //console.log('perms', perms) const modStatus = await config.getUserAccess(usertoken.userid); resObj={ meta: { diff --git a/dialects/token/dialect_tokens_helpers.js b/dialects/token/dialect_tokens_helpers.js index 5a21722..2555de0 100644 --- a/dialects/token/dialect_tokens_helpers.js +++ b/dialects/token/dialect_tokens_helpers.js @@ -61,15 +61,12 @@ const deleteTempStorageForToken = (pubKey, token) => { } const checkTempStorageForToken = (token) => { - //console.log('searching for', token) // check temp storage for(var pubKey in tempDB) { const found = tempDB[pubKey].find(tempObjs => { const tempToken = tempObjs.token; - //console.log('pubKey', pubKey, 'token', tempToken); if (tempToken === token) return true; }) - //console.log('pubKey', pubKey, 'found', found); if (found) { return true; } @@ -107,7 +104,6 @@ const findToken = (token) => { return rej(err); } // report back existence - //console.log('backend has token', usertoken?true:false, token); res(usertoken?true:false); }); }); @@ -126,11 +122,9 @@ const generateString = () => { } const createToken = (pubKey) => { - //console.log('dialect_tokens_helpers::createToken', pubKey) return new Promise((res, rej) => { findOrCreateUser(pubKey) .then(async user => { - //console.log('Creating token for', user.id) // generate new random token and make sure it's not in use let inUse = true; while(inUse) { @@ -146,30 +140,25 @@ const createToken = (pubKey) => { } const findOrCreateUser = (pubKey) => { - //console.log('dialect_tokens_helpers::findOrCreateUser', pubKey) return new Promise((res, rej) => { cache.getUserID(pubKey, (user, err) => { if (err) { rej(err); return; } - //console.log('findOrCreateUser', pubKey, 'new', user === null); if (user === null) { // create user // "password" (2nd) parameter is not saved/used - //console.log('calling addUser') cache.addUser(pubKey, '', (newUser, err2) => { if (err2) { console.error('addUser err', err2); rej(err2); } else { - //console.log('passing back newly created', newUser) res(newUser); } }) } else { // we have this user - //console.log('findOrCreateUser', user) res(user); } }); @@ -242,7 +231,6 @@ const confirmToken = (pubKey, token) => { if (!userObj) { return rej('user'); } - console.log('confirming token for user', userObj.id, 'for', pubKey); // promote token to usable for user cache.addUnconstrainedAPIUserToken(userObj.id, 'messenger', ADN_SCOPES, token, TOKEN_TTL_MINS, (tokenObj, err) => { if (err) { @@ -250,7 +238,6 @@ const confirmToken = (pubKey, token) => { return rej('tokenCreation'); } // if no, err we assume everything is fine... - //console.log('addUnconstrainedAPIUserToken result', tokenObj) // ok token is now registered // remove from temp storage deleteTempStorageForToken(pubKey, token); diff --git a/lib.overlay.js b/lib.overlay.js index cfa3bb4..88f5c96 100644 --- a/lib.overlay.js +++ b/lib.overlay.js @@ -9,8 +9,8 @@ const logic = require('./logic'); const dialect = require('./lib.dialect'); // Look for a config file -const disk_config = config.getDiskConfig() -storage.start(disk_config) +const disk_config = config.getDiskConfig(); +storage.start(disk_config); const setup = (cache, dispatcher) => { config.setup({ cache, storage }); @@ -21,4 +21,4 @@ const setup = (cache, dispatcher) => { module.exports = { setup -} +}; diff --git a/logic.js b/logic.js index c9ad533..871b15e 100644 --- a/logic.js +++ b/logic.js @@ -1,22 +1,22 @@ -const funcs = [] -funcs.push(require('./logic/permissions.js')) +const funcs = []; +funcs.push(require('./logic/permissions.js')); -let storage -let cache +let storage; +let cache; function setup(configObject) { - ({ storage, cache, config } = configObject) + ({ storage, cache, config } = configObject); funcs.forEach((func) => { - func.start(configObject) + func.start(configObject); }); } -let functions = {} +let functions = {}; funcs.forEach((func) => { - functions = Object.assign(functions, func) + functions = Object.assign(functions, func); }); -module.exports = functions +module.exports = functions; // override all those starts -module.exports.setup = setup +module.exports.setup = setup; diff --git a/logic/permissions.js b/logic/permissions.js index 4b84a28..83f1b82 100644 --- a/logic/permissions.js +++ b/logic/permissions.js @@ -1,11 +1,11 @@ // have to generalize these since almost every system needs to check permissions -let storage -let cache +let storage; +let cache; module.exports = { start: (configObject) => { - ({ storage, cache } = configObject) + ({ storage, cache } = configObject); }, // maybe only needed in dialog_token passesWhitelist: async (pubKey) => { @@ -36,6 +36,7 @@ module.exports = { // by default everyone is allowed return true; }, + // FIXME: should return a promise getPermissionsByUser: (pubKey, entity, entityId) => { // get userID const ref = this; @@ -44,7 +45,6 @@ module.exports = { }) }, getEntityPermissionsByUserId: async (userid, entity, entityId) => { - //console.log('logic:::permissions::getPermissionsByUserId(', userid, entity, entityId, ')'); if (userid === undefined) { console.warn('logic:::permissions::getPermissionsByUserId - no userid'); return [ 'no userid' ]; @@ -60,9 +60,9 @@ module.exports = { // get user roles let roles try { - console.log('logic:::permissions::getPermissionsByUserId - ', userid) + console.log('logic:::permissions::getPermissionsByUserId - ', userid); roles = await storage.getRolesByUserId(userid, (err, roles) => { - console.log('roles', roles) + console.log('roles', roles); // get roles permissions by entity // get user permissions by entity // collapse it down... @@ -97,7 +97,7 @@ module.exports = { // get channel roles try { const roles = await storage.getRolesByChannelId(channelid, (err, roles) => { - console.log('channel roles', roles) + console.log('channel roles', roles); // get roles permissions by entity // get user permissions by entity // collapse it down... @@ -105,7 +105,7 @@ module.exports = { } catch(e) { console.error('getPermissionsByChannelId failure', e); } - console.log('roles return', roles) + console.log('roles return', roles); // we need to return a list of users that fit these permissions? }, whoHasThisPerm: (entity, entityId, permission) => { @@ -113,7 +113,6 @@ module.exports = { }, getModeratorsByChannelId: async (channelId, cb) => { const mods = await storage.getModeratorsByChannelId(channelId); - console.log('logic:::permissions::getModeratorsByChannelId - mods', mods); return mods; }, addGlobalModerator: async userid => { @@ -136,7 +135,6 @@ module.exports = { function removeAllTokens(username) { return new Promise( async (resolve, rej) => { cache.getAPITokenByUsername(username, (usertoken, err, meta) => { - //console.log('getAPITokenByUsername'); if (err) console.error('logic:::permissions::blacklistUserFromServer - getAPITokenByUsername err', err); if (usertoken) { cache.delAPIUserToken(usertoken.token, async (delToken, err) => { @@ -162,26 +160,20 @@ module.exports = { } // mark the database as such, so they can't get any new tokens const result = await storage.blacklistUserFromServer(userid); - //console.log('logic::permission:blacklistUserFromServer - result', result) if (!result) { console.warn('logic:::permissions::blacklistUserFromServer - failed to blacklist'); return false; } // get username, so we can query token by username - //console.log('logic::permission:blacklistUserFromServer - lookup', userid) const user = await getUserPromise(userid); const username = user.username; - //console.log('logic:::permissions::blacklistUserFromServer -', userid, 'is', username) if (username !== null ) { - //console.log('checkForToken') // expire all their tokens they have await removeAllTokens(username) - //console.log('all tokens removed for', username); } else { console.error('logic:::permissions::blacklistUserFromServer - null username for', userid) } return true; - //console.log('logic::permission:blacklistUserFromServer - wait') }, } diff --git a/models/role_permissions.js b/models/role_permissions.js index 6190c9a..4ba36c6 100644 --- a/models/role_permissions.js +++ b/models/role_permissions.js @@ -74,9 +74,10 @@ const getRolesByUserId = (user_id, cb) => { module.exports = { start: start, - addRolePermissions: (role) => { + // is this even needed? + addRolePermissions: async (role) => { const perm = new permissionModel(role); - perm.save(); + await perm.save(); }, getRolesByChannelId: (channel_id, cb) => { return permissionModel.find({ @@ -85,8 +86,8 @@ module.exports = { }, getRolesByUserId, getUsers, - getRoles: async (cb) => { - return await permissionModel.find({ + getRoles: (cb) => { + return permissionModel.find({ where: { entity_type: 'role' } }, cb); }, @@ -112,21 +113,46 @@ module.exports = { permission.object = 'server'; permission.object_id = 0; permission.moderator = 1; - permission.moderator.ord = 0; - //console.log('starting mod save'); + permission.ord = 0; await permission.save(); - //console.log('starting mod saved'); return; } }); }, + removeServerModerator: async user_id => { + if (user_id === undefined) { + console.error('role_permissions:removeServerModerator given a user_id that is undefined'); + return; + } + const criteria = { + entity_type: 'user', entityid: user_id, + object: 'server', object_id, + moderator: 1 + }; + permissionModel.find({ where: criteria }, async (err, permissions) => { + if (err) { + console.error('role_permissions:removeServerModerator err', err); + return; + } + if (!permissions || !permissions.length) { + console.warn('role_permissions:removeServerModerator no roles that match', criteria); + return; + } + await Promise.all(permissions.map(perm => { + return new Promise((resolve, rej) => { + perm.destroy(function() { + resolve(); + }); + }); + })); + }); + }, isGlobalModerator: async user_id => { if (user_id === undefined) { console.error('role_permissions:isGlobalModerator given a user_id that is undefined'); return; } const userPerms = await getRolesByUserId(user_id); - //console.log('isBlacklisted userPerms', userPerms); if (!userPerms || !userPerms.length) { // no entries at all // FIXME: look up server default @@ -175,7 +201,6 @@ module.exports = { console.error('role_permissions:blacklistUserFromServer given a user_id that is undefined'); return; } - console.log('blacklistUserFromServer user_id', user_id) const permission = new permissionModel; permission.entity_type = 'user'; permission.entity_id = user_id; @@ -193,7 +218,6 @@ module.exports = { return; } const userPerms = await getRolesByUserId(user_id); - //console.log('isBlacklisted userPerms', userPerms); if (!userPerms || !userPerms.length) { // no entries at all // FIXME: look up server default diff --git a/overlay_server.js b/overlay_server.js index b4fac9f..f6b07f6 100644 --- a/overlay_server.js +++ b/overlay_server.js @@ -8,9 +8,8 @@ const config = require('./config'); const app = express(); // Look for a config file -const disk_config = config.getDiskConfig() +const disk_config = config.getDiskConfig(); -//console.log('disk_config', disk_config) const overlay_port = parseInt(disk_config.api.port) || 8080; const config_path = path.join('./server/config.json'); @@ -91,17 +90,14 @@ app.all('/*', (req, res, next) => { const pageParams = {}; pageParams.since_id = false; if (req.query.since_id) { - //console.log("Overriding since_id to "+req.query.since_id); pageParams.since_id = parseInt(req.query.since_id); } pageParams.before_id=false; if (req.query.before_id) { - //console.log("Overriding before_id to "+req.query.before_id); pageParams.before_id = parseInt(req.query.before_id); } pageParams.count=20; if (req.query.count) { - //console.log("Overriding count to "+req.query.count); pageParams.count = Math.min(Math.max(req.query.count, -200), 200); } // stream marker supported endpoints only diff --git a/storage.js b/storage.js index 5bc47f3..c13b9dc 100644 --- a/storage.js +++ b/storage.js @@ -1,100 +1,89 @@ -const funcs = [] -funcs.push(require('./models/users.js')) -funcs.push(require('./models/challenges.js')) -funcs.push(require('./models/roles.js')) -funcs.push(require('./models/user_roles.js')) -funcs.push(require('./models/role_permissions.js')) +const funcs = []; +funcs.push(require('./models/users.js')); +funcs.push(require('./models/challenges.js')); +funcs.push(require('./models/roles.js')); +funcs.push(require('./models/user_roles.js')); +funcs.push(require('./models/role_permissions.js')); const Schema = require('caminte').Schema memoryUpdate = function (model, filter, data, callback) { 'use strict'; if ('function' === typeof filter) { - return filter(new Error('Get parametrs undefined'), null) + return filter(new Error('Get parametrs undefined'), null); } if ('function' === typeof data) { - return data(new Error('Set parametrs undefined'), null) + return data(new Error('Set parametrs undefined'), null); } - filter = filter.where ? filter.where : filter - var mem = this - //console.log('memoryUpdate - model', model, 'fitler', filter, 'data', data, 'callback', callback) + filter = filter.where ? filter.where : filter; + var mem = this; // filter input to make sure it only contains valid fields - var cleanData = this.toDatabase(model, data) + var cleanData = this.toDatabase(model, data); if (data.id) { // should find one and only one this.exists(model, data.id, function (err, exists) { if (exists) { - mem.save(model, Object.assign(exists, cleanData), callback) + mem.save(model, Object.assign(exists, cleanData), callback); } else { - callback(err, cleanData) + callback(err, cleanData); } }) } else { - //console.log('memoryUpdate - not implemented, search by?', filter, data) this.all(model, filter, function(err, nodes) { - //console.log('memoryUpdate - records', nodes) - var count = nodes.length + var count = nodes.length; if (!count) { - return callback(false, cleanData) + return callback(false, cleanData); } nodes.forEach(function(node) { - mem.cache[model][node.id] = Object.assign(node, cleanData) + mem.cache[model][node.id] = Object.assign(node, cleanData); if (--count === 0) { - callback(false, cleanData) + callback(false, cleanData); } - }) - }) + }); + }); } } function start(config) { - /** schema data backend type */ - const schemaType = 'memory' - const options = {} - const schema = new Schema(schemaType, options) + // schema backend type + const schemaType = 'memory'; + const options = {}; + const schema = new Schema(schemaType, options); if (schemaType === 'memory') { - schema.adapter.update = memoryUpdate + schema.adapter.update = memoryUpdate; } if (schemaType==='mysql') { - //console.log('MySQL is active') //charset: "utf8_general_ci" / utf8mb4_general_ci // run a query "set names utf8" - schemaData.client.changeUser({ charset: 'utf8mb4' }, function(err) { - if (err) console.error('Couldnt set UTF8mb4', err) - //console.log('Set charset to utf8mb4 on Data') - }) - schemaToken.client.changeUser({ charset: 'utf8mb4' }, function(err) { - if (err) console.error('Couldnt set UTF8mb4', err) - //console.log('Set charset to utf8mb4 on Token') - }) + schema.client.changeUser({ charset: 'utf8mb4' }, function(err) { + if (err) console.error('Couldnt set UTF8mb4', err); + }); // to enable emojis we may need to run these - // alter table post MODIFY `text` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; + // alter table X MODIFY `Y` type CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; } var modelOptions = { schema: schema, - } + }; funcs.forEach((func) => { - func.start(modelOptions) + func.start(modelOptions); }); if (schemaType=='mysql' || schemaType=='sqlite3') { - //schemaData.automigrate(function() {}) - //schemaToken.automigrate(function() {}) + //schema.automigrate(function() {}); // don't lose data - schemaData.autoupdate(function() {}) - schemaToken.autoupdate(function() {}) + schema.autoupdate(function() {}); } } -let functions = {} +let functions = {}; funcs.forEach((func) => { - functions = Object.assign(functions, func) + functions = Object.assign(functions, func); }); -module.exports = functions +module.exports = functions; // override all those starts -module.exports.start = start +module.exports.start = start;