Skip to content

Commit

Permalink
Move setting-based permissions to own collection
Browse files Browse the repository at this point in the history
  • Loading branch information
mrsimpson committed Nov 27, 2017
1 parent 293ad73 commit 8f59f1c
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 33 deletions.
6 changes: 3 additions & 3 deletions packages/rocketchat-authorization/client/hasPermission.js
Original file line number Diff line number Diff line change
@@ -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) => {
Expand All @@ -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) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
});
55 changes: 42 additions & 13 deletions packages/rocketchat-authorization/server/startup.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
});

0 comments on commit 8f59f1c

Please sign in to comment.