mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-03 12:36:02 +01:00
fix: check if user has read priv before flagging
This commit is contained in:
17
src/flags.js
17
src/flags.js
@@ -251,18 +251,21 @@ Flags.create = async function (type, id, uid, reason, timestamp) {
|
||||
timestamp = Date.now();
|
||||
doHistoryAppend = true;
|
||||
}
|
||||
const [exists, targetExists, targetUid, targetCid] = await Promise.all([
|
||||
const [flagExists, targetExists, canFlag, targetUid, targetCid] = await Promise.all([
|
||||
// Sanity checks
|
||||
Flags.exists(type, id, uid),
|
||||
Flags.targetExists(type, id),
|
||||
Flags.canFlag(type, id, uid),
|
||||
// Extra data for zset insertion
|
||||
Flags.getTargetUid(type, id),
|
||||
Flags.getTargetCid(type, id),
|
||||
]);
|
||||
if (exists) {
|
||||
if (flagExists) {
|
||||
throw new Error('[[error:already-flagged]]');
|
||||
} else if (!targetExists) {
|
||||
throw new Error('[[error:invalid-data]]');
|
||||
} else if (!canFlag) {
|
||||
throw new Error('[[error:no-privileges]]');
|
||||
}
|
||||
const flagId = await db.incrObjectField('global', 'nextFlagId');
|
||||
|
||||
@@ -307,6 +310,16 @@ Flags.exists = async function (type, id, uid) {
|
||||
return await db.isSortedSetMember('flags:hash', [type, id, uid].join(':'));
|
||||
};
|
||||
|
||||
Flags.canFlag = async function (type, id, uid) {
|
||||
if (type === 'user') {
|
||||
return true;
|
||||
}
|
||||
if (type === 'post') {
|
||||
return await privileges.posts.can('topics:read', id, uid);
|
||||
}
|
||||
throw new Error('[[error:invalid-data]]');
|
||||
};
|
||||
|
||||
Flags.getTarget = async function (type, id, uid) {
|
||||
if (type === 'user') {
|
||||
const userData = await user.getUserData(id);
|
||||
|
||||
@@ -11,18 +11,19 @@ var Posts = require('../src/posts');
|
||||
var User = require('../src/user');
|
||||
var Groups = require('../src/groups');
|
||||
var Meta = require('../src/meta');
|
||||
var Privileges = require('../src/privileges');
|
||||
|
||||
describe('Flags', function () {
|
||||
let uid1;
|
||||
let uid2;
|
||||
let adminUid;
|
||||
let uid3;
|
||||
let category;
|
||||
before(async () => {
|
||||
// Create some stuff to flag
|
||||
uid1 = await User.create({ username: 'testUser', password: 'abcdef', email: 'b@c.com' });
|
||||
|
||||
uid2 = await User.create({ username: 'testUser2', password: 'abcdef', email: 'c@d.com' });
|
||||
await Groups.join('administrators', uid2);
|
||||
adminUid = await User.create({ username: 'testUser2', password: 'abcdef', email: 'c@d.com' });
|
||||
await Groups.join('administrators', adminUid);
|
||||
|
||||
category = await Categories.create({
|
||||
name: 'test category',
|
||||
@@ -264,9 +265,9 @@ describe('Flags', function () {
|
||||
|
||||
describe('.update()', function () {
|
||||
it('should alter a flag\'s various attributes and persist them to the database', function (done) {
|
||||
Flags.update(1, uid2, {
|
||||
Flags.update(1, adminUid, {
|
||||
state: 'wip',
|
||||
assignee: uid2,
|
||||
assignee: adminUid,
|
||||
}, function (err) {
|
||||
assert.ifError(err);
|
||||
db.getObjectFields('flag:1', ['state', 'assignee'], function (err, data) {
|
||||
@@ -276,7 +277,7 @@ describe('Flags', function () {
|
||||
|
||||
assert.strictEqual('wip', data.state);
|
||||
assert.ok(!isNaN(parseInt(data.assignee, 10)));
|
||||
assert.strictEqual(uid2, parseInt(data.assignee, 10));
|
||||
assert.strictEqual(adminUid, parseInt(data.assignee, 10));
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -305,17 +306,17 @@ describe('Flags', function () {
|
||||
});
|
||||
|
||||
it('should allow assignment if user is an admin and do nothing otherwise', async () => {
|
||||
await Flags.update(1, uid2, {
|
||||
assignee: uid2,
|
||||
await Flags.update(1, adminUid, {
|
||||
assignee: adminUid,
|
||||
});
|
||||
let assignee = await db.getObjectField('flag:1', 'assignee');
|
||||
assert.strictEqual(uid2, parseInt(assignee, 10));
|
||||
assert.strictEqual(adminUid, parseInt(assignee, 10));
|
||||
|
||||
await Flags.update(1, uid2, {
|
||||
await Flags.update(1, adminUid, {
|
||||
assignee: uid3,
|
||||
});
|
||||
assignee = await db.getObjectField('flag:1', 'assignee');
|
||||
assert.strictEqual(uid2, parseInt(assignee, 10));
|
||||
assert.strictEqual(adminUid, parseInt(assignee, 10));
|
||||
});
|
||||
|
||||
it('should allow assignment if user is a global mod and do nothing otherwise', async () => {
|
||||
@@ -355,7 +356,7 @@ describe('Flags', function () {
|
||||
});
|
||||
|
||||
it('should do nothing when you attempt to set a bogus state', async () => {
|
||||
await Flags.update(1, uid2, {
|
||||
await Flags.update(1, adminUid, {
|
||||
state: 'hocus pocus',
|
||||
});
|
||||
|
||||
@@ -630,6 +631,23 @@ describe('Flags', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not allow flagging post in private category', async function () {
|
||||
const category = await Categories.create({ name: 'private category' });
|
||||
|
||||
await Privileges.categories.rescind(['topics:read'], category.cid, 'registered-users');
|
||||
const result = await Topics.post({
|
||||
cid: category.cid,
|
||||
uid: adminUid,
|
||||
title: 'private topic',
|
||||
content: 'private post',
|
||||
});
|
||||
try {
|
||||
await SocketFlags.create({ uid: uid3 }, { type: 'post', id: result.postData.pid, reason: 'foobar' });
|
||||
} catch (err) {
|
||||
assert.equal(err.message, '[[error:no-privileges]]');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('.update()', function () {
|
||||
|
||||
Reference in New Issue
Block a user