Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

THREESCALE-10663: Do not reveal that email doesn't exist on Forgot password form #3837

Merged
merged 3 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -113,7 +113,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