more work on #1518

still needs more work, category is next
v1.18.x
barisusakli 11 years ago
parent 822cf56af1
commit 3e86bdb38f

@ -278,7 +278,7 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
pagination.recreatePaginationLinks(newPageCount);
if(pagination.currentPage === pagination.pageCount) {
if (pagination.currentPage === pagination.pageCount) {
createNewPosts(data);
} else if(data.posts && data.posts.length && parseInt(data.posts[0].uid, 10) === parseInt(app.uid, 10)) {
pagination.loadPage(pagination.pageCount);
@ -390,8 +390,11 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
}
function toggleModTools(postHtml, privileges) {
postHtml.find('.edit, .delete').toggleClass('none', !privileges.editable);
postHtml.find('.move').toggleClass('none', !privileges.move);
postHtml.find('.edit, .delete').toggleClass('none', !privileges.meta.editable);
postHtml.find('.move').toggleClass('none', !privileges.meta.move);
postHtml.find('.reply, .quote').toggleClass('none', !$('.post_reply').length)
var isSelfPost = parseInt(postHtml.attr('data-uid'), 10) === parseInt(app.uid, 10);
postHtml.find('.chat, .flag').toggleClass('none', isSelfPost);
}
function loadMorePosts(tid, after, callback) {

@ -21,53 +21,48 @@ define(['forum/topic/fork', 'forum/topic/move'], function(fork, move) {
ThreadTools.setPinnedState({tid: tid, isPinned: true});
}
if (ajaxify.variables.get('expose_tools') === '1') {
$('.delete_thread').on('click', function(e) {
var command = threadState.deleted !== '1' ? 'delete' : 'restore';
$('.thread-tools').removeClass('hide');
$('.delete_thread').on('click', function(e) {
var command = threadState.deleted !== '1' ? 'delete' : 'restore';
translator.translate('[[topic:thread_tools.' + command + '_confirm]]', function(msg) {
bootbox.confirm(msg, function(confirm) {
if (confirm) {
socket.emit('topics.' + command, [tid]);
}
});
translator.translate('[[topic:thread_tools.' + command + '_confirm]]', function(msg) {
bootbox.confirm(msg, function(confirm) {
if (confirm) {
socket.emit('topics.' + command, [tid]);
}
});
return false;
});
$('.lock_thread').on('click', function(e) {
socket.emit(threadState.locked !== '1' ? 'topics.lock' : 'topics.unlock', [tid]);
return false;
});
return false;
});
$('.pin_thread').on('click', function(e) {
socket.emit(threadState.pinned !== '1' ? 'topics.pin' : 'topics.unpin', [tid]);
return false;
});
$('.lock_thread').on('click', function(e) {
socket.emit(threadState.locked !== '1' ? 'topics.lock' : 'topics.unlock', [tid]);
return false;
});
$('.markAsUnreadForAll').on('click', function() {
var btn = $(this);
socket.emit('topics.markAsUnreadForAll', [tid], function(err) {
if(err) {
return app.alertError(err.message);
}
app.alertSuccess('[[topic:markAsUnreadForAll.success]]');
btn.parents('.thread-tools.open').find('.dropdown-toggle').trigger('click');
});
return false;
});
$('.pin_thread').on('click', function(e) {
socket.emit(threadState.pinned !== '1' ? 'topics.pin' : 'topics.unpin', [tid]);
return false;
});
$('.move_thread').on('click', function(e) {
move.init([tid], ajaxify.variables.get('category_id'));
return false;
$('.markAsUnreadForAll').on('click', function() {
var btn = $(this);
socket.emit('topics.markAsUnreadForAll', [tid], function(err) {
if(err) {
return app.alertError(err.message);
}
app.alertSuccess('[[topic:markAsUnreadForAll.success]]');
btn.parents('.thread-tools.open').find('.dropdown-toggle').trigger('click');
});
return false;
});
fork.init();
}
$('.move_thread').on('click', function(e) {
move.init([tid], ajaxify.variables.get('category_id'));
return false;
});
fork.init();
socket.emit('topics.followCheck', tid, function(err, state) {
setFollowState(state);

@ -10,27 +10,27 @@ var topicsController = {},
meta = require('./../meta'),
topics = require('./../topics'),
posts = require('../posts'),
threadTools = require('./../threadTools'),
privileges = require('../privileges'),
utils = require('./../../public/src/utils');
topicsController.get = function(req, res, next) {
var tid = req.params.topic_id,
page = req.query.page || 1,
uid = req.user ? req.user.uid : 0,
privileges;
userPrivileges;
async.waterfall([
function(next) {
threadTools.privileges(tid, uid, function(err, userPrivileges) {
privileges.topics.get(tid, uid, function(err, privileges) {
if (err) {
return next(err);
}
if (!userPrivileges.meta.read) {
if (!privileges.meta.read) {
return next(new Error('[[error:no-privileges]]'));
}
privileges = userPrivileges;
userPrivileges = privileges;
next();
});
},
@ -45,7 +45,7 @@ topicsController.get = function(req, res, next) {
topics.getTopicWithPosts(tid, uid, start, end, function (err, topicData) {
if (topicData) {
if (parseInt(topicData.deleted, 10) === 1 && parseInt(topicData.expose_tools, 10) === 0) {
if (parseInt(topicData.deleted, 10) === 1 && !userPrivileges.view_deleted) {
return next(new Error('[[error:no-topic]]'));
}
topicData.currentPage = page;
@ -154,7 +154,7 @@ topicsController.get = function(req, res, next) {
}
}
data.privileges = privileges;
data.privileges = userPrivileges;
var topic_url = tid + (req.params.slug ? '/' + req.params.slug : '');
var queryString = qs.stringify(req.query);

@ -2,7 +2,8 @@
var privileges = {};
require('./privileges/categories')(privileges);
require('./privileges/topics')(privileges);
require('./privileges/posts')(privileges);
module.exports = privileges;

@ -0,0 +1,28 @@
'use strict';
var async = require('async'),
user = require('../user'),
helpers = require('./helpers');
module.exports = function(privileges) {
privileges.categories = {};
privileges.categories.canRead = function(cid, uid, callback) {
helpers.some([
function(next) {
helpers.allowedTo('read', uid, cid, next);
},
function(next) {
user.isModerator(uid, cid, next);
},
function(next) {
user.isAdministrator(uid, next);
}
], callback);
};
};

@ -10,6 +10,16 @@ var async = require('async'),
var helpers = {};
helpers.some = function(tasks, callback) {
async.some(tasks, function(task, next) {
task(function(err, result) {
next(!err && result);
});
}, function(result) {
callback(null, result);
});
};
helpers.allowedTo = function(privilege, uid, cid, callback) {
categories.getCategoryField(cid, 'disabled', function(err, disabled) {
if (err) {
@ -47,7 +57,7 @@ function isMember(method, group, uid, callback) {
return callback(null, null);
}
method(group, uid, callback);
method(uid, group, callback);
});
}

@ -59,28 +59,12 @@ module.exports = function(privileges) {
return callback(err);
}
async.some([
function(next) {
helpers.allowedTo('read', uid, cid, next);
},
function(next) {
user.isModerator(uid, cid, next);
},
function(next) {
user.isAdministrator(uid, next);
}
], function(task, next) {
task(function(err, result) {
next(!err && result);
});
}, function(result) {
callback(null, result);
});
privileges.categories.canRead(cid, uid, callback);
});
};
privileges.posts.canEdit = function(pid, uid, callback) {
async.some([
helpers.some([
function(next) {
posts.isOwner(pid, uid, next);
},
@ -101,12 +85,22 @@ module.exports = function(privileges) {
function(next) {
user.isAdministrator(uid, next);
}
], function(task, next) {
task(function(err, result) {
next(!err && result);
});
}, function(result) {
callback(null, result);
});
], callback);
};
privileges.posts.canMove = function(pid, uid, callback) {
helpers.some([
function(next) {
posts.getCidByPid(pid, function(err, cid) {
if (err) {
return next(err);
}
user.isModerator(uid, cid, next);
});
},
function(next) {
user.isAdministrator(uid, next);
}
], callback);
};
};

@ -0,0 +1,122 @@
'use strict';
var async = require('async'),
topics = require('../topics'),
user = require('../user'),
helpers = require('./helpers'),
groups = require('../groups'),
categories = require('../categories');
module.exports = function(privileges) {
privileges.topics = {};
privileges.topics.get = function(tid, uid, callback) {
topics.getTopicField(tid, 'cid', function(err, cid) {
if (err) {
return callback(err);
}
async.parallel({
'topics:reply': function(next) {
helpers.allowedTo('topics:reply', uid, cid, next);
},
read: function(next) {
helpers.allowedTo('read', uid, cid, next);
},
manage_topic: function(next) {
helpers.hasEnoughReputationFor('privileges:manage_topic', uid, next);
},
isAdministrator: function(next) {
user.isAdministrator(uid, next);
},
isModerator: function(next) {
user.isModerator(uid, cid, next);
}
}, function(err, results) {
if(err) {
return callback(err);
}
var editable = results.isAdministrator || results.isModerator || results.manage_topic;
callback(null, {
meta: {
'topics:reply': results['topics:reply'],
editable: editable,
view_deleted: editable,
read: results.read
}
});
});
});
};
privileges.topics.canRead = function(tid, uid, callback) {
topics.getTopicField(tid, 'cid', function(err, cid) {
if (err) {
return callback(err);
}
privileges.categories.canRead(cid, uid, callback);
});
};
privileges.topics.canReply = function(tid, uid, callback) {
topics.getTopicField(tid, 'cid', function(err, cid) {
if (err) {
return callback(err);
}
helpers.some([
function(next) {
helpers.allowedTo('topics:reply', uid, cid, next);
},
function(next) {
user.isModerator(uid, cid, next);
},
function(next) {
user.isAdministrator(uid, next);
}
], callback);
});
};
privileges.topics.canEdit = function(tid, uid, callback) {
helpers.some([
function(next) {
helpers.hasEnoughReputationFor('privileges:manage_topic', uid, next);
},
function(next) {
topics.getTopicField(tid, 'cid', function(err, cid) {
if (err) {
return next(err);
}
user.isModerator(uid, cid, next);
});
},
function(next) {
user.isAdministrator(uid, next);
}
], callback);
};
privileges.topics.canMove = function(tid, uid, callback) {
helpers.some([
function(next) {
topics.getTopicField(tid, 'cid', function(err, cid) {
if (err) {
return next(err);
}
user.isModerator(uid, cid, next);
});
},
function(next) {
user.isAdministrator(uid, next);
}
], callback);
};
};

@ -7,30 +7,29 @@ var posts = require('./../posts'),
rss = require('rss'),
nconf = require('nconf'),
ThreadTools = require('./../threadTools'),
CategoryTools = require('./../categoryTools');
privileges = require('../privileges');
function hasTopicPrivileges(req, res, next) {
var tid = req.params.topic_id;
hasPrivileges(ThreadTools, tid, req, res, next);
hasPrivileges(privileges.topics.canRead, tid, req, res, next);
}
function hasCategoryPrivileges(req, res, next) {
var cid = req.params.category_id;
hasPrivileges(CategoryTools, cid, req, res, next);
hasPrivileges(privileges.categories.canRead, cid, req, res, next);
}
function hasPrivileges(module, id, req, res, next) {
function hasPrivileges(method, id, req, res, next) {
var uid = req.user ? req.user.uid || 0 : 0;
module.privileges(id, uid, function(err, privileges) {
if(err) {
method(id, uid, function(err, canRead) {
if (err) {
return next(err);
}
if(!privileges.read) {
if (!canRead) {
return res.redirect('403');
}
@ -66,7 +65,7 @@ function generateForTopic(req, res, next) {
}
topicData.posts.forEach(function(postData) {
if (parseInt(postData.deleted, 10) === 0) {
if (!postData.deleted) {
dateStamp = new Date(parseInt(parseInt(postData.edited, 10) === 0 ? postData.timestamp : postData.edited, 10)).toUTCString();
feed.item({

@ -37,8 +37,15 @@ SocketPosts.reply = function(socket, data, callback) {
}
if (postData) {
var privileges = {
meta : {
'topics:reply': true
}
};
websockets.server.sockets.emit('event:new_post', {
posts: [postData]
posts: [postData],
privileges: privileges
});
module.parent.exports.emitTopicPostStats();

@ -3,6 +3,7 @@
var topics = require('../topics'),
categories = require('../categories'),
privileges = require('../privileges'),
threadTools = require('../threadTools'),
categoryTools = require('../categoryTools'),
websockets = require('./index'),
@ -181,12 +182,12 @@ function doTopicAction(action, socket, tids, callback) {
}
async.each(tids, function(tid, next) {
threadTools.privileges(tid, socket.uid, function(err, privileges) {
privileges.topics.canEdit(tid, socket.uid, function(err, canEdit) {
if(err) {
return next(err);
}
if(!privileges || !privileges.meta.editable) {
if(!canEdit) {
return next(new Error('[[error:no-privileges]]'));
}
@ -210,21 +211,17 @@ SocketTopics.createTopicFromPosts = function(socket, data, callback) {
};
SocketTopics.movePost = function(socket, data, callback) {
if(!socket.uid) {
if (!socket.uid) {
return callback(new Error('[[error:not-logged-in]]'));
}
if(!data || !data.pid || !data.tid) {
if (!data || !data.pid || !data.tid) {
return callback(new Error('[[error:invalid-data]]'));
}
threadTools.privileges(data.tid, socket.uid, function(err, privileges) {
if(err) {
return callback(err);
}
if(!(privileges.admin || privileges.moderator)) {
return callback(new Error('[[error:no-privileges]]'));
privileges.posts.canMove(data.tid, socket.uid, function(err, canMove) {
if (err || !canMove) {
return callback(err || new Error('[[error:no-privileges]]'));
}
topics.movePostToTopic(data.pid, data.tid, callback);
@ -240,10 +237,10 @@ SocketTopics.move = function(socket, data, callback) {
var oldCid;
async.waterfall([
function(next) {
threadTools.privileges(tid, socket.uid, next);
privileges.topics.canMove(tid, socket.uid, next);
},
function(privileges, next) {
if(!(privileges.admin || privileges.moderator)) {
function(canMove, next) {
if (!canMove) {
return next(new Error('[[error:no-privileges]]'));
}
next();
@ -336,7 +333,7 @@ SocketTopics.loadMore = function(socket, data, callback) {
topics.getTopicPosts(data.tid, start, end, socket.uid, false, next);
},
privileges: function(next) {
threadTools.privileges(data.tid, socket.uid, next);
privileges.topics.get(data.tid, socket.uid, next);
}
}, callback);
});

@ -23,38 +23,6 @@ var winston = require('winston'),
db.isSortedSetMember('topics:tid', tid, callback);
};
ThreadTools.privileges = function(tid, uid, callback) {
async.parallel({
categoryPrivs: function(next) {
topics.getTopicField(tid, 'cid', function(err, cid) {
CategoryTools.privileges(cid, uid, next);
});
},
hasEnoughRep: function(next) {
if (parseInt(meta.config['privileges:disabled'], 10)) {
return next(null, false);
} else {
user.getUserField(uid, 'reputation', function(err, reputation) {
if (err) {
return next(null, false);
}
next(null, parseInt(reputation, 10) >= parseInt(meta.config['privileges:manage_topic'], 10));
});
}
}
}, function(err, results) {
if (err) {
return callback(err);
}
var privileges = results.categoryPrivs;
privileges.meta.editable = privileges.meta.editable || results.hasEnoughRep;
privileges.meta.view_deleted = privileges.meta.view_deleted || results.hasEnoughRep;
callback(null, privileges);
});
};
ThreadTools.delete = function(tid, uid, callback) {
toggleDelete(tid, uid, true, callback);
};

@ -11,7 +11,8 @@ var async = require('async'),
user = require('./user'),
categories = require('./categories'),
categoryTools = require('./categoryTools'),
threadTools = require('./threadTools');
threadTools = require('./threadTools'),
privileges = require('./privileges');
(function(Topics) {
@ -132,8 +133,8 @@ var async = require('async'),
}
async.filter(tids, function(tid, next) {
threadTools.privileges(tid, uid, function(err, privileges) {
next(!err && privileges.meta.read);
privileges.topics.canRead(tid, uid, function(err, canRead) {
next(!err && canRead);
});
}, function(tids) {
Topics.getTopicsByTids(tids, uid, function(err, topicData) {
@ -269,9 +270,6 @@ var async = require('async'),
posts: function(next) {
Topics.getTopicPosts(tid, start, end, uid, false, next);
},
privileges: function(next) {
threadTools.privileges(tid, uid, next);
},
category: function(next) {
Topics.getCategoryData(tid, next);
},
@ -291,7 +289,6 @@ var async = require('async'),
topicData.thread_tools = results.threadTools;
topicData.pageCount = results.pageCount;
topicData.unreplied = parseInt(topicData.postcount, 10) === 1;
topicData.expose_tools = results.privileges.meta.editable ? 1 : 0;
callback(null, topicData);
});

@ -9,6 +9,7 @@ var async = require('async'),
meta = require('./../meta'),
posts = require('./../posts'),
threadTools = require('./../threadTools'),
privileges = require('../privileges'),
categoryTools = require('./../categoryTools');
module.exports = function(Topics) {
@ -144,7 +145,6 @@ module.exports = function(Topics) {
uid = data.uid,
toPid = data.toPid,
content = data.content,
privileges,
postData;
async.waterfall([
@ -173,11 +173,10 @@ module.exports = function(Topics) {
return next(new Error('[[error:topic-locked]]'));
}
threadTools.privileges(tid, uid, next);
privileges.topics.canReply(tid, uid, next);
},
function(privilegesData, next) {
privileges = privilegesData;
if (!privileges.meta['topics:reply']) {
function(canReply, next) {
if (!canReply) {
return next(new Error('[[error:no-privileges]]'));
}
next();
@ -232,7 +231,8 @@ module.exports = function(Topics) {
postData.favourited = false;
postData.votes = 0;
postData.display_moderator_tools = true;
postData.display_move_tools = privileges.admin || privileges.moderator;
postData.display_move_tools = true;
postData.selfPost = false;
postData.relativeTime = utils.toISOString(postData.timestamp);
next(null, postData);

@ -8,7 +8,7 @@ var async = require('async'),
user = require('./../user'),
notifications = require('./../notifications'),
categories = require('./../categories'),
threadTools = require('./../threadTools');
privileges = require('../privileges');
module.exports = function(Topics) {
@ -49,8 +49,8 @@ module.exports = function(Topics) {
});
async.filter(newtids, function(tid, next) {
threadTools.privileges(tid, uid, function(err, privileges) {
next(!err && privileges.meta.read);
privileges.topics.canRead(tid, uid, function(err, canRead) {
next(!err && canRead);
});
}, function(newtids) {
unreadTids.push.apply(unreadTids, newtids);

Loading…
Cancel
Save