v1.18.x
Barış Soner Uşaklı 8 years ago
parent 8f5f5eb56a
commit d65f494c6d

@ -55,7 +55,7 @@
"morgan": "^1.3.2",
"mousetrap": "^1.5.3",
"nconf": "~0.8.2",
"nodebb-plugin-composer-default": "4.4.13",
"nodebb-plugin-composer-default": "4.4.14",
"nodebb-plugin-dbsearch": "2.0.4",
"nodebb-plugin-emoji-extended": "1.1.1",
"nodebb-plugin-emoji-one": "1.2.1",

@ -52,7 +52,18 @@ module.exports = function (Categories) {
function (data, next) {
category = data.category;
var defaultPrivileges = ['find', 'read', 'topics:read', 'topics:create', 'topics:reply', 'posts:edit', 'posts:delete', 'topics:delete', 'upload:post:image'];
var defaultPrivileges = [
'find',
'read',
'topics:read',
'topics:create',
'topics:reply',
'topics:tag',
'posts:edit',
'posts:delete',
'topics:delete',
'upload:post:image',
];
async.series([
async.apply(db.setObject, 'category:' + category.cid, category),

@ -48,9 +48,7 @@ module.exports = function (Posts) {
},
function (result, next) {
postData = result.post;
Posts.setPostFields(data.pid, postData, next);
},
function (next) {
async.parallel({
editor: function (next) {
user.getUserFields(data.uid, ['username', 'userslug'], next);
@ -62,7 +60,9 @@ module.exports = function (Posts) {
},
function (_results, next) {
results = _results;
Posts.setPostFields(data.pid, postData, next);
},
function (next) {
postData.cid = results.topic.cid;
postData.topic = results.topic;
plugins.fireHook('action:post.edit', { post: _.clone(postData), uid: data.uid });
@ -123,6 +123,17 @@ module.exports = function (Posts) {
data.tags = data.tags || [];
if (!data.tags.length) {
return next(null, true);
}
privileges.categories.can('topics:tag', topicData.cid, data.uid, next);
},
function (canTag, next) {
if (!canTag) {
return next(new Error('[[error:no-privileges]]'));
}
plugins.fireHook('filter:topic.edit', { req: data.req, topic: topicData, data: data }, next);
},
function (results, next) {

@ -2,12 +2,29 @@
var privileges = module.exports;
privileges.privilegeLabels = [
{ name: 'Find Category' },
{ name: 'Access Category' },
{ name: 'Access Topics' },
{ name: 'Create Topics' },
{ name: 'Reply to Topics' },
{ name: 'Tag Topics' },
{ name: 'Edit Posts' },
{ name: 'Delete Posts' },
{ name: 'Delete Topics' },
{ name: 'Upload Images' },
{ name: 'Upload Files' },
{ name: 'Purge' },
{ name: 'Moderate' },
];
privileges.userPrivilegeList = [
'find',
'read',
'topics:read',
'topics:create',
'topics:reply',
'topics:tag',
'posts:edit',
'posts:delete',
'topics:delete',

@ -16,28 +16,13 @@ module.exports = function (privileges) {
privileges.categories.list = function (cid, callback) {
// Method used in admin/category controller to show all users/groups with privs in that given cid
var privilegeLabels = [
{ name: 'Find Category' },
{ name: 'Access Category' },
{ name: 'Access Topics' },
{ name: 'Create Topics' },
{ name: 'Reply to Topics' },
{ name: 'Edit Posts' },
{ name: 'Delete Posts' },
{ name: 'Delete Topics' },
{ name: 'Upload Images' },
{ name: 'Upload Files' },
{ name: 'Purge' },
{ name: 'Moderate' },
];
async.waterfall([
function (next) {
async.parallel({
labels: function (next) {
async.parallel({
users: async.apply(plugins.fireHook, 'filter:privileges.list_human', privilegeLabels),
groups: async.apply(plugins.fireHook, 'filter:privileges.groups.list_human', privilegeLabels),
users: async.apply(plugins.fireHook, 'filter:privileges.list_human', privileges.privilegeLabels),
groups: async.apply(plugins.fireHook, 'filter:privileges.groups.list_human', privileges.privilegeLabels),
}, next);
},
users: function (next) {
@ -155,7 +140,7 @@ module.exports = function (privileges) {
};
privileges.categories.get = function (cid, uid, callback) {
var privs = ['topics:create', 'topics:read', 'read'];
var privs = ['topics:create', 'topics:read', 'topics:tag', 'read'];
async.waterfall([
function (next) {
async.parallel({
@ -177,6 +162,7 @@ module.exports = function (privileges) {
plugins.fireHook('filter:privileges.categories.get', {
'topics:create': privData['topics:create'] || isAdminOrMod,
'topics:read': privData['topics:read'] || isAdminOrMod,
'topics:tag': privData['topics:tag'] || isAdminOrMod,
read: privData.read || isAdminOrMod,
cid: cid,
uid: uid,

@ -16,7 +16,7 @@ module.exports = function (privileges) {
privileges.topics.get = function (tid, uid, callback) {
var topic;
var privs = ['topics:reply', 'topics:read', 'topics:delete', 'posts:edit', 'posts:delete', 'read'];
var privs = ['topics:reply', 'topics:read', 'topics:tag', 'topics:delete', 'posts:edit', 'posts:delete', 'read'];
async.waterfall([
async.apply(topics.getTopicFields, tid, ['cid', 'uid', 'locked', 'deleted']),
function (_topic, next) {
@ -41,6 +41,7 @@ module.exports = function (privileges) {
plugins.fireHook('filter:privileges.topics.get', {
'topics:reply': (privData['topics:reply'] && !locked && !deleted) || isAdminOrMod,
'topics:read': privData['topics:read'] || isAdminOrMod,
'topics:tag': privData['topics:tag'] || isAdminOrMod,
'topics:delete': (isOwner && privData['topics:delete']) || isAdminOrMod,
'posts:edit': (privData['posts:edit'] && !locked) || isAdminOrMod,
'posts:delete': (privData['posts:delete'] && !locked) || isAdminOrMod,

@ -107,18 +107,30 @@ module.exports = function (Topics) {
check(data.content, meta.config.minimumPostLength, meta.config.maximumPostLength, 'content-too-short', 'content-too-long', next);
},
function (next) {
categories.exists(data.cid, next);
async.parallel({
categoryExists: function (next) {
categories.exists(data.cid, next);
},
canCreate: function (next) {
privileges.categories.can('topics:create', data.cid, data.uid, next);
},
canTag: function (next) {
if (!data.tags.length) {
return next(null, true);
}
privileges.categories.can('topics:tag', data.cid, data.uid, next);
},
}, next);
},
function (categoryExists, next) {
if (!categoryExists) {
function (results, next) {
if (!results.categoryExists) {
return next(new Error('[[error:no-category]]'));
}
privileges.categories.can('topics:create', data.cid, data.uid, next);
},
function (canCreate, next) {
if (!canCreate) {
if (!results.canCreate || !results.canTag) {
return next(new Error('[[error:no-privileges]]'));
}
guestHandleValid(data, next);
},
function (next) {

@ -0,0 +1,22 @@
'use strict';
var async = require('async');
var batch = require('../../batch');
module.exports = {
name: 'Give tag privilege to registered-users on all categories',
timestamp: Date.UTC(2017, 5, 16),
method: function (callback) {
var progress = this.progress;
var privileges = require('../../privileges');
batch.processSortedSet('categories:cid', function (cids, next) {
async.eachSeries(cids, function (cid, next) {
progress.incr();
privileges.categories.give(['topics:tag'], cid, 'registered-users', next);
}, next);
}, {
progress: progress,
}, callback);
},
};

@ -645,6 +645,7 @@ describe('Categories', function () {
'topics:reply': false,
'topics:read': false,
'topics:create': false,
'topics:tag': false,
'topics:delete': false,
'posts:edit': false,
'upload:post:file': false,
@ -666,6 +667,7 @@ describe('Categories', function () {
'groups:topics:delete': false,
'groups:topics:create': true,
'groups:topics:reply': true,
'groups:topics:tag': true,
'groups:posts:delete': true,
'groups:read': true,
'groups:topics:read': true,

@ -7,7 +7,9 @@ var nconf = require('nconf');
var db = require('./mocks/databasemock');
var topics = require('../src/topics');
var posts = require('../src/posts');
var categories = require('../src/categories');
var privileges = require('../src/privileges');
var meta = require('../src/meta');
var User = require('../src/user');
var groups = require('../src/groups');
@ -825,7 +827,7 @@ describe('Topic\'s', function () {
});
it('should 404 if tid is not a number', function (done) {
request(nconf.get('url') + '/api/topic/teaser/nan', { json: true }, function (err, response, body) {
request(nconf.get('url') + '/api/topic/teaser/nan', { json: true }, function (err, response) {
assert.ifError(err);
assert.equal(response.statusCode, 404);
done();
@ -858,7 +860,7 @@ describe('Topic\'s', function () {
it('should 404 if tid is not a number', function (done) {
request(nconf.get('url') + '/api/topic/pagination/nan', { json: true }, function (err, response, body) {
request(nconf.get('url') + '/api/topic/pagination/nan', { json: true }, function (err, response) {
assert.ifError(err);
assert.equal(response.statusCode, 404);
done();
@ -866,7 +868,7 @@ describe('Topic\'s', function () {
});
it('should 404 if tid does not exist', function (done) {
request(nconf.get('url') + '/api/topic/pagination/1231231', { json: true }, function (err, response, body) {
request(nconf.get('url') + '/api/topic/pagination/1231231', { json: true }, function (err, response) {
assert.ifError(err);
assert.equal(response.statusCode, 404);
done();
@ -1643,4 +1645,61 @@ describe('Topic\'s', function () {
});
});
});
describe('tag privilege', function () {
var uid;
var cid;
before(function (done) {
async.waterfall([
function (next) {
User.create({ username: 'tag_poster' }, next);
},
function (_uid, next) {
uid = _uid;
categories.create({ name: 'tag category' }, next);
},
function (categoryObj, next) {
cid = categoryObj.cid;
next();
},
], done);
});
it('should fail to post if user does not have tag privilege', function (done) {
privileges.categories.rescind(['topics:tag'], cid, 'registered-users', function (err) {
assert.ifError(err);
topics.post({ uid: uid, cid: cid, tags: ['tag1'], title: 'topic with tags', content: 'some content here' }, function (err) {
assert.equal(err.message, '[[error:no-privileges]]');
done();
});
});
});
it('should fail to edit if user does not have tag privilege', function (done) {
topics.post({ uid: uid, cid: cid, title: 'topic with tags', content: 'some content here' }, function (err, result) {
assert.ifError(err);
var pid = result.postData.pid;
posts.edit({ pid: pid, uid: uid, content: 'edited content', tags: ['tag2'] }, function (err) {
assert.equal(err.message, '[[error:no-privileges]]');
done();
});
});
});
it('should be able to edit topic and add tags if allowed', function (done) {
privileges.categories.give(['topics:tag'], cid, 'registered-users', function (err) {
assert.ifError(err);
topics.post({ uid: uid, cid: cid, tags: ['tag1'], title: 'topic with tags', content: 'some content here' }, function (err, result) {
assert.ifError(err);
posts.edit({ pid: result.postData.pid, uid: uid, content: 'edited content', tags: ['tag1', 'tag2'] }, function (err, result) {
assert.ifError(err);
assert.deepEqual(result.topic.tags.map(function (tag) {
return tag.value;
}), ['tag1', 'tag2']);
done();
});
});
});
});
});
});

Loading…
Cancel
Save