mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 03:26:04 +01:00
refactored the entire privileges stack. .editable() is now deprecated, use
.privileges instead. Privileges now are inherited, so querying a topic's privileges will automatically query it's parent category's privileges as well, etc.
This commit is contained in:
@@ -164,6 +164,10 @@ footer.footer {
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
|
|
||||||
|
&.deleted {
|
||||||
|
-moz-opacity: 0.30;
|
||||||
|
opacity: 0.30;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child li {
|
&:last-child li {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<div class="span9">
|
<div class="span9">
|
||||||
<ul id="topics-container">
|
<ul id="topics-container">
|
||||||
<!-- BEGIN topics -->
|
<!-- BEGIN topics -->
|
||||||
<a href="../../topic/{topics.slug}"><li>
|
<a href="../../topic/{topics.slug}"><li class="{topics.deleted-class}">
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span1 thread-rating hidden-phone hidden-tablet">
|
<div class="span1 thread-rating hidden-phone hidden-tablet">
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
var RDB = require('./redis.js'),
|
var RDB = require('./redis.js'),
|
||||||
posts = require('./posts.js'),
|
posts = require('./posts.js'),
|
||||||
utils = require('./utils.js'),
|
utils = require('./utils.js'),
|
||||||
user = require('./user.js');
|
user = require('./user.js'),
|
||||||
|
async = require('async');
|
||||||
|
|
||||||
(function(Categories) {
|
(function(Categories) {
|
||||||
|
|
||||||
@@ -27,6 +28,30 @@ var RDB = require('./redis.js'),
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Categories.privileges = function(cid, uid, callback) {
|
||||||
|
async.parallel([
|
||||||
|
// function(next) {
|
||||||
|
// user.getUserField(uid, 'reputation', function(reputation) {
|
||||||
|
// next(null, reputation >= config.privilege_thresholds.manage_category);
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
function(next) {
|
||||||
|
user.isModerator(uid, cid, function(isMod) {
|
||||||
|
next(null, isMod);
|
||||||
|
});
|
||||||
|
}, function(next) {
|
||||||
|
user.isAdministrator(uid, function(isAdmin) {
|
||||||
|
next(null, isAdmin);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
], function(err, results) {
|
||||||
|
callback({
|
||||||
|
editable: results.indexOf(true) !== -1 ? true : false,
|
||||||
|
view_deleted: results.indexOf(true) !== -1 ? true : false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Categories.edit = function(data, callback) {
|
Categories.edit = function(data, callback) {
|
||||||
// just a reminder to self that name + slugs are stored into topics data as well.
|
// just a reminder to self that name + slugs are stored into topics data as well.
|
||||||
};
|
};
|
||||||
|
|||||||
92
src/posts.js
92
src/posts.js
@@ -13,34 +13,28 @@ marked.setOptions({
|
|||||||
(function(Posts) {
|
(function(Posts) {
|
||||||
|
|
||||||
Posts.get = function(callback, tid, current_user, start, end) {
|
Posts.get = function(callback, tid, current_user, start, end) {
|
||||||
|
|
||||||
if (start == null) start = 0;
|
if (start == null) start = 0;
|
||||||
if (end == null) end = -1;//start + 10;
|
if (end == null) end = -1;//start + 10;
|
||||||
|
|
||||||
var post_data, user_data, thread_data, vote_data, viewer_data;
|
var post_data, user_data, thread_data, vote_data, privileges;
|
||||||
|
|
||||||
getTopicPosts();
|
getTopicPosts();
|
||||||
|
|
||||||
getViewerData();
|
getPrivileges();
|
||||||
|
|
||||||
|
|
||||||
//compile thread after all data is asynchronously called
|
//compile thread after all data is asynchronously called
|
||||||
function generateThread() {
|
function generateThread() {
|
||||||
if (!post_data || !user_data || !thread_data || !vote_data || !viewer_data) return;
|
if (!post_data || !user_data || !thread_data || !vote_data || !privileges) return;
|
||||||
|
|
||||||
var posts = [],
|
var posts = [],
|
||||||
main_posts = [],
|
main_posts = [];
|
||||||
manage_content = (
|
|
||||||
viewer_data.reputation >= config.privilege_thresholds.manage_content ||
|
|
||||||
viewer_data.isModerator ||
|
|
||||||
viewer_data.isAdministrator
|
|
||||||
);
|
|
||||||
|
|
||||||
for (var i=0, ii= post_data.pid.length; i<ii; i++) {
|
for (var i=0, ii= post_data.pid.length; i<ii; i++) {
|
||||||
var uid = post_data.uid[i],
|
var uid = post_data.uid[i],
|
||||||
pid = post_data.pid[i];
|
pid = post_data.pid[i];
|
||||||
|
|
||||||
if (post_data.deleted[i] === null || (post_data.deleted[i] === '1' && manage_content) || current_user === uid) {
|
if (post_data.deleted[i] === null || (post_data.deleted[i] === '1' && privileges.view_deleted) || current_user === uid) {
|
||||||
var post_obj = {
|
var post_obj = {
|
||||||
'pid' : pid,
|
'pid' : pid,
|
||||||
'uid' : uid,
|
'uid' : uid,
|
||||||
@@ -53,7 +47,7 @@ marked.setOptions({
|
|||||||
'gravatar' : user_data[uid].picture || 'http://www.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e',
|
'gravatar' : user_data[uid].picture || 'http://www.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e',
|
||||||
'signature' : user_data[uid].signature,
|
'signature' : user_data[uid].signature,
|
||||||
'fav_star_class' : vote_data[pid] ? 'icon-star' : 'icon-star-empty',
|
'fav_star_class' : vote_data[pid] ? 'icon-star' : 'icon-star-empty',
|
||||||
'display_moderator_tools': (uid == current_user || manage_content || viewer_data.isModerator) ? 'show' : 'none',
|
'display_moderator_tools': (uid == current_user || privileges.editable) ? 'show' : 'none',
|
||||||
'edited-class': post_data.editor[i] !== null ? '' : 'none',
|
'edited-class': post_data.editor[i] !== null ? '' : 'none',
|
||||||
'editor': post_data.editor[i] !== null ? user_data[post_data.editor[i]].username : '',
|
'editor': post_data.editor[i] !== null ? user_data[post_data.editor[i]].username : '',
|
||||||
'relativeEditTime': post_data.editTime !== null ? utils.relativeTime(post_data.editTime[i]) : '',
|
'relativeEditTime': post_data.editTime !== null ? utils.relativeTime(post_data.editTime[i]) : '',
|
||||||
@@ -73,7 +67,7 @@ marked.setOptions({
|
|||||||
'deleted': parseInt(thread_data.deleted) || 0,
|
'deleted': parseInt(thread_data.deleted) || 0,
|
||||||
'pinned': parseInt(thread_data.pinned) || 0,
|
'pinned': parseInt(thread_data.pinned) || 0,
|
||||||
'topic_id': tid,
|
'topic_id': tid,
|
||||||
'expose_tools': manage_content ? 1 : 0,
|
'expose_tools': privileges.editable ? 1 : 0,
|
||||||
'posts': posts,
|
'posts': posts,
|
||||||
'main_posts': main_posts
|
'main_posts': main_posts
|
||||||
});
|
});
|
||||||
@@ -159,40 +153,23 @@ marked.setOptions({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getViewerData() {
|
function getPrivileges() {
|
||||||
async.parallel([
|
topics.privileges(tid, current_user, function(user_privs) {
|
||||||
function(callback) {
|
privileges = user_privs;
|
||||||
user.getUserField(current_user, 'reputation', function(reputation){
|
generateThread();
|
||||||
viewer_data = viewer_data || {};
|
|
||||||
viewer_data.reputation = reputation;
|
|
||||||
|
|
||||||
callback(null);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(callback) {
|
|
||||||
RDB.get('tid:' + tid + ':cid', function(err, cid) {
|
|
||||||
user.isModerator(current_user, cid, function(isMod) {
|
|
||||||
viewer_data = viewer_data || {};
|
|
||||||
viewer_data.isModerator = isMod;
|
|
||||||
callback(null);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
},
|
|
||||||
function(callback) {
|
|
||||||
user.isAdministrator(current_user, function(isAdmin) {
|
|
||||||
viewer_data = viewer_data || {};
|
|
||||||
viewer_data.isAdministrator = isAdmin;
|
|
||||||
callback(null);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
], function(err) {
|
|
||||||
generateThread();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Posts.editable = function(uid, pid, callback) {
|
Posts.privileges = function(pid, uid, callback) {
|
||||||
async.parallel([
|
async.parallel([
|
||||||
|
function(next) {
|
||||||
|
Posts.get_tid_by_pid(pid, function(tid) {
|
||||||
|
topics.privileges(tid, uid, function(privileges) {
|
||||||
|
next(null, privileges);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
RDB.get('pid:' + pid + ':uid', function(err, author) {
|
RDB.get('pid:' + pid + ':uid', function(err, author) {
|
||||||
if (author && parseInt(author) > 0) next(null, author === uid);
|
if (author && parseInt(author) > 0) next(null, author === uid);
|
||||||
@@ -202,23 +179,12 @@ marked.setOptions({
|
|||||||
user.getUserField(uid, 'reputation', function(reputation) {
|
user.getUserField(uid, 'reputation', function(reputation) {
|
||||||
next(null, reputation >= config.privilege_thresholds.manage_content);
|
next(null, reputation >= config.privilege_thresholds.manage_content);
|
||||||
});
|
});
|
||||||
},
|
|
||||||
function(next) {
|
|
||||||
Posts.get_tid_by_pid(pid, function(tid) {
|
|
||||||
RDB.get('tid:' + tid + ':cid', function(err, cid) {
|
|
||||||
user.isModerator(uid, cid, function(isMod) {
|
|
||||||
next(null, isMod);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, function(next) {
|
|
||||||
user.isAdministrator(uid, function(isAdmin) {
|
|
||||||
next(null, isAdmin);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
], function(err, results) {
|
], function(err, results) {
|
||||||
// If any return true, allow the edit
|
callback({
|
||||||
if (results.indexOf(true) !== -1) callback(true);
|
editable: results[0].editable || (results.slice(1).indexOf(true) !== -1 ? true : false),
|
||||||
|
view_deleted: results[0].view_deleted || (results.slice(1).indexOf(true) !== -1 ? true : false)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,8 +428,8 @@ marked.setOptions({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Posts.editable(uid, pid, function(editable) {
|
Posts.privileges(pid, uid, function(privileges) {
|
||||||
if (editable) success();
|
if (privileges.editable) success();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,8 +442,8 @@ marked.setOptions({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Posts.editable(uid, pid, function(editable) {
|
Posts.privileges(pid, uid, function(privileges) {
|
||||||
if (editable) success();
|
if (privileges.editable) success();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,8 +456,8 @@ marked.setOptions({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Posts.editable(uid, pid, function(editable) {
|
Posts.privileges(pid, uid, function(privileges) {
|
||||||
if (editable) success();
|
if (privileges.editable) success();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}(exports));
|
}(exports));
|
||||||
102
src/topics.js
102
src/topics.js
@@ -87,29 +87,33 @@ marked.setOptions({
|
|||||||
var usernames,
|
var usernames,
|
||||||
has_read,
|
has_read,
|
||||||
moderators,
|
moderators,
|
||||||
teaser_info;
|
teaser_info,
|
||||||
|
privileges;
|
||||||
|
|
||||||
function generate_topic() {
|
function generate_topic() {
|
||||||
if (!usernames || !has_read || !moderators || !teaser_info) return;
|
if (!usernames || !has_read || !moderators || !teaser_info || !privileges) return;
|
||||||
|
|
||||||
if (tids.length > 0) {
|
if (tids.length > 0) {
|
||||||
for (var i=0, ii=title.length; i<ii; i++) {
|
for (var i=0, ii=title.length; i<ii; i++) {
|
||||||
topics.push({
|
if (!deleted[i] || (deleted[i] && privileges.view_deleted) || uid[i] === current_user) {
|
||||||
'title' : title[i],
|
topics.push({
|
||||||
'uid' : uid[i],
|
'title' : title[i],
|
||||||
'username': usernames[i],
|
'uid' : uid[i],
|
||||||
'timestamp' : timestamp[i],
|
'username': usernames[i],
|
||||||
'relativeTime': utils.relativeTime(timestamp[i]),
|
'timestamp' : timestamp[i],
|
||||||
'slug' : slug[i],
|
'relativeTime': utils.relativeTime(timestamp[i]),
|
||||||
'post_count' : postcount[i],
|
'slug' : slug[i],
|
||||||
'lock-icon': locked[i] === '1' ? 'icon-lock' : 'none',
|
'post_count' : postcount[i],
|
||||||
'deleted': deleted[i],
|
'lock-icon': locked[i] === '1' ? 'icon-lock' : 'none',
|
||||||
'pinned': parseInt(pinned[i] || 0), // For sorting purposes
|
'deleted': deleted[i],
|
||||||
'pin-icon': pinned[i] === '1' ? 'icon-pushpin' : 'none',
|
'deleted-class': deleted[i] ? 'deleted' : '',
|
||||||
'badgeclass' : (has_read[i] && current_user !=0) ? '' : 'badge-important',
|
'pinned': parseInt(pinned[i] || 0), // For sorting purposes
|
||||||
'teaser_text': teaser_info[i].text,
|
'pin-icon': pinned[i] === '1' ? 'icon-pushpin' : 'none',
|
||||||
'teaser_username': teaser_info[i].username
|
'badgeclass' : (has_read[i] && current_user !=0) ? '' : 'badge-important',
|
||||||
});
|
'teaser_text': teaser_info[i].text,
|
||||||
|
'teaser_username': teaser_info[i].username
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,39 +161,33 @@ marked.setOptions({
|
|||||||
teaser_info = teasers;
|
teaser_info = teasers;
|
||||||
generate_topic();
|
generate_topic();
|
||||||
});
|
});
|
||||||
// else {
|
|
||||||
// callback({
|
categories.privileges(category_id, current_user, function(user_privs) {
|
||||||
// 'category_name' : category_id ? category_name : 'Recent',
|
privileges = user_privs;
|
||||||
// 'show_topic_button' : category_id ? 'show' : 'hidden',
|
});
|
||||||
// 'category_id': category_id || 0,
|
|
||||||
// 'topics': []
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Topics.editable = function(tid, uid, callback) {
|
Topics.privileges = function(tid, uid, callback) {
|
||||||
async.parallel([
|
async.parallel([
|
||||||
|
function(next) {
|
||||||
|
Topics.get_cid_by_tid(tid, function(cid) {
|
||||||
|
categories.privileges(cid, uid, function(privileges) {
|
||||||
|
next(null, privileges);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
user.getUserField(uid, 'reputation', function(reputation) {
|
user.getUserField(uid, 'reputation', function(reputation) {
|
||||||
next(null, reputation >= config.privilege_thresholds.manage_thread);
|
next(null, reputation >= config.privilege_thresholds.manage_thread);
|
||||||
});
|
});
|
||||||
},
|
|
||||||
function(next) {
|
|
||||||
Topics.get_cid_by_tid(tid, function(cid) {
|
|
||||||
user.isModerator(uid, cid, function(isMod) {
|
|
||||||
next(null, isMod);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, function(next) {
|
|
||||||
user.isAdministrator(uid, function(isAdmin) {
|
|
||||||
next(null, isAdmin);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
], function(err, results) {
|
], function(err, results) {
|
||||||
// If any return true, allow the edit
|
callback({
|
||||||
if (results.indexOf(true) !== -1) callback(true);
|
editable: results[0].editable || (results.slice(1).indexOf(true) !== -1 ? true : false),
|
||||||
|
view_deleted: results[0].view_deleted || (results.slice(1).indexOf(true) !== -1 ? true : false)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,8 +381,8 @@ marked.setOptions({
|
|||||||
};
|
};
|
||||||
|
|
||||||
Topics.lock = function(tid, uid, socket) {
|
Topics.lock = function(tid, uid, socket) {
|
||||||
Topics.editable(tid, uid, function(editable) {
|
Topics.privileges(tid, uid, function(privileges) {
|
||||||
if (editable) {
|
if (privileges.editable) {
|
||||||
// Mark thread as locked
|
// Mark thread as locked
|
||||||
RDB.set('tid:' + tid + ':locked', 1);
|
RDB.set('tid:' + tid + ':locked', 1);
|
||||||
|
|
||||||
@@ -399,8 +397,8 @@ marked.setOptions({
|
|||||||
}
|
}
|
||||||
|
|
||||||
Topics.unlock = function(tid, uid, socket) {
|
Topics.unlock = function(tid, uid, socket) {
|
||||||
Topics.editable(tid, uid, function(editable) {
|
Topics.privileges(tid, uid, function(privileges) {
|
||||||
if (editable) {
|
if (privileges.editable) {
|
||||||
// Mark thread as unlocked
|
// Mark thread as unlocked
|
||||||
RDB.del('tid:' + tid + ':locked');
|
RDB.del('tid:' + tid + ':locked');
|
||||||
|
|
||||||
@@ -415,8 +413,8 @@ marked.setOptions({
|
|||||||
}
|
}
|
||||||
|
|
||||||
Topics.delete = function(tid, uid, socket) {
|
Topics.delete = function(tid, uid, socket) {
|
||||||
Topics.editable(tid, uid, function(editable) {
|
Topics.privileges(tid, uid, function(privileges) {
|
||||||
if (editable) {
|
if (privileges.editable) {
|
||||||
// Mark thread as deleted
|
// Mark thread as deleted
|
||||||
RDB.set('tid:' + tid + ':deleted', 1);
|
RDB.set('tid:' + tid + ':deleted', 1);
|
||||||
Topics.lock(tid, uid);
|
Topics.lock(tid, uid);
|
||||||
@@ -432,8 +430,8 @@ marked.setOptions({
|
|||||||
}
|
}
|
||||||
|
|
||||||
Topics.restore = function(tid, uid, socket) {
|
Topics.restore = function(tid, uid, socket) {
|
||||||
Topics.editable(tid, uid, function(editable) {
|
Topics.privileges(tid, uid, function(privileges) {
|
||||||
if (editable) {
|
if (privileges.editable) {
|
||||||
// Mark thread as restored
|
// Mark thread as restored
|
||||||
RDB.del('tid:' + tid + ':deleted');
|
RDB.del('tid:' + tid + ':deleted');
|
||||||
Topics.unlock(tid, uid);
|
Topics.unlock(tid, uid);
|
||||||
@@ -449,8 +447,8 @@ marked.setOptions({
|
|||||||
}
|
}
|
||||||
|
|
||||||
Topics.pin = function(tid, uid, socket) {
|
Topics.pin = function(tid, uid, socket) {
|
||||||
Topics.editable(tid, uid, function(editable) {
|
Topics.privileges(tid, uid, function(privileges) {
|
||||||
if (editable) {
|
if (privileges.editable) {
|
||||||
// Mark thread as pinned
|
// Mark thread as pinned
|
||||||
RDB.set('tid:' + tid + ':pinned', 1);
|
RDB.set('tid:' + tid + ':pinned', 1);
|
||||||
|
|
||||||
@@ -465,8 +463,8 @@ marked.setOptions({
|
|||||||
}
|
}
|
||||||
|
|
||||||
Topics.unpin = function(tid, uid, socket) {
|
Topics.unpin = function(tid, uid, socket) {
|
||||||
Topics.editable(tid, uid, function(editable) {
|
Topics.privileges(tid, uid, function(privileges) {
|
||||||
if (editable) {
|
if (privileges.editable) {
|
||||||
// Mark thread as unpinned
|
// Mark thread as unpinned
|
||||||
RDB.del('tid:' + tid + ':pinned');
|
RDB.del('tid:' + tid + ':pinned');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user