module Authentication
  extend ActiveSupport::Concern
  SESSION_LOGIN_NAME_KEY = :login_name
  SESSION_EMAIL_KEY = :email
  SESSION_2FA_KEY = :twofa

  included do
    helper_method :current_user
    before_action :authentication_required
  end

  protected

  def log_in(user)
    session[SESSION_LOGIN_NAME_KEY] = user.ldap_login
    session[SESSION_EMAIL_KEY] = user.email
  end

  def log_out
    flash.now[:success] = "Logged out successfully"
    [SESSION_LOGIN_NAME_KEY, SESSION_EMAIL_KEY, SESSION_2FA_KEY].each do |key|
      session.delete key
    end
  end

  def twofa_performed?
    session[SESSION_2FA_KEY].present?
  end

  def twofa_performed
    flash[:success] = "Logged in as #{current_user.ldap_login}"
    session[SESSION_2FA_KEY] = true
  end

  def login_required
    return true if signed_in?
    save_state_and_redirect login_path
  end

  def twofa_required
    return true if twofa_performed?
    save_state_and_redirect twofa_path
  end

  def authentication_required
    login_required && twofa_required
  end

  def save_state_and_redirect(path)
    store_location
    redirect_to path
    return false
  end

  def signed_in?
    current_user.present?
  end

  def current_user
    @current_user ||= BeefCake::User.find(session[SESSION_LOGIN_NAME_KEY], email: session[SESSION_EMAIL_KEY]) if session[SESSION_LOGIN_NAME_KEY].present?
  end
end
