mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-24 20:16:08 +10:00
Only allow password reset emails once per minute
Addresses internal https://dev.gitlab.org/gitlab/gitlabhq/issues/2611
This commit is contained in:
@@ -2,18 +2,19 @@ class PasswordsController < Devise::PasswordsController
|
||||
|
||||
def create
|
||||
email = resource_params[:email]
|
||||
resource_found = resource_class.find_by_email(email)
|
||||
if resource_found && resource_found.ldap_user?
|
||||
self.resource = resource_class.find_by_email(email)
|
||||
|
||||
if resource && resource.ldap_user?
|
||||
flash[:alert] = "Cannot reset password for LDAP user."
|
||||
respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name)) and return
|
||||
end
|
||||
|
||||
self.resource = resource_class.send_reset_password_instructions(resource_params)
|
||||
if successfully_sent?(resource)
|
||||
respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name))
|
||||
else
|
||||
respond_with(resource)
|
||||
unless can_send_reset_email?
|
||||
flash[:alert] = "Instructions about how to reset your password have already been sent recently. Please wait a few minutes to try again."
|
||||
respond_with({}, location: new_password_path(resource_name)) and return
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def edit
|
||||
@@ -35,4 +36,11 @@ class PasswordsController < Devise::PasswordsController
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def can_send_reset_email?
|
||||
resource && (resource.reset_password_sent_at.blank? ||
|
||||
resource.reset_password_sent_at < 1.minute.ago)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,13 +1,44 @@
|
||||
require 'spec_helper'
|
||||
|
||||
feature 'Password reset', feature: true do
|
||||
describe 'with two-factor authentication' do
|
||||
let(:user) { create(:user, :two_factor) }
|
||||
describe 'throttling' do
|
||||
it 'sends reset instructions when not previously sent' do
|
||||
visit root_path
|
||||
forgot_password(create(:user))
|
||||
|
||||
expect(page).to have_content(I18n.t('devise.passwords.send_instructions'))
|
||||
expect(current_path).to eq new_user_session_path
|
||||
end
|
||||
|
||||
it 'sends reset instructions when previously sent more than a minute ago' do
|
||||
user = create(:user)
|
||||
user.send_reset_password_instructions
|
||||
user.update_attribute(:reset_password_sent_at, 5.minutes.ago)
|
||||
|
||||
visit root_path
|
||||
forgot_password(user)
|
||||
|
||||
expect(page).to have_content(I18n.t('devise.passwords.send_instructions'))
|
||||
expect(current_path).to eq new_user_session_path
|
||||
end
|
||||
|
||||
it "throttles multiple resets in a short timespan" do
|
||||
user = create(:user)
|
||||
user.send_reset_password_instructions
|
||||
|
||||
visit root_path
|
||||
forgot_password(user)
|
||||
|
||||
expect(page).to have_content("Instructions about how to reset your password have already been sent recently. Please wait a few minutes to try again.")
|
||||
expect(current_path).to eq new_user_password_path
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with two-factor authentication' do
|
||||
it 'requires login after password reset' do
|
||||
visit root_path
|
||||
|
||||
forgot_password
|
||||
forgot_password(create(:user, :two_factor))
|
||||
reset_password
|
||||
|
||||
expect(page).to have_content("Your password was changed successfully.")
|
||||
@@ -17,12 +48,10 @@ feature 'Password reset', feature: true do
|
||||
end
|
||||
|
||||
describe 'without two-factor authentication' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'requires login after password reset' do
|
||||
visit root_path
|
||||
|
||||
forgot_password
|
||||
forgot_password(create(:user))
|
||||
reset_password
|
||||
|
||||
expect(page).to have_content("Your password was changed successfully.")
|
||||
@@ -30,7 +59,7 @@ feature 'Password reset', feature: true do
|
||||
end
|
||||
end
|
||||
|
||||
def forgot_password
|
||||
def forgot_password(user)
|
||||
click_on 'Forgot your password?'
|
||||
fill_in 'Email', with: user.email
|
||||
click_button 'Reset password'
|
||||
|
||||
Reference in New Issue
Block a user