# class Devise::FailureApp

Failure application that will be called every time :warden is thrown from any strategy or hook. Responsible for redirect the user to the sign in page based on current scope and mapping. If no scope is given, redirect to the default_url.

### Public Class Methods

call(env) click to toggle source

    # File lib/devise/failure_app.rb, line 18
    def self.call(env)
      @respond ||= action(:respond)
      @respond.call(env)
    end

default_url_options(*args) click to toggle source

    # File lib/devise/failure_app.rb, line 23
    def self.default_url_options(*args)
      if defined?(ApplicationController)
        ApplicationController.default_url_options(*args)
      else
        {}
      end
    end

### Public Instance Methods

http_auth() click to toggle source

    # File lib/devise/failure_app.rb, line 41
    def http_auth
      self.status = 401
      self.headers["WWW-Authenticate"] = %Q(Basic realm=#{Devise.http_authentication_realm.inspect}) if http_auth_header?
      self.content_type = request.format.to_s
      self.response_body = http_auth_body
    end

recall() click to toggle source

    # File lib/devise/failure_app.rb, line 48
    def recall
      env["PATH_INFO"]  = attempted_path
      flash.now[:alert] = i18n_message(:invalid)
      self.response = recall_app(warden_options[:recall]).call(env)
    end

redirect() click to toggle source

    # File lib/devise/failure_app.rb, line 54
    def redirect
      store_location!
      if flash[:timedout] && flash[:alert]
        flash.keep(:timedout)
        flash.keep(:alert)
      else
        flash[:alert] = i18n_message
      end
      redirect_to redirect_url
    end

respond() click to toggle source

    # File lib/devise/failure_app.rb, line 31
    def respond
      if http_auth?
        http_auth
      elsif warden_options[:recall]
        recall
      else
        redirect
      end
    end

### Protected Instance Methods

attempted_path() click to toggle source

    # File lib/devise/failure_app.rb, line 164
    def attempted_path
      warden_options[:attempted_path]
    end

http_auth?() click to toggle source

Choose whether we should respond in a http authentication fashion, including 401 and optional headers.

This method allows the user to explicitly disable http authentication on ajax requests in case they want to redirect on failures instead of handling the errors on their own. This is useful in case your ajax API is the same as your public API and uses a format like JSON (so you cannot mark JSON as a navigational format).

    # File lib/devise/failure_app.rb, line 115
    def http_auth?
      if request.xhr?
        Devise.http_authenticatable_on_xhr
      else
        !(request_format && is_navigational_format?)
      end
    end

http_auth_body() click to toggle source

    # File lib/devise/failure_app.rb, line 129
    def http_auth_body
      return i18n_message unless request_format
      method = "to_#{request_format}"
      if method == "to_xml"
        { :error => i18n_message }.to_xml(:root => "errors")
      elsif {}.respond_to?(method)
        { :error => i18n_message }.send(method)
      else
        i18n_message
      end
    end

http_auth_header?() click to toggle source

It does not make sense to send authenticate headers in ajax requests or if the user disabled them.

    # File lib/devise/failure_app.rb, line 125
    def http_auth_header?
      Devise.mappings[scope].to.http_authenticatable && !request.xhr?
    end

i18n_message(default = nil) click to toggle source

    # File lib/devise/failure_app.rb, line 67
    def i18n_message(default = nil)
      message = warden_message || default || :unauthenticated

      if message.is_a?(Symbol)
        I18n.t(:"#{scope}.#{message}", :resource_name => scope,
               :scope => "devise.failure", :default => [message])
      else
        message.to_s
      end
    end

is_navigational_format?() click to toggle source

    # File lib/devise/failure_app.rb, line 176
    def is_navigational_format?
      Devise.navigational_formats.include?(request_format)
    end

recall_app(app) click to toggle source

    # File lib/devise/failure_app.rb, line 141
    def recall_app(app)
      controller, action = app.split("#")
      controller_name  = ActiveSupport::Inflector.camelize(controller)
      controller_klass = ActiveSupport::Inflector.constantize("#{controller_name}Controller")
      controller_klass.action(action)
    end

redirect_url() click to toggle source

    # File lib/devise/failure_app.rb, line 78
    def redirect_url
      if warden_message == :timeout
        flash[:timedout] = true
        attempted_path || scope_path
      else
        scope_path
      end
    end

request_format() click to toggle source

    # File lib/devise/failure_app.rb, line 180
    def request_format
      @request_format ||= request.format.try(:ref)
    end

scope() click to toggle source

    # File lib/devise/failure_app.rb, line 160
    def scope
      @scope ||= warden_options[:scope] || Devise.default_scope
    end

scope_path() click to toggle source

    # File lib/devise/failure_app.rb, line 87
    def scope_path
      opts  = {}
      route = :"new_#{scope}_session_path"
      opts[:format] = request_format unless skip_format?

      context = send(Devise.router_name)

      if context.respond_to?(route)
        context.send(route, opts)
      elsif respond_to?(:root_path)
        root_path(opts)
      else
        "/"
      end
    end

skip_format?() click to toggle source

    # File lib/devise/failure_app.rb, line 103
    def skip_format?
      %w(html */*).include? request_format.to_s
    end

store_location!() click to toggle source

Stores requested uri to redirect the user after signing in. We cannot use scoped session provided by warden here, since the user is not authenticated yet, but we still need to store the uri based on scope, so different scopes would never use the same uri to redirect.

    # File lib/devise/failure_app.rb, line 172
    def store_location!
      session["#{scope}_return_to"] = attempted_path if request.get? && !http_auth?
    end

warden() click to toggle source

    # File lib/devise/failure_app.rb, line 148
    def warden
      env['warden']
    end

warden_message() click to toggle source

    # File lib/devise/failure_app.rb, line 156
    def warden_message
      @message ||= warden.message || warden_options[:message]
    end

warden_options() click to toggle source

    # File lib/devise/failure_app.rb, line 152
    def warden_options
      env['warden.options']
    end