From eed869ac9031c63f47c0ecea7d8ddfa9aa8440c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20J=C3=A4gle?= Date: Fri, 17 Nov 2017 18:28:14 +0100 Subject: [PATCH 01/20] Allow maintenance of per-setting permissions - first draft, not beautified yet --- package-lock.json | 12 +- package.json | 4 +- .../client/lib/SettingPermissions.js | 8 + .../client/views/permissions.html | 66 ++++--- .../client/views/permissions.js | 75 +++++--- .../lib/rocketchat.js | 4 + packages/rocketchat-authorization/package.js | 1 + .../server/publications/permissions.js | 21 ++- .../server/startup.js | 174 +++++++++++------- .../server/publications/settings.js | 30 +++ .../rocketchat-livechat/app/package-lock.json | 22 +-- packages/rocketchat-ui-admin/client/admin.js | 82 ++++++--- 12 files changed, 337 insertions(+), 162 deletions(-) create mode 100644 packages/rocketchat-authorization/client/lib/SettingPermissions.js diff --git a/package-lock.json b/package-lock.json index 9827c6fdf1d0..139e1f2264cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -327,7 +327,7 @@ "async": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "integrity": "sha1-hDGQ/WtzV6C54clW7d3V7IRitU0=", "requires": { "lodash": "4.17.4" } @@ -352,7 +352,7 @@ "autoprefixer": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.1.6.tgz", - "integrity": "sha512-C9yv/UF3X+eJTi/zvfxuyfxmLibYrntpF3qoJYrMeQwgUJOZrZvpJiMG2FMQ3qnhWtF/be4pYONBBw95ZGe3vA==", + "integrity": "sha1-+5MwOfdK90qD5xIlznjZ/Vi6hNc=", "dev": true, "requires": { "browserslist": "2.6.1", @@ -6927,7 +6927,7 @@ "postcss-custom-properties": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-6.2.0.tgz", - "integrity": "sha512-eNR2h9T9ciKMoQEORrPjH33XeN/nuvVuxArOKmHtsFbGbNss631tgTrKou3/pmjAZbA4QQkhLIkPQkIk3WW+8w==", + "integrity": "sha1-XZKafwbpuE4PETNBlMC6mjCs++k=", "dev": true, "requires": { "balanced-match": "1.0.0", @@ -6949,7 +6949,7 @@ "postcss-less": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-1.1.1.tgz", - "integrity": "sha512-zl0EEqq8Urh37Ppdv9zzhpZpLHrgkxmt6e3O4ftRa7/b8Uq2LV+/KBVM8/KuzmHNu+mthhOArg1lxbfqQ3NUdg==", + "integrity": "sha1-S9JA21F840B1g9knhYGE9QBF9Ks=", "dev": true, "requires": { "postcss": "5.2.18" @@ -7035,7 +7035,7 @@ "postcss-nesting": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-3.0.0.tgz", - "integrity": "sha512-ijQlEXUcYXXNPdLMFcMEr4i5SEPRKR8fq/Iya4L0mQbNOCz+szTGCBlf0Cvu2HiQLjCNqLnGO4fKFLbNnXe7Ag==", + "integrity": "sha1-sKdJ1+/xHSVQoE3qZCtpXXWC+x0=", "dev": true, "requires": { "postcss": "6.0.13" @@ -7562,7 +7562,7 @@ "retry-request": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-3.1.0.tgz", - "integrity": "sha512-jOwZQlWR/boHhbAfzfOoUn28EDDotW2A7YxV2o5mfBb07H0k/zZAgbxRcckW08GKl/aT0JtPk1NViuk2BfHqVg==", + "integrity": "sha1-+UjKF5JlemSryJoPrXJ90HtisNY=", "requires": { "request": "2.83.0", "through2": "2.0.3" diff --git a/package.json b/package.json index 06fc561dba30..8b92ce12e480 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,9 @@ "chat" ], "scripts": { - "start": "meteor npm i && meteor", + "start": "meteor npm i && meteor run", + "debug": "meteor run --inspect", + "debug-brk": "meteor run --inspect-brk", "lint": "eslint .", "lint-fix": "eslint . --fix", "stylelint": "stylelint packages/**/*.css", diff --git a/packages/rocketchat-authorization/client/lib/SettingPermissions.js b/packages/rocketchat-authorization/client/lib/SettingPermissions.js new file mode 100644 index 000000000000..1ae099a28c64 --- /dev/null +++ b/packages/rocketchat-authorization/client/lib/SettingPermissions.js @@ -0,0 +1,8 @@ +RocketChat.authz.settingCachedCollectiong = new RocketChat.CachedCollection({ + name: 'setting-permissions', + eventType: 'onLogged', + userRelated: false +}); +RocketChat.authz.settingCachedCollectiong.init(); + +this.SettingPermissions = RocketChat.authz.settingCachedCollectiong.collection; diff --git a/packages/rocketchat-authorization/client/views/permissions.html b/packages/rocketchat-authorization/client/views/permissions.html index e0e47d6b426d..8f88f6e3948d 100644 --- a/packages/rocketchat-authorization/client/views/permissions.html +++ b/packages/rocketchat-authorization/client/views/permissions.html @@ -1,34 +1,46 @@ + diff --git a/packages/rocketchat-authorization/client/views/permissions.js b/packages/rocketchat-authorization/client/views/permissions.js index a7ef073d520e..49ed36dfac48 100644 --- a/packages/rocketchat-authorization/client/views/permissions.js +++ b/packages/rocketchat-authorization/client/views/permissions.js @@ -1,4 +1,6 @@ /* globals ChatPermissions, SettingPermissions */ +import {permissionLevel} from '../../lib/rocketchat'; + Template.permissions.helpers({ roles() { return Template.instance().roles.get(); @@ -54,7 +56,7 @@ Template.permissionsTable.helpers({ }, permissionName(permission) { - return t(permission._id); + return permission.level === permissionLevel.SETTING ? t(permission.settingId) : t(permission._id); }, permissionDescription(permission) { diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index 958f7c5b8217..db32471cc2ce 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -113,7 +113,8 @@ Meteor.startup(function() { const permissionId = getSettingPermissionId(setting._id); const permission = { _id: permissionId, - level: permissionLevel.SETTING + level: permissionLevel.SETTING, + settingId: setting._id }; // copy previously assigned roles if available if (previousSettingPermissions[permissionId] && previousSettingPermissions[permissionId].roles) { diff --git a/packages/rocketchat-ui-admin/client/admin.html b/packages/rocketchat-ui-admin/client/admin.html index b47e6e83cf5f..a63acd6c93c6 100644 --- a/packages/rocketchat-ui-admin/client/admin.html +++ b/packages/rocketchat-ui-admin/client/admin.html @@ -23,7 +23,7 @@

{{description}}

{{/if}} -
+
{{#each sections}}
{{#if section}} From c87a30d3afc0f03553bcf6183d7ad68fe3287d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20J=C3=A4gle?= Date: Sun, 19 Nov 2017 20:20:05 +0100 Subject: [PATCH 04/20] Add path to permission title --- .../client/views/permissions.js | 14 +++++++++++++- .../server/publications/permissions.js | 2 +- .../rocketchat-authorization/server/startup.js | 4 +++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/rocketchat-authorization/client/views/permissions.js b/packages/rocketchat-authorization/client/views/permissions.js index 49ed36dfac48..bd33ff69ec5c 100644 --- a/packages/rocketchat-authorization/client/views/permissions.js +++ b/packages/rocketchat-authorization/client/views/permissions.js @@ -56,7 +56,19 @@ Template.permissionsTable.helpers({ }, permissionName(permission) { - return permission.level === permissionLevel.SETTING ? t(permission.settingId) : t(permission._id); + if (permission.level === permissionLevel.SETTING) { + let path = ''; + if (permission.group) { + path = `${ t(permission.group) } > `; + } + if (permission.section) { + path = `${ path }${ t(permission.section) } > `; + } + path = `${ path }${ t(permission.settingId) }`; + return path; + } else { + return t(permission._id); + } }, permissionDescription(permission) { diff --git a/packages/rocketchat-authorization/server/publications/permissions.js b/packages/rocketchat-authorization/server/publications/permissions.js index a18e3faff476..1c967cfa7619 100644 --- a/packages/rocketchat-authorization/server/publications/permissions.js +++ b/packages/rocketchat-authorization/server/publications/permissions.js @@ -28,7 +28,7 @@ Meteor.methods({ const records = RocketChat.models.Permissions.find({ level: permissionLevel.SETTING, groupPermissionId: {$exists: true} //filter group permissions themselves, as they are being assigned implicitly - }).fetch(); + }, {}, {sort:{group: 1, section: 1}}).fetch(); if (updatedAt instanceof Date) { return { diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index db32471cc2ce..23ad9738708c 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -114,7 +114,9 @@ Meteor.startup(function() { const permission = { _id: permissionId, level: permissionLevel.SETTING, - settingId: setting._id + settingId: setting._id, + group: setting.group, + section: setting.section }; // copy previously assigned roles if available if (previousSettingPermissions[permissionId] && previousSettingPermissions[permissionId].roles) { From 48b107602d02e5f81c2189b068f9c7cba594c90f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20J=C3=A4gle?= Date: Mon, 20 Nov 2017 08:22:50 +0100 Subject: [PATCH 05/20] Permission to access setting permissions --- .../client/views/permissions.html | 44 ++++++++++--------- .../client/views/permissions.js | 4 ++ .../server/methods/addPermissionToRole.js | 7 ++- .../methods/removeRoleFromPermission.js | 8 +++- .../server/publications/permissions.js | 2 +- .../server/startup.js | 1 + packages/rocketchat-i18n/i18n/de.i18n.json | 2 + packages/rocketchat-i18n/i18n/en.i18n.json | 2 + 8 files changed, 47 insertions(+), 23 deletions(-) diff --git a/packages/rocketchat-authorization/client/views/permissions.html b/packages/rocketchat-authorization/client/views/permissions.html index b7382df1ac2f..5bdaf31c4328 100644 --- a/packages/rocketchat-authorization/client/views/permissions.html +++ b/packages/rocketchat-authorization/client/views/permissions.html @@ -41,29 +41,33 @@ {{> permissionsTable permissions=permissions allRoles=roles}}
-
-
-
-
- {{_ "setting-permissions"}}
-
- + {{#if hasSettingPermission}} +
+
+
+
+ {{_ "Setting_permissions"}}
+
+ +
+
+
+ {{#if settingPermissionExpanded }} + {{> permissionsTable permissions=settingPermissions allRoles=roles}} + {{else}} + {{_ "Not_authorized"}} + {{/if}}
-
-
- {{#if settingPermissionExpanded }} - {{> permissionsTable permissions=settingPermissions allRoles=roles}} - {{/if}}
-
+ {{/if}} {{else}} {{_ "Not_authorized"}} {{/if}} diff --git a/packages/rocketchat-authorization/client/views/permissions.js b/packages/rocketchat-authorization/client/views/permissions.js index bd33ff69ec5c..143c253d8787 100644 --- a/packages/rocketchat-authorization/client/views/permissions.js +++ b/packages/rocketchat-authorization/client/views/permissions.js @@ -26,6 +26,10 @@ Template.permissions.helpers({ return RocketChat.authz.hasAllPermission('access-permissions'); }, + hasSettingPermission() { + return RocketChat.authz.hasAllPermission('access-setting-permissions'); + }, + settingPermissionExpanded() { return Template.instance().settingPermissionsExpanded.get(); } diff --git a/packages/rocketchat-authorization/server/methods/addPermissionToRole.js b/packages/rocketchat-authorization/server/methods/addPermissionToRole.js index 9fe4a94f2144..e2d2e85c2a9b 100644 --- a/packages/rocketchat-authorization/server/methods/addPermissionToRole.js +++ b/packages/rocketchat-authorization/server/methods/addPermissionToRole.js @@ -1,12 +1,17 @@ +import {permissionLevel} from '../../lib/rocketchat'; + Meteor.methods({ 'authorization:addPermissionToRole'(permission, role) { - if (!Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'access-permissions')) { + if (!Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'access-permissions') + || (permission.level === permissionLevel.SETTING && !RocketChat.authz.hasPermission(Meteor.userId(), 'access-setting-permissions')) + ) { throw new Meteor.Error('error-action-not-allowed', 'Adding permission is not allowed', { method: 'authorization:addPermissionToRole', action: 'Adding_permission' }); } + // for setting-based-permissions, authorize the group access as well const addParentPermissions = function(permissionId, role) { const permission = RocketChat.models.Permissions.findOneById(permissionId); if (permission.groupPermissionId) { diff --git a/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.js b/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.js index b48f9752d9f4..d9c828bba5fb 100644 --- a/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.js +++ b/packages/rocketchat-authorization/server/methods/removeRoleFromPermission.js @@ -1,12 +1,18 @@ +import {permissionLevel} from '../../lib/rocketchat'; + Meteor.methods({ 'authorization:removeRoleFromPermission'(permission, role) { - if (!Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'access-permissions')) { + if (!Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'access-permissions') + || (permission.level === permissionLevel.SETTING && !RocketChat.authz.hasPermission(Meteor.userId(), 'access-setting-permissions')) + ) { throw new Meteor.Error('error-action-not-allowed', 'Accessing permissions is not allowed', { method: 'authorization:removeRoleFromPermission', action: 'Accessing_permissions' }); } + // for setting based permissions, revoke the group permission once all setting permissions + // related to this group have been removed const removeStaleParentPermissions = function(permissionId, role) { const permission = RocketChat.models.Permissions.findOneById(permissionId); if (permission.groupPermissionId) { diff --git a/packages/rocketchat-authorization/server/publications/permissions.js b/packages/rocketchat-authorization/server/publications/permissions.js index 1c967cfa7619..5963b532a048 100644 --- a/packages/rocketchat-authorization/server/publications/permissions.js +++ b/packages/rocketchat-authorization/server/publications/permissions.js @@ -28,7 +28,7 @@ Meteor.methods({ const records = RocketChat.models.Permissions.find({ level: permissionLevel.SETTING, groupPermissionId: {$exists: true} //filter group permissions themselves, as they are being assigned implicitly - }, {}, {sort:{group: 1, section: 1}}).fetch(); + }, {}, {sort: {group: 1, section: 1}}).fetch(); if (updatedAt instanceof Date) { return { diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index 23ad9738708c..f8e23016b3cd 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -10,6 +10,7 @@ Meteor.startup(function() { // 2. admin, moderator, and user roles should not be deleted as they are referened in the code. const permissions = [ {_id: 'access-permissions', roles: ['admin']}, + {_id: 'access-setting-permissions', roles: ['admin']}, {_id: 'add-oauth-service', roles: ['admin']}, {_id: 'add-user-to-joined-room', roles: ['admin', 'owner', 'moderator']}, {_id: 'add-user-to-any-c-room', roles: ['admin']}, diff --git a/packages/rocketchat-i18n/i18n/de.i18n.json b/packages/rocketchat-i18n/i18n/de.i18n.json index 1d5195f8380d..c3b0830d6c26 100644 --- a/packages/rocketchat-i18n/i18n/de.i18n.json +++ b/packages/rocketchat-i18n/i18n/de.i18n.json @@ -16,6 +16,7 @@ "access-mailer_description": "Berechtigung, Massen-E-Mails an alle Benutzer zu versenden.", "access-permissions": "Zugriff auf die Berechtigungs-Übersicht", "access-permissions_description": "Anpassen der Berechtigungen für die unterschiedlichen Rollen.", + "access-setting-permissions": "Zugriff die Übersicht der Einstellungs-Berechtigungen", "Access_not_authorized": "Der Zugriff ist nicht gestattet.", "Access_Token_URL": "URL des Access-Token", "Accessing_permissions": "Zugriff auf Berechtigungen", @@ -1573,6 +1574,7 @@ "Set_as_leader": "Zum Diskussionsleiter ernennen", "Set_as_moderator": "Zum Moderator ernennen", "Set_as_owner": "Zum Besitzer machen", + "Setting_permissions": "Berechtigung, Einstellungen zu ändern", "Settings": "Einstellungen", "Settings_updated": "Die Einstellungen wurden aktualisiert", "Share_Location_Title": "Standort teilen?", diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 823a77f35cc5..ed9539cbee2e 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -16,6 +16,7 @@ "access-mailer_description": "Permission to send mass email to all users.", "access-permissions": "Access Permissions Screen", "access-permissions_description": "Modify permissions for various roles.", + "access-setting-permissions": "Modify setting-based permissions", "Access_not_authorized": "Access not authorized", "Access_Token_URL": "Access Token URL", "Accessing_permissions": "Accessing permissions", @@ -1606,6 +1607,7 @@ "Set_as_leader": "Set as leader", "Set_as_moderator": "Set as moderator", "Set_as_owner": "Set as owner", + "Setting_permissions": "Permission to change settings", "Settings": "Settings", "Settings_updated": "Settings updated", "Share_Location_Title": "Share Location?", From daccad86fb17000346c4c631ea02ef30b352db81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20J=C3=A4gle?= Date: Mon, 20 Nov 2017 08:28:02 +0100 Subject: [PATCH 06/20] Adapt wording --- .../.npm/package/npm-shrinkwrap.json | 6 +++--- packages/rocketchat-i18n/i18n/de.i18n.json | 4 ++-- packages/rocketchat-i18n/i18n/en.i18n.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/rocketchat-google-vision/.npm/package/npm-shrinkwrap.json b/packages/rocketchat-google-vision/.npm/package/npm-shrinkwrap.json index 2b45ef4db29d..ff2d82be12c7 100644 --- a/packages/rocketchat-google-vision/.npm/package/npm-shrinkwrap.json +++ b/packages/rocketchat-google-vision/.npm/package/npm-shrinkwrap.json @@ -1124,9 +1124,9 @@ "integrity": "sha1-O0tCACOmbKfjK9uhbnEJN+FNGws=" }, "nan": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz", - "integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY=" + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=" }, "node-forge": { "version": "0.7.1", diff --git a/packages/rocketchat-i18n/i18n/de.i18n.json b/packages/rocketchat-i18n/i18n/de.i18n.json index c3b0830d6c26..9f4fd1827c4a 100644 --- a/packages/rocketchat-i18n/i18n/de.i18n.json +++ b/packages/rocketchat-i18n/i18n/de.i18n.json @@ -16,7 +16,7 @@ "access-mailer_description": "Berechtigung, Massen-E-Mails an alle Benutzer zu versenden.", "access-permissions": "Zugriff auf die Berechtigungs-Übersicht", "access-permissions_description": "Anpassen der Berechtigungen für die unterschiedlichen Rollen.", - "access-setting-permissions": "Zugriff die Übersicht der Einstellungs-Berechtigungen", + "access-setting-permissions": "Einstellungsbasierte Berechtigungen ändern", "Access_not_authorized": "Der Zugriff ist nicht gestattet.", "Access_Token_URL": "URL des Access-Token", "Accessing_permissions": "Zugriff auf Berechtigungen", @@ -1574,7 +1574,7 @@ "Set_as_leader": "Zum Diskussionsleiter ernennen", "Set_as_moderator": "Zum Moderator ernennen", "Set_as_owner": "Zum Besitzer machen", - "Setting_permissions": "Berechtigung, Einstellungen zu ändern", + "Setting_permissions": "Einstellungsbezogene Berechtigungen", "Settings": "Einstellungen", "Settings_updated": "Die Einstellungen wurden aktualisiert", "Share_Location_Title": "Standort teilen?", diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index ed9539cbee2e..dc9812d71c45 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -1607,7 +1607,7 @@ "Set_as_leader": "Set as leader", "Set_as_moderator": "Set as moderator", "Set_as_owner": "Set as owner", - "Setting_permissions": "Permission to change settings", + "Setting_permissions": "Setting-based permissions", "Settings": "Settings", "Settings_updated": "Settings updated", "Share_Location_Title": "Share Location?", From 00e4bb545533b056f06eaf72fb4e25bca6f53102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20J=C3=A4gle?= Date: Tue, 21 Nov 2017 16:38:13 +0100 Subject: [PATCH 07/20] UI-adaptation: Allow users with permission 'manage-selected-permissions' to see and change the affected settings. However, this is not reactive: Once the permissions for a particular setting are changed, the user needs to log off and on again before it becomes effective in the UI. This is most probably a consequence of the CachedCollection. This collection needed to be changed on permission-change. In the backend however, the permissions become effective immediately. --- .../client/views/permissions.html | 4 +- .../client/views/permissions.js | 11 +++-- .../server/publications/permissions.js | 3 ++ .../server/startup.js | 2 +- .../server/methods/saveSetting.js | 8 +++- .../server/publications/settings.js | 42 ++++--------------- .../rocketchat-ui-admin/client/admin.html | 2 +- packages/rocketchat-ui-admin/client/admin.js | 20 +++------ .../rocketchat-ui-admin/client/adminFlex.html | 2 +- .../rocketchat-ui-admin/client/adminFlex.js | 4 ++ .../client/accountBox.js | 2 +- 11 files changed, 40 insertions(+), 60 deletions(-) diff --git a/packages/rocketchat-authorization/client/views/permissions.html b/packages/rocketchat-authorization/client/views/permissions.html index 5bdaf31c4328..5b63d667e007 100644 --- a/packages/rocketchat-authorization/client/views/permissions.html +++ b/packages/rocketchat-authorization/client/views/permissions.html @@ -38,7 +38,7 @@ {{_ "New_role"}}
- {{> permissionsTable permissions=permissions allRoles=roles}} + {{> permissionsTable permissions=permissions allRoles=roles collection='Chat'}}
{{#if hasSettingPermission}} @@ -60,7 +60,7 @@
{{#if settingPermissionExpanded }} - {{> permissionsTable permissions=settingPermissions allRoles=roles}} + {{> permissionsTable permissions=settingPermissions allRoles=roles collection='Setting'}} {{else}} {{_ "Not_authorized"}} {{/if}} diff --git a/packages/rocketchat-authorization/client/views/permissions.js b/packages/rocketchat-authorization/client/views/permissions.js index 143c253d8787..4bc4466b920f 100644 --- a/packages/rocketchat-authorization/client/views/permissions.js +++ b/packages/rocketchat-authorization/client/views/permissions.js @@ -94,7 +94,6 @@ Template.permissionsTable.events({ } }); - Template.permissionsTable.onCreated(function() { this.permissionByRole = {}; this.actions = { @@ -114,7 +113,13 @@ Template.permissionsTable.onCreated(function() { delete this.permissionByRole[id]; } }; - ChatPermissions.find().observeChanges(observer); - SettingPermissions.find().observeChanges(observer); + if (this.data.collection === 'Chat') { + ChatPermissions.find().observeChanges(observer); + } + + if (this.data.collection === 'Setting') { + SettingPermissions.find().observeChanges(observer); + } }); }); + diff --git a/packages/rocketchat-authorization/server/publications/permissions.js b/packages/rocketchat-authorization/server/publications/permissions.js index 5963b532a048..f6a5901f153e 100644 --- a/packages/rocketchat-authorization/server/publications/permissions.js +++ b/packages/rocketchat-authorization/server/publications/permissions.js @@ -51,5 +51,8 @@ Meteor.methods({ RocketChat.models.Permissions.on('changed', (type, permission) => { RocketChat.Notifications.notifyLoggedInThisInstance('permissions-changed', type, permission); + if (permission.level === permissionLevel.SETTING) { + RocketChat.Notifications.notifyLoggedInThisInstance('selected-settings-changed', type, permission); + } }); diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index f8e23016b3cd..85bce3bc4451 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -64,7 +64,7 @@ Meteor.startup(function() { {_id: 'view-other-user-channels', roles: ['admin']}, {_id: 'view-p-room', roles: ['admin', 'user', 'anonymous']}, {_id: 'view-privileged-setting', roles: ['admin']}, - {_id: 'view-selected-settings', roles: ['admin']}, + {_id: 'manage-selected-settings', roles: ['admin']}, {_id: 'view-room-administration', roles: ['admin']}, {_id: 'view-statistics', roles: ['admin']}, {_id: 'view-user-administration', roles: ['admin']}, diff --git a/packages/rocketchat-lib/server/methods/saveSetting.js b/packages/rocketchat-lib/server/methods/saveSetting.js index 963876864e31..a52250ecb95a 100644 --- a/packages/rocketchat-lib/server/methods/saveSetting.js +++ b/packages/rocketchat-lib/server/methods/saveSetting.js @@ -8,9 +8,13 @@ Meteor.methods({ }); } - if (!RocketChat.authz.hasPermission(Meteor.userId(), 'edit-privileged-setting')) { + if (!RocketChat.authz.hasPermission(Meteor.userId(), 'edit-privileged-setting') + && !( + RocketChat.authz.hasAllPermission(Meteor.userId(), ['manage-selected-settings', `change-setting-${ _id }`]) + )) { throw new Meteor.Error('error-action-not-allowed', 'Editing settings is not allowed', { - method: 'saveSetting' + method: 'saveSetting', + settingId: _id }); } diff --git a/packages/rocketchat-lib/server/publications/settings.js b/packages/rocketchat-lib/server/publications/settings.js index 80b41e338cb3..f4b1787f9b01 100644 --- a/packages/rocketchat-lib/server/publications/settings.js +++ b/packages/rocketchat-lib/server/publications/settings.js @@ -31,42 +31,16 @@ Meteor.methods({ return []; } this.unblock(); - if (!RocketChat.authz.hasPermission(Meteor.userId(), 'view-privileged-setting')) { - return []; - } - const records = RocketChat.models.Settings.find().fetch().filter(function(record) { - return record.hidden !== true; - }); - if (updatedAt instanceof Date) { - return { - update: records.filter(function(record) { - return record._updatedAt > updatedAt; - }), - remove: RocketChat.models.Settings.trashFindDeletedAfter(updatedAt, { - hidden: { - $ne: true - } - }, { - fields: { - _id: 1, - _deletedAt: 1 - } - }).fetch() - }; - } - return records; - }, - 'selected-settings/get'(updatedAt) { - if (!Meteor.userId()) { - return []; - } - this.unblock(); - if (!RocketChat.authz.hasPermission(Meteor.userId(), 'view-selected-settings')) { - return []; - } const records = RocketChat.models.Settings.find().fetch().filter(function(record) { - return record.hidden !== true && RocketChat.authz.hasPermission(Meteor.userId(), `change-setting-${ record._id }`); + if (RocketChat.authz.hasPermission(Meteor.userId(), 'view-privileged-setting')) { + return record.hidden !== true; + } else if (RocketChat.authz.hasPermission(Meteor.userId(), 'manage-selected-settings')) { + return record.hidden !== true && RocketChat.authz.hasPermission(Meteor.userId(), `change-setting-${ record._id }`); + } else { + return false; + } }); + if (updatedAt instanceof Date) { return { update: records.filter(function(record) { diff --git a/packages/rocketchat-ui-admin/client/admin.html b/packages/rocketchat-ui-admin/client/admin.html index a63acd6c93c6..e360e0724672 100644 --- a/packages/rocketchat-ui-admin/client/admin.html +++ b/packages/rocketchat-ui-admin/client/admin.html @@ -15,7 +15,7 @@

- {{#unless hasPermission 'view-privileged-setting'}} + {{#unless hasSettingPermission}}

{{_ "You_are_not_authorized_to_view_this_page"}}

{{else}} {{#if description}} diff --git a/packages/rocketchat-ui-admin/client/admin.js b/packages/rocketchat-ui-admin/client/admin.js index d0155c2b608d..f43b9f469651 100644 --- a/packages/rocketchat-ui-admin/client/admin.js +++ b/packages/rocketchat-ui-admin/client/admin.js @@ -52,18 +52,8 @@ Template.admin.onCreated(function() { RocketChat.settings.collectionPrivate = RocketChat.settings.cachedCollectionPrivate.collection; RocketChat.settings.cachedCollectionPrivate.init(); } - - // settings which the user is explicitly allowed to change - if (RocketChat.settings.cachedCollectionSelected == null) { - RocketChat.settings.cachedCollectionSelected = new RocketChat.CachedCollection({ - name: 'selected-settings', - eventType: 'onLogged' - }); - RocketChat.settings.collectionSelected = RocketChat.settings.cachedCollectionSelected.collection; - RocketChat.settings.cachedCollectionSelected.init(); - } this.selectedRooms = new ReactiveVar({}); - const observation = { + RocketChat.settings.collectionPrivate.find().observe({ added: (data) => { const selectedRooms = this.selectedRooms.get(); if (data.type === 'roomPick') { @@ -88,10 +78,7 @@ Template.admin.onCreated(function() { } TempSettings.remove(data._id); } - }; - - RocketChat.settings.collectionPrivate.find().observe(observation); - RocketChat.settings.collectionSelected.find().observe(observation); + }); }); Template.admin.onDestroyed(function() { @@ -99,6 +86,9 @@ Template.admin.onDestroyed(function() { }); Template.admin.helpers({ + hasSettingPermission() { + return RocketChat.authz.hasAtLeastOnePermission(['view-privileged-setting', 'manage-selected-settings']); + }, languages() { const languages = TAPi18n.getLanguages(); diff --git a/packages/rocketchat-ui-admin/client/adminFlex.html b/packages/rocketchat-ui-admin/client/adminFlex.html index 98c3207f9b20..aa66794fe688 100644 --- a/packages/rocketchat-ui-admin/client/adminFlex.html +++ b/packages/rocketchat-ui-admin/client/adminFlex.html @@ -31,7 +31,7 @@

{{_ "Administration"}}

{{/each}} - {{#if hasPermission 'view-privileged-setting'}} + {{#if hasSettingPermission}}

{{_ "Settings"}}

- {{#if hasSettingPermission}} -
-
-
-
- {{_ "Setting_permissions"}}
-
- -
-
-
- {{#if settingPermissionExpanded }} - {{> permissionsTable permissions=settingPermissions allRoles=roles collection='Setting'}} - {{else}} - {{_ "Not_authorized"}} - {{/if}} + {{/if}} + {{#if hasSettingPermission}} +
+
+
+
+ {{_ "Setting_permissions"}}
+
+
+
+ {{#if settingPermissionExpanded }} + {{> permissionsTable permissions=settingPermissions allRoles=roles collection='Setting'}} + {{else}} + {{_ "Not_authorized"}} + {{/if}} +
- {{/if}} - {{else}} +
+ {{/if}} + {{#if hasNoPermission}} {{_ "Not_authorized"}} {{/if}}
diff --git a/packages/rocketchat-authorization/client/views/permissions.js b/packages/rocketchat-authorization/client/views/permissions.js index 07ed97a84d0f..951f37ce3d1a 100644 --- a/packages/rocketchat-authorization/client/views/permissions.js +++ b/packages/rocketchat-authorization/client/views/permissions.js @@ -43,6 +43,10 @@ Template.permissions.helpers({ return RocketChat.authz.hasAllPermission('access-setting-permissions'); }, + hasNoPermission() { + return !RocketChat.authz.hasAtLeastOnePermission(['access-permissions', 'access-setting-permissions']); + }, + settingPermissionExpanded() { return Template.instance().settingPermissionsExpanded.get(); } diff --git a/packages/rocketchat-authorization/server/startup.js b/packages/rocketchat-authorization/server/startup.js index 2332a05ae694..cc761027ee83 100644 --- a/packages/rocketchat-authorization/server/startup.js +++ b/packages/rocketchat-authorization/server/startup.js @@ -10,7 +10,7 @@ Meteor.startup(function() { // 2. admin, moderator, and user roles should not be deleted as they are referened in the code. const permissions = [ { _id: 'access-permissions', roles : ['admin'] }, - { _id: 'access-setting-permissions', roles: ['admin']}, + { _id: 'access-setting-permissions', roles: ['admin'] }, { _id: 'add-oauth-service', roles : ['admin'] }, { _id: 'add-user-to-joined-room', roles : ['admin', 'owner', 'moderator'] }, { _id: 'add-user-to-any-c-room', roles : ['admin'] }, diff --git a/packages/rocketchat-ui-sidenav/client/accountBox.js b/packages/rocketchat-ui-sidenav/client/accountBox.js deleted file mode 100644 index 69eca6b38bb7..000000000000 --- a/packages/rocketchat-ui-sidenav/client/accountBox.js +++ /dev/null @@ -1,134 +0,0 @@ -/* globals popover isRtl */ - -Template.accountBox.helpers({ - myUserInfo() { - if (Meteor.user() == null && RocketChat.settings.get('Accounts_AllowAnonymousRead')) { - return { - name: t('Anonymous'), - fname: RocketChat.settings.get('UI_Use_Real_Name') && t('Anonymous'), - status: 'online', - visualStatus: t('online'), - bullet: 'general-success-background', - username: 'anonymous' - }; - } - - const user = Meteor.user() || {}; - const { name, username } = user; - const userStatus = Session.get(`user_${ username }_status`); - - return { - name: Session.get(`user_${ username }_name`) || username, - status: Session.get(`user_${ username }_status`), - visualStatus: t(userStatus.charAt(0).toUpperCase() + userStatus.slice(1)), - bullet: userStatus, - _id: Meteor.userId(), - username, - fname: RocketChat.settings.get('UI_Use_Real_Name') && name - }; - }, - - isAnonymous() { - if (Meteor.userId() == null && RocketChat.settings.get('Accounts_AllowAnonymousRead')) { - return 'disabled'; - } - } -}); - -Template.accountBox.events({ - 'click .sidebar__account.active'() { - let adminOption; - if (RocketChat.authz.hasAtLeastOnePermission(['view-statistics', 'view-room-administration', 'view-user-administration', 'view-privileged-setting', 'edit-privileged-setting', 'manage-selected-settings']) || (RocketChat.AdminBox.getOptions().length > 0)) { - adminOption = { - icon: 'customize', - name: t('Administration'), - type: 'open', - id: 'administration' - }; - } - - const accountBox = document.querySelector('.sidebar__account'); - - const config = { - popoverClass: 'account', - columns: [ - { - groups: [ - { - title: t('User'), - items: [ - { - icon: 'circle', - name: t('Online'), - type: 'set-state', - id: 'online', - modifier: 'online' - }, - { - icon: 'circle', - name: t('Away'), - type: 'set-state', - id: 'away', - modifier: 'away' - }, - { - icon: 'circle', - name: t('Busy'), - type: 'set-state', - id: 'busy', - modifier: 'busy' - }, - { - icon: 'circle', - name: t('Invisible'), - type: 'set-state', - id: 'offline', - modifier: 'offline' - } - ] - }, - { - items: AccountBox.getItems().map(item => { - return { - icon: item.icon, - name: t(item.name), - type: 'open', - id: item.name, - href: item.href, - sideNav: item.sideNav - }; - }).concat([ - adminOption, - { - icon: 'user', - name: t('My_Account'), - type: 'open', - id: 'account' - }, - { - icon: 'sign-out', - name: t('Logout'), - type: 'open', - id: 'logout' - } - ]) - } - - ] - } - ], - position: { - top: accountBox.offsetHeight - }, - customCSSProperties: { - width: `${ accountBox.offsetWidth - parseInt(getComputedStyle(accountBox)['padding-left'].replace('px', '')) * 2 }px`, - left: isRtl() ? 'auto' : getComputedStyle(accountBox)['padding-left'], - right: 'auto' - } - }; - - popover.open(config); - } -}); - -Template.accountBox.onRendered(() => AccountBox.init()); diff --git a/packages/rocketchat-ui-sidenav/client/sidebarHeader.js b/packages/rocketchat-ui-sidenav/client/sidebarHeader.js index c59d0ec05546..cddfd80e408d 100644 --- a/packages/rocketchat-ui-sidenav/client/sidebarHeader.js +++ b/packages/rocketchat-ui-sidenav/client/sidebarHeader.js @@ -140,10 +140,10 @@ const toolbarButtons = (user) => { { name: t('Options'), icon: 'menu', - condition: () => AccountBox.getItems().length || RocketChat.authz.hasAtLeastOnePermission([ 'manage-emoji', 'manage-integrations', 'manage-oauth-apps', 'manage-own-integrations', 'manage-sounds', 'view-logs', 'view-privileged-setting', 'view-room-administration', 'view-statistics', 'view-user-administration', 'manage-selected-settings' ]), + condition: () => AccountBox.getItems().length || RocketChat.authz.hasAtLeastOnePermission([ 'access-permissions', 'access-setting-permissions', 'edit-privileged-setting', 'manage-emoji', 'manage-integrations', 'manage-oauth-apps', 'manage-own-integrations', 'manage-selected-settings', 'manage-sounds', 'view-logs', 'view-privileged-setting', 'view-room-administration', 'view-statistics', 'view-user-administration' ]), action: (e) => { let adminOption; - if (RocketChat.authz.hasAtLeastOnePermission([ 'manage-emoji', 'manage-integrations', 'manage-oauth-apps', 'manage-own-integrations', 'manage-sounds', 'view-logs', 'view-privileged-setting', 'view-room-administration', 'view-statistics', 'view-user-administration', 'manage-selected-settings' ])) { + if (RocketChat.authz.hasAtLeastOnePermission([ 'access-permissions', 'access-setting-permissions', 'edit-privileged-setting', 'manage-emoji', 'manage-integrations', 'manage-oauth-apps', 'manage-own-integrations', 'manage-selected-settings', 'manage-sounds', 'view-logs', 'view-privileged-setting', 'view-room-administration', 'view-statistics', 'view-user-administration' ])) { adminOption = { icon: 'customize', name: t('Administration'), From 2209f4d0a3d0f0f95c8abe632712fb0a63fbcb11 Mon Sep 17 00:00:00 2001 From: vickyokrm Date: Tue, 4 Sep 2018 16:02:47 +0200 Subject: [PATCH 20/20] check disable-smarti for test-with-oplog tests --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 15b6ce9316d5..9117c2745588 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -173,6 +173,7 @@ jobs: - run: name: Run Tests command: | + if [[ $DISABLE_SMARTI ]]; then rm -rf ./tests/end-to-end/ui_smarti; fi; for i in $(seq 1 5); do npm test && s=0 && break || s=$? && sleep 1; done; (exit $s) - store_artifacts: