From ff094ec2e69dc40ef56c2c3ec6f152cc892a23fc Mon Sep 17 00:00:00 2001 From: Marcelo Schmidt Date: Tue, 6 Oct 2015 13:40:55 -0300 Subject: [PATCH] Rate-limit username and avatar changes --- client/views/account/avatar/prompt.coffee | 14 ++++++--- i18n/en.i18n.json | 1 + .../rocketchat-lib/lib/rateLimiter.coffee | 31 ++++++++++++++++++- .../server/functions/setUsername.coffee | 2 +- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/client/views/account/avatar/prompt.coffee b/client/views/account/avatar/prompt.coffee index dd9d88cecdd..a73f8da8f27 100644 --- a/client/views/account/avatar/prompt.coffee +++ b/client/views/account/avatar/prompt.coffee @@ -38,11 +38,17 @@ Template.avatarPrompt.helpers Template.avatarPrompt.events 'click .select-service': -> if @service is 'initials' - Meteor.call 'resetAvatar' - toastr.success t('Avatar_changed_successfully') + Meteor.call 'resetAvatar', (err) -> + if err?.details?.timeToReset? + toastr.error t('Error_too_many_requests', parseInt(err.details.timeToReset / 1000)) + else + toastr.success t('Avatar_changed_successfully') else - Meteor.call 'setAvatarFromService', @blob, @contentType, @service, -> - toastr.success t('Avatar_changed_successfully') + Meteor.call 'setAvatarFromService', @blob, @contentType, @service, (err) -> + if err?.details?.timeToReset? + toastr.error t('Error_too_many_requests', parseInt(err.details.timeToReset / 1000)) + else + toastr.success t('Avatar_changed_successfully') 'click .login-with-service': (event, template) -> loginWithService = "loginWith#{_.capitalize(this)}" diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 216df7f1a23..7fb818188d4 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -105,6 +105,7 @@ "Enter_info" : "Enter your information", "Enter_to" : "Enter to", "Error_changing_password" : "Error changing password", + "Error_too_many_requests" : "Error, too many requests. Please slow down. You must wait %s seconds before trying again", "Esc_to" : "Esc to", "False" : "False", "Favorites" : "Favorites", diff --git a/packages/rocketchat-lib/lib/rateLimiter.coffee b/packages/rocketchat-lib/lib/rateLimiter.coffee index c566b671a71..7a6813446b1 100644 --- a/packages/rocketchat-lib/lib/rateLimiter.coffee +++ b/packages/rocketchat-lib/lib/rateLimiter.coffee @@ -1,7 +1,7 @@ # Limit sending messages to 5 messages per second per user DDPRateLimiter.addRule userId: (userId) -> - return Meteor.users.findOne(userId)?.username isnt RocketChat.settings.get('RocketBot_Name') + return RocketChat.models.Users.findOneById(userId)?.username isnt RocketChat.settings.get('RocketBot_Name') clientAddress: null type: 'method' name: 'sendMessage' @@ -9,3 +9,32 @@ DDPRateLimiter.addRule return true , 5, 1000 + +# Limit changing avatar once per minute +DDPRateLimiter.addRule + userId: -> return true + connectionId: -> return true + clientAddress: null + type: 'method' + name: 'setAvatarFromService' +, 1, 60000 + + +# Limit changing avatar once per minute +DDPRateLimiter.addRule + userId: -> return true + connectionId: -> return true + clientAddress: null + type: 'method' + name: 'resetAvatar' +, 1, 60000 + +# Limit setting username once per minute +DDPRateLimiter.addRule + userId: -> return not RocketChat.authz.hasPermission( user._id, 'edit-other-user-info') + connectionId: -> return true + clientAddress: null + type: 'method' + name: 'setUsername' +, 1, 60000 + diff --git a/packages/rocketchat-lib/server/functions/setUsername.coffee b/packages/rocketchat-lib/server/functions/setUsername.coffee index 664b48e9e85..24cabea806f 100644 --- a/packages/rocketchat-lib/server/functions/setUsername.coffee +++ b/packages/rocketchat-lib/server/functions/setUsername.coffee @@ -31,6 +31,6 @@ RocketChat.setUsername = (user, username) -> RocketChat.models.Subscriptions.setNameForDirectRoomsWithOldName previousUsername, username # Set new username - Meteor.users.update { _id: user._id }, { $set: { username: username } } + RocketChat.models.Users.setUsername user._id, username user.username = username return user