require 'uri' require 'rack' require 'rack/utils' module CasrackTheAuthenticator class Configuration DEFAULT_LOGIN_URL = "%s/login" DEFAULT_SERVICE_VALIDATE_URL = "%s/serviceValidate" # @param [Hash] params configuration options # @option params [String, nil] :cas_server the CAS server root URL; probably something like # 'http://cas.mycompany.com' or 'http://cas.mycompany.com/cas'; optional. # @option params [String, nil] :cas_login_url (:cas_server + '/login') the URL to which to # redirect for logins; options if :cas_server is specified, # required otherwise. # @option params [String, nil] :cas_service_validate_url (:cas_server + '/serviceValidate') the # URL to use for validating service tickets; optional if :cas_server is # specified, requred otherwise. def initialize(params) parse_params params end # Build a CAS login URL from +service+. # # @param [String] service the service (a.k.a. return-to) URL # # @return [String] a URL like # "http://cas.mycompany.com/login?service=..." def login_url(service) append_service @login_url, service end # Build a service-validation URL from +service+ and +ticket+. # # @param [String] service the service (a.k.a. return-to) URL # @param [String] ticket the ticket to validate # # @return [String] a URL like # "http://cas.mycompany.com/serviceValidate?service=...&ticket=..." def service_validate_url(service, ticket) url = append_service @service_validate_url, service url << '&ticket=' << Rack::Utils.escape(ticket) end private def parse_params(params) if params[:cas_server].nil? && params[:cas_login_url].nil? raise ArgumentError.new(":cas_server or :cas_login_url MUST be provided") end @login_url = params[:cas_login_url] @login_url ||= DEFAULT_LOGIN_URL % params[:cas_server] validate_is_url 'login URL', @login_url if params[:cas_server].nil? && params[:cas_service_validate_url].nil? raise ArgumentError.new(":cas_server or :cas_service_validate_url MUST be provided") end @service_validate_url = params[:cas_service_validate_url] @service_validate_url ||= DEFAULT_SERVICE_VALIDATE_URL % params[:cas_server] validate_is_url 'service-validate URL', @service_validate_url end IS_NOT_URL_ERROR_MESSAGE = "%s is not a valid URL" def validate_is_url(name, possibly_a_url) url = URI.parse(possibly_a_url) rescue nil raise ArgumentError.new(IS_NOT_URL_ERROR_MESSAGE % name) unless url.kind_of?(URI::HTTP) end # Adds +service+ as an URL-escaped parameter to +base+. # # @param [String] base the base URL # @param [String] service the service (a.k.a. return-to) URL. # # @return [String] the new joined URL. def append_service(base, service) result = base.dup result << (result.include?('?') ? '&' : '?') result << 'service=' result << Rack::Utils.escape(service) end end end