Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix saveRoomSettings method complexity #18840

Merged
merged 1 commit into from
Sep 9, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
352 changes: 200 additions & 152 deletions app/channel-settings/server/methods/saveRoomSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,188 @@ import { saveStreamingOptions } from '../functions/saveStreamingOptions';
import { RoomSettingsEnum, roomTypes } from '../../../utils';

const fields = ['roomAvatar', 'featured', 'roomName', 'roomTopic', 'roomAnnouncement', 'roomCustomFields', 'roomDescription', 'roomType', 'readOnly', 'reactWhenReadOnly', 'systemMessages', 'default', 'joinCode', 'tokenpass', 'streamingOptions', 'retentionEnabled', 'retentionMaxAge', 'retentionExcludePinned', 'retentionFilesOnly', 'retentionIgnoreThreads', 'retentionOverrideGlobal', 'encrypted', 'favorite'];

const validators = {
default({ userId }) {
if (!hasPermission(userId, 'view-room-administration')) {
throw new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', {
method: 'saveRoomSettings',
action: 'Viewing_room_administration',
});
}
},
featured({ userId }) {
if (!hasPermission(userId, 'view-room-administration')) {
throw new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', {
method: 'saveRoomSettings',
action: 'Viewing_room_administration',
});
}
},
roomType({ userId, room, value }) {
if (value === room.t) {
return;
}

if (value === 'c' && !hasPermission(userId, 'create-c')) {
throw new Meteor.Error('error-action-not-allowed', 'Changing a private group to a public channel is not allowed', {
method: 'saveRoomSettings',
action: 'Change_Room_Type',
});
}

if (value === 'p' && !hasPermission(userId, 'create-p')) {
throw new Meteor.Error('error-action-not-allowed', 'Changing a public channel to a private room is not allowed', {
method: 'saveRoomSettings',
action: 'Change_Room_Type',
});
}
},
encrypted({ value, room }) {
if (value !== room.encrypted && !roomTypes.getConfig(room.t).allowRoomSettingChange(room, RoomSettingsEnum.E2E)) {
throw new Meteor.Error('error-action-not-allowed', 'Only groups or direct channels can enable encryption', {
method: 'saveRoomSettings',
action: 'Change_Room_Encrypted',
});
}
},
retentionEnabled({ userId, value, room, rid }) {
if (!hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.enabled) {
throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', {
method: 'saveRoomSettings',
action: 'Editing_room',
});
}
},
retentionMaxAge({ userId, value, room, rid }) {
if (!hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.maxAge) {
throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', {
method: 'saveRoomSettings',
action: 'Editing_room',
});
}
},
retentionExcludePinned({ userId, value, room, rid }) {
if (!hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.excludePinned) {
throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', {
method: 'saveRoomSettings',
action: 'Editing_room',
});
}
},
retentionFilesOnly({ userId, value, room, rid }) {
if (!hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.filesOnly) {
throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', {
method: 'saveRoomSettings',
action: 'Editing_room',
});
}
},
retentionIgnoreThreads({ userId, value, room, rid }) {
if (!hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.ignoreThreads) {
throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', {
method: 'saveRoomSettings',
action: 'Editing_room',
});
}
},
};

const settingSavers = {
roomName({ value, rid, user }) {
saveRoomName(rid, value, user);
},
roomTopic({ value, room, rid, user }) {
if (value !== room.topic) {
saveRoomTopic(rid, value, user);
}
},
roomAnnouncement({ value, room, rid, user }) {
if (value !== room.announcement) {
saveRoomAnnouncement(rid, value, user);
}
},
roomCustomFields({ value, room, rid }) {
if (value !== room.customFields) {
saveRoomCustomFields(rid, value);
}
},
roomDescription({ value, room, rid, user }) {
if (value !== room.description) {
saveRoomDescription(rid, value, user);
}
},
roomType({ value, room, rid, user }) {
if (value !== room.t) {
saveRoomType(rid, value, user);
}
},
tokenpass({ value, rid }) {
check(value, {
require: String,
tokens: [{
token: String,
balance: String,
}],
});
saveRoomTokenpass(rid, value);
},
streamingOptions({ value, rid }) {
saveStreamingOptions(rid, value);
},
readOnly({ value, room, rid, user }) {
if (value !== room.ro) {
saveRoomReadOnly(rid, value, user);
}
},
reactWhenReadOnly({ value, room, rid, user }) {
if (value !== room.reactWhenReadOnly) {
saveReactWhenReadOnly(rid, value, user);
}
},
systemMessages({ value, room, rid, user }) {
if (JSON.stringify(value) !== JSON.stringify(room.sysMes)) {
saveRoomSystemMessages(rid, value, user);
}
},
joinCode({ value, rid }) {
Rooms.setJoinCodeById(rid, String(value));
},
default({ value, rid }) {
Rooms.saveDefaultById(rid, value);
},
featured({ value, rid }) {
Rooms.saveFeaturedById(rid, value);
},
retentionEnabled({ value, rid }) {
Rooms.saveRetentionEnabledById(rid, value);
},
retentionMaxAge({ value, rid }) {
Rooms.saveRetentionMaxAgeById(rid, value);
},
retentionExcludePinned({ value, rid }) {
Rooms.saveRetentionExcludePinnedById(rid, value);
},
retentionFilesOnly({ value, rid }) {
Rooms.saveRetentionFilesOnlyById(rid, value);
},
retentionIgnoreThreads({ value, rid }) {
Rooms.saveRetentionIgnoreThreadsById(rid, value);
},
retentionOverrideGlobal({ value, rid }) {
Rooms.saveRetentionOverrideGlobalById(rid, value);
},
encrypted({ value, rid }) {
Rooms.saveEncryptedById(rid, value);
},
favorite({ value, rid }) {
Rooms.saveFavoriteById(rid, value.favorite, value.defaultValue);
},
roomAvatar({ value, rid, user }) {
setRoomAvatar(rid, value, user);
},
};

Meteor.methods({
saveRoomSettings(rid, settings, value) {
const userId = Meteor.userId();
Expand Down Expand Up @@ -71,70 +253,19 @@ Meteor.methods({
const user = Meteor.user();

// validations

Object.keys(settings).forEach((setting) => {
const value = settings[setting];
if (settings === 'default' && !hasPermission(userId, 'view-room-administration')) {
throw new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', {
method: 'saveRoomSettings',
action: 'Viewing_room_administration',
});
}
if (settings === 'featured' && !hasPermission(userId, 'view-room-administration')) {
throw new Meteor.Error('error-action-not-allowed', 'Viewing room administration is not allowed', {
method: 'saveRoomSettings',
action: 'Viewing_room_administration',
});
}
if (setting === 'roomType' && value !== room.t && value === 'c' && !hasPermission(userId, 'create-c')) {
throw new Meteor.Error('error-action-not-allowed', 'Changing a private group to a public channel is not allowed', {
method: 'saveRoomSettings',
action: 'Change_Room_Type',
});
}
if (setting === 'roomType' && value !== room.t && value === 'p' && !hasPermission(userId, 'create-p')) {
throw new Meteor.Error('error-action-not-allowed', 'Changing a public channel to a private room is not allowed', {
method: 'saveRoomSettings',
action: 'Change_Room_Type',
});
}
if (setting === 'encrypted' && value !== room.encrypted && !roomTypes.getConfig(room.t).allowRoomSettingChange(room, RoomSettingsEnum.E2E)) {
throw new Meteor.Error('error-action-not-allowed', 'Only groups or direct channels can enable encryption', {
method: 'saveRoomSettings',
action: 'Change_Room_Encrypted',
});
}

if (setting === 'retentionEnabled' && !hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.enabled) {
throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', {
method: 'saveRoomSettings',
action: 'Editing_room',
});
}
if (setting === 'retentionMaxAge' && !hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.maxAge) {
throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', {
method: 'saveRoomSettings',
action: 'Editing_room',
});
}
if (setting === 'retentionExcludePinned' && !hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.excludePinned) {
throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', {
method: 'saveRoomSettings',
action: 'Editing_room',
});
}
if (setting === 'retentionFilesOnly' && !hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.filesOnly) {
throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', {
method: 'saveRoomSettings',
action: 'Editing_room',
});
}
if (setting === 'retentionIgnoreThreads' && !hasPermission(userId, 'edit-room-retention-policy', rid) && value !== room.retention.ignoreThreads) {
throw new Meteor.Error('error-action-not-allowed', 'Editing room retention policy is not allowed', {
method: 'saveRoomSettings',
action: 'Editing_room',
const validator = validators[setting];
if (validator) {
validator({
userId,
value,
room,
rid,
});
}

if (setting === 'retentionOverrideGlobal') {
delete settings.retentionMaxAge;
delete settings.retentionExcludePinned;
Expand All @@ -143,101 +274,18 @@ Meteor.methods({
}
});

// saving data
Object.keys(settings).forEach((setting) => {
const value = settings[setting];
switch (setting) {
case 'roomName':
saveRoomName(rid, value, user);
break;
case 'roomTopic':
if (value !== room.topic) {
saveRoomTopic(rid, value, user);
}
break;
case 'roomAnnouncement':
if (value !== room.announcement) {
saveRoomAnnouncement(rid, value, user);
}
break;
case 'roomCustomFields':
if (value !== room.customFields) {
saveRoomCustomFields(rid, value);
}
break;
case 'roomDescription':
if (value !== room.description) {
saveRoomDescription(rid, value, user);
}
break;
case 'roomType':
if (value !== room.t) {
saveRoomType(rid, value, user);
}
break;
case 'tokenpass':
check(value, {
require: String,
tokens: [{
token: String,
balance: String,
}],
});
saveRoomTokenpass(rid, value);
break;
case 'streamingOptions':
saveStreamingOptions(rid, value);
break;
case 'readOnly':
if (value !== room.ro) {
saveRoomReadOnly(rid, value, user);
}
break;
case 'reactWhenReadOnly':
if (value !== room.reactWhenReadOnly) {
saveReactWhenReadOnly(rid, value, user);
}
break;
case 'systemMessages':
if (JSON.stringify(value) !== JSON.stringify(room.sysMes)) {
saveRoomSystemMessages(rid, value, user);
}
break;
case 'joinCode':
Rooms.setJoinCodeById(rid, String(value));
break;
case 'default':
Rooms.saveDefaultById(rid, value);
break;
case 'featured':
Rooms.saveFeaturedById(rid, value);
break;
case 'retentionEnabled':
Rooms.saveRetentionEnabledById(rid, value);
break;
case 'retentionMaxAge':
Rooms.saveRetentionMaxAgeById(rid, value);
break;
case 'retentionExcludePinned':
Rooms.saveRetentionExcludePinnedById(rid, value);
break;
case 'retentionFilesOnly':
Rooms.saveRetentionFilesOnlyById(rid, value);
break;
case 'retentionIgnoreThreads':
Rooms.saveRetentionIgnoreThreadsById(rid, value);
break;
case 'retentionOverrideGlobal':
Rooms.saveRetentionOverrideGlobalById(rid, value);
break;
case 'encrypted':
Rooms.saveEncryptedById(rid, value);
break;
case 'favorite':
Rooms.saveFavoriteById(rid, value.favorite, value.defaultValue);
break;
case 'roomAvatar':
setRoomAvatar(rid, value, user);
break;

const saver = settingSavers[setting];
if (saver) {
saver({
value,
room,
rid,
user,
});
}
});

Expand Down