feat: patch low-level privilege query calls to accept privilege masks at the cid level

This commit is contained in:
Julian Lam
2025-12-02 13:18:15 -05:00
parent 76b6b3b259
commit 4020e1be35

View File

@@ -4,6 +4,7 @@
const _ = require('lodash'); const _ = require('lodash');
const validator = require('validator'); const validator = require('validator');
const db = require('../database');
const groups = require('../groups'); const groups = require('../groups');
const user = require('../user'); const user = require('../user');
const categories = require('../categories'); const categories = require('../categories');
@@ -25,16 +26,25 @@ helpers.isUsersAllowedTo = async function (privilege, uids, cid) {
cid = -1; cid = -1;
} }
const [hasUserPrivilege, hasGroupPrivilege] = await Promise.all([ let allowed;
groups.isMembers(uids, `cid:${cid}:privileges:${privilege}`), const masked = db.isSetMember(`cid:${cid}:privilegeMask`, privilege);
groups.isMembersOfGroupList(uids, `cid:${cid}:privileges:groups:${privilege}`), if (!masked) {
]); const [hasUserPrivilege, hasGroupPrivilege] = await Promise.all([
const allowed = uids.map((uid, index) => hasUserPrivilege[index] || hasGroupPrivilege[index]); groups.isMembers(uids, `cid:${cid}:privileges:${privilege}`),
const result = await plugins.hooks.fire('filter:privileges:isUsersAllowedTo', { allowed: allowed, privilege: privilege, uids: uids, cid: cid }); groups.isMembersOfGroupList(uids, `cid:${cid}:privileges:groups:${privilege}`),
]);
allowed = uids.map((uid, index) => hasUserPrivilege[index] || hasGroupPrivilege[index]);
} else {
allowed = uids.map(() => false);
}
const result = await plugins.hooks.fire('filter:privileges:isUsersAllowedTo', { allowed, privilege, uids, cid });
return result.allowed; return result.allowed;
}; };
helpers.isAllowedTo = async function (privilege, uidOrGroupName, cid) { helpers.isAllowedTo = async function (privilege, uidOrGroupName, cid) {
const _cid = cid; // original passed-in cid needed for privilege mask checks
// Remote categories (non-numeric) inherit world privileges // Remote categories (non-numeric) inherit world privileges
if (Array.isArray(cid)) { if (Array.isArray(cid)) {
cid = cid.map(cid => (utils.isNumber(cid) ? cid : -1)); cid = cid.map(cid => (utils.isNumber(cid) ? cid : -1));
@@ -44,10 +54,15 @@ helpers.isAllowedTo = async function (privilege, uidOrGroupName, cid) {
let allowed; let allowed;
if (Array.isArray(privilege) && !Array.isArray(cid)) { if (Array.isArray(privilege) && !Array.isArray(cid)) {
const mask = await db.isSetMembers(`cid:${_cid}:privilegeMask`, privilege);
allowed = await isAllowedToPrivileges(privilege, uidOrGroupName, cid); allowed = await isAllowedToPrivileges(privilege, uidOrGroupName, cid);
allowed = allowed.map((allowed, idx) => mask[idx] ? false : allowed);
} else if (Array.isArray(cid) && !Array.isArray(privilege)) { } else if (Array.isArray(cid) && !Array.isArray(privilege)) {
const mask = await db.isMemberOfSets(_cid.map(cid => `cid:${cid}:privilegeMask`), privilege);
allowed = await isAllowedToCids(privilege, uidOrGroupName, cid); allowed = await isAllowedToCids(privilege, uidOrGroupName, cid);
allowed = allowed.map((allowed, idx) => mask[idx] ? false : allowed);
} }
if (allowed) { if (allowed) {
({ allowed } = await plugins.hooks.fire('filter:privileges:isAllowedTo', { allowed: allowed, privilege: privilege, uid: uidOrGroupName, cid: cid })); ({ allowed } = await plugins.hooks.fire('filter:privileges:isAllowedTo', { allowed: allowed, privilege: privilege, uid: uidOrGroupName, cid: cid }));
return allowed; return allowed;