From f0e8633dccacb30b661ea73420a1004dc9e1961c Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 27 Nov 2013 12:47:00 -0500 Subject: [PATCH] category whitelisting for posting messages, isAdmin now error-first --- src/admin/user.js | 10 +++++----- src/categoryTools.js | 16 ++++++++++++++-- src/groups.js | 27 +++++++++++++++++++++++++-- src/routes/admin.js | 2 +- src/routes/api.js | 34 ++++++++++++---------------------- src/user.js | 2 +- src/webserver.js | 2 +- 7 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/admin/user.js b/src/admin/user.js index befd9566a5..580c032a12 100644 --- a/src/admin/user.js +++ b/src/admin/user.js @@ -6,7 +6,7 @@ var RDB = require('../redis'), (function(UserAdmin) { UserAdmin.makeAdmin = function(uid, theirid, socket) { - user.isAdministrator(uid, function(isAdmin) { + user.isAdministrator(uid, function(err, isAdmin) { if (isAdmin) { Groups.getGidFromName('Administrators', function(err, gid) { Groups.join(gid, theirid, function(err) { @@ -32,7 +32,7 @@ var RDB = require('../redis'), }; UserAdmin.removeAdmin = function(uid, theirid, socket) { - user.isAdministrator(uid, function(isAdmin) { + user.isAdministrator(uid, function(err, isAdmin) { if (isAdmin) { Groups.getGidFromName('Administrators', function(err, gid) { Groups.leave(gid, theirid, function(err) { @@ -52,8 +52,8 @@ var RDB = require('../redis'), }; UserAdmin.banUser = function(uid, theirid, socket, callback) { - user.isAdministrator(uid, function(amIAdmin) { - user.isAdministrator(theirid, function(areTheyAdmin) { + user.isAdministrator(uid, function(err, amIAdmin) { + user.isAdministrator(theirid, function(err, areTheyAdmin) { if (amIAdmin && !areTheyAdmin) { user.ban(theirid, function(err, result) { callback(true); @@ -70,7 +70,7 @@ var RDB = require('../redis'), }; UserAdmin.unbanUser = function(uid, theirid, socket) { - user.isAdministrator(uid, function(amIAdmin) { + user.isAdministrator(uid, function(err, amIAdmin) { if (amIAdmin) { user.unban(theirid, function(err, result) { socket.emit('event:alert', { diff --git a/src/categoryTools.js b/src/categoryTools.js index b4cb9770c9..7ef88d3854 100644 --- a/src/categoryTools.js +++ b/src/categoryTools.js @@ -8,10 +8,22 @@ var Groups = require('./groups'), CategoryTools.privileges = function(cid, uid, callback) { async.parallel({ "+r": function(next) { - Groups.isMemberByGroupName(uid, 'cid:' + cid + ':privileges:+r', next); + Groups.exists('cid:' + cid + ':privileges:+r', function(err, exists) { + if (exists) { + Groups.isMemberByGroupName(uid, 'cid:' + cid + ':privileges:+r', next); + } else { + next(null, true); + } + }); }, "+w": function(next) { - Groups.isMemberByGroupName(uid, 'cid:' + cid + ':privileges:+w', next); + Groups.exists('cid:' + cid + ':privileges:+w', function(err, exists) { + if (exists) { + Groups.isMemberByGroupName(uid, 'cid:' + cid + ':privileges:+w', next); + } else { + next(null, true); + } + }); }, moderator: function(next) { User.isModerator(uid, cid, next); diff --git a/src/groups.js b/src/groups.js index 372d659b97..d47e93624d 100644 --- a/src/groups.js +++ b/src/groups.js @@ -63,12 +63,24 @@ }); }; + Groups.isDeleted = function(gid, callback) { + RDB.hget('gid:' + gid, 'deleted', function(err, deleted) { + callback(err, deleted === '1'); + }); + }; + Groups.getGidFromName = function(name, callback) { RDB.hget('group:gid', name, callback); }; Groups.isMember = function(uid, gid, callback) { - RDB.sismember('gid:' + gid + ':members', uid, callback); + Groups.isDeleted(gid, function(err, deleted) { + if (!deleted) { + RDB.sismember('gid:' + gid + ':members', uid, callback); + } else { + callback(err, false); + } + }); }; Groups.isMemberByGroupName = function(uid, groupName, callback) { @@ -84,7 +96,18 @@ }; Groups.exists = function(name, callback) { - RDB.hexists('group:gid', name, callback); + async.parallel({ + exists: function(next) { + RDB.hexists('group:gid', name, next); + }, + deleted: function(next) { + Groups.getGidFromName(name, function(err, gid) { + Groups.isDeleted(gid, next); + }); + } + }, function(err, results) { + callback(err, !results ? null : (results.exists && !results.deleted)); + }); }; Groups.create = function(name, description, callback) { diff --git a/src/routes/admin.js b/src/routes/admin.js index 8f92976dd7..ec3d8b8c80 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -13,7 +13,7 @@ var user = require('./../user.js'), (function (Admin) { Admin.isAdmin = function (req, res, next) { - user.isAdministrator((req.user && req.user.uid) ? req.user.uid : 0, function (isAdmin) { + user.isAdministrator((req.user && req.user.uid) ? req.user.uid : 0, function (err, isAdmin) { if (!isAdmin) res.redirect('/403'); else next(); }); diff --git a/src/routes/api.js b/src/routes/api.js index ba97e3a391..8c8cf5ecdd 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -1,12 +1,14 @@ -var user = require('./../user.js'), - auth = require('./authentication.js'), - topics = require('./../topics.js'), - posts = require('./../posts.js'), - categories = require('./../categories.js'), +var user = require('../user'), + auth = require('./authentication'), + topics = require('../topics'), + posts = require('../posts'), + categories = require('../categories'), + CategoryTools = require('../categoryTools') Groups = require('../groups'), - utils = require('./../../public/src/utils.js'), + utils = require('../../public/src/utils'), pkg = require('../../package.json'), - meta = require('./../meta.js'), + meta = require('../meta'), + path = require('path'), nconf = require('nconf'), async = require('async'); @@ -129,27 +131,15 @@ var user = require('./../user.js'), app.get('/category/:id/:slug?', function (req, res, next) { var uid = (req.user) ? req.user.uid : 0; - // Category Whitelisting (support for "-r" to come later) - var whitelistReadKey = 'cid:' + req.params.id + ':privileges:+r', - success = function() { + // Category Whitelisting + CategoryTools.privileges(req.params.id, uid, function(err, privileges) { + if (!err && privileges.read) { categories.getCategoryById(req.params.id, uid, function (err, data) { if (!err && data && data.disabled === "0") res.json(data); else next(); }, req.params.id, uid); - }; - Groups.exists(whitelistReadKey, function(err, exists) { - if (!err && exists) { - Groups.isMemberByGroupName(uid, whitelistReadKey, function(err, isMember) { - if (!err && isMember) { - success(); - } else { - res.send(403); - } - }); - } else if (!err && !exists) { - success(); } else { res.send(403); } diff --git a/src/user.js b/src/user.js index ac492bd3cd..fc63329382 100644 --- a/src/user.js +++ b/src/user.js @@ -338,7 +338,7 @@ var bcrypt = require('bcrypt'), function iterator(uid, callback) { User.getUserData(uid, function(err, userData) { - User.isAdministrator(uid, function(isAdmin) { + User.isAdministrator(uid, function(err, isAdmin) { if (userData) { userData.administrator = isAdmin?"1":"0"; data.push(userData); diff --git a/src/webserver.js b/src/webserver.js index 2798de5733..08c0f35634 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -106,7 +106,7 @@ var path = require('path'), uid = options.req.user.uid; } - user.isAdministrator(uid, function(isAdmin) { + user.isAdministrator(uid, function(err, isAdmin) { templateValues.adminDisplay = isAdmin ? 'show' : 'hide'; translator.translate(templates.header.parse(templateValues), function(template) {