Commit 4e3fbf5d320a875de1c61299ad65772c5bef7616
- Diff rendering mode:
- inline
- side by side
|   | |||
| 12 | 12 | end | |
| 13 | 13 | ||
| 14 | 14 | def create | |
| 15 | authentication_methods_chain(:create) | ||
| 16 | |||
| 17 | unless performed? | ||
| 18 | flash[:error] = t(:invalid_credentials) | ||
| 19 | render(:action => "new") | ||
| 15 | if authentication_methods_chain(:create) | ||
| 16 | redirect_back_or_default(after_create_path) if ! performed? | ||
| 17 | else | ||
| 18 | unless performed? | ||
| 19 | flash[:error] ||= t(:invalid_credentials) | ||
| 20 | render(:action => "new") | ||
| 21 | end | ||
| 20 | 22 | end | |
| 21 | 23 | end | |
| 22 | 24 | ||
| 23 | 25 | def destroy | |
| 24 | 26 | authentication_methods_chain(:destroy) | |
| 27 | |||
| 25 | 28 | reset_session | |
| 26 | 29 | ||
| 27 | 30 | return if performed? |
|   | |||
| 10 | 10 | module Sessions | |
| 11 | 11 | class << self | |
| 12 | 12 | def included(base) # :nodoc: | |
| 13 | base.send :include, ActionController::Authentication unless base.ancestors.include?(ActionController::Authentication) | ||
| 13 | base.__send__ :include, ActionController::Authentication unless base.ancestors.include?(ActionController::Authentication) | ||
| 14 | 14 | ||
| 15 | 15 | ActiveRecord::Agent.authentication_methods.each do |method| | |
| 16 | 16 | mod = "ActionController::Sessions::#{ method.to_s.classify }".constantize | |
| 17 | base.send :include, mod | ||
| 17 | base.__send__ :include, mod | ||
| 18 | 18 | end | |
| 19 | 19 | end | |
| 20 | 20 | end | |
| 21 | 21 | ||
| 22 | # Go through all authentication methods definded for this action | ||
| 23 | # Return is one of them is performed | ||
| 24 | def authentication_methods_chain(controller_method_name) | ||
| 22 | # Authentication is supported in several ways; Login and password, OpenID, CAS, etc... | ||
| 23 | # | ||
| 24 | # Each of the modules define methods that should be called in each session stage: new, create, destroy. | ||
| 25 | # | ||
| 26 | # authentication_methods_chain evaluates each of the available methods, trying to authenticate one of the Agent classes. | ||
| 27 | # | ||
| 28 | # When one of the method performs the action, the chain stops. This is typical for redirections, like in OpenID. | ||
| 29 | # | ||
| 30 | # The chain is evaluated while the methods return nil. | ||
| 31 | # | ||
| 32 | # The chain is stopped when one of the methods returns an object. In the case of create, this object is the authenticated Agent. | ||
| 33 | # | ||
| 34 | # | ||
| 35 | def authentication_methods_chain(controller_method_name, &block) | ||
| 25 | 36 | authentication_methods.each do |authentication_method| | |
| 26 | chain_method = "#{ controller_method_name }_with_#{ authentication_method }" | ||
| 27 | send(chain_method) if respond_to?(chain_method) | ||
| 37 | chain_method = "#{ controller_method_name }_session_with_#{ authentication_method }" | ||
| 38 | |||
| 39 | # Only call existing authentication methods | ||
| 40 | next unless respond_to?(chain_method) | ||
| 41 | |||
| 42 | # Evaluate this authentication method | ||
| 43 | auth_response = __send__(chain_method) | ||
| 44 | |||
| 45 | # End if the method has performed the renderization | ||
| 28 | 46 | break if performed? | |
| 47 | |||
| 48 | # Return auth_response if authentication was successful | ||
| 49 | return auth_response if auth_response | ||
| 29 | 50 | end | |
| 51 | |||
| 52 | # If we reach here, none of the authentication methods succeeded | ||
| 53 | nil | ||
| 30 | 54 | end | |
| 31 | 55 | ||
| 32 | 56 | private |
|   | |||
| 10 | 10 | # Central Authentication Service (CAS) session support | |
| 11 | 11 | module CAS | |
| 12 | 12 | # Initialize CAS session | |
| 13 | def new_with_cas | ||
| 13 | def new_session_with_cas | ||
| 14 | 14 | initialize_cas_filter | |
| 15 | 15 | ||
| 16 | 16 | cas_filter_result = ::CASClient::Frameworks::Rails::Filter.filter(self) | |
| … | … | ||
| 23 | 23 | end | |
| 24 | 24 | ||
| 25 | 25 | # Create session using CAS | |
| 26 | def create_with_cas | ||
| 27 | return unless params[:ticket] | ||
| 26 | def create_session_with_cas | ||
| 27 | return nil unless params[:ticket] | ||
| 28 | 28 | initialize_cas_filter | |
| 29 | 29 | ||
| 30 | 30 | if ::CASClient::Frameworks::Rails::Filter.filter(self) | |
| … | … | ||
| 37 | 37 | ||
| 38 | 38 | if authenticated? | |
| 39 | 39 | flash[:success] = t(:logged_in_successfully) | |
| 40 | redirect_back_or_default(after_create_path) | ||
| 40 | return self.current_agent | ||
| 41 | 41 | else | |
| 42 | 42 | redirect_to :controller => ActiveRecord::Agent.authentication_classes(:cas).first.to_s.tableize, | |
| 43 | 43 | :action => "new", | |
| … | … | ||
| 51 | 51 | end | |
| 52 | 52 | ||
| 53 | 53 | # Logout on CAS Server | |
| 54 | def destroy_with_cas | ||
| 54 | def destroy_session_with_cas | ||
| 55 | 55 | initialize_cas_filter | |
| 56 | 56 | ||
| 57 | 57 | redirect_to ::CASClient::Frameworks::Rails::Filter.client.logout_url(nil, request.referer) |
|   | |||
| 5 | 5 | # CookieToken remembers the Autnentication in the browser for certain amount of time | |
| 6 | 6 | module CookieToken | |
| 7 | 7 | # Destroy CookieToken Session data | |
| 8 | def destroy_with_cookie_token | ||
| 8 | def destroy_session_with_cookie_token | ||
| 9 | 9 | current_agent.forget_me if authenticated? | |
| 10 | 10 | cookies.delete :auth_token | |
| 11 | nil | ||
| 11 | 12 | end | |
| 12 | 13 | end | |
| 13 | 14 | end |
|   | |||
| 3 | 3 | # Methods for Sessions based on LoginAndPassword Authentication | |
| 4 | 4 | module LoginAndPassword | |
| 5 | 5 | # Init Session using LoginAndPassword Authentication | |
| 6 | def create_with_login_and_password | ||
| 6 | def create_session_with_login_and_password(params = self.params) | ||
| 7 | 7 | return if params[:login].blank? || params[:password].blank? | |
| 8 | 8 | ||
| 9 | 9 | agent = nil | |
| … | … | ||
| 19 | 19 | elsif agent.respond_to?(:disabled) && agent.disabled | |
| 20 | 20 | flash[:error] = t(:disabled, :scope => agent.class.to_s.tableize) | |
| 21 | 21 | else | |
| 22 | self.current_agent = agent | ||
| 23 | 22 | flash[:success] = t(:logged_in_successfully) | |
| 24 | redirect_back_or_default(after_create_path) | ||
| 25 | return | ||
| 23 | return self.current_agent = agent | ||
| 26 | 24 | end | |
| 27 | 25 | else | |
| 28 | 26 | flash[:error] ||= t(:invalid_credentials) | |
| 29 | 27 | end | |
| 30 | render :action => 'new' | ||
| 28 | return | ||
| 31 | 29 | end | |
| 32 | 30 | end | |
| 33 | 31 | end |
|   | |||
| 10 | 10 | # OpenID sessions management | |
| 11 | 11 | module OpenID | |
| 12 | 12 | # Create new Session using OpenID | |
| 13 | def create_with_openid | ||
| 14 | if !params[:openid_identifier].blank? | ||
| 13 | def create_session_with_openid(params = self.params, options = {}) | ||
| 14 | options[:return_to] ||= open_id_complete_url | ||
| 15 | options[:realm] ||= "http://#{ request.host_with_port }/" | ||
| 16 | options[:sreg_fields] ||= ['nickname', 'email'] | ||
| 17 | |||
| 18 | if params[:openid_identifier].present? | ||
| 15 | 19 | begin | |
| 16 | 20 | openid_request = openid_consumer.begin params[:openid_identifier] | |
| 17 | 21 | rescue ::OpenID::OpenIDError => e | |
| 18 | 22 | flash[:error] = t('openid.client.discovery_failed', :id => params[:openid_identifier], :error => e) | |
| 19 | render :action => "new" | ||
| 20 | 23 | return | |
| 21 | 24 | end | |
| 22 | 25 | ||
| 23 | 26 | sreg_request = ::OpenID::SReg::Request.new | |
| 24 | 27 | # required fields | |
| 25 | sreg_request.request_fields(['nickname', 'email'], true) | ||
| 28 | sreg_request.request_fields(options[:sreg_fields], true) | ||
| 26 | 29 | # optional fields | |
| 27 | 30 | # sreg_request.request_fields(['fullname'], false) | |
| 28 | 31 | ||
| … | … | ||
| 34 | 34 | # papereq = ::OpenID::PAPE::Request.new | |
| 35 | 35 | # ... | |
| 36 | 36 | ||
| 37 | return_to = open_id_complete_url | ||
| 38 | realm = "http://#{ request.host_with_port }/" | ||
| 39 | |||
| 40 | if openid_request.send_redirect?(realm, return_to) | ||
| 41 | redirect_to openid_request.redirect_url(realm, return_to) | ||
| 37 | if openid_request.send_redirect?(options[:realm], options[:return_to]) | ||
| 38 | redirect_to openid_request.redirect_url(options[:realm], options[:return_to]) | ||
| 42 | 39 | else | |
| 40 | #FIXME: create | ||
| 43 | 41 | @form_text = openid_request.form_markup(realm, return_to, true, { 'id' => 'openid_form' }) | |
| 44 | 42 | render :layout => nil | |
| 45 | 43 | end | |
| … | … | ||
| 46 | 46 | # Filter path parameters | |
| 47 | 47 | parameters = params.reject{ |k,v| request.path_parameters[k] } | |
| 48 | 48 | # Complete the OpenID verification process | |
| 49 | openid_response = openid_consumer.complete(parameters, return_to) | ||
| 49 | openid_response = openid_consumer.complete(parameters, options[:return_to]) | ||
| 50 | 50 | ||
| 51 | 51 | case openid_response.status | |
| 52 | 52 | when ::OpenID::Consumer::SUCCESS | |
| … | … | ||
| 57 | 57 | if authenticated? && ! current_agent.openid_uris.include?(uri) | |
| 58 | 58 | current_agent.openid_uris << uri | |
| 59 | 59 | flash[:notice] = t(:id_attached_to_account, :id => uri) | |
| 60 | return | ||
| 60 | return current_agent | ||
| 61 | 61 | end | |
| 62 | 62 | ||
| 63 | 63 | ActiveRecord::Agent.authentication_classes(:openid).each do |klass| | |
| … | … | ||
| 67 | 67 | end | |
| 68 | 68 | ||
| 69 | 69 | if authenticated? | |
| 70 | redirect_back_or_default after_create_path | ||
| 70 | # redirect_back_or_default after_create_path | ||
| 71 | 71 | flash[:success] = t(:logged_in_successfully) | |
| 72 | return current_agent | ||
| 72 | 73 | else | |
| 73 | 74 | # We create new local Agent with OpenID data | |
| 74 | 75 | session[:openid_identifier] = openid_response.display_identifier | |
| … | … | ||
| 84 | 84 | flash[:error] = openid_response.display_identifier ? | |
| 85 | 85 | t('openid.client.verification_failed_with_id', :id => openid_response.display_identifier, :message => openid_response.message) : | |
| 86 | 86 | t('openid.client.verification_failed', :message => openid_response.message) | |
| 87 | render :action => 'new' | ||
| 87 | return | ||
| 88 | 88 | when ::OpenID::Consumer::SETUP_NEEDED | |
| 89 | flash[:error] = t(:immediate_request_failed) | ||
| 90 | render :action => 'new' | ||
| 89 | flash[:error] = t('openid.client.immediate_request_failed') | ||
| 90 | return | ||
| 91 | 91 | when ::OpenID::Consumer::CANCEL | |
| 92 | flash[:notice] = t(:transaction_cancelled) | ||
| 93 | render :action => 'new' | ||
| 92 | flash[:error] = t('openid.client.transaction_cancelled') | ||
| 93 | return | ||
| 94 | 94 | end | |
| 95 | 95 | end | |
| 96 | 96 | end |

