Skip to content
Snippets Groups Projects
Commit 514c059b authored by Gabriel Engel's avatar Gabriel Engel
Browse files

Merge pull request #1889 from RocketChat/set-moderator-stream

Room owners and moderators received via method call then stream
parents 82f7aca2 9ea75972
No related branches found
No related tags found
No related merge requests found
Showing
with 206 additions and 48 deletions
......@@ -406,6 +406,7 @@
"Remove" : "Remove",
"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",
"Removed" : "Removed",
......@@ -459,6 +460,8 @@
"Set_as_moderator" : "Set as moderator",
"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" : "<p>Showing <b>%s</b> archived results</p>",
......@@ -563,10 +566,18 @@
"User_or_channel_name" : "User or channel name",
"User_removed_by" : "User <em>__user_removed__</em> removed by <em>__user_by__</em>.",
"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 <em>__user_unmuted__</em> unmuted by <em>__user_by__</em>.",
"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 <em>__username__</em> was added as a moderator by <em>__user_by__</em>",
"User__username__was_added_as_a_owner_by__user_by_" : "User <em>__username__</em> was added as a owner by <em>__user_by__</em>",
"User__username__was_removed_as_a_moderator_by__user_by_" : "User <em>__username__</em> was removed as a moderator by <em>__user_by__</em>",
"User__username__was_removed_as_a_owner_by__user_by_" : "User <em>__username__</em> was removed as a owner by <em>__user_by__</em>",
"Username" : "Username",
"Username_cant_be_empty" : "The username cannot be empty",
"Username_Change_Disabled" : "Your Rocket.Chat administrator has disabled the changing of usernames",
......@@ -604,4 +615,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
}
......@@ -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' }
]
......
......@@ -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 }
......@@ -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 =
......
......@@ -25,6 +25,15 @@ RocketChat.models.Subscriptions = new class extends RocketChat.models._Base
return @find query, options
# FIND
findByRoomIdAndRoles: (roomId, roles, options) ->
roles = [].concat roles
query =
"rid": roomId
"roles": { $in: roles }
return @find query, options
getLastSeen: (options = {}) ->
query = { ls: { $exists: 1 } }
options.sort = { ls: -1 }
......
......@@ -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, roles: '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 = @
......
......@@ -33,6 +33,13 @@
{{#if canDirectMessage user.username}}
<button class='button button-block pvt-msg'><span><i class='icon-chat'></i> {{_ "Conversation"}}</span></button>
{{/if}}
{{#if canSetOwner}}
{{#if isOwner}}
<button class="button button-block unset-owner lightblue"><span>{{_ "Remove_as_owner"}}</span></button>
{{else}}
<button class="button button-block set-owner lightblue"><span>{{_ "Set_as_owner"}}</span></button>
{{/if}}
{{/if}}
{{#if canSetModerator}}
{{#if isModerator}}
<button class="button button-block unset-moderator lightblue"><span>{{_ "Remove_as_moderator"}}</span></button>
......
@ChatMessage = new Meteor.Collection null
@ChatRoom = new Meteor.Collection 'rocketchat_room'
@ChatSubscription = new Meteor.Collection 'rocketchat_subscription'
@RoomModerators = new Mongo.Collection 'room_moderators'
@RoomModeratorsAndOwners = new Mongo.Collection null
@UserAndRoom = new Meteor.Collection null
@CachedChannelList = new Meteor.Collection null
......
Meteor.startup(function() {
RocketChat.callbacks.add('streamMessage', function(msg) {
if (msg.t === 'new-moderator') {
user = Meteor.users.findOne({ username: msg.msg }, { fields: { username: 1 } });
RoomModeratorsAndOwners.upsert({ rid: msg.rid, "u._id": user._id }, { $setOnInsert: { u: user }, $addToSet: { roles: 'moderator' } });
} else if (msg.t === 'moderator-removed') {
user = Meteor.users.findOne({ username: msg.msg });
moderator = RoomModeratorsAndOwners.findOne({ rid: msg.rid, "u._id": user._id, roles: 'moderator' });
if (moderator && moderator.roles && moderator.roles.length === 1 && moderator.roles[0] === 'moderator') {
RoomModeratorsAndOwners.remove({ rid: msg.rid, "u._id": user._id, roles: 'moderator' });
} else if (moderator) {
RoomModeratorsAndOwners.update({ rid: msg.rid, "u._id": user._id }, { $pull: { roles: 'moderator' } });
}
}
return msg;
}, RocketChat.callbacks.priority.LOW, 'addOrRemoveModerator');
RocketChat.callbacks.add('streamMessage', function(msg) {
if (msg.t === 'new-owner') {
user = Meteor.users.findOne({ username: msg.msg }, { fields: { username: 1 } });
RoomModeratorsAndOwners.upsert({ rid: msg.rid, "u._id": user._id }, { $setOnInsert: { u: user }, $addToSet: { roles: 'owner' } });
} else if (msg.t === 'owner-removed') {
user = Meteor.users.findOne({ username: msg.msg });
owner = RoomModeratorsAndOwners.findOne({ rid: msg.rid, "u._id": user._id, roles: 'owner' });
if (owner && owner.roles && owner.roles.length === 1 && owner.roles[0] === 'owner') {
RoomModeratorsAndOwners.remove({ rid: msg.rid, "u._id": user._id, roles: 'owner' });
} else if (owner) {
RoomModeratorsAndOwners.update({ rid: msg.rid, "u._id": user._id }, { $pull: { roles: 'owner' } });
}
}
return msg;
}, RocketChat.callbacks.priority.LOW, 'addOrRemoveOwner');
})
......@@ -56,6 +56,7 @@ Package.onUse(function(api) {
api.addFiles('lib/sideNav.coffee', 'client');
api.addFiles('lib/tapi18n.coffee', 'client');
api.addFiles('lib/textarea-autogrow.js', 'client');
api.addFiles('lib/updateModeratorsAndOwners.js', 'client');
// LIB CORDOVA
api.addFiles('lib/cordova/facebook-login.coffee', 'client');
......
......@@ -493,7 +493,13 @@ Template.room.onCreated ->
@autorun =>
@subscribe 'fullUserData', Session.get('showUserInfo'), 1
@subscribe 'roomModerators', @data._id
Meteor.call 'getRoomModeratorsAndOwners', @data._id, (error, results) ->
if error
return toastr.error error.reason
for record in results
delete record._id
RoomModeratorsAndOwners.upsert { rid: record.rid, "u._id": record.u._id }, record
Template.room.onDestroyed ->
window.removeEventListener 'resize', this.onWindowResize
......
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
......@@ -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
......
......@@ -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 }})
......
Meteor.methods
getRoomModeratorsAndOwners: (rid) ->
unless Meteor.userId()
throw new Meteor.Error 'invalid-user', '[methods] getRoomModeratorsAndOwners -> Invalid user'
check rid, String
options =
sort:
"u.username": 1
fields:
rid: 1
u: 1
roles: 1
return RocketChat.models.Subscriptions.findByRoomIdAndRoles(rid, ['moderator', 'owner'], options).fetch()
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
......@@ -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,
......
Meteor.publish 'roomModerators', (rid, limit = 50) ->
unless this.userId
return this.ready()
pub = this
query =
rid: rid
roles: 'moderator'
options =
limit: limit
sort:
"u.username": 1
fields:
rid: 1
u: 1
cursor = RocketChat.models.Subscriptions.find(query, options).observeChanges
added: (_id, record) ->
pub.added('room_moderators', _id, record)
changed: (_id, record) ->
pub.changed('room_moderators', _id, record)
removed: (_id, record) ->
pub.removed('room_moderators', _id, record)
this.ready()
this.onStop ->
cursor.stop()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment