Skip to content

Commit

Permalink
THREESCALE-10074: Do not reveal that email doesn't exist on Forgot pa…
Browse files Browse the repository at this point in the history
…ssword form (#3837)

* Do not reveal that email doesn't exist on Forgot password form

* Some fixes

* Reorganize cucumbers for password reset
  • Loading branch information
mayorova authored Jul 5, 2024
1 parent 3898a60 commit bb1b2f0
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 97 deletions.
101 changes: 82 additions & 19 deletions features/developer_portal/buyer_password_reset.feature
Original file line number Diff line number Diff line change
@@ -1,25 +1,88 @@
Feature: Buyer signup
Feature: Buyer password reset
I want to reset my password as a buyer

Background:
Given a provider exists
And the default product of provider "master" has name "Master API"
And the following application plan:
| Product | Name |
| Master API | enterprise |
And the provider has bot protection enabled
And the provider account allows signups

@recaptcha
Scenario: Bot protection doesn't detect the client as a bot
And the client will be marked as a bot
When the buyer wants to reset their password
And the buyer fills in the form
Then the page should contain "Bot protection failed."
Rule: ReCAPTCHA protects from bots
Background:
Given the provider has bot protection enabled

@recaptcha
Scenario: Bot protection doesn't detect the client as a bot
And the client won't be marked as a bot
When the buyer wants to reset their password
And the buyer fills in the form
Then the page should contain "Email not found."
@recaptcha
Scenario: Bot protection doesn't detect the client as a bot
Given the client will be marked as a bot
When the buyer wants to reset their password
And the buyer fills in the form
Then the page should contain "Bot protection failed."

@recaptcha
Scenario: Bot protection doesn't detect the client as a bot
Given the client won't be marked as a bot
When the buyer wants to reset their password
And the buyer fills in the form
Then the page should contain "A password reset link will be sent"

Rule: Reset password flow for different scenarios
Background:
Given a buyer "bob" signed up to the provider
And an active user "zed" of account "bob" with email "zed@3scale.localhost"
And the current domain is foo.3scale.localhost
And they go to the login page

Scenario: Reset password of an existing user
Given they follow "Forgot password?"
And they fill in "Email" with "zed@3scale.localhost"
And they press "Send instructions"
Then they should see "A password reset link will be sent to zed@3scale.localhost if a user exists with this email."
When they follow the link found in the password reset email send to "zed@3scale.localhost"
And they fill in "Password" with "monkey"
And they fill in "Password confirmation" with "monkey"
And they press "Change Password"
Then they should see "The password has been changed"

When they go to the login page
And they fill in "Username" with "zed@3scale.localhost"
And they fill in "Password" with "monkey"
And they press "Sign in"
Then they should be logged in as "zed"

Scenario: Invalid email
Given no user exists with an email of "bob@3scale.localhost"
And they follow "Forgot password?"
And they fill in "Email" with "bob@3scale.localhost"
And they press "Send instructions"
Then they should see "A password reset link will be sent to bob@3scale.localhost if a user exists with this email."
And "bob@3scale.localhost" should receive no emails

Scenario: Wrong confirmation
Given they follow "Forgot password?"
And they fill in "Email" with "zed@3scale.localhost"
And they press "Send instructions"
And they follow the link found in the password reset email send to "zed@3scale.localhost"
And they fill in "Password" with "monkey"
And they fill in "Password confirmation" with "donkey"
And they press "Change Password"
Then they should see the password confirmation error
And the password of user "zed" should not be "monkey"

Scenario: Blank passwords
When they follow "Forgot password?"
And they fill in "Email" with "zed@3scale.localhost"
And they press "Send instructions"
And they follow the link found in the password reset email send to "zed@3scale.localhost"
And they press "Change Password"
Then they should see "The password is invalid"

Scenario: Invalid token
When they go to the password page with invalid password reset token
Then they should see "The password reset token is invalid"

Scenario: Attempt to login with invalid credentials, then reset password
Given they fill in "Username" with "zed@3scale.localhost"
And they fill in "Password" with "ihavenoclue"
And they press "Sign in"
Then they should see "Incorrect email or password. Please try again."
When they follow "Forgot password?"
And they fill in "Email" with "zed@3scale.localhost"
And they press "Send instructions"
Then they should see "A password reset link will be sent to zed@3scale.localhost if a user exists with this email."
68 changes: 0 additions & 68 deletions features/old/accounts/buyers/buyer_password_reset.feature

This file was deleted.

4 changes: 2 additions & 2 deletions features/step_definitions/password_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
assert !user.authenticated?(password)
end

When /^I follow the link found in the password reset email send to "([^"]*)"$/ do |email|
When /^(?:|I |they )follow the link found in the password reset email send to "([^"]*)"$/ do |email|
visit_url_in_email(email, /Lost password recovery/)

end
Expand All @@ -34,7 +34,7 @@ def visit_url_in_email(email, subject)
visit url
end

Then 'I should see the password confirmation error' do
Then /^(?:|I |they )should see the password confirmation error$/ do
%q(I should see error "doesn't match Password" for field "Password confirmation")
end

Expand Down
2 changes: 1 addition & 1 deletion features/step_definitions/session_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
click_button('Sign in')
end

Then /^I should be logged in as "([^"]*)"$/ do |username|
Then /^(?:|I |they )should be logged in as "([^"]*)"$/ do |username|
assert_current_user(username)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ class DeveloperPortal::Admin::Account::PasswordsController < ::DeveloperPortal::
def create
return redirect_to_request_password('Bot protection failed.') unless bot_check({ flash: false })

user = @provider.buyer_users.find_by_email(params[:email])
return redirect_to_request_password('Email not found.') unless user
email = params[:email]
user = @provider.buyer_users.find_by(email: email)
user&.generate_lost_password_token!

user.generate_lost_password_token!
flash[:notice] = 'A password reset link has been emailed to you.'
flash[:notice] = "A password reset link will be sent to #{email} if a user exists with this email."
redirect_to login_url
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ def test_update_password
post developer_portal.admin_account_password_path(email: user.email)
end
assert_in_delta Time.now, user.reload.lost_password_token_generated_at, 2.seconds
assert_equal 'A password reset link has been emailed to you.', flash[:notice]
assert_equal "A password reset link will be sent to #{user.email} if a user exists with this email.", flash[:notice]
assert_redirected_to developer_portal.login_path
end

test 'create renders the right error message when the email is not found' do
post developer_portal.admin_account_password_path(email: 'fake@example.com')
assert_equal 'Email not found.', flash[:error]
assert_redirected_to developer_portal.new_admin_account_password_path(request_password_reset: true)
assert_equal "A password reset link will be sent to fake@example.com if a user exists with this email.", flash[:notice]
assert_redirected_to developer_portal.login_path
end

private
Expand Down

0 comments on commit bb1b2f0

Please sign in to comment.