From 0c53c612376bbf316b971cf43011a87cf75c45f7 Mon Sep 17 00:00:00 2001 From: Aditya Prakash Date: Sat, 7 Jan 2017 17:07:01 +0530 Subject: [PATCH] Expire password reset token after 15 minutes generate_confirmation_token method overides the one provide by clearance. --- .../email_confirmations_controller.rb | 4 +- app/controllers/passwords_controller.rb | 8 ++++ app/models/user.rb | 6 +-- test/functional/passwords_controller_test.rb | 38 +++++++++++++++++++ 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/app/controllers/email_confirmations_controller.rb b/app/controllers/email_confirmations_controller.rb index 66c53fb38ce..454292e110e 100644 --- a/app/controllers/email_confirmations_controller.rb +++ b/app/controllers/email_confirmations_controller.rb @@ -18,7 +18,7 @@ def create user = User.find_by(email: confirmation_params[:email]) if user - user.regenerate_confirmation_token + user.generate_confirmation_token Mailer.delay.email_confirmation(user) if user.save end redirect_to root_path, notice: t('.promise_resend') @@ -26,7 +26,7 @@ def create # used to resend confirmation mail for unconfirmed_email validation def unconfirmed - if current_user.regenerate_confirmation_token && current_user.save + if current_user.generate_confirmation_token && current_user.save Mailer.delay.email_reset(current_user) flash[:notice] = t('profiles.update.confirmation_mail_sent') else diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb index 896db0a5b46..f04e60ed72e 100644 --- a/app/controllers/passwords_controller.rb +++ b/app/controllers/passwords_controller.rb @@ -1,4 +1,6 @@ class PasswordsController < Clearance::PasswordsController + before_action :validate_confirmation_token, only: :edit + def find_user_for_create Clearance.configuration.user_model .find_by_normalized_email password_params[:email] @@ -13,4 +15,10 @@ def url_after_update def password_params params.require(:password).permit(:email) end + + def validate_confirmation_token + user = find_user_for_edit + return if user&.valid_confirmation_token? + redirect_to root_path, alert: t('failure_when_forbidden') + end end diff --git a/app/models/user.rb b/app/models/user.rb index e2a38d65fa1..e39af482975 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -24,7 +24,7 @@ class User < ActiveRecord::Base has_many :web_hooks after_validation :set_unconfirmed_email, if: :email_changed?, on: :update - before_create :generate_api_key, :regenerate_confirmation_token + before_create :generate_api_key, :generate_confirmation_token validates :handle, uniqueness: true, allow_nil: true validates :handle, format: { @@ -104,7 +104,7 @@ def encode_with(coder) def set_unconfirmed_email self.attributes = { unconfirmed_email: email, email: email_was } - regenerate_confirmation_token + generate_confirmation_token end def generate_api_key @@ -133,7 +133,7 @@ def valid_confirmation_token? token_expires_at > Time.zone.now end - def regenerate_confirmation_token + def generate_confirmation_token self.confirmation_token = Clearance::Token.new self.token_expires_at = Time.zone.now + 15.minutes end diff --git a/test/functional/passwords_controller_test.rb b/test/functional/passwords_controller_test.rb index 5d226d5efcf..7c0fd0e0236 100644 --- a/test/functional/passwords_controller_test.rb +++ b/test/functional/passwords_controller_test.rb @@ -9,5 +9,43 @@ class PasswordsControllerTest < ActionController::TestCase assert page.has_content?("Request is missing param 'password'") end end + + context "with valid params" do + setup do + @user = create(:user) + get :create, password: { email: @user.email } + end + + should "set a valid confirmation_token" do + assert @user.valid_confirmation_token? + end + end + end + + context "on GET to edit" do + setup do + @user = create(:user) + @user.forgot_password! + end + + context "with valid confirmation_token" do + setup do + get :edit, token: @user.confirmation_token, user_id: @user.id + end + + should redirect_to("password edit page") { edit_user_password_path } + end + + context "with expired confirmation_token" do + setup do + @user.update_attribute(:token_expires_at, 1.minute.ago) + get :edit, token: @user.confirmation_token, user_id: @user.id + end + + should redirect_to("the home page") { root_path } + should "warn about invalid url" do + assert_equal flash[:alert], "Please double check the URL or try submitting it again." + end + end end end