fix: check if user has read priv before flagging

v1.18.x
Barış Soner Uşaklı 5 years ago
parent 1f13ab8a19
commit 51236df4ed

@ -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 () {

Loading…
Cancel
Save