From fa8fb88f822eaec2e6d16491485a2bd243fe42eb Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 22 Sep 2022 18:27:43 +0100 Subject: [PATCH] Updating a few core endpoints to better integrate the groups system and make sure users always have the correct role ID updated onto them. --- packages/backend-core/src/security/roles.js | 20 +++++++++++++++++-- packages/server/src/middleware/authorized.ts | 4 ++-- packages/server/src/utilities/global.js | 7 ++++--- .../worker/src/api/controllers/global/self.ts | 5 ++++- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/packages/backend-core/src/security/roles.js b/packages/backend-core/src/security/roles.js index 983aebf676..33c9123b63 100644 --- a/packages/backend-core/src/security/roles.js +++ b/packages/backend-core/src/security/roles.js @@ -78,7 +78,7 @@ function isBuiltin(role) { */ exports.builtinRoleToNumber = id => { const builtins = exports.getBuiltinRoles() - const MAX = Object.values(BUILTIN_IDS).length + 1 + const MAX = Object.values(builtins).length + 1 if (id === BUILTIN_IDS.ADMIN || id === BUILTIN_IDS.BUILDER) { return MAX } @@ -94,6 +94,22 @@ exports.builtinRoleToNumber = id => { return count } +/** + * Converts any role to a number, but has to be async to get the roles from db. + */ +exports.roleToNumber = async id => { + if (exports.isBuiltin(id)) { + return exports.builtinRoleToNumber(id) + } + const hierarchy = await exports.getUserRoleHierarchy(id) + for (let role of hierarchy) { + if (isBuiltin(role.inherits)) { + return exports.builtinRoleToNumber(role.inherits) + 1 + } + } + return 0 +} + /** * Returns whichever builtin roleID is lower. */ @@ -172,7 +188,7 @@ async function getAllUserRoles(userRoleId) { * to determine if a user can access something that requires a specific role. * @param {string} userRoleId The user's role ID, this can be found in their access token. * @param {object} opts Various options, such as whether to only retrieve the IDs (default true). - * @returns {Promise} returns an ordered array of the roles, with the first being their + * @returns {Promise} returns an ordered array of the roles, with the first being their * highest level of access and the last being the lowest level. */ exports.getUserRoleHierarchy = async (userRoleId, opts = { idOnly: true }) => { diff --git a/packages/server/src/middleware/authorized.ts b/packages/server/src/middleware/authorized.ts index 298a50988a..1fa983a72a 100644 --- a/packages/server/src/middleware/authorized.ts +++ b/packages/server/src/middleware/authorized.ts @@ -52,9 +52,9 @@ const checkAuthorizedResource = async ( ) => { // get the user's roles const roleId = ctx.roleId || BUILTIN_ROLE_IDS.PUBLIC - const userRoles = await getUserRoleHierarchy(roleId, { + const userRoles = (await getUserRoleHierarchy(roleId, { idOnly: false, - }) + })) as { _id: string }[] const permError = "User does not have permission" // check if the user has the required role if (resourceRoles.length > 0) { diff --git a/packages/server/src/utilities/global.js b/packages/server/src/utilities/global.js index 462ef6ba5d..3a2c7dff41 100644 --- a/packages/server/src/utilities/global.js +++ b/packages/server/src/utilities/global.js @@ -43,9 +43,10 @@ exports.updateAppRole = (user, { appId } = {}) => { } async function checkGroupRoles(user, { appId } = {}) { - let roleId = await groups.getGroupRoleId(user, appId) - user.roleId = roleId - + if (user.roleId && user.roleId !== BUILTIN_ROLE_IDS.PUBLIC) { + return user + } + user.roleId = await groups.getGroupRoleId(user, appId) return user } diff --git a/packages/worker/src/api/controllers/global/self.ts b/packages/worker/src/api/controllers/global/self.ts index 6376e0e395..5a36ed5540 100644 --- a/packages/worker/src/api/controllers/global/self.ts +++ b/packages/worker/src/api/controllers/global/self.ts @@ -10,6 +10,8 @@ import { encryption, } from "@budibase/backend-core" import env from "../../../environment" +import { groups } from "@budibase/pro" +import { enrichUserRolesFromGroups } from "../../../../../../../budibase-pro/packages/pro/src/sdk/groups" const { hash, platformLogout, getCookie, clearCookie, newid } = utils const { user: userCache } = cache @@ -115,7 +117,8 @@ export async function getSelf(ctx: any) { checkCurrentApp(ctx) // get the main body of the user - ctx.body = await users.getUser(userId) + const user = await users.getUser(userId) + ctx.body = await groups.enrichUserRolesFromGroups(user) // add the feature flags for this tenant const tenantId = tenancy.getTenantId()