Retrospring/app/controllers/user/sessions_controller.rb

69 lines
1.7 KiB
Ruby

# frozen_string_literal: true
class User::SessionsController < Devise::SessionsController
def new
session.delete(:user_sign_in_uid)
super
end
def create
authenticate!
if resource.active_for_authentication? && resource.otp_module_enabled?
if params[:user][:otp_attempt].blank?
prompt_for_2fa
else
attempt_2fa
end
else
continue_sign_in(resource, resource_name)
end
end
private
def authenticate!
self.resource = session.key?(:user_sign_in_uid) ? User.find(session.delete(:user_sign_in_uid)) : warden.authenticate!(auth_options)
end
def continue_sign_in(resource, resource_name)
set_flash_message!(:notice, :signed_in)
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, location: after_sign_in_path_for(resource)
end
def prompt_for_2fa
session[:user_sign_in_uid] = resource.id
sign_out(resource)
warden.lock!
render "auth/two_factor_authentication"
end
def attempt_2fa
if params[:user][:otp_attempt].length == 8
try_recovery_code
elsif resource.authenticate_otp(params[:user][:otp_attempt], drift: APP_CONFIG.fetch(:otp_drift_period, 30).to_i)
continue_sign_in(resource, resource_name)
else
fail_2fa
end
end
def try_recovery_code
found = TotpRecoveryCode.where(user_id: resource.id, code: params[:user][:otp_attempt].downcase).delete_all
if found == 1
flash[:info] = t(".info", count: TotpRecoveryCode.where(user_id: resource.id).count)
continue_sign_in(resource, resource_name)
else
fail_2fa
end
end
def fail_2fa
sign_out(resource)
flash[:error] = t(".error")
redirect_to new_user_session_url
end
end