diff --git a/server/core/auth.js b/server/core/auth.js index fb30c970..c92962e9 100644 --- a/server/core/auth.js +++ b/server/core/auth.js @@ -317,6 +317,49 @@ module.exports = { return true }, + /** + * Check if user can perform assignment to a group with elevated permissions + * + * @param {User} user + * @param {Array} groupIds + * @returns {Boolean} + */ + async checkAssignUserToGroupAccess(user, groupIds = []) { + if (!groupIds || groupIds.length < 1) { + return true + } + + const userPermissions = user.permissions ? user.permissions : user.getGlobalPermissions() + + // System Admin + if (userPermissions.includes('manage:system')) { + return true + } + + // Ensure basic user management permission + if (!userPermissions.some(p => ['write:users', 'manage:users', 'write:groups', 'manage:groups'].includes(p))) { + return false + } + + const groups = await WIKI.models.groups.query().whereIn('id', groupIds) + return !groups.some(grp => { + // Check for manage:system permission + if (grp.permissions.includes('manage:system') && !userPermissions.includes('manage:groups')) { + return false + } + + // Check for elevated permissions + if (grp.permissions.some(p => { + const permType = _.last(p.split(':')) + return ['users', 'groups', 'navigation', 'theme', 'api'].includes(permType) + }) && !(userPermissions.includes('write:groups') || userPermissions.includes('manage:groups'))) { + return false + } + + return true + }) + }, + /** * Check and apply Page Rule specificity * diff --git a/server/graph/resolvers/group.js b/server/graph/resolvers/group.js index 1e295979..68da2ffe 100644 --- a/server/graph/resolvers/group.js +++ b/server/graph/resolvers/group.js @@ -56,6 +56,14 @@ module.exports = { throw new gql.GraphQLError('You are not authorized to assign a user to this elevated group.') } + // Check assigned permissions for manage:groups + if ( + WIKI.auth.checkExclusiveAccess(req.user, ['manage:groups'], ['manage:system']) && + grp.permissions.some(p => _.last(p.split(':')) === 'system') + ) { + throw new gql.GraphQLError('You are not authorized to assign a user to a group with the manage:system permission.') + } + // Check for valid user const usr = await WIKI.models.users.query().findById(args.userId) if (!usr) { diff --git a/server/graph/resolvers/user.js b/server/graph/resolvers/user.js index a94aef8a..50a9d37d 100644 --- a/server/graph/resolvers/user.js +++ b/server/graph/resolvers/user.js @@ -62,8 +62,12 @@ module.exports = { } }, UserMutation: { - async create (obj, args) { + async create (obj, args, context) { try { + if (!(await WIKI.auth.checkAssignUserToGroupAccess(context.req.user, args.groups))) { + throw new Error('You are not authorized to assign a user to a group with elevated permissions.') + } + await WIKI.models.users.createNewUser(args) return { @@ -94,8 +98,12 @@ module.exports = { } } }, - async update (obj, args) { + async update (obj, args, context) { try { + if (!(await WIKI.auth.checkAssignUserToGroupAccess(context.req.user, args.groups))) { + throw new Error('You are not authorized to assign a user to a group with elevated permissions.') + } + await WIKI.models.users.updateUser(args) return {