slovensko-digital/navody.digital

View on GitHub
app/controllers/sessions_controller.rb

Summary

Maintainability
A
3 hrs
Test Coverage
C
71%
class SessionsController < ApplicationController
  before_action :disable_feedback

  def new
    session[:after_login_callback] = params[:callback]
  end

  def create
    if should_put_eid_token_in_session?
      session[:eid_encoded_token] = eid_encoded_token_from_auth
    end

    if new_eid_identity?
      unless fully_represents_subject?
        render :insufficient_representation, locals: { eid_token: eid_token }
        return
      end

      render :new_eid_identity, locals: { eid_token: eid_token }
      return
    end

    unless auth_email.present?
      redirect_to new_session_path, alert: 'Prosím zadajte e-mail'
      return
    end

    user = User.find_by('lower(email) = lower(?)', auth_email) || User.create!(email: auth_email)

    notice = user.previously_new_record? ? 'first_time_login' : 'Prihlásenie úspešné. Vitajte!'

    if eid_identity_approval?
      assertion = Upvs::Assertion.assertion(eid_token)

      if assertion
        user.update!(
          eid_sub: eid_sub_from_auth,
          subject_name: assertion.subject_name,
          subject_cin: assertion.subject_cin,
          subject_edesk_number: assertion.subject_edesk_number,
          )
      else
        user.update!(eid_sub: eid_sub_from_auth)
      end
    end

    unless should_keep_eid_token_in_session?(user.eid_sub)
      session.delete(:eid_encoded_token)
    end

    session[:user_id] = user.id

    redirect_to after_login_redirect_path, notice: notice
  end
  def magic_link_info
    @email = params[:email]
  end

  def failure
    @message = params[:message]
    @strategy = params[:strategy]
  end

  def logout
    reset_session

    if params[:callback].present?
      redirect_to params[:callback]
    else
      redirect_to root_path, notice: 'Odhlásenie bolo úspešné.'
    end
  end

  def destroy
    if should_perform_eid_logout?
      eid_logout_url = eid_token.generate_logout_url(expires_in: 5.minutes)
      reset_session

      redirect_to eid_logout_url
    else
      logout
    end
  end

  protected

  def auth_email
    auth_hash.dig('info', 'email')
  end

  private

  def should_perform_eid_logout?
    eid_token.present? && !eid_token.expired?
  end

  def new_eid_identity?
    auth_hash.provider == "eid" && auth_hash.info['email'].blank?
  end

  def eid_identity_approval?
    auth_hash.provider == "magiclink" && eid_sub_from_auth.present?
  end

  def should_keep_eid_token_in_session?(user_eid_sub)
    eid_encoded_token_from_session.present? && EidToken.new(eid_encoded_token_from_session, config: eid_config).sub == user_eid_sub
  end

  def should_put_eid_token_in_session?
    auth_hash.provider == "eid" && eid_encoded_token_from_auth.present?
  end

  def after_login_redirect_path
    return session[:after_login_callback] if session[:after_login_callback]&.start_with?("/") # Only allow local redirects
    root_path
  end

  def fully_represents_subject?
    assertion = Upvs::Assertion.assertion(eid_token)
    assertion&.fully_represents_subject?
  end
end