From 28b769b18f427fbaf1c5b3c7fb6d7b5f1302ca3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20J=C3=A4gle?= Date: Sun, 19 Nov 2017 10:20:57 +0100 Subject: [PATCH] Implicitly assign and revoke setting group permissions --- .../server/methods/addPermissionToRole.js | 11 ++++++++ .../methods/removeRoleFromPermission.js | 18 ++++++++++++- .../server/publications/permissions.js | 19 ++++++++++--- .../server/startup.js | 27 ++++++++++++++----- 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/packages/rocketchat-authorization/server/methods/addPermissionToRole.js b/packages/rocketchat-authorization/server/methods/addPermissionToRole.js index bae94f4d3dc8..9fe4a94f2144 100644 --- a/packages/rocketchat-authorization/server/methods/addPermissionToRole.js +++ b/packages/rocketchat-authorization/server/methods/addPermissionToRole.js @@ -7,6 +7,17 @@ Meteor.methods({ }); } + const addParentPermissions = function(permissionId, role) { + const permission = RocketChat.models.Permissions.findOneById(permissionId); + if (permission.groupPermissionId) { + const groupPermission = RocketChat.models.Permissions.findOneById(permission.groupPermissionId); + if (groupPermission.roles.indexOf(role) === -1) { + RocketChat.models.Permissions.addRole(permission.groupPermissionId, role); + } + } + }; + + addParentPermissions(permission, role); return RocketChat.models.Permissions.addRole(permission, role); } }); diff --git a/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.js b/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.js index 0602d1e3437b..b48f9752d9f4 100644 --- a/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.js +++ b/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.js @@ -7,6 +7,22 @@ Meteor.methods({ }); } - return RocketChat.models.Permissions.removeRole(permission, role); + const removeStaleParentPermissions = function(permissionId, role) { + const permission = RocketChat.models.Permissions.findOneById(permissionId); + if (permission.groupPermissionId) { + const groupPermission = RocketChat.models.Permissions.findOneById(permission.groupPermissionId); + if (groupPermission.roles.indexOf(role) !== -1) { + // the role has the group permission assigned, so check whether it's still needed + if (RocketChat.models.Permissions.find({ + groupPermissionId: permission.groupPermissionId, + roles: role + }).count() === 0) { + RocketChat.models.Permissions.removeRole(permission.groupPermissionId, role); + } + } + } + }; + RocketChat.models.Permissions.removeRole(permission, role); + removeStaleParentPermissions(permission, role); } }); diff --git a/packages/rocketchat-authorization/server/publications/permissions.js b/packages/rocketchat-authorization/server/publications/permissions.js index b6f9fe094794..a18e3faff476 100644 --- a/packages/rocketchat-authorization/server/publications/permissions.js +++ b/packages/rocketchat-authorization/server/publications/permissions.js @@ -11,7 +11,12 @@ Meteor.methods({ update: records.filter((record) => { return record._updatedAt > updatedAt; }), - remove: RocketChat.models.Permissions.trashFindDeletedAfter(updatedAt, {}, {fields: {_id: 1, _deletedAt: 1}}).fetch() + remove: RocketChat.models.Permissions.trashFindDeletedAfter(updatedAt, {}, { + fields: { + _id: 1, + _deletedAt: 1 + } + }).fetch() }; } @@ -20,14 +25,22 @@ Meteor.methods({ 'setting-permissions/get'(updatedAt) { this.unblock(); - const records = RocketChat.models.Permissions.find({level: permissionLevel.SETTING}).fetch(); + const records = RocketChat.models.Permissions.find({ + level: permissionLevel.SETTING, + groupPermissionId: {$exists: true} //filter group permissions themselves, as they are being assigned implicitly + }).fetch(); if (updatedAt instanceof Date) { return { update: records.filter((record) => { return record._updatedAt > updatedAt; }), - remove: RocketChat.models.Permissions.trashFindDeletedAfter(updatedAt, {}, {fields: {_id: 1, _deletedAt: 1}}).fetch() + remove: RocketChat.models.Permissions.trashFindDeletedAfter(updatedAt, {}, { + fields: { + _id: 1, + _deletedAt: 1 + } + }).fetch() }; } diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index fe3b3e110fb5..958f7c5b8217 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -104,20 +104,35 @@ Meteor.startup(function() { return `change-setting-${ settingId }`; }; - const obsoleteSettingPermissions = {}; + const previousSettingPermissions = {}; RocketChat.models.Permissions.find({level: permissionLevel.SETTING}).fetch().forEach( function(permission) { - obsoleteSettingPermissions[permission._id] = permission; + previousSettingPermissions[permission._id] = permission; }); RocketChat.models.Settings.findNotHidden().fetch().forEach((setting) => { const permissionId = getSettingPermissionId(setting._id); - const permission = {_id: permissionId, level: permissionLevel.SETTING}; + const permission = { + _id: permissionId, + level: permissionLevel.SETTING + }; + // copy previously assigned roles if available + if (previousSettingPermissions[permissionId] && previousSettingPermissions[permissionId].roles) { + permission.roles = previousSettingPermissions[permissionId].roles; + } else { + permission.roles = []; + } + if (setting.group) { + permission.groupPermissionId = getSettingPermissionId(setting.group); + } + if (setting.section) { + permission.sectionPermissionId = getSettingPermissionId(setting.section); + } RocketChat.models.Permissions.upsert(permission._id, {$set: permission}); - delete obsoleteSettingPermissions[permissionId]; + delete previousSettingPermissions[permissionId]; }); - for (const obsoletePermission in obsoleteSettingPermissions) { - if (obsoleteSettingPermissions.hasOwnProperty(obsoletePermission)) { + for (const obsoletePermission in previousSettingPermissions) { + if (previousSettingPermissions.hasOwnProperty(obsoletePermission)) { RocketChat.models.Permissions.remove({_id: obsoletePermission}); SystemLogger.info('Removed permission', obsoletePermission); }