From ccfece614200e4467f11383466b1211997d0f978 Mon Sep 17 00:00:00 2001 From: Christian Hofmaier Date: Sun, 14 Jun 2020 04:04:52 +0000 Subject: [permissionmanager] add new function to get allowed childs only get allowed childs of given ids for given permission --- server/lib/grouphelper.js | 2 +- server/lib/permissions/permissionhelper.js | 83 ++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) (limited to 'server') diff --git a/server/lib/grouphelper.js b/server/lib/grouphelper.js index fe94b50..8139cd6 100644 --- a/server/lib/grouphelper.js +++ b/server/lib/grouphelper.js @@ -89,4 +89,4 @@ function _buildPaths (parentMap, group, knownIds = []) { return paths } -module.exports = { getAllChildren, addPathsToGroups, addPathsToClients } +module.exports = { getAllChildren, getAllChildrenByIds, addPathsToGroups, addPathsToClients } diff --git a/server/lib/permissions/permissionhelper.js b/server/lib/permissions/permissionhelper.js index 65f160d..7acf269 100644 --- a/server/lib/permissions/permissionhelper.js +++ b/server/lib/permissions/permissionhelper.js @@ -11,6 +11,7 @@ function exportFunctions (req, res, next) { req.user.hasPermissionForGroup = (permissionName, groupId) => hasPermissionForGroup(req.user.id, permissionName, groupId) req.user.getAllowedClients = permissionName => getAllowedClients(req.user.id, permissionName) req.user.hasPermissionForClient = (permissionName, clientId) => hasPermissionForClient(req.user.id, permissionName, clientId) + req.user.getAllowedChilds = (permissionName, groupIds) => getAllowedChilds(req.user.id, permissionName, groupIds) next() } @@ -248,3 +249,85 @@ async function checkParents (groupIds, whitelist, blacklist, knownGrps = []) { result = await checkParents(parentIds, whitelist, blacklist, knownGrps) return result } + +async function getAllowedChilds (userid, permissionName, groupIds) { + if (Number.isInteger(groupIds) && !Array.isArray(groupIds)) groupIds = [groupIds] + + var superAdmin = await isSuperadmin(userid) + if (superAdmin) return groupHelper.getAllChildrenByIds(groupIds, {}, {}) + + var user = await db.user.findOne({ + where: { id: userid, '$roles.permissions.name$': permissionName }, + include: [{ as: 'roles', model: db.role, include: ['permissions', 'groups'] }] + }) + + // User doesn't have the permission + if (user === null) return {} + + // User has permission, permission is not groupdependent + else if (!user.roles[0].permissions[0].groupdependent) return groupHelper.getAllChildrenByIds(groupIds, {}, {}) + + // User has permission, permission is groupdependent + else { + var subgroups = [] + var clients = [] + var groupList = [] + + for (let j = 0; j < groupIds.length; j++) { + if (await hasPermissionForGroup(userid, permissionName, groupIds[j])) groupList.push(groupIds[j]) + } + + var allChilds = await groupHelper.getAllChildrenByIds(groupIds, {}, {}) + + for (let i = 0; i < user.roles.length; i++) { + var roleWhitelist = [] + var roleBlacklistMap = {} + var roleGroupList = groupList + + for (let j = 0; j < user.roles[i].groups.length; j++) { + if (user.roles[i].groups[j].role_x_group.blacklist) { + roleBlacklistMap[user.roles[i].groups[j].id] = true + } else { + roleWhitelist.push(user.roles[i].groups[j]) + } + } + + // TODO: This is just overwhelming inefficient. Even if whitelist contains only a few ids, if the function is called for the root, allChilds are 18k+ ids. + for (let j = 0; j < roleWhitelist.length; j++) { + for (let k = 0; k < allChilds.subgroups.length; k++) { + if (allChilds.subgroups[k].id === roleWhitelist[j].id) { + roleGroupList.push(roleWhitelist[j].id) + subgroups = subgroups.concat(roleWhitelist[j]) + } + } + } + + var childs = await groupHelper.getAllChildrenByIds(roleGroupList, roleBlacklistMap, {}) + subgroups = subgroups.concat(childs.subgroups) + clients = clients.concat(childs.clients) + } + + // Filter result for unique entries + const filteredGroups = [] + const groupMap = new Map() + for (const item of subgroups) { + if (!groupMap.has(item.id)) { + groupMap.set(item.id, true) + filteredGroups.push(item) + } + } + subgroups = filteredGroups + + const filteredClients = [] + const clientMap = new Map() + for (const item of clients) { + if (!clientMap.has(item.id)) { + clientMap.set(item.id, true) + filteredClients.push(item) + } + } + clients = filteredClients + + return { subgroups, clients } + } +} -- cgit v1.2.3-55-g7522