class LoginController < ApplicationController before_filter :authenticate_user def logout if @user reset_session end redirect_to "/" end def index @title = "Login" @referer ||= request.referer render :action => "index" end def login if params[:email].to_s.match(/@/) user = User.where(:email => params[:email]).first else user = User.where(:username => params[:email]).first end begin if !user raise "no user" end if !user.try(:authenticate, params[:password].to_s) raise "authentication failed" end if user.is_banned? raise "user is banned" end if !user.is_active? user.undelete! flash[:success] = "Your account has been reactivated and your " << "unmoderated comments have been undeleted." end if !user.password_digest.to_s.match(/^\$2a\$#{BCrypt::Engine::DEFAULT_COST}\$/) user.password = user.password_confirmation = params[:password].to_s user.save! end if user.has_2fa? if params[:totp].present? if !user.authenticate_totp(params[:totp]) raise "invalid TOTP code" end else return respond_to do |format| format.html { session[:twofa_u] = user.session_token redirect_to "/login/2fa" } format.json { render :json => { :status => 0, :error => "must supply totp parameter" } } end end end return respond_to do |format| format.html { session[:u] = user.session_token if (rd = session[:redirect_to]).present? session.delete(:redirect_to) return redirect_to rd elsif params[:referer].present? begin ru = URI.parse(params[:referer]) if ru.host == Rails.application.domain return redirect_to ru.to_s end rescue => e Rails.logger.error "error parsing referer: #{e}" end end redirect_to "/" } format.json { render :json => { :status => 1, :username => user.username } } end rescue end respond_to do |format| format.html { flash.now[:error] = I18n.t 'controllers.login_controller.flashlogininvalid' @referer = params[:referer] index } format.json { render :json => { :status => 0, :error => "invalid 'email' and/or 'password' parameter" } } end end def forgot_password @title = "Reset Password" render :action => "forgot_password" end def reset_password @found_user = User.where("email = ? OR username = ?", params[:email].to_s, params[:email].to_s).first if !@found_user flash.now[:error] = "Invalid e-mail address or username." return forgot_password end @found_user.initiate_password_reset_for_ip(request.remote_ip) flash.now[:success] = "Password reset instructions have been e-mailed " << "to you." return index end def set_new_password @title = "Reset Password" if (m = params[:token].to_s.match(/^(\d+)-/)) && (Time.now - Time.at(m[1].to_i)) < 24.hours @reset_user = User.where(:password_reset_token => params[:token].to_s).first end if @reset_user && !@reset_user.is_banned? if params[:password].present? @reset_user.password = params[:password] @reset_user.password_confirmation = params[:password_confirmation] @reset_user.password_reset_token = nil # this will get reset upon save @reset_user.session_token = nil if !@reset_user.is_active? && !@reset_user.is_banned? @reset_user.deleted_at = nil end if @reset_user.save && @reset_user.is_active? session[:u] = @reset_user.session_token return redirect_to "/" else flash[:error] = "Could not reset password." end end else flash[:error] = "Invalid reset token. It may have already been " << "used or you may have copied it incorrectly." return redirect_to forgot_password_path end end def twofa if tmpu = find_twofa_user Rails.logger.info " Authenticated as user #{tmpu.id} " << "(#{tmpu.username}), verifying TOTP" else reset_session return redirect_to "/login" end end def twofa_verify if (tmpu = find_twofa_user) && tmpu.authenticate_totp(params[:totp_code]) session[:u] = tmpu.session_token session.delete(:twofa_u) return redirect_to "/" else flash[:error] = t('.totpcodenotmatch') return redirect_to "/login/2fa" end end private def find_twofa_user if session[:twofa_u].present? return User.where(:session_token => session[:twofa_u]).first end end end