module AuthlogicCrowdRest module Session def self.included(klass) klass.class_eval do extend Config include Methods end end module Config # The URL of your crowd rest API. Should be # something like https://localhost:8095/crowd/rest # # * Default: nil # * Accepts: String def crowd_base_url(value = nil) rw_config(:crowd_base_url, value) end alias_method :crowd_base_url=, :crowd_base_url # The name in crowd for your application # # * Default: nil # * Accepts: String def crowd_application_name(value = nil) rw_config(:crowd_application_name, value) end alias_method :crowd_application_name=, :crowd_application_name # The password in crowd for your application # # * Default: nil # * Accepts: String def crowd_application_password(value = nil) rw_config(:crowd_application_password, value) end alias_method :crowd_application_password=, :crowd_application_password end module Methods def self.included(klass) klass.class_eval do validate :validate_by_crowd_rest, :if => :authenticating_with_crowd_rest? end end private def authenticating_with_crowd_rest? !(crowd_base_url.blank? || crowd_application_name.blank? || crowd_application_password.blank?) end def validate_by_crowd_rest self.invalid_password = false errors.add(login_field, I18n.t('error_messages.login_blank', :default => "cannot be blank")) if send(login_field).blank? errors.add(password_field, I18n.t('error_messages.password_blank', :default => "cannot be blank")) if send("protected_#{password_field}").blank? return if errors.count > 0 self.attempted_record = search_for_record(find_by_login_method, send(login_field)) if attempted_record.blank? generalize_credentials_error_messages? ? add_general_credentials_error : errors.add(login_field, I18n.t('error_messages.login_not_found', :default => "is not valid")) return end if !(send( :verify_crowd_password, attempted_record)) puts "Invalid!" self.invalid_password = true generalize_credentials_error_messages? ? add_general_credentials_error : errors.add(password_field, I18n.t('error_messages.password_invalid', :default => "is not valid")) return end end def verify_crowd_password(attempted_record) password = attempted_record.send(verify_password_method, send("protected_#{password_field}")) require 'net/http' require 'net/https' uri = URI.parse(send("crowd_base_url")) begin http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = uri.scheme == "https" http.start {|http| req = Net::HTTP::Post.new(uri.path + "?" + "username=#{send(login_field)}") req.basic_auth send("crowd_application_name"), send("crowd_application_password") req.body="#{send("protected_#{password_field}")}" req.add_field 'Content-Type', 'text/xml' resp, data = http.request(req) resp.code.to_i == 200 } rescue Interrupt errors.add(password_field, I18n.t('error_messages.crowd_password_timeout', :default=>"Timeout occurred when connecting to crowd")) end end def crowd_application_password self.class.crowd_application_password end def crowd_application_name self.class.crowd_application_name end def crowd_base_url self.class.crowd_base_url end end end end