From 0713482bd414219ee4b51804102c7751ff2a4c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Mon, 30 Jan 2023 12:26:08 -0500 Subject: [PATCH] feat: #11240, only show relevant users in flags assignee list for user flags-> admins + all users who have `admin:users` privilege for post flags -> admins + global mods + moderators of the category the post is in refactor getModeratorUids function so it can be used for different privileges --- src/categories/index.js | 34 +--------------------------------- src/controllers/mods.js | 28 ++++++++++++++++++++++++++-- src/privileges/admin.js | 5 +++++ src/privileges/categories.js | 4 ++++ src/privileges/global.js | 5 +++++ src/privileges/helpers.js | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 76 insertions(+), 35 deletions(-) diff --git a/src/categories/index.js b/src/categories/index.js index 619f756642..027913ccd9 100644 --- a/src/categories/index.js +++ b/src/categories/index.js @@ -99,39 +99,7 @@ Categories.getModerators = async function (cid) { }; Categories.getModeratorUids = async function (cids) { - // Only check active categories - const disabled = (await Categories.getCategoriesFields(cids, ['disabled'])).map(obj => obj.disabled); - // cids = cids.filter((_, idx) => !disabled[idx]); - - const groupNames = cids.reduce((memo, cid) => { - memo.push(`cid:${cid}:privileges:moderate`); - memo.push(`cid:${cid}:privileges:groups:moderate`); - return memo; - }, []); - - const memberSets = await groups.getMembersOfGroups(groupNames); - // Every other set is actually a list of user groups, not uids, so convert those to members - const sets = memberSets.reduce((memo, set, idx) => { - if (idx % 2) { - memo.groupNames.push(set); - } else { - memo.uids.push(set); - } - - return memo; - }, { groupNames: [], uids: [] }); - - const uniqGroups = _.uniq(_.flatten(sets.groupNames)); - const groupUids = await groups.getMembersOfGroups(uniqGroups); - const map = _.zipObject(uniqGroups, groupUids); - const moderatorUids = cids.map((cid, index) => { - if (disabled[index]) { - return []; - } - - return _.uniq(sets.uids[index].concat(_.flatten(sets.groupNames[index].map(g => map[g])))); - }); - return moderatorUids; + return await privileges.categories.getUidsWithPrivilege(cids, 'moderate'); }; Categories.getCategories = async function (cids, uid) { diff --git a/src/controllers/mods.js b/src/controllers/mods.js index 48a3bd8ff3..3656146652 100644 --- a/src/controllers/mods.js +++ b/src/controllers/mods.js @@ -1,6 +1,9 @@ 'use strict'; +const _ = require('lodash'); + const user = require('../user'); +const groups = require('../groups'); const posts = require('../posts'); const flags = require('../flags'); const analytics = require('../analytics'); @@ -110,7 +113,6 @@ modsController.flags.detail = async function (req, res, next) { isAdminOrGlobalMod: user.isAdminOrGlobalMod(req.uid), moderatedCids: user.getModeratedCids(req.uid), flagData: flags.get(req.params.flagId), - assignees: user.getAdminsandGlobalModsandModerators(), privileges: Promise.all(['global', 'admin'].map(async type => privileges[type].get(req.uid))), }); results.privileges = { ...results.privileges[0], ...results.privileges[1] }; @@ -119,6 +121,28 @@ modsController.flags.detail = async function (req, res, next) { return next(); // 404 } + async function getAssignees(flagData) { + let uids = []; + const [admins, globalMods] = await Promise.all([ + groups.getMembers('administrators', 0, -1), + groups.getMembers('Global Moderators', 0, -1), + ]); + if (flagData.type === 'user') { + uids = await privileges.admin.getUidsWithPrivilege('admin:users'); + uids = _.uniq(admins.concat(uids)); + } else if (flagData.type === 'post') { + const cid = await posts.getCidByPid(flagData.targetId); + if (!cid) { + return []; + } + uids = (await privileges.categories.getUidsWithPrivilege([cid], 'moderate'))[0]; + uids = _.uniq(admins.concat(globalMods).concat(uids)); + } + const userData = await user.getUsersData(uids); + return userData.filter(u => u && u.userslug); + } + + const assignees = await getAssignees(results.flagData); results.flagData.history = results.isAdminOrGlobalMod ? (await flags.getHistory(req.params.flagId)) : null; if (results.flagData.type === 'user') { @@ -128,7 +152,7 @@ modsController.flags.detail = async function (req, res, next) { } res.render('flags/detail', Object.assign(results.flagData, { - assignees: results.assignees, + assignees: assignees, type_bool: ['post', 'user', 'empty'].reduce((memo, cur) => { if (cur !== 'empty') { memo[cur] = results.flagData.type === cur && ( diff --git a/src/privileges/admin.js b/src/privileges/admin.js index 166236ac76..e77d2e9982 100644 --- a/src/privileges/admin.js +++ b/src/privileges/admin.js @@ -211,3 +211,8 @@ privsAdmin.groupPrivileges = async function (groupName) { const groupPrivilegeList = await privsAdmin.getGroupPrivilegeList(); return await helpers.userOrGroupPrivileges(0, groupName, groupPrivilegeList); }; + +privsAdmin.getUidsWithPrivilege = async function (privilege) { + const uidsByCid = await helpers.getUidsWithPrivilege([0], privilege); + return uidsByCid[0]; +}; diff --git a/src/privileges/categories.js b/src/privileges/categories.js index 8abdd0b34f..76b9248bd2 100644 --- a/src/privileges/categories.js +++ b/src/privileges/categories.js @@ -218,3 +218,7 @@ privsCategories.groupPrivileges = async function (cid, groupName) { const groupPrivilegeList = await privsCategories.getGroupPrivilegeList(); return await helpers.userOrGroupPrivileges(cid, groupName, groupPrivilegeList); }; + +privsCategories.getUidsWithPrivilege = async function (cids, privilege) { + return await helpers.getUidsWithPrivilege(cids, privilege); +}; diff --git a/src/privileges/global.js b/src/privileges/global.js index 472448d4c4..3cfe50e522 100644 --- a/src/privileges/global.js +++ b/src/privileges/global.js @@ -134,3 +134,8 @@ privsGlobal.groupPrivileges = async function (groupName) { const groupPrivilegeList = await privsGlobal.getGroupPrivilegeList(); return await helpers.userOrGroupPrivileges(0, groupName, groupPrivilegeList); }; + +privsGlobal.getUidsWithPrivilege = async function (privilege) { + const uidsByCid = await helpers.getUidsWithPrivilege([0], privilege); + return uidsByCid[0]; +}; diff --git a/src/privileges/helpers.js b/src/privileges/helpers.js index e6a0266f67..b8c45dfdb3 100644 --- a/src/privileges/helpers.js +++ b/src/privileges/helpers.js @@ -6,6 +6,7 @@ const validator = require('validator'); const groups = require('../groups'); const user = require('../user'); +const categories = require('../categories'); const plugins = require('../plugins'); const translator = require('../translator'); @@ -189,4 +190,38 @@ helpers.userOrGroupPrivileges = async function (cid, uidOrGroup, privilegeList) return _.zipObject(privilegeList, isMembers); }; +helpers.getUidsWithPrivilege = async (cids, privilege) => { + const disabled = (await categories.getCategoriesFields(cids, ['disabled'])).map(obj => obj.disabled); + + const groupNames = cids.reduce((memo, cid) => { + memo.push(`cid:${cid}:privileges:${privilege}`); + memo.push(`cid:${cid}:privileges:groups:${privilege}`); + return memo; + }, []); + + const memberSets = await groups.getMembersOfGroups(groupNames); + // Every other set is actually a list of user groups, not uids, so convert those to members + const sets = memberSets.reduce((memo, set, idx) => { + if (idx % 2) { + memo.groupNames.push(set); + } else { + memo.uids.push(set); + } + + return memo; + }, { groupNames: [], uids: [] }); + + const uniqGroups = _.uniq(_.flatten(sets.groupNames)); + const groupUids = await groups.getMembersOfGroups(uniqGroups); + const map = _.zipObject(uniqGroups, groupUids); + const uidsByCid = cids.map((cid, index) => { + if (disabled[index]) { + return []; + } + + return _.uniq(sets.uids[index].concat(_.flatten(sets.groupNames[index].map(g => map[g])))); + }); + return uidsByCid; +}; + require('../promisify')(helpers);