diff --git a/packages/rocketchat-authorization/client/hasPermission.js b/packages/rocketchat-authorization/client/hasPermission.js index 134a014e34a4..f4c361d2fb3a 100644 --- a/packages/rocketchat-authorization/client/hasPermission.js +++ b/packages/rocketchat-authorization/client/hasPermission.js @@ -1,8 +1,8 @@ -/* globals ChatPermissions */ +/* globals ChatPermissions, SettingPermissions */ function atLeastOne(permissions = [], scope) { return permissions.some((permissionId) => { - const permission = ChatPermissions.findOne(permissionId); + const permission = ChatPermissions.findOne(permissionId) || SettingPermissions.findOne(permissionId); const roles = (permission && permission.roles) || []; return roles.some((roleName) => { @@ -17,7 +17,7 @@ function atLeastOne(permissions = [], scope) { function all(permissions = [], scope) { return permissions.every((permissionId) => { - const permission = ChatPermissions.findOne(permissionId); + const permission = ChatPermissions.findOne(permissionId) || SettingPermissions.findOne(permissionId); const roles = (permission && permission.roles) || []; return roles.some((roleName) => { diff --git a/packages/rocketchat-authorization/client/lib/SettingPermissions.js b/packages/rocketchat-authorization/client/lib/SettingPermissions.js index 1ae099a28c64..cbe5c12dfa1a 100644 --- a/packages/rocketchat-authorization/client/lib/SettingPermissions.js +++ b/packages/rocketchat-authorization/client/lib/SettingPermissions.js @@ -1,8 +1,8 @@ -RocketChat.authz.settingCachedCollectiong = new RocketChat.CachedCollection({ +RocketChat.authz.settingCachedCollection = new RocketChat.CachedCollection({ name: 'setting-permissions', eventType: 'onLogged', userRelated: false }); -RocketChat.authz.settingCachedCollectiong.init(); +RocketChat.authz.settingCachedCollection.init(); -this.SettingPermissions = RocketChat.authz.settingCachedCollectiong.collection; +this.SettingPermissions = RocketChat.authz.settingCachedCollection.collection; diff --git a/packages/rocketchat-authorization/server/publications/permissions.js b/packages/rocketchat-authorization/server/publications/permissions.js index d37246a1e403..8f57302455fe 100644 --- a/packages/rocketchat-authorization/server/publications/permissions.js +++ b/packages/rocketchat-authorization/server/publications/permissions.js @@ -48,21 +48,19 @@ Meteor.methods({ } }); -function notifySettings(type, permission) { - if (permission.level === permissionLevel.SETTING) { - // if the permission changes, the effect on the visible settings depends on the role affected. - // The selected-settings-based consumers have to react accordingly and either add or remove the - // setting from the user's collection - const setting = RocketChat.models.Settings.findOneById(permission.settingId); - RocketChat.Notifications.notifyLoggedInThisInstance('private-settings-changed', 'auth', setting); - } +function notifyPermissionSettingsChanged(type, permission) { + // if the permission changes, the effect on the visible settings depends on the role affected. + // The selected-settings-based consumers have to react accordingly and either add or remove the + // setting from the user's collection + const setting = RocketChat.models.Settings.findOneById(permission.settingId); + RocketChat.Notifications.notifyLoggedInThisInstance('private-settings-changed', 'auth', setting); + RocketChat.Notifications.notifyLoggedInThisInstance('setting-permissions-changed', type, permission); } RocketChat.models.Permissions.on('changed', (type, permission) => { - RocketChat.Notifications.notifyLoggedInThisInstance('permissions-changed', type, permission); - notifySettings(type, permission); -}); - -RocketChat.models.Permissions.on('removed', (type, permission) => { - notifySettings(type, permission); + if (permission.level && permission.level === permissionLevel.SETTING) { + notifyPermissionSettingsChanged(type, permission); + } else { + RocketChat.Notifications.notifyLoggedInThisInstance('permissions-changed', type, permission); + } }); diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index 85bce3bc4451..4537e1a4d096 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -99,18 +99,27 @@ Meteor.startup(function() { }); } - // for each setting, create a permission to allow just this one setting + // setting-based permissions const getSettingPermissionId = function(settingId) { return `change-setting-${ settingId }`; }; - const previousSettingPermissions = {}; - RocketChat.models.Permissions.find({level: permissionLevel.SETTING}).fetch().forEach( - function(permission) { - previousSettingPermissions[permission._id] = permission; - }); - RocketChat.models.Settings.findNotHidden().fetch().forEach((setting) => { + const getPreviousPermissions = function(settingId) { + const previousSettingPermissions = {}; + + const selector = {level: permissionLevel.SETTING}; + if (settingId) { + selector.settingId = settingId; + } + + RocketChat.models.Permissions.find(selector).fetch().forEach( + function(permission) { + previousSettingPermissions[permission._id] = permission; + }); + return previousSettingPermissions; + }; + const createSettingPermission = function(setting, previousSettingPermissions) { const permissionId = getSettingPermissionId(setting._id); const permission = { _id: permissionId, @@ -133,13 +142,33 @@ Meteor.startup(function() { } RocketChat.models.Permissions.upsert(permission._id, {$set: permission}); delete previousSettingPermissions[permissionId]; - }); + }; - for (const obsoletePermission in previousSettingPermissions) { - if (previousSettingPermissions.hasOwnProperty(obsoletePermission)) { - RocketChat.models.Permissions.remove({_id: obsoletePermission}); - SystemLogger.info('Removed permission', obsoletePermission); + const createPermissionsForExistingSettings = function() { + const previousSettingPermissions = getPreviousPermissions(); + + RocketChat.models.Settings.findNotHidden().fetch().forEach((setting) => { + createSettingPermission(setting, previousSettingPermissions); + }); + + // remove permissions for non-existent settings + for (const obsoletePermission in previousSettingPermissions) { + if (previousSettingPermissions.hasOwnProperty(obsoletePermission)) { + RocketChat.models.Permissions.remove({_id: obsoletePermission}); + SystemLogger.info('Removed permission', obsoletePermission); + } } - } + }; + + // for each setting which already exists, create a permission to allow changing just this one setting + createPermissionsForExistingSettings(); + + // register a callback for settings for be create in higher-level-packages + const createPermissionForAddedSetting = function(settingId) { + const previousSettingPermissions = getPreviousPermissions(settingId); + const setting = RocketChat.models.Settings.findOneNotHiddenById(settingId); + createSettingPermission(setting, previousSettingPermissions); + }; + RocketChat.settings.onload('*', createPermissionForAddedSetting); });