Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to add authorization to endorsement API #36

Open
wants to merge 11 commits into
base: f24
Choose a base branch
from
Open
2 changes: 2 additions & 0 deletions src/api/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,9 +514,11 @@ postsAPI.getReplies = async (caller, { pid }) => {
};

postsAPI.endorse = async (caller, { pid }) => {
console.log("VICKYC3", pid, caller.uid);
return await posts.endorse(pid, caller.uid);
};

postsAPI.unendorse = async (caller, { pid }) => {
console.log("VICKYC4", pid, caller.uid);
return await posts.unendorse(pid, caller.uid);
};
8 changes: 8 additions & 0 deletions src/posts/endorsements.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

const db = require('../database');
const plugins = require('../plugins');
const privileges = require('../privileges');

module.exports = function (Posts) {
Posts.endorse = async function (pid, uid) {
console.log("Calling toggleEndorse with UID VICKY2:", uid);
return await toggleEndorse('endorse', pid, uid);
};

Expand All @@ -16,6 +18,12 @@ module.exports = function (Posts) {
if (parseInt(uid, 10) <= 0) {
throw new Error('[[error:not-logged-in]]');
}
console.log("USER ID BEFORE CALLING CAN ENDORSE VICKY: ", uid);
const isAllowed = await privileges.posts.canEndorse(uid);

if (!isAllowed) {
throw new Error('[[error:permission-denied]]');
}

const isEndorsing = type === 'endorse';

Expand Down
20 changes: 20 additions & 0 deletions src/privileges/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,26 @@ privsPosts.canPurge = async function (pid, uid) {
return (results.purge && (results.owner || results.isModerator)) || results.isAdmin;
};

privsPosts.canEndorse = async function (uid) {
console.log("CAN ENDORSE FUNCTION IS BEING CALLED");
if (parseInt(uid, 10) <= 0) {
console.error("VICKY CHEN HERE");
console.error("Invalid UID", uid);
return false;
}
console.error("Checking if UID", uid, "is admin...");
const isAdmin = await user.isAdministrator(uid);
console.error("isAdmin result for UID VICKY13", uid, ":", isAdmin);
if (isAdmin) {
console.log("True VICKY14");
return true;
}
console.error("Checking if UID", uid, "is global moderator...");
const isGlobalMod = await user.isGlobalModerator(uid);
console.error("isGlobalMod result for UID", uid, ":", isGlobalMod);
return isGlobalMod;
};

async function isAdminOrMod(pid, uid) {
if (parseInt(uid, 10) <= 0) {
return false;
Expand Down
17 changes: 13 additions & 4 deletions src/socket.io/posts/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,21 @@ module.exports = function (SocketPosts) {
await Promise.all(logs);
};

// SocketPosts.endorse = async function (socket, data) {
// if (!data || !data.pid) {
// throw new Error('[[error:invalid-data]]');
// }
// return await apiPosts.endorse(socket, { pid: data.pid });
// };

SocketPosts.endorse = async function (socket, data) {
if (!data || !data.pid) {
throw new Error('[[error:invalid-data]]');
console.log("VICKY8 Socket handshake query: ", socket.handshake.query);
const uid = socket.handshake.query.uid;
if (!uid || !data || !data.pid ) {
throw new Error('[error:invalid-data');
}
return await apiPosts.endorse(socket, { pid: data.pid });
};
return await apiPosts.endorse({ uid }, { pid: data.pid });
}

SocketPosts.unendorse = async function (socket, data) {
if (!data || !data.pid) {
Expand Down
6 changes: 5 additions & 1 deletion test/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ helpers.logoutUser = async function (jar) {
return { response, body };
};

helpers.connectSocketIO = function (res, csrf_token) {
helpers.connectSocketIO = function (res, csrf_token, uid) {
console.log("VICKY7 UID passed to connectSocketIO", uid);

const io = require('socket.io-client');
const cookie = res.headers['set-cookie'];

const socket = io(nconf.get('base_url'), {
path: `${nconf.get('relative_path')}/socket.io`,
extraHeaders: {
Expand All @@ -70,6 +73,7 @@ helpers.connectSocketIO = function (res, csrf_token) {
},
query: {
_csrf: csrf_token,
uid: uid
},
});
return new Promise((resolve, reject) => {
Expand Down
95 changes: 74 additions & 21 deletions test/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,33 +133,86 @@ describe('Post\'s', () => {
});

describe('endorsing and unendorsing', function () {
let testPid;
let testUid;
let adminUid;
let globalModUid;
let regularUserUid;
let postResult;

before(async () => {
testUid = await user.create({ username: 'endorser' });
const postResult = await topics.post({
uid: testUid,
cid: cid,
title: 'test topic for endorsement feature',
content: 'endorsement topic content',
});
testPid = postResult.postData.pid;
// adminUid = await user.create({ username: 'admin' });
// await groups.join('administrators', adminUid);

adminUid = await user.create({ username: 'admin', password: '123456' });
console.log("Admin UID VICKY9:", adminUid);
await groups.join('administrators', adminUid);

globalModUid = await user.create({ username: 'global mod' });
await groups.join('Global Moderators', globalModUid);

regularUserUid = await user.create({ username: 'regular user' });

({ cid } = await categories.create({
name: 'test endorsement category',
description: 'category for testing endorsements',
}));

postResult = await topics.post({
uid: regularUserUid,
cid: cid,
title: 'test topic for endorsement feature',
content: 'endorsement topic content',
});
});

it('should mark post as endorsed', async function () {
const caller = { uid: testUid };
const data = { pid: testPid };
const result = await apiPosts.endorse(caller, data);
assert.strictEqual(result.isEndorsed, true);
// it('should allow an admin to endorse a post', async function () {
// console.log("VICKY10", postResult.postData.pid, adminUid)
// const result = await apiPosts.endorse(postResult.postData.pid, adminUid);
// console.log("VICKYC11 Endorsement result:", result);
// assert.strictEqual(result.isEndorsed, true);
// });

it('should allow an admin to endorse a post', async function () {
try {
console.log("VICKY10", postResult.postData.pid, adminUid);
const result = await apiPosts.endorse(postResult.postData.pid, adminUid);
console.log("Endorsement result:", result); // This will log the result if it works
assert.strictEqual(result.isEndorsed, true);
} catch (err) {
console.error("Endorsement failed with error:", err); // This will log the actual error
}
});

it('should allow a global mod to endorse a post', async function () {
const result = await apiPosts.endorse(postResult.postData.pid, globalModUid);
assert.strictEqual(result.isEndorsed, true);
});

it('should change post to unendorsed', async function () {
await apiPosts.endorse({ uid: testUid }, { pid: testPid });
const caller = { uid: testUid };
const data = { pid: testPid };
const result = await apiPosts.unendorse(caller, data);
assert.strictEqual(result.isEndorsed, false);
it('should not allow a regular user to endorse a post', async () => {
try {
await apiPosts.endorse(postResult.postData.pid, regularUserUid);
assert.fail('Regular user should not be able to endorse a post');
} catch (err) {
assert.strictEqual(err.message, '[[error:permission-denied]]');
}
});

it('should allow an admin to unendorse a post', async () => {
const result = await apiPosts.unendorse(postResult.postData.pid, adminUid);
assert.strictEqual(result.isEndorsed, false);
});

it('should allow a global mod to unendorse a post', async () => {
const result = await apiPosts.unendorse(postResult.postData.pid, globalModUid);
assert.strictEqual(result.isEndorsed, false);
});

it('should not allow a regular user to unendorse a post', async function () {
try {
await apiPosts.unendorse(postResult.postData.pid, regularUserUid);
assert.fail('Regular user should not be able to unendorse a post');
} catch (err) {
assert.strictEqual(err.message, '[[error:permission-denied]]');
}
});
});

Expand Down
7 changes: 6 additions & 1 deletion test/socket.io.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ describe('socket.io', () => {

it('should connect and auth properly', async () => {
const { response, csrf_token } = await helpers.loginUser('admin', 'adminpwd');
io = await helpers.connectSocketIO(response, csrf_token);
console.log("VICKY5 Login response object: ", response);

const uid = response.user?.uid || 'No UID';
console.log("VICKY6 Retrieved UID: ", uid);

io = await helpers.connectSocketIO(response, csrf_token, uid);
assert(io);
assert(io.emit);
});
Expand Down