From efdffa9407c74b992bb0fec5681d4e9f235aafa9 Mon Sep 17 00:00:00 2001 From: Marcelo Schmidt Date: Tue, 12 Jan 2016 18:20:07 -0200 Subject: [PATCH] Do for owners as for moderators --- i18n/en.i18n.json | 8 ++++- .../server/startup.coffee | 19 ++++++---- .../rocketchat-lib/lib/MessageTypes.coffee | 14 ++++++++ .../server/models/Messages.coffee | 8 +++++ .../flex-tab/tabs/userInfo.coffee | 36 +++++++++++++++++-- .../flex-tab/tabs/userInfo.html | 7 ++++ packages/rocketchat-ui/lib/collections.coffee | 2 +- packages/rocketchat-ui/views/app/room.coffee | 18 +++++++--- server/methods/addRoomOwner.coffee | 25 +++++++++++++ server/methods/createChannel.coffee | 2 +- server/methods/createPrivateGroup.coffee | 2 +- ...ffee => getRoomModeratorsAndOwners.coffee} | 7 ++-- server/methods/removeRoomOwner.coffee | 25 +++++++++++++ server/methods/removeUserFromRoom.coffee | 2 +- 14 files changed, 153 insertions(+), 22 deletions(-) create mode 100644 server/methods/addRoomOwner.coffee rename server/methods/{getRoomModerators.coffee => getRoomModeratorsAndOwners.coffee} (67%) create mode 100644 server/methods/removeRoomOwner.coffee diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index b694485e80e..a64d5fd799b 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -402,6 +402,7 @@ "Removed" : "Removed", "Remove_Admin" : "Remove Admin", "Remove_as_moderator" : "Remove as moderator", + "Remove_as_owner" : "Remove as owner", "Remove_custom_oauth" : "Remove custom oauth", "Remove_from_room" : "Remove from room", "Reset" : "Reset", @@ -454,6 +455,7 @@ "Settings" : "Settings", "Settings_updated" : "Settings updated", "Set_as_moderator" : "Set as moderator", + "Set_as_owner" : "Set as owner", "Should_be_a_URL_of_an_image" : "Should be a URL of an image.", "Should_exists_a_user_with_this_username" : "The user must already exist.", "Showing_archived_results" : "

Showing %s archived results

", @@ -553,13 +555,17 @@ "User_removed_by" : "User __user_removed__ removed by __user_by__.", "User_removed_from_room" : "The user has been removed from the room", "User__username__removed_from__room_name__moderators" : "User __username__ removed from __room_name__ moderators", + "User__username__removed_from__room_name__owners" : "User __username__ removed from __room_name__ owners", "User_Settings" : "User Settings", "User_unmuted_by" : "User __user_unmuted__ unmuted by __user_by__.", "User_unmuted_in_room" : "User unmuted in room", "User_updated_successfully" : "User updated successfully", "User__username__is_now_a_moderator_of__room_name_" : "User __username__ is now a moderator of __room_name__", + "User__username__is_now_a_owner_of__room_name_" : "User __username__ is now a owner of __room_name__", "User__username__was_added_as_a_moderator_by__user_by_" : "User __username__ was added as a moderator by __user_by__", + "User__username__was_added_as_a_owner_by__user_by_" : "User __username__ was added as a owner by __user_by__", "User__username__was_removed_as_a_moderator_by__user_by_" : "User __username__ was removed as a moderator by __user_by__", + "User__username__was_removed_as_a_owner_by__user_by_" : "User __username__ was removed as a owner by __user_by__", "Username" : "Username", "Username_cant_be_empty" : "The username cannot be empty", "Username_Change_Disabled" : "Your Rocket.Chat administrator has disabled the changing of usernames", @@ -595,4 +601,4 @@ "Your_mail_was_sent_to_s" : "Your mail was sent to %s", "Your_Open_Source_solution" : "Your own Open Source chat solution", "Your_push_was_sent_to_s_devices" : "Your push was sent to %s devices" -} \ No newline at end of file +} diff --git a/packages/rocketchat-authorization/server/startup.coffee b/packages/rocketchat-authorization/server/startup.coffee index b2b0942c3bd..7febc408c37 100644 --- a/packages/rocketchat-authorization/server/startup.coffee +++ b/packages/rocketchat-authorization/server/startup.coffee @@ -55,25 +55,29 @@ Meteor.startup -> roles : ['admin']} { _id: 'edit-room', - roles : ['admin', 'moderator']} + roles : ['admin', 'moderator', 'owner']} { _id: 'edit-message', - roles : ['admin', 'moderator']} + roles : ['admin', 'moderator', 'owner']} { _id: 'delete-message', - roles : ['admin', 'moderator']} + roles : ['admin', 'moderator', 'owner']} { _id: 'remove-user', - roles : ['admin', 'moderator']} + roles : ['admin', 'moderator', 'owner']} { _id: 'mute-user', - roles : ['admin', 'moderator']} + roles : ['admin', 'moderator', 'owner']} { _id: 'ban-user', - roles : ['admin', 'moderator']} + roles : ['admin', 'moderator', 'owner']} { _id: 'set-moderator', - roles : ['admin', 'moderator']} + roles : ['admin', 'owner']} + + { _id: 'set-owner', + roles : ['admin']} + { _id: 'create-p', roles : ['admin', 'user']} @@ -117,6 +121,7 @@ Meteor.startup -> defaultRoles = [ { name: 'admin', scope: 'Users' } { name: 'moderator', scope: 'Subscriptions' } + { name: 'owner', scope: 'Subscriptions' } { name: 'user', scope: 'Users' } { name: 'bot', scope: 'Users' } ] diff --git a/packages/rocketchat-lib/lib/MessageTypes.coffee b/packages/rocketchat-lib/lib/MessageTypes.coffee index a9407e0cc1a..58f651d4586 100644 --- a/packages/rocketchat-lib/lib/MessageTypes.coffee +++ b/packages/rocketchat-lib/lib/MessageTypes.coffee @@ -96,3 +96,17 @@ Meteor.startup -> message: 'User__username__was_removed_as_a_moderator_by__user_by_' data: (message) -> return { username: message.msg, user_by: message.u.username } + + RocketChat.MessageTypes.registerType + id: 'new-owner' + system: true + message: 'User__username__was_added_as_a_owner_by__user_by_' + data: (message) -> + return { username: message.msg, user_by: message.u.username } + + RocketChat.MessageTypes.registerType + id: 'owner-removed' + system: true + message: 'User__username__was_removed_as_a_owner_by__user_by_' + data: (message) -> + return { username: message.msg, user_by: message.u.username } diff --git a/packages/rocketchat-lib/server/models/Messages.coffee b/packages/rocketchat-lib/server/models/Messages.coffee index 6591b251d22..c7e7bf5ba00 100644 --- a/packages/rocketchat-lib/server/models/Messages.coffee +++ b/packages/rocketchat-lib/server/models/Messages.coffee @@ -302,6 +302,14 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base message = user.username return @createWithTypeRoomIdMessageAndUser 'moderator-removed', roomId, message, user, extraData + createNewOwnerWithRoomIdAndUser: (roomId, user, extraData) -> + message = user.username + return @createWithTypeRoomIdMessageAndUser 'new-owner', roomId, message, user, extraData + + createOwnerRemovedWithRoomIdAndUser: (roomId, user, extraData) -> + message = user.username + return @createWithTypeRoomIdMessageAndUser 'owner-removed', roomId, message, user, extraData + # REMOVE removeById: (_id) -> query = diff --git a/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.coffee b/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.coffee index 2b1a1754027..16af8660d7e 100644 --- a/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.coffee +++ b/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.coffee @@ -49,7 +49,13 @@ Template.userInfo.helpers return RocketChat.authz.hasAllPermission('set-moderator', Session.get('openedRoom')) isModerator: -> - return !!RoomModerators.findOne({ rid: Session.get('openedRoom'), "u._id": @user?._id }) + return !!RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user?._id, roles: 'moderator' }) + + canSetOwner: -> + return RocketChat.authz.hasAllPermission('set-owner', Session.get('openedRoom')) + + isOwner: -> + return !!RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user?._id, role: 'owner' }) Template.userInfo.events 'click .pvt-msg': (e) -> @@ -160,7 +166,7 @@ Template.userInfo.events 'click .set-moderator': (e, t) -> e.preventDefault() - userModerator = RoomModerators.findOne({ rid: Session.get('openedRoom'), "u._id": @user._id }, { fields: { _id: 1 } }) + userModerator = RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user._id, roles: 'moderator' }, { fields: { _id: 1 } }) unless userModerator? Meteor.call 'addRoomModerator', Session.get('openedRoom'), @user._id, (err, results) => if err @@ -172,7 +178,7 @@ Template.userInfo.events 'click .unset-moderator': (e, t) -> e.preventDefault() - userModerator = RoomModerators.findOne({ rid: Session.get('openedRoom'), "u._id": @user._id }, { fields: { _id: 1 } }) + userModerator = RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user._id, roles: 'moderator' }, { fields: { _id: 1 } }) if userModerator? Meteor.call 'removeRoomModerator', Session.get('openedRoom'), @user._id, (err, results) => if err @@ -181,6 +187,30 @@ Template.userInfo.events room = ChatRoom.findOne(Session.get('openedRoom')) toastr.success TAPi18n.__ 'User__username__removed_from__room_name__moderators', { username: @user.username, room_name: room.name } + 'click .set-owner': (e, t) -> + e.preventDefault() + + userOwner = RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user._id, roles: 'owner' }, { fields: { _id: 1 } }) + unless userOwner? + Meteor.call 'addRoomOwner', Session.get('openedRoom'), @user._id, (err, results) => + if err + return toastr.error(err.reason or err.message) + + room = ChatRoom.findOne(Session.get('openedRoom')) + toastr.success TAPi18n.__ 'User__username__is_now_a_owner_of__room_name_', { username: @user.username, room_name: room.name } + + 'click .unset-owner': (e, t) -> + e.preventDefault() + + userOwner = RoomModeratorsAndOwners.findOne({ rid: Session.get('openedRoom'), "u._id": @user._id, roles: 'owner' }, { fields: { _id: 1 } }) + if userOwner? + Meteor.call 'removeRoomOwner', Session.get('openedRoom'), @user._id, (err, results) => + if err + return toastr.error(err.reason or err.message) + + room = ChatRoom.findOne(Session.get('openedRoom')) + toastr.success TAPi18n.__ 'User__username__removed_from__room_name__owners', { username: @user.username, room_name: room.name } + Template.userInfo.onCreated -> @now = new ReactiveVar moment() self = @ diff --git a/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.html b/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.html index c4e3e9b2e68..bad3b31f478 100644 --- a/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.html +++ b/packages/rocketchat-ui-flextab/flex-tab/tabs/userInfo.html @@ -33,6 +33,13 @@ {{#if canDirectMessage user.username}} {{/if}} + {{#if canSetOwner}} + {{#if isOwner}} + + {{else}} + + {{/if}} + {{/if}} {{#if canSetModerator}} {{#if isModerator}} diff --git a/packages/rocketchat-ui/lib/collections.coffee b/packages/rocketchat-ui/lib/collections.coffee index 1ac9008435f..f02353c5501 100644 --- a/packages/rocketchat-ui/lib/collections.coffee +++ b/packages/rocketchat-ui/lib/collections.coffee @@ -1,7 +1,7 @@ @ChatMessage = new Meteor.Collection null @ChatRoom = new Meteor.Collection 'rocketchat_room' @ChatSubscription = new Meteor.Collection 'rocketchat_subscription' -@RoomModerators = new Mongo.Collection null +@RoomModeratorsAndOwners = new Mongo.Collection null @UserAndRoom = new Meteor.Collection null @CachedChannelList = new Meteor.Collection null diff --git a/packages/rocketchat-ui/views/app/room.coffee b/packages/rocketchat-ui/views/app/room.coffee index d26c22594c7..dcc25cac967 100644 --- a/packages/rocketchat-ui/views/app/room.coffee +++ b/packages/rocketchat-ui/views/app/room.coffee @@ -493,23 +493,33 @@ Template.room.onCreated -> @autorun => @subscribe 'fullUserData', Session.get('showUserInfo'), 1 - Meteor.call 'getRoomModerators', @data._id, (error, results) -> + Meteor.call 'getRoomModeratorsAndOwners', @data._id, (error, results) -> if error return toastr.error error.reason for record in results - RoomModerators.insert record + RoomModeratorsAndOwners.insert record RocketChat.callbacks.add('streamMessage', (msg) -> if msg.t is 'new-moderator' user = Meteor.users.findOne({ username: msg.msg }, { fields: { username: 1 } }) - RoomModerators.upsert({ _id: msg._id }, { $set: { rid: msg.rid, u: user } }) # use message _id to prevent from running it twice (https://github.com/RocketChat/Rocket.Chat/issues/1876) + RoomModeratorsAndOwners.upsert({ _id: msg._id }, { $set: { rid: msg.rid, u: user }, $addToSet: { roles: 'moderator' } }) # use message _id to prevent from running it twice (https://github.com/RocketChat/Rocket.Chat/issues/1876) else if msg.t is 'moderator-removed' user = Meteor.users.findOne({ username: msg.msg }) - RoomModerators.remove({ rid: msg.rid, "u._id": user._id }); + RoomModeratorsAndOwners.remove({ rid: msg.rid, "u._id": user._id }); return msg , RocketChat.callbacks.priority.LOW, 'addOrRemoveModerator') + RocketChat.callbacks.add('streamMessage', (msg) -> + if msg.t is 'new-owner' + user = Meteor.users.findOne({ username: msg.msg }, { fields: { username: 1 } }) + RoomModeratorsAndOwners.upsert({ _id: msg._id }, { $set: { rid: msg.rid, u: user }, $addToSet: { roles: 'owner' } }) # use message _id to prevent from running it twice (https://github.com/RocketChat/Rocket.Chat/issues/1876) + else if msg.t is 'owner-removed' + user = Meteor.users.findOne({ username: msg.msg }) + RoomModeratorsAndOwners.remove({ rid: msg.rid, "u._id": user._id }); + return msg + , RocketChat.callbacks.priority.LOW, 'addOrRemoveOwner') + Template.room.onDestroyed -> window.removeEventListener 'resize', this.onWindowResize diff --git a/server/methods/addRoomOwner.coffee b/server/methods/addRoomOwner.coffee new file mode 100644 index 00000000000..d3838be0b03 --- /dev/null +++ b/server/methods/addRoomOwner.coffee @@ -0,0 +1,25 @@ +Meteor.methods + addRoomOwner: (rid, userId) -> + unless Meteor.userId() + throw new Meteor.Error 'invalid-user', '[methods] addRoomOwner -> Invalid user' + + check rid, String + check userId, String + + unless RocketChat.authz.hasPermission Meteor.userId(), 'set-owner', rid + throw new Meteor.Error 403, 'Not allowed' + + subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId rid, userId + unless subscription? + throw new Meteor.Error 'invalid-subscription', '[methods] addRoomOwner -> Invalid Subscription' + + RocketChat.models.Subscriptions.addRoleById(subscription._id, 'owner') + + user = RocketChat.models.Users.findOneById userId + fromUser = RocketChat.models.Users.findOneById Meteor.userId() + RocketChat.models.Messages.createNewOwnerWithRoomIdAndUser rid, user, + u: + _id: fromUser._id + username: fromUser.username + + return true diff --git a/server/methods/createChannel.coffee b/server/methods/createChannel.coffee index 570d85bfa22..3edf800ec94 100644 --- a/server/methods/createChannel.coffee +++ b/server/methods/createChannel.coffee @@ -55,7 +55,7 @@ Meteor.methods RocketChat.models.Subscriptions.createWithRoomAndUser room, member, extra # set creator as channel moderator. permission limited to channel by scoping to rid - RocketChat.authz.addUserRoles(Meteor.userId(), 'moderator', room._id) + RocketChat.authz.addUserRoles(Meteor.userId(), ['moderator','owner'], room._id) Meteor.defer -> RocketChat.callbacks.run 'afterCreateChannel', user, room diff --git a/server/methods/createPrivateGroup.coffee b/server/methods/createPrivateGroup.coffee index 3a0dd23fa4c..657fa879463 100644 --- a/server/methods/createPrivateGroup.coffee +++ b/server/methods/createPrivateGroup.coffee @@ -34,7 +34,7 @@ Meteor.methods ts: now # set creator as group moderator. permission limited to group by scoping to rid - RocketChat.authz.addUserRoles(Meteor.userId(), 'moderator', room._id) + RocketChat.authz.addUserRoles(Meteor.userId(), ['moderator','owner'], room._id) for username in members member = RocketChat.models.Users.findOneByUsername(username, { fields: { username: 1 }}) diff --git a/server/methods/getRoomModerators.coffee b/server/methods/getRoomModeratorsAndOwners.coffee similarity index 67% rename from server/methods/getRoomModerators.coffee rename to server/methods/getRoomModeratorsAndOwners.coffee index 2cd263ac2db..37adf060156 100644 --- a/server/methods/getRoomModerators.coffee +++ b/server/methods/getRoomModeratorsAndOwners.coffee @@ -1,7 +1,7 @@ Meteor.methods - getRoomModerators: (rid) -> + getRoomModeratorsAndOwners: (rid) -> unless Meteor.userId() - throw new Meteor.Error 'invalid-user', '[methods] getRoomModerators -> Invalid user' + throw new Meteor.Error 'invalid-user', '[methods] getRoomModeratorsAndOwners -> Invalid user' check rid, String @@ -11,5 +11,6 @@ Meteor.methods fields: rid: 1 u: 1 + roles: 1 - return RocketChat.models.Subscriptions.findByRoomIdAndRoles(rid, 'moderator', options).fetch() + return RocketChat.models.Subscriptions.findByRoomIdAndRoles(rid, ['moderator', 'owner'], options).fetch() diff --git a/server/methods/removeRoomOwner.coffee b/server/methods/removeRoomOwner.coffee new file mode 100644 index 00000000000..b29a5f431ec --- /dev/null +++ b/server/methods/removeRoomOwner.coffee @@ -0,0 +1,25 @@ +Meteor.methods + removeRoomOwner: (rid, userId) -> + unless Meteor.userId() + throw new Meteor.Error 'invalid-user', '[methods] removeRoomOwner -> Invalid user' + + check rid, String + check userId, String + + unless RocketChat.authz.hasPermission Meteor.userId(), 'set-owner', rid + throw new Meteor.Error 403, 'Not allowed' + + subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId rid, userId + unless subscription? + throw new Meteor.Error 'invalid-subscription', '[methods] removeRoomOwner -> Invalid Subscription' + + RocketChat.models.Subscriptions.removeRoleById(subscription._id, 'owner') + + user = RocketChat.models.Users.findOneById userId + fromUser = RocketChat.models.Users.findOneById Meteor.userId() + RocketChat.models.Messages.createOwnerRemovedWithRoomIdAndUser rid, user, + u: + _id: fromUser._id + username: fromUser.username + + return true diff --git a/server/methods/removeUserFromRoom.coffee b/server/methods/removeUserFromRoom.coffee index f45e43a5bab..2c737d9e83d 100644 --- a/server/methods/removeUserFromRoom.coffee +++ b/server/methods/removeUserFromRoom.coffee @@ -18,7 +18,7 @@ Meteor.methods RocketChat.models.Subscriptions.removeByRoomIdAndUserId data.rid, removedUser._id if room.t in [ 'c', 'p' ] - RocketChat.authz.removeUserFromRoles(removedUser._id; 'moderator', data.rid) + RocketChat.authz.removeUserFromRoles(removedUser._id, ['moderator', 'owner'], data.rid) fromUser = RocketChat.models.Users.findOneById fromId RocketChat.models.Messages.createUserRemovedWithRoomIdAndUser data.rid, removedUser,