mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-28 17:46:16 +01:00
privilege fixes
This commit is contained in:
@@ -183,6 +183,17 @@ module.exports = function(privileges) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
privileges.categories.isAdminOrMod = function(cid, uid, callback) {
|
||||||
|
helpers.some([
|
||||||
|
function (next) {
|
||||||
|
user.isModerator(uid, cid, next);
|
||||||
|
},
|
||||||
|
function (next) {
|
||||||
|
user.isAdministrator(uid, next);
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
|
};
|
||||||
|
|
||||||
privileges.categories.can = function(privilege, cid, uid, callback) {
|
privileges.categories.can = function(privilege, cid, uid, callback) {
|
||||||
if (!cid) {
|
if (!cid) {
|
||||||
return callback(null, false);
|
return callback(null, false);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var async = require('async'),
|
var async = require('async'),
|
||||||
|
winston = require('winston'),
|
||||||
|
|
||||||
db = require('../database'),
|
db = require('../database'),
|
||||||
topics = require('../topics'),
|
topics = require('../topics'),
|
||||||
@@ -170,21 +171,27 @@ module.exports = function(privileges) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
privileges.topics.canEdit = function(tid, uid, callback) {
|
privileges.topics.canEdit = function(tid, uid, callback) {
|
||||||
|
winston.warn('[deprecated] please use privileges.topics.isOwnerOrAdminOrMod');
|
||||||
|
privileges.topics.isOwnerOrAdminOrMod(tid, uid, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
privileges.topics.isOwnerOrAdminOrMod = function(tid, uid, callback) {
|
||||||
helpers.some([
|
helpers.some([
|
||||||
function(next) {
|
function(next) {
|
||||||
topics.isOwner(tid, uid, next);
|
topics.isOwner(tid, uid, next);
|
||||||
},
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
isAdminOrMod(tid, uid, next);
|
privileges.topics.isAdminOrMod(tid, uid, next);
|
||||||
}
|
}
|
||||||
], callback);
|
], callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
privileges.topics.canMove = function(tid, uid, callback) {
|
privileges.topics.canMove = function(tid, uid, callback) {
|
||||||
isAdminOrMod(tid, uid, callback);
|
winston.warn('[deprecated] please use privileges.topics.isAdminOrMod');
|
||||||
|
privileges.topics.isAdminOrMod(tid, uid, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
function isAdminOrMod(tid, uid, callback) {
|
privileges.topics.isAdminOrMod = function(tid, uid, callback) {
|
||||||
helpers.some([
|
helpers.some([
|
||||||
function(next) {
|
function(next) {
|
||||||
topics.getTopicField(tid, 'cid', function(err, cid) {
|
topics.getTopicField(tid, 'cid', function(err, cid) {
|
||||||
@@ -198,5 +205,5 @@ module.exports = function(privileges) {
|
|||||||
user.isAdministrator(uid, next);
|
user.isAdministrator(uid, next);
|
||||||
}
|
}
|
||||||
], callback);
|
], callback);
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -234,42 +234,33 @@ SocketTopics.doTopicAction = function(action, event, socket, data, callback) {
|
|||||||
if (!socket.uid) {
|
if (!socket.uid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!data || !Array.isArray(data.tids) || !data.cid) {
|
|
||||||
|
if (!data || !Array.isArray(data.tids) || !data.cid) {
|
||||||
return callback(new Error('[[error:invalid-tid]]'));
|
return callback(new Error('[[error:invalid-tid]]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof threadTools[action] !== 'function') {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
|
||||||
async.each(data.tids, function(tid, next) {
|
async.each(data.tids, function(tid, next) {
|
||||||
privileges.topics.canEdit(tid, socket.uid, function(err, canEdit) {
|
threadTools[action](tid, socket.uid, function(err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canEdit) {
|
emitToTopicAndCategory(event, data);
|
||||||
return next(new Error('[[error:no-privileges]]'));
|
|
||||||
|
if (action === 'delete' || action === 'restore' || action === 'purge') {
|
||||||
|
events.log({
|
||||||
|
type: 'topic-' + action,
|
||||||
|
uid: socket.uid,
|
||||||
|
ip: socket.ip,
|
||||||
|
tid: tid
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof threadTools[action] !== 'function') {
|
next();
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
threadTools[action](tid, socket.uid, function(err, data) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
emitToTopicAndCategory(event, data);
|
|
||||||
|
|
||||||
if (action === 'delete' || action === 'restore' || action === 'purge') {
|
|
||||||
events.log({
|
|
||||||
type: 'topic-' + action,
|
|
||||||
uid: socket.uid,
|
|
||||||
ip: socket.ip,
|
|
||||||
tid: tid
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}, callback);
|
}, callback);
|
||||||
};
|
};
|
||||||
@@ -325,7 +316,7 @@ SocketTopics.move = function(socket, data, callback) {
|
|||||||
var topicData;
|
var topicData;
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function(next) {
|
function(next) {
|
||||||
privileges.topics.canMove(tid, socket.uid, next);
|
privileges.topics.isAdminOrMod(tid, socket.uid, next);
|
||||||
},
|
},
|
||||||
function(canMove, next) {
|
function(canMove, next) {
|
||||||
if (!canMove) {
|
if (!canMove) {
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ var async = require('async'),
|
|||||||
categories = require('./categories'),
|
categories = require('./categories'),
|
||||||
posts = require('./posts'),
|
posts = require('./posts'),
|
||||||
plugins = require('./plugins'),
|
plugins = require('./plugins'),
|
||||||
batch = require('./batch');
|
batch = require('./batch'),
|
||||||
|
privileges = require('./privileges');
|
||||||
|
|
||||||
|
|
||||||
(function(ThreadTools) {
|
(function(ThreadTools) {
|
||||||
@@ -21,21 +22,29 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
function toggleDelete(tid, uid, isDelete, callback) {
|
function toggleDelete(tid, uid, isDelete, callback) {
|
||||||
topics.getTopicFields(tid, ['tid', 'cid', 'uid', 'deleted', 'title', 'mainPid'], function(err, topicData) {
|
var topicData;
|
||||||
if (err) {
|
async.waterfall([
|
||||||
return callback(err);
|
function (next) {
|
||||||
}
|
privileges.topics.isOwnerOrAdminOrMod(tid, uid, next);
|
||||||
|
},
|
||||||
if (parseInt(topicData.deleted, 10) === 1 && isDelete) {
|
function (isOwnerOrAdminOrMod, next) {
|
||||||
return callback(new Error('[[error:topic-already-deleted]]'));
|
if (!isOwnerOrAdminOrMod) {
|
||||||
} else if(parseInt(topicData.deleted, 10) !== 1 && !isDelete) {
|
return next(new Error('[[error:no-privileges]]'));
|
||||||
return callback(new Error('[[error:topic-already-restored]]'));
|
|
||||||
}
|
|
||||||
|
|
||||||
topics[isDelete ? 'delete' : 'restore'](tid, function(err) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
}
|
||||||
|
topics.getTopicFields(tid, ['tid', 'cid', 'uid', 'deleted', 'title', 'mainPid'], next);
|
||||||
|
},
|
||||||
|
function (_topicData, next) {
|
||||||
|
topicData = _topicData;
|
||||||
|
|
||||||
|
if (parseInt(topicData.deleted, 10) === 1 && isDelete) {
|
||||||
|
return callback(new Error('[[error:topic-already-deleted]]'));
|
||||||
|
} else if(parseInt(topicData.deleted, 10) !== 1 && !isDelete) {
|
||||||
|
return callback(new Error('[[error:topic-already-restored]]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
topics[isDelete ? 'delete' : 'restore'](tid, next);
|
||||||
|
},
|
||||||
|
function (next) {
|
||||||
topicData.deleted = isDelete ? 1 : 0;
|
topicData.deleted = isDelete ? 1 : 0;
|
||||||
|
|
||||||
if (isDelete) {
|
if (isDelete) {
|
||||||
@@ -52,8 +61,8 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
callback(null, data);
|
callback(null, data);
|
||||||
});
|
}
|
||||||
});
|
], callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadTools.purge = function(tid, uid, callback) {
|
ThreadTools.purge = function(tid, uid, callback) {
|
||||||
@@ -66,21 +75,29 @@ var async = require('async'),
|
|||||||
if (!exists) {
|
if (!exists) {
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
|
privileges.topics.isOwnerOrAdminOrMod(tid, uid, next);
|
||||||
|
},
|
||||||
|
function (isOwnerOrAdminOrMod, next) {
|
||||||
|
if (!isOwnerOrAdminOrMod) {
|
||||||
|
return next(new Error('[[error:no-privileges]]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
topics.getTopicFields(tid, ['mainPid', 'cid'], next);
|
||||||
|
},
|
||||||
|
function (_topic, next) {
|
||||||
|
topic = _topic;
|
||||||
|
|
||||||
batch.processSortedSet('tid:' + tid + ':posts', function(pids, next) {
|
batch.processSortedSet('tid:' + tid + ':posts', function(pids, next) {
|
||||||
async.eachLimit(pids, 10, posts.purge, next);
|
async.eachLimit(pids, 10, posts.purge, next);
|
||||||
}, {alwaysStartAt: 0}, next);
|
}, {alwaysStartAt: 0}, next);
|
||||||
},
|
},
|
||||||
function(next) {
|
function (next) {
|
||||||
topics.getTopicFields(tid, ['mainPid', 'cid'], next);
|
|
||||||
},
|
|
||||||
function(_topic, next) {
|
|
||||||
topic = _topic;
|
|
||||||
posts.purge(topic.mainPid, next);
|
posts.purge(topic.mainPid, next);
|
||||||
},
|
},
|
||||||
function(next) {
|
function (next) {
|
||||||
topics.purge(tid, next);
|
topics.purge(tid, next);
|
||||||
},
|
},
|
||||||
function(next) {
|
function (next) {
|
||||||
next(null, {tid: tid, cid: topic.cid, uid: uid});
|
next(null, {tid: tid, cid: topic.cid, uid: uid});
|
||||||
}
|
}
|
||||||
], callback);
|
], callback);
|
||||||
@@ -96,24 +113,40 @@ var async = require('async'),
|
|||||||
|
|
||||||
function toggleLock(tid, uid, lock, callback) {
|
function toggleLock(tid, uid, lock, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
topics.getTopicField(tid, 'cid', function(err, cid) {
|
|
||||||
if (err) {
|
var cid;
|
||||||
return callback(err);
|
|
||||||
|
async.waterfall([
|
||||||
|
function (next) {
|
||||||
|
topics.getTopicField(tid, 'cid', next);
|
||||||
|
},
|
||||||
|
function (_cid, next) {
|
||||||
|
cid = _cid;
|
||||||
|
if (!cid) {
|
||||||
|
return next(new Error('[[error:no-topic]]'));
|
||||||
|
}
|
||||||
|
privileges.categories.isAdminOrMod(cid, uid, next);
|
||||||
|
},
|
||||||
|
function (isAdminOrMod, next) {
|
||||||
|
if (!isAdminOrMod) {
|
||||||
|
return next(new Error('[[error:no-privileges]]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
topics.setTopicField(tid, 'locked', lock ? 1 : 0, next);
|
||||||
|
},
|
||||||
|
function (next) {
|
||||||
|
var data = {
|
||||||
|
tid: tid,
|
||||||
|
isLocked: lock,
|
||||||
|
uid: uid,
|
||||||
|
cid: cid
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins.fireHook('action:topic.lock', data);
|
||||||
|
|
||||||
|
next(null, data);
|
||||||
}
|
}
|
||||||
|
], callback);
|
||||||
topics.setTopicField(tid, 'locked', lock ? 1 : 0);
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
tid: tid,
|
|
||||||
isLocked: lock,
|
|
||||||
uid: uid,
|
|
||||||
cid: cid
|
|
||||||
};
|
|
||||||
|
|
||||||
plugins.fireHook('action:topic.lock', data);
|
|
||||||
|
|
||||||
callback(null, data);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadTools.pin = function(tid, uid, callback) {
|
ThreadTools.pin = function(tid, uid, callback) {
|
||||||
@@ -127,11 +160,23 @@ var async = require('async'),
|
|||||||
function togglePin(tid, uid, pin, callback) {
|
function togglePin(tid, uid, pin, callback) {
|
||||||
var topicData;
|
var topicData;
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function(next) {
|
function (next) {
|
||||||
|
topics.exists(tid, next);
|
||||||
|
},
|
||||||
|
function (exists, next) {
|
||||||
|
if (!exists) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
topics.getTopicFields(tid, ['cid', 'lastposttime'], next);
|
topics.getTopicFields(tid, ['cid', 'lastposttime'], next);
|
||||||
},
|
},
|
||||||
function(_topicData, next) {
|
function (_topicData, next) {
|
||||||
topicData = _topicData;
|
topicData = _topicData;
|
||||||
|
privileges.categories.isAdminOrMod(_topicData.cid, uid, next);
|
||||||
|
},
|
||||||
|
function(isAdminOrMod, next) {
|
||||||
|
if (!isAdminOrMod) {
|
||||||
|
return next(new Error('[[error:no-privileges]]'));
|
||||||
|
}
|
||||||
async.parallel([
|
async.parallel([
|
||||||
async.apply(topics.setTopicField, tid, 'pinned', pin ? 1 : 0),
|
async.apply(topics.setTopicField, tid, 'pinned', pin ? 1 : 0),
|
||||||
async.apply(db.sortedSetAdd, 'cid:' + topicData.cid + ':tids', pin ? Math.pow(2, 53) : topicData.lastposttime, tid)
|
async.apply(db.sortedSetAdd, 'cid:' + topicData.cid + ':tids', pin ? Math.pow(2, 53) : topicData.lastposttime, tid)
|
||||||
|
|||||||
Reference in New Issue
Block a user