remove comments meant for logging, implement moderator removal, cleanup

This commit is contained in:
Ryan Tharp 2019-11-08 23:32:18 +00:00
parent 67be61dc7d
commit 091e4798e4
11 changed files with 101 additions and 140 deletions

View File

@ -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);
}

View File

@ -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);
});
}

View File

@ -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);

View File

@ -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: {

View File

@ -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);

View File

@ -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
}
};

View File

@ -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;

View File

@ -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')
},
}

View File

@ -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

View File

@ -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

View File

@ -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;