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.
# 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
# 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
# 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
# File lib/devise/failure_app.rb, line 31 def respond if http_auth? http_auth elsif warden_options[:recall] recall else redirect end end
# File lib/devise/failure_app.rb, line 167 def attempted_path warden_options[:attempted_path] end
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 118 def http_auth? if request.xhr? Devise.http_authenticatable_on_xhr else !(request_format && is_navigational_format?) end end
# File lib/devise/failure_app.rb, line 132 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
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 128 def http_auth_header? Devise.mappings[scope].to.http_authenticatable && !request.xhr? end
# 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
# File lib/devise/failure_app.rb, line 144 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
# 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
# File lib/devise/failure_app.rb, line 183 def request_format @request_format ||= request.format.try(:ref) end
# File lib/devise/failure_app.rb, line 163 def scope @scope ||= warden_options[:scope] || Devise.default_scope end
# File lib/devise/failure_app.rb, line 87 def scope_path opts = {} route = :"new_#{scope}_session_path" opts[:format] = request_format unless skip_format? config = Rails.application.config opts[:script_name] = (config.relative_url_root if config.respond_to?(:relative_url_root)) context = send(Devise.available_router_name) if context.respond_to?(route) context.send(route, opts) elsif respond_to?(:root_path) root_path(opts) else "/" end end
# File lib/devise/failure_app.rb, line 106 def skip_format? %w(html */*).include? request_format.to_s end
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 175 def store_location! session["#{scope}_return_to"] = attempted_path if request.get? && !http_auth? end
# File lib/devise/failure_app.rb, line 151 def warden env['warden'] end
# File lib/devise/failure_app.rb, line 159 def warden_message @message ||= warden.message || warden_options[:message] end
# File lib/devise/failure_app.rb, line 155 def warden_options env['warden.options'] end
# File lib/devise/failure_app.rb, line 18 def self.call(env) @respond ||= action(:respond) @respond.call(env) end
# 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