lib/janus/controllers/sessions_controller.rb in janus-0.5.0 vs lib/janus/controllers/sessions_controller.rb in janus-0.6.0

- old
+ new

@@ -1,7 +1,15 @@ require 'addressable/uri' +# This controller is responsible for creating and destroying +# authenticated user sessions. +# +# The creation uses the DatabaseAuthenticatable strategy, while the destruction +# simply destroys any session, whatever strategy it was created with. Janus +# hooks will be called, of course, allowing to destroy any Rememberable cookies +# for instance, as well as any user defined behavior. +# class Janus::SessionsController < ApplicationController include Janus::InternalHelpers # include Janus::UrlHelpers helper JanusHelper @@ -32,11 +40,10 @@ respond_to do |format| format.html do self.resource ||= resource_class.new(params[resource_name]) resource.clean_up_passwords resource.errors.add(:base, :not_found) - render "new", :status => :unauthorized end format.any { head :unauthorized } end end @@ -49,44 +56,74 @@ format.html { redirect_to after_sign_out_url(janus_scope) } format.any { head :ok } end end + # An overridable method that returns the default path to return the just + # signed in user to. Defaults to return the user object, which will be + # interpreted by rails as `user_path(user)`. def after_sign_in_url(user) user end + # An overridable method that returns the default path to return the just + # signed out user to. Defaults to `root_url`. def after_sign_out_url(scope) root_url end - # Returns true if remote host is known and redirect with an auth_token should - # be allowed or not. It must be overwritten by child class since it always - # returns true by default. + # Returns true if host is known and that we allow to redirect the user + # with an auth_token. + # + # Warning: must be overwritten by child classes because it always + # returns false by default! def valid_remote_host?(host) - true + false end - # Either redirects the user to after_sign_in_url or to - # <tt>params[:return_to]</tt>. If return_to is an absolute URL, and not just - # a path, valid_remote_host? will be invoked to check if we should redirect - # to this URL or not --which is moslty of use for RemoteAuthenticatable to - # securize auth tokens from unknown domains. + # Returns an Array of URL that we shouldn't automatically return to. It + # actually returns URL to prevent infinite loops. We must for instance + # never return to new_sesssion_path. + # + # If you ever needd to override this method, don't forget to call `super`. + # For instance: + # + # def never_return_to(scope) + # super + [ my_peculiar_path, another_path ] + # end + # + def never_return_to(scope) + scope = Janus.scope_for(scope) + [ + new_session_path(scope), + new_password_path(scope), + edit_password_path(scope) + ] + end + + # Either redirects the user to after_sign_in_url or to <tt>params[:return_to]</tt>. + # + # If <tt>params[:return_to] is an absolute URL, and not just a path, + # valid_remote_host? will be invoked to check wether we should redirect + # to this URL or not, in order to secure auth tokens for + # RemoteAuthenticatable to leak into the wild. def redirect_after_sign_in(user) unless params[:return_to].blank? return_to = Addressable::URI.parse(params[:return_to]) - - if return_to.host.nil? || return_to.host == request.host - redirect_to params[:return_to] - return - elsif valid_remote_host?(return_to.host) - if user.class.include?(Janus::Models::RemoteAuthenticatable) - query = return_to.query_values || {} - return_to.query_values = query.merge(user.class.remote_authentication_key => user.generate_remote_token!) + + unless never_return_to(user).include?(return_to.path) + if return_to.host.nil? || return_to.host == request.host + redirect_to params[:return_to] + return + elsif valid_remote_host?(return_to.host) + if user.class.include?(Janus::Models::RemoteAuthenticatable) + query = return_to.query_values || {} + return_to.query_values = query.merge(user.class.remote_authentication_key => user.generate_remote_token!) + end + + redirect_to return_to.to_s + return end - - redirect_to return_to.to_s - return end end redirect_to after_sign_in_url(user) end