mardi 30 mars 2021

throw :warden not always caught by failure_app

I have a Ruby on Rails project (Rails 3.2, Ruby 1.9.3) in which there are two kinds of user and both of them are set up with devise. When the sing in fails for one kind of user (Pc), I wish to try if the credentials are correct for the other one (Tutor), since some Tutor users forget to use their specific login page. I created a custom failure app in which I recreate the call but for the other resource name. It works correctly if there is a user of type Tutor with the credentials (login succeeds). However, if the second attempt fails, the failure app is not called again and the warden error is not caught. I can't see why it would be called the first time but not the second. While debugging I have checked that warden.manager.config.failure_app keeps being my custom failure app through all the calls. Could anyone tell me if this is the expected behaviour? These are some key parts of the code:


class CustomFailureApp < Devise::FailureApp

  def respond
    if warden_options[:scope] == :pc && (warden_message == :invalid || warden_message == :not_found_in_database)
      params[:tutor] = params[:pc] # copy the credentials as if they were tutor credentials
      params.except!(:pc) # remove pc params
      flash.keep # it gets cleared otherwise, which leads to errors
      request.env["devise.mapping"] = Devise.mappings[:tutor]
      sessions_controller = SessionsController.new
      sessions_controller.request = request
      sessions_controller.response = response
      sessions_controller.process(:create)
    else
      super
    end
  end

#... other unrelated code
config.warden do |manager|
    manager.failure_app = CustomFailureApp
  end

What I observed is that in proxy.rb (warden gem), in:

   def authenticate!(*args)
      user, opts = _perform_authentication(*args)
      throw(:warden, opts) unless user
      user
    end

the first time, CustomFailureApp is called after throw(:warden, opts) unless user but on the second time it is not, it continues and leads to some other errors related to user being nil here

Aucun commentaire:

Enregistrer un commentaire