From 2476ab368418190221a8e806eb35da7ff047609f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 15 Nov 2016 12:45:00 +0300 Subject: [PATCH] closes #5202 --- src/controllers/accounts/edit.js | 6 ++---- src/controllers/accounts/helpers.js | 17 +++++++++++------ src/middleware/user.js | 8 +++----- src/privileges/users.js | 25 +++++++++++++++++++++++++ src/socket.io/user.js | 8 +++----- src/socket.io/user/profile.js | 18 +++++++++++++----- 6 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/controllers/accounts/edit.js b/src/controllers/accounts/edit.js index 3fe2c57092..1c61756da8 100644 --- a/src/controllers/accounts/edit.js +++ b/src/controllers/accounts/edit.js @@ -12,6 +12,7 @@ var plugins = require('../../plugins'); var helpers = require('../helpers'); var groups = require('../../groups'); var accountHelpers = require('./helpers'); +var privileges = require('../../privileges'); var editController = {}; @@ -118,11 +119,8 @@ editController.uploadPicture = function (req, res, next) { }, function (uid, next) { updateUid = uid; - if (parseInt(req.uid, 10) === parseInt(uid, 10)) { - return next(null, true); - } - user.isAdminOrGlobalMod(req.uid, next); + privileges.users.canEdit(req.uid, uid, next); }, function (isAllowed, next) { if (!isAllowed) { diff --git a/src/controllers/accounts/helpers.js b/src/controllers/accounts/helpers.js index 1e120cc0d0..7a90930053 100644 --- a/src/controllers/accounts/helpers.js +++ b/src/controllers/accounts/helpers.js @@ -24,13 +24,16 @@ helpers.getUserDataByUserSlug = function (userslug, callerUID, callback) { } async.parallel({ - userData : function (next) { + userData: function (next) { user.getUserData(uid, next); }, - userSettings : function (next) { + isTargetAdmin: function (next) { + user.isAdministrator(uid, next); + }, + userSettings: function (next) { user.getSettings(uid, next); }, - isAdmin : function (next) { + isAdmin: function (next) { user.isAdministrator(callerUID, next); }, isGlobalModerator: function (next) { @@ -87,7 +90,7 @@ helpers.getUserDataByUserSlug = function (userslug, callerUID, callback) { userData.fullname = ''; } - if (isAdmin || isGlobalModerator || isSelf) { + if (isAdmin || isSelf || (isGlobalModerator && !results.isTargetAdmin)) { userData.ips = results.ips; } @@ -98,16 +101,18 @@ helpers.getUserDataByUserSlug = function (userslug, callerUID, callback) { userData.uid = userData.uid; userData.yourid = callerUID; userData.theirid = userData.uid; + userData.isTargetAdmin = results.isTargetAdmin; userData.isAdmin = isAdmin; userData.isGlobalModerator = isGlobalModerator; userData.isModerator = isModerator; userData.isAdminOrGlobalModerator = isAdmin || isGlobalModerator; userData.isAdminOrGlobalModeratorOrModerator = isAdmin || isGlobalModerator || isModerator; - userData.canBan = isAdmin || isGlobalModerator; + userData.canEdit = isAdmin || (isGlobalModerator && !results.isTargetAdmin); + userData.canBan = isAdmin || (isGlobalModerator && !results.isTargetAdmin); userData.canChangePassword = isAdmin || (isSelf && parseInt(meta.config['password:disableEdit'], 10) !== 1); userData.isSelf = isSelf; userData.isFollowing = results.isFollowing; - userData.showHidden = isSelf || isAdmin || isGlobalModerator; + userData.showHidden = isSelf || isAdmin || (isGlobalModerator && !results.isTargetAdmin); userData.groups = Array.isArray(results.groups) && results.groups.length ? results.groups[0] : []; userData.disableSignatures = meta.config.disableSignatures !== undefined && parseInt(meta.config.disableSignatures, 10) === 1; userData['reputation:disabled'] = parseInt(meta.config['reputation:disabled'], 10) === 1; diff --git a/src/middleware/user.js b/src/middleware/user.js index c4c39a1e81..4b4af39c5f 100644 --- a/src/middleware/user.js +++ b/src/middleware/user.js @@ -2,8 +2,10 @@ var async = require('async'); var nconf = require('nconf'); + var meta = require('../meta'); var user = require('../user'); +var privileges = require('../privileges'); var controllers = { helpers: require('../controllers/helpers') @@ -29,11 +31,7 @@ module.exports = function (middleware) { user.getUidByUserslug(req.params.userslug, next); }, function (uid, next) { - if (parseInt(uid, 10) === req.uid) { - return next(null, true); - } - - user.isAdminOrGlobalMod(req.uid, next); + privileges.users.canEdit(req.uid, uid, next); }, function (allowed, next) { if (allowed) { diff --git a/src/privileges/users.js b/src/privileges/users.js index 4f6341be9f..82553647a4 100644 --- a/src/privileges/users.js +++ b/src/privileges/users.js @@ -136,4 +136,29 @@ module.exports = function (privileges) { }); } + privileges.users.canEdit = function (callerUid, uid, callback) { + if (parseInt(callerUid, 10) === parseInt(uid, 10)) { + return process.nextTick(callback, null, true); + } + + async.parallel({ + isAdmin: function (next) { + privileges.users.isAdministrator(callerUid, next); + }, + isGlobalMod: function (next) { + privileges.users.isGlobalModerator(callerUid, next); + }, + isTargetAdmin: function (next) { + privileges.users.isAdministrator(uid, next); + } + }, function (err, results) { + if (err) { + return callback(err); + } + var canEdit = results.isAdmin || (results.isGlobalMod && !results.isTargetAdmin); + + callback(null, canEdit); + }); + }; + }; \ No newline at end of file diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 4d5f752b5d..1c322fe1e4 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -13,6 +13,7 @@ var events = require('../events'); var emailer = require('../emailer'); var db = require('../database'); var apiController = require('../controllers/api'); +var privileges = require('../privileges'); var SocketUser = {}; @@ -211,10 +212,7 @@ SocketUser.saveSettings = function (socket, data, callback) { async.waterfall([ function (next) { - if (socket.uid === parseInt(data.uid, 10)) { - return next(null, true); - } - user.isAdminOrGlobalMod(socket.uid, next); + privileges.users.canEdit(socket.uid, data.uid, next); }, function (allowed, next) { if (!allowed) { @@ -326,7 +324,7 @@ SocketUser.setModerationNote = function (socket, data, callback) { async.waterfall([ function (next) { - user.isAdminOrGlobalMod(socket.uid, next); + privileges.users.canEdit(socket.uid, data.uid, next); }, function (allowed, next) { if (allowed) { diff --git a/src/socket.io/user/profile.js b/src/socket.io/user/profile.js index 8e2cbda7bd..89d49f59c3 100644 --- a/src/socket.io/user/profile.js +++ b/src/socket.io/user/profile.js @@ -5,6 +5,7 @@ var async = require('async'); var user = require('../../user'); var meta = require('../../meta'); var events = require('../../events'); +var privileges = require('../../privileges'); module.exports = function (SocketUser) { @@ -127,18 +128,25 @@ module.exports = function (SocketUser) { return next(new Error('[[error:invalid-data]]')); } - user.isAdminOrGlobalMod(socket.uid, next); + async.parallel({ + isAdminOrGlobalMod: function (next) { + user.isAdminOrGlobalMod(socket.uid, next); + }, + canEdit: function (next) { + privileges.users.canEdit(socket.uid, data.uid, next); + } + }, next); }, - function (isAdminOrGlobalMod, next) { - if (!isAdminOrGlobalMod && socket.uid !== parseInt(data.uid, 10)) { + function (results, next) { + if (!results.canEdit) { return next(new Error('[[error:no-privileges]]')); } - if (!isAdminOrGlobalMod && parseInt(meta.config['username:disableEdit'], 10) === 1) { + if (!results.isAdminOrGlobalMod && parseInt(meta.config['username:disableEdit'], 10) === 1) { data.username = oldUserData.username; } - if (!isAdminOrGlobalMod && parseInt(meta.config['email:disableEdit'], 10) === 1) { + if (!results.isAdminOrGlobalMod && parseInt(meta.config['email:disableEdit'], 10) === 1) { data.email = oldUserData.email; }