app/controllers/password_retrieval_controller.rb
class PasswordRetrievalController < ApplicationController
def action_allowed?
true
end
def forgotten
render template: "password_retrieval/forgotten"
end
def send_password
if params[:user][:email].nil? || params[:user][:email].strip.empty?
flash[:error] = "Please enter an e-mail address."
else
user = User.find_by(email: params[:user][:email])
if user
url_format = "/password_edit/check_reset_url?token="
token = SecureRandom.urlsafe_base64
PasswordReset.save_token(user, token)
url = self.request.base_url + url_format + token
MailerHelper.send_mail_to_user(user, "Expertiza password reset", "send_password", url).deliver_now
ExpertizaLogger.info LoggerMessage.new(controller_name, user.name, 'A link to reset your password has been sent to users e-mail address.', request)
flash[:success] = "A link to reset your password has been sent to your e-mail address."
redirect_to "/"
else
ExpertizaLogger.error LoggerMessage.new(controller_name, params[:user][:email], 'No user is registered with provided email id!', request)
flash[:error] = "No account is associated with the e-mail address: \"" + params[:user][:email] + "\". Please try again."
render template: "password_retrieval/forgotten"
end
end
end
# The token obtained from the reset url is first checked if it is valid ( if actually generated by the application), then checks if the token is active.
def check_reset_url
if params[:token].nil?
flash[:error] = "Password reset page can only be accessed with a generated link, sent to your email"
render template: "password_retrieval/forgotten"
else
@token = Digest::SHA1.hexdigest(params[:token])
password_reset = PasswordReset.find_by(token: @token)
if password_reset
# URL expires after 1 day
expired_url = password_reset.updated_at + 1.day
if Time.now < expired_url
# redirect_to action: 'reset_password', email: password_reset.user_email
@email = password_reset.user_email
render template: "password_retrieval/reset_password"
else
ExpertizaLogger.error LoggerMessage.new(controller_name, '', 'User tried to access expired link!', request)
flash[:error] = "Link expired . Please request to reset password again"
render template: "password_retrieval/forgotten"
end
else
ExpertizaLogger.error LoggerMessage.new(controller_name, '', 'User tried to access either expired link or wrong token!', request)
flash[:error] = "Link either expired or wrong Token. Please request to reset password again"
render template: "password_retrieval/forgotten"
end
end
end
# avoid users to access this page without a valid token
def reset_password
flash[:error] = "Password reset page can only be accessed with a generated link, sent to your email"
render template: "password_retrieval/forgotten"
end
# called after entering password and repassword, checks for validation and updates the password of the email
def update_password
if params[:reset][:password] == params[:reset][:repassword]
user = User.find_by(email: params[:reset][:email])
user.password = params[:reset][:password]
user.password_confirmation = params[:reset][:repassword]
if user.save
PasswordReset.delete_all(user_email: user.email)
ExpertizaLogger.info LoggerMessage.new(controller_name, user.name, 'Password was reset for the user', request)
flash[:success] = "Password was successfully reset"
redirect_to "/"
else
ExpertizaLogger.error LoggerMessage.new(controller_name, user.name, 'Password reset operation failed for the user while saving record', request)
flash[:error] = "Password cannot be updated. Please try again"
redirect_to "/"
end
else
ExpertizaLogger.error LoggerMessage.new(controller_name, "", 'Password provided by the user did not match', request)
flash[:error] = "Password and confirm-password do not match. Try again"
@email = params[:reset][:email]
render template: "password_retrieval/reset_password"
end
end
end