From bc5d60a42aca07f8c6ffd3c1ae6cb0a15026547a Mon Sep 17 00:00:00 2001 From: Nat Budin Date: Sun, 6 Jul 2014 09:07:05 -0700 Subject: [PATCH 1/3] Pass the request, rather than @env instance variable which doesn't seem to exist --- lib/cassy/cas.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cassy/cas.rb b/lib/cassy/cas.rb index 6669a05..df360e9 100644 --- a/lib/cassy/cas.rb +++ b/lib/cassy/cas.rb @@ -201,7 +201,7 @@ def valid_credentials? credentials = { :username => @username, :password => @password, :service => @service, - :request => @env + :request => request } @user = authenticator.find_user(credentials) || authenticator.find_user_from_ticket(@tgt) valid = ((@user == @ticketed_user) || authenticator.validate(credentials)) && !!@user From 6b9d443aaf5a5717665ec89babe0fe833a2923c1 Mon Sep 17 00:00:00 2001 From: Nat Budin Date: Sun, 27 Sep 2015 12:55:10 -0400 Subject: [PATCH 2/3] Rails 4 compat update --- app/controllers/cassy/sessions_controller.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/controllers/cassy/sessions_controller.rb b/app/controllers/cassy/sessions_controller.rb index ebeaf50..7d59d64 100644 --- a/app/controllers/cassy/sessions_controller.rb +++ b/app/controllers/cassy/sessions_controller.rb @@ -77,10 +77,9 @@ def destroy if tgt Cassy::TicketGrantingTicket.transaction do - pgts = Cassy::ProxyGrantingTicket.find(:all, - :conditions => [ActiveRecord::Base.connection.quote_table_name(Cassy::ServiceTicket.table_name)+".username = ?", tgt.username], - :include => :service_ticket) - pgts.each do |pgt| + pgts = Cassy::ProxyGrantingTicket.where(Cassy::ServiceTicket.table_name => { :username => tgt.username }). + includes(:service_ticket) + pgts.find_each do |pgt| pgt.destroy end if Cassy.config[:enable_single_sign_out] From 31b3a4cb7a43a4878e68f8072d767f9900aa25b9 Mon Sep 17 00:00:00 2001 From: Nat Budin Date: Mon, 10 Feb 2020 15:21:22 -0800 Subject: [PATCH 3/3] Rails 5 compat updates --- Gemfile | 2 +- app/controllers/cassy/sessions_controller.rb | 40 ++++++++--------- app/models/cassy/login_ticket.rb | 8 ++-- app/models/cassy/proxy_granting_ticket.rb | 8 ++-- app/models/cassy/proxy_ticket.rb | 10 ++--- app/models/cassy/service_ticket.rb | 18 ++++---- app/models/cassy/ticket_granting_ticket.rb | 18 ++++---- cassy.gemspec | 6 +-- lib/cassy.rb | 10 ++--- lib/cassy/cas.rb | 26 +++++------ lib/cassy/engine.rb | 4 +- lib/cassy/utils.rb | 2 +- spec/dummy/app/assets/config/manifest.js | 0 spec/models/login_ticket_spec.rb | 16 +++---- spec/models/service_ticket_spec.rb | 30 ++++++------- spec/models/ticket_granting_ticket_spec.rb | 46 ++++++++++---------- spec/spec_helper.rb | 2 +- 17 files changed, 123 insertions(+), 123 deletions(-) create mode 100644 spec/dummy/app/assets/config/manifest.js diff --git a/Gemfile b/Gemfile index 8777c2b..ca50f20 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source "http://rubygems.org" if ENV.key?('RAILS_VERSION') railsversion = "= #{ENV['RAILS_VERSION']}" else - railsversion = ['>= 3.1.10'] + railsversion = ['5.2.4'] end gem 'rails', railsversion diff --git a/app/controllers/cassy/sessions_controller.rb b/app/controllers/cassy/sessions_controller.rb index 7d59d64..3c598bd 100644 --- a/app/controllers/cassy/sessions_controller.rb +++ b/app/controllers/cassy/sessions_controller.rb @@ -5,11 +5,11 @@ class SessionsController < ApplicationController def new detect_ticketing_service(params[:service]) - + @renew = params['renew'] @gateway = params['gateway'] == 'true' || params['gateway'] == '1' - @hostname = env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_HOST'] || env['REMOTE_ADDR'] - @tgt, tgt_error = Cassy::TicketGrantingTicket.validate(request.cookies['tgt']) + @hostname = request.env['HTTP_X_FORWARDED_FOR'] || request.env['REMOTE_HOST'] || request.env['REMOTE_ADDR'] + @tgt, tgt_error = Cassy::TicketGrantingTicket.validate_ticket(request.cookies['tgt']) if @tgt flash.now[:notice] = "You are currently logged in as '%s'." % ticketed_user(@tgt).send(settings[:username_field]) end @@ -17,7 +17,7 @@ def new if params['redirection_loop_intercepted'] flash.now[:error] = "The client and server are unable to negotiate authentication. Please try logging in again later." end - + if @service if @ticketed_user && cas_login redirect_to @service_with_ticket @@ -36,12 +36,12 @@ def new @lt = generate_login_ticket.ticket end - + def create @lt = generate_login_ticket.ticket # in case the login isn't successful, another ticket needs to be generated for the next attempt at login detect_ticketing_service(params[:service]) - @hostname = env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_HOST'] || env['REMOTE_ADDR'] - consume_ticket = Cassy::LoginTicket.validate(@lt) + @hostname = request.env['HTTP_X_FORWARDED_FOR'] || request.env['REMOTE_HOST'] || request.env['REMOTE_ADDR'] + consume_ticket = Cassy::LoginTicket.validate_ticket(@lt) if !consume_ticket[:valid] flash.now[:error] = consume_ticket[:error] @lt = generate_login_ticket.ticket @@ -55,12 +55,12 @@ def create else flash.now[:notice] = "You have successfully logged in." render :new - end + end else incorrect_credentials! end end - + def destroy # The behaviour here is somewhat non-standard. Rather than showing just a blank # "logout" page, we take the user back to the login page with a "you have been logged out" @@ -71,10 +71,10 @@ def destroy @gateway = params['gateway'] == 'true' || params['gateway'] == '1' - tgt = Cassy::TicketGrantingTicket.find_by_ticket(request.cookies['tgt']) + tgt = Cassy::TicketGrantingTicket.find_by(ticket: request.cookies['tgt']) response.delete_cookie 'tgt' - + if tgt Cassy::TicketGrantingTicket.transaction do pgts = Cassy::ProxyGrantingTicket.where(Cassy::ServiceTicket.table_name => { :username => tgt.username }). @@ -91,7 +91,7 @@ def destroy tgt.destroy end end - + flash[:notice] = "You have successfully logged out." @lt = generate_login_ticket @@ -101,10 +101,10 @@ def destroy redirect_to :action => :new, :service => @service end end - + def service_validate # takes a params[:service] and a params[:ticket] and validates them - + # required @service = clean_service_url(params['service']) @ticket = params['ticket'] @@ -112,7 +112,7 @@ def service_validate @renew = params['renew'] @pgt_url = params['pgtUrl'] - @service_ticket, @error = Cassy::ServiceTicket.validate(@service, @ticket) + @service_ticket, @error = Cassy::ServiceTicket.validate_ticket(@service, @ticket) if @service_ticket @username = ticketed_user(@service_ticket).send(settings[:client_app_user_field]) if @pgt_url @@ -123,7 +123,7 @@ def service_validate end render :proxy_validate, :layout => false, :status => @service_ticket ? 200 : 422 end - + def proxy_validate # required @service = clean_service_url(params['service']) @@ -134,7 +134,7 @@ def proxy_validate @proxies = [] - @service_ticket, @error = Cassy::ServiceTicket.validate(@service, @ticket) + @service_ticket, @error = Cassy::ServiceTicket.validate_ticket(@service, @ticket) @extra_attributes = {} if @service_ticket @username = ticketed_user(@service_ticket).send(settings[:client_app_user_field]) @@ -152,11 +152,11 @@ def proxy_validate end render :proxy_validate, :layout => false, :status => @service_ticket ? 200 : 422 - + end - + private - + def incorrect_credentials! @lt = generate_login_ticket.ticket flash.now[:error] = "Incorrect username or password." diff --git a/app/models/cassy/login_ticket.rb b/app/models/cassy/login_ticket.rb index bed366d..3e1eafb 100644 --- a/app/models/cassy/login_ticket.rb +++ b/app/models/cassy/login_ticket.rb @@ -3,9 +3,9 @@ class LoginTicket < ActiveRecord::Base include Cassy::Ticket self.table_name = 'casserver_lt' include Consumable - - def self.validate(ticket="invalid") - ticket = LoginTicket.find_by_ticket(ticket) + + def self.validate_ticket(ticket="invalid") + ticket = LoginTicket.find_by(ticket: ticket) if ticket if ticket.consumed? {:valid => false, :error => "The login ticket you provided has already been used up. Please try logging in again."} @@ -18,6 +18,6 @@ def self.validate(ticket="invalid") {:valid => false, :error => "The login ticket you provided is invalid. There may be a problem with the authentication system."} end end - + end end diff --git a/app/models/cassy/proxy_granting_ticket.rb b/app/models/cassy/proxy_granting_ticket.rb index a13de1a..9e8022c 100644 --- a/app/models/cassy/proxy_granting_ticket.rb +++ b/app/models/cassy/proxy_granting_ticket.rb @@ -7,12 +7,12 @@ class ProxyGrantingTicket < ActiveRecord::Base :class_name => 'Cassy::ProxyTicket', :foreign_key => :granted_by_pgt_id end - - def self.validate(ticket) + + def self.validate_ticket(ticket) if ticket.nil? error = Error.new(:INVALID_REQUEST, "pgt parameter was missing in the request.") logger.warn("#{error.code} - #{error.message}") - elsif pgt = ProxyGrantingTicket.find_by_ticket(ticket) + elsif pgt = ProxyGrantingTicket.find_by(ticket: ticket) if pgt.service_ticket logger.info("Proxy granting ticket '#{ticket}' belonging to user '#{pgt.service_ticket.username}' successfully validated.") else @@ -26,5 +26,5 @@ def self.validate(ticket) [pgt, error] end - + end diff --git a/app/models/cassy/proxy_ticket.rb b/app/models/cassy/proxy_ticket.rb index 71e3380..b0f1183 100644 --- a/app/models/cassy/proxy_ticket.rb +++ b/app/models/cassy/proxy_ticket.rb @@ -4,9 +4,9 @@ class ProxyTicket < ServiceTicket :class_name => 'Cassy::ProxyGrantingTicket', :foreign_key => :granted_by_pgt_id end - - def validate(service, ticket) - pt, error = Cassy::ServiceTicket.validate(service, ticket, true) + + def validate_ticket(service, ticket) + pt, error = Cassy::ServiceTicket.validate_ticket(service, ticket, true) if pt.kind_of?(Cassy::ProxyTicket) && !error if not pt.granted_by_pgt @@ -19,5 +19,5 @@ def validate(service, ticket) [pt, error] end - -end \ No newline at end of file + +end diff --git a/app/models/cassy/service_ticket.rb b/app/models/cassy/service_ticket.rb index 6ed8012..0f7872f 100644 --- a/app/models/cassy/service_ticket.rb +++ b/app/models/cassy/service_ticket.rb @@ -19,14 +19,14 @@ def set_type_column belongs_to :granted_by_tgt, :class_name => 'Cassy::TicketGrantingTicket', :foreign_key => :granted_by_tgt_id has_one :proxy_granting_ticket, :foreign_key => :created_by_st_id - - def self.validate(service, ticket, allow_proxy_tickets = false) + + def self.validate_ticket(service, ticket, allow_proxy_tickets = false) logger.debug "Validating service ticket '#{ticket}' for service '#{service}'" if service.nil? logger.warn "Service not provided to validate service ticket" [nil, "Ticket or service parameter was missing in the request"] - elsif st = Cassy::ServiceTicket.find_by_ticket(ticket) + elsif st = Cassy::ServiceTicket.find_by(ticket: ticket) if st.consumed? logger.warn "Ticket #{ticket} has already been used" [nil, "Ticket #{ticket} has already been consumed."] @@ -49,7 +49,7 @@ def self.validate(service, ticket, allow_proxy_tickets = false) [nil, "Ticket '#{ticket}' not recognized."] end end - + def matches_service?(service) if Cassy.config[:loosely_match_services] == true @@ -58,7 +58,7 @@ def matches_service?(service) Cassy::CAS.clean_service_url(self.service) == Cassy::CAS.clean_service_url(service) end end - + # Takes an existing ServiceTicket object (presumably pulled from the database) # and sends a POST with logout information to the service that the ticket # was generated for. @@ -89,20 +89,20 @@ def send_logout_notification return false end end - + # XML to be posted when using single sign out def logout_notification_message time = Time.now rand = Cassy::Utils.random_string {'logoutRequest' => %{#{self.ticket}}} end - + # Try to find an existing service ticket for the given user and service def self.find_or_generate(service, username, tgt, hostname) st = tgt.granted_service_tickets.where(:service => service).where("created_on > ?", Time.now - Cassy.config[:maximum_session_lifetime]).order("created_on DESC").first st || self.generate(service, username, tgt, hostname) end - + def self.generate(service, username, tgt, hostname) st = ServiceTicket.new st.ticket = "ST-" + Cassy::Utils.random_string @@ -115,6 +115,6 @@ def self.generate(service, username, tgt, hostname) " for user '#{st.username}' at '#{st.client_hostname}'") st end - + end end diff --git a/app/models/cassy/ticket_granting_ticket.rb b/app/models/cassy/ticket_granting_ticket.rb index a852f6c..4551c3f 100644 --- a/app/models/cassy/ticket_granting_ticket.rb +++ b/app/models/cassy/ticket_granting_ticket.rb @@ -9,12 +9,12 @@ class TicketGrantingTicket < ActiveRecord::Base :class_name => 'Cassy::ServiceTicket', :foreign_key => :granted_by_tgt_id, :dependent => :destroy - - - def self.validate(ticket) + + + def self.validate_ticket(ticket) if ticket.nil? [nil, "No ticket provided."] - elsif tgt = TicketGrantingTicket.find_by_ticket(ticket) + elsif tgt = TicketGrantingTicket.find_by(ticket: ticket) if Cassy.config[:maximum_session_lifetime] && Time.now - Cassy.config[:maximum_session_lifetime] > tgt.created_on tgt.destroy [nil, "Ticket TGT-12345678901234567890 has expired. Please log in again."] @@ -28,7 +28,7 @@ def self.validate(ticket) [nil, "Ticket '#{ticket}' not recognized."] end end - + # Creates a TicketGrantingTicket for the given username. This is done when the user logs in # for the first time to establish their SSO session (after their credentials have been validated). # @@ -51,17 +51,17 @@ def self.generate(username, extra_attributes={}, hostname) end tgt end - + # Returns the users previous ticket_granting_ticket def previous_ticket Cassy::TicketGrantingTicket.where(:username => username.to_s).where("id <> ?",self.id).where("created_on > ?", Time.now - Cassy.config[:maximum_session_lifetime]).order("created_on DESC").first end - + # Returns true if the ticket is not the most recent ticket granting ticket for that username def not_the_latest_for_this_user? Cassy::TicketGrantingTicket.where(:username => username).where("created_on > ? AND id <> ?",created_on,self.id).any? end - + # If enable_single_sign_out is true, sends a logout notification to each service before destroying the ticket def destroy_and_logout_all_service_tickets if Cassy.config[:enable_single_sign_out] @@ -73,6 +73,6 @@ def destroy_and_logout_all_service_tickets raise "Single Sign Out is not enabled for Cassy. If you want to enable it, add 'enable_single_sign_out: true' to the Cassy config file." end end - + end end diff --git a/cassy.gemspec b/cassy.gemspec index 2cc013e..86095bd 100644 --- a/cassy.gemspec +++ b/cassy.gemspec @@ -11,11 +11,11 @@ Gem::Specification.new do |s| s.add_dependency 'crypt-isaac' s.add_dependency 'rails', '>= 3.0.9' - s.add_development_dependency 'rspec-rails', '~> 2.7.0' - s.add_development_dependency 'capybara', '~> 1.0' + s.add_development_dependency 'rspec-rails', '~> 3.9.0' + s.add_development_dependency 'capybara', '~> 2.2.0' s.add_development_dependency 'database_cleaner' s.add_development_dependency 'sqlite3' s.add_development_dependency 'launchy' - s.add_development_dependency 'devise', '~> 3.2.4' + s.add_development_dependency 'devise', '~> 4.7.1' s.add_development_dependency 'webmock' end diff --git a/lib/cassy.rb b/lib/cassy.rb index 987b730..5dddeef 100644 --- a/lib/cassy.rb +++ b/lib/cassy.rb @@ -3,23 +3,23 @@ module Cassy extend ActiveSupport::Autoload - + autoload :CAS autoload :Utils autoload :Engine - + def self.root Pathname.new(File.dirname(__FILE__) + "../..") end - + # Just an easier way to get to the configuration for the engine def self.config Cassy::Engine.config.configuration end - + class AuthenticatorError < Exception end end require 'cassy/authenticators' -require 'cassy/engine' \ No newline at end of file +require 'cassy/engine' diff --git a/lib/cassy/cas.rb b/lib/cassy/cas.rb index df360e9..a47e345 100644 --- a/lib/cassy/cas.rb +++ b/lib/cassy/cas.rb @@ -8,7 +8,7 @@ # the Cassy::Controllers module. module Cassy module CAS - + def settings Cassy.config end @@ -18,7 +18,7 @@ def generate_login_ticket lt = Cassy::LoginTicket.new lt.ticket = "LT-" + Cassy::Utils.random_string - lt.client_hostname = env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_HOST'] || env['REMOTE_ADDR'] + lt.client_hostname = request.env['HTTP_X_FORWARDED_FOR'] || request.env['REMOTE_HOST'] || request.env['REMOTE_ADDR'] lt.save! logger.debug("Generated login ticket '#{lt.ticket}' for client at '#{lt.client_hostname}'") lt @@ -43,7 +43,7 @@ def generate_proxy_ticket(target_service, pgt) pt.username = pgt.service_ticket.username pt.granted_by_pgt_id = pgt.id pt.granted_by_tgt_id = pgt.service_ticket.granted_by_tgt.id - pt.client_hostname = @env['HTTP_X_FORWARDED_FOR'] || @env['REMOTE_HOST'] || @env['REMOTE_ADDR'] + pt.client_hostname = request.env['HTTP_X_FORWARDED_FOR'] || request.env['REMOTE_HOST'] || request.env['REMOTE_ADDR'] pt.save! logger.debug("Generated proxy ticket '#{pt.ticket}' for target service '#{pt.service}'" + " for user '#{pt.username}' at '#{pt.client_hostname}' using proxy-granting" + @@ -66,12 +66,12 @@ def generate_proxy_granting_ticket(pgt_url, st) https.start do |conn| path = uri.path.empty? ? '/' : uri.path path += '?' + uri.query unless (uri.query.nil? || uri.query.empty?) - + pgt = ProxyGrantingTicket.new pgt.ticket = "PGT-" + Cassy::Utils.random_string(60) pgt.iou = "PGTIOU-" + Cassy::Utils.random_string(57) pgt.service_ticket_id = st.id - pgt.client_hostname = @env['HTTP_X_FORWARDED_FOR'] || @env['REMOTE_HOST'] || @env['REMOTE_ADDR'] + pgt.client_hostname = request.env['HTTP_X_FORWARDED_FOR'] || request.env['REMOTE_HOST'] || request.env['REMOTE_ADDR'] # FIXME: The CAS protocol spec says to use 'pgt' as the parameter, but in practice # the JA-SIG and Yale server implementations use pgtId. We'll go with the @@ -81,7 +81,7 @@ def generate_proxy_granting_ticket(pgt_url, st) response = conn.request_get(path) # TODO: follow redirects... 2.5.4 says that redirects MAY be followed # NOTE: The following response codes are valid according to the JA-SIG implementation even without following redirects - + if %w(200 202 301 302 304).include?(response.code) # 3.4 (proxy-granting ticket IOU) pgt.save! @@ -143,7 +143,7 @@ def clean_service_url(dirty_service) module_function :clean_service_url def base_service_url(full_service_url) - # strips a url back to the domain part only + # strips a url back to the domain part only # so that a service ticket can work for all urls on a given domain # eg http://www.something.com/something_else # is stripped back to @@ -154,13 +154,13 @@ def base_service_url(full_service_url) match && match[0] end module_function :base_service_url - + def detect_ticketing_service(service) # try to find the service in the valid_services list # if loosely_matched_services is true, try to match the base url of the service to one in the valid_services list # if still no luck, check if there is a default_redirect_url that we can use @service||= service - @ticketing_service||= valid_services.detect{|s| s == @service } || + @ticketing_service||= valid_services.detect{|s| s == @service } || (settings[:loosely_match_services] == true && valid_services.detect{|s| base_service_url(s) == base_service_url(@service)}) if !@ticketing_service && settings[:default_redirect_url] @default_redirect_url||= settings[:default_redirect_url][Rails.env] @@ -171,7 +171,7 @@ def detect_ticketing_service(service) @lt||= params['lt'] end module_function :detect_ticketing_service - + def cas_login if valid_credentials? @tgt||= Cassy::TicketGrantingTicket.generate(ticket_username, @extra_attributes, @hostname) @@ -191,7 +191,7 @@ def cas_login end end module_function :cas_login - + # Initializes authenticator, returns true / false depending on if user credentials are accurate def valid_credentials? detect_ticketing_service(params[:service]) @@ -213,7 +213,7 @@ def valid_credentials? return valid end module_function :valid_credentials? - + protected def ticket_username @@ -223,7 +223,7 @@ def ticket_username @cas_client_username = user.send(settings["client_app_user_field"]) if settings["client_app_user_field"].present? && !!user @cas_client_username || @username end - + def ticketed_user(ticket) # Find the SSO's instance of the user @ticketed_user ||= authenticator.find_user_from_ticket(ticket) unless !ticket diff --git a/lib/cassy/engine.rb b/lib/cassy/engine.rb index c49dbb0..07daf7c 100644 --- a/lib/cassy/engine.rb +++ b/lib/cassy/engine.rb @@ -1,8 +1,8 @@ module Cassy class Engine < Rails::Engine config.config_file = ENV["RUBYCAS_CONFIG_FILE"] - config.after_initialize do - config.configuration = HashWithIndifferentAccess.new(YAML.load_file(config.config_file)) + config.after_initialize do + config.configuration = ActiveSupport::HashWithIndifferentAccess.new(YAML.load_file(config.config_file)) end end end diff --git a/lib/cassy/utils.rb b/lib/cassy/utils.rb index 482b4b6..6848c7c 100644 --- a/lib/cassy/utils.rb +++ b/lib/cassy/utils.rb @@ -1,4 +1,4 @@ -require 'crypt-isaac' +require 'crypt/isaac' # Misc utility function used throughout by the RubyCAS-Server. module Cassy diff --git a/spec/dummy/app/assets/config/manifest.js b/spec/dummy/app/assets/config/manifest.js new file mode 100644 index 0000000..e69de29 diff --git a/spec/models/login_ticket_spec.rb b/spec/models/login_ticket_spec.rb index 141c8d0..80553be 100644 --- a/spec/models/login_ticket_spec.rb +++ b/spec/models/login_ticket_spec.rb @@ -6,24 +6,24 @@ Cassy::LoginTicket.delete_all @login_ticket = Cassy::LoginTicket.create(:ticket => "ST-12345678901234567890", :consumed => false, :client_hostname => "http://sso.something.com") end - + it "should validate" do - Cassy::LoginTicket.validate("ST-12345678901234567890").should == {:valid => true} + Cassy::LoginTicket.validate_ticket("ST-12345678901234567890").should == {:valid => true} end - + it "should not validate if the ticket has already been consumed" do @login_ticket.consume! - Cassy::LoginTicket.validate("ST-12345678901234567890").should == {:valid => false, :error => "The login ticket you provided has already been used up. Please try logging in again."} + Cassy::LoginTicket.validate_ticket("ST-12345678901234567890").should == {:valid => false, :error => "The login ticket you provided has already been used up. Please try logging in again."} end it "should not validate if the ticket is too old" do @login_ticket.created_on = Time.now-7201 @login_ticket.save! - Cassy::LoginTicket.validate("ST-12345678901234567890").should == {:valid => false, :error => "You took too long to enter your credentials. Please try again."} + Cassy::LoginTicket.validate_ticket("ST-12345678901234567890").should == {:valid => false, :error => "You took too long to enter your credentials. Please try again."} end - + it "should not validate if the ticket is invalid" do - Cassy::LoginTicket.validate("ST-09876543210987654321").should == {:valid => false, :error => "The login ticket you provided is invalid. There may be a problem with the authentication system."} + Cassy::LoginTicket.validate_ticket("ST-09876543210987654321").should == {:valid => false, :error => "The login ticket you provided is invalid. There may be a problem with the authentication system."} end - + end diff --git a/spec/models/service_ticket_spec.rb b/spec/models/service_ticket_spec.rb index 560aa4c..3d9e8e1 100644 --- a/spec/models/service_ticket_spec.rb +++ b/spec/models/service_ticket_spec.rb @@ -7,48 +7,48 @@ @ticket_granting_ticket = Cassy::TicketGrantingTicket.create(:ticket => "TGT-12345678900987654321", :created_on => Time.now, :username => "1", :client_hostname => "http://sss.something.com", :extra_attributes => {}) @service_ticket = Cassy::ServiceTicket.create!(:ticket => "ST-12345678901234567890", :consumed => false, :client_hostname => "http://sso.something.com", :granted_by_tgt => @ticket_granting_ticket, :service => "http://members.something.com", :username => "1") end - + it "should validate" do - Cassy::ServiceTicket.validate("http://members.something.com","ST-12345678901234567890").should == [@service_ticket, "Ticket 'ST-12345678901234567890' for 'http://members.something.com' for user '1' successfully validted."] + Cassy::ServiceTicket.validate_ticket("http://members.something.com","ST-12345678901234567890").should == [@service_ticket, "Ticket 'ST-12345678901234567890' for 'http://members.something.com' for user '1' successfully validted."] end - + it "should not validate if the ticket has already been consumed" do @service_ticket.consume! - Cassy::ServiceTicket.validate("http://members.something.com","ST-12345678901234567890").should == [nil, "Ticket ST-12345678901234567890 has already been consumed."] + Cassy::ServiceTicket.validate_ticket("http://members.something.com","ST-12345678901234567890").should == [nil, "Ticket ST-12345678901234567890 has already been consumed."] end it "should not validate if the ticket is too old" do @service_ticket.created_on = Time.now-7201 @service_ticket.save! - Cassy::ServiceTicket.validate("http://members.something.com", "ST-12345678901234567890").should == [nil, "Ticket ST-12345678901234567890 has expired. Please try again."] + Cassy::ServiceTicket.validate_ticket("http://members.something.com", "ST-12345678901234567890").should == [nil, "Ticket ST-12345678901234567890 has expired. Please try again."] end - + it "should not validate if the ticket is invalid" do - Cassy::ServiceTicket.validate("http://members.something.com", "ST-09876543210987654321").should == [nil, "Ticket 'ST-09876543210987654321' not recognized."] + Cassy::ServiceTicket.validate_ticket("http://members.something.com", "ST-09876543210987654321").should == [nil, "Ticket 'ST-09876543210987654321' not recognized."] end - + describe "#send_logout_notification" do - + it "should send valid single sign out XML to the service URL" do - + service_stub = stub_request(:post, 'http://example.com') - + st = Cassy::ServiceTicket.new( :ticket => 'ST-0123456789ABCDEFGHIJKLMNOPQRS', :service => 'http://example.com', :consumed => false, :client_hostname => "http://sso.something.com" ) - + st.send_logout_notification a_request(:post, 'example.com').with{ |req| xml = CGI.parse(req.body)['logoutRequest'].first Nokogiri::XML(xml).at_xpath('//samlp:SessionIndex').text.strip == st.ticket }.should have_been_made - + end - + end - + end diff --git a/spec/models/ticket_granting_ticket_spec.rb b/spec/models/ticket_granting_ticket_spec.rb index c1f1034..c91b979 100644 --- a/spec/models/ticket_granting_ticket_spec.rb +++ b/spec/models/ticket_granting_ticket_spec.rb @@ -6,29 +6,29 @@ Cassy::TicketGrantingTicket.delete_all @ticket_granting_ticket = Cassy::TicketGrantingTicket.create(:ticket => "TGT-12345678900987654321", :created_on => Time.now, :username => "1", :client_hostname => "http://sss.something.com", :extra_attributes => {}) end - + it "should validate" do - Cassy::TicketGrantingTicket.validate("TGT-12345678900987654321").should == [@ticket_granting_ticket, "Ticket granting ticket 'TGT-12345678900987654321' for user '1' successfully validated."] + Cassy::TicketGrantingTicket.validate_ticket("TGT-12345678900987654321").should == [@ticket_granting_ticket, "Ticket granting ticket 'TGT-12345678900987654321' for user '1' successfully validated."] end it "should not validate if the ticket is too old" do @ticket_granting_ticket.created_on = Time.now-7201 @ticket_granting_ticket.save! - Cassy::TicketGrantingTicket.validate("TGT-12345678900987654321").should == [nil, "Ticket TGT-12345678901234567890 has expired. Please log in again."] + Cassy::TicketGrantingTicket.validate_ticket("TGT-12345678900987654321").should == [nil, "Ticket TGT-12345678901234567890 has expired. Please log in again."] end - + it "should not validate if the ticket is invalid" do - Cassy::TicketGrantingTicket.validate("TGT-09876543210987654321").should == [nil, "Ticket 'TGT-09876543210987654321' not recognized."] + Cassy::TicketGrantingTicket.validate_ticket("TGT-09876543210987654321").should == [nil, "Ticket 'TGT-09876543210987654321' not recognized."] end - + context "single sign out" do - + before do - @service_ticket = Cassy::ServiceTicket.create!(:granted_by_tgt_id => @ticket_granting_ticket.id, + @service_ticket = Cassy::ServiceTicket.create!(:granted_by_tgt_id => @ticket_granting_ticket.id, :service => "www.another.com", :ticket => "ST-1362563155rFE13971A3BCC04C6B5", :client_hostname => "another", :username => "1") Cassy.config[:enable_single_sign_out] = true end - + it "sends a logout notification for all granted service tickets before being destroyed" do Cassy::ServiceTicket.any_instance.should_receive(:send_logout_notification) @ticket_granting_ticket.destroy_and_logout_all_service_tickets @@ -36,55 +36,55 @@ Cassy::TicketGrantingTicket.find(@ticket_granting_ticket.id) }.to raise_error(ActiveRecord::RecordNotFound) end - + it "raises an error if single sign out is not enabled" do Cassy.config[:enable_single_sign_out] = false expect { @ticket_granting_ticket.destroy_and_logout_all_service_tickets }.to raise_error("Single Sign Out is not enabled for Cassy. If you want to enable it, add 'enable_single_sign_out: true' to the Cassy config file.") end - + context "logging in with a second session and 'no_concurrent_sessions' enabled" do - + before do Cassy.config[:no_concurrent_sessions] = true @ticket_granting_ticket = Cassy::TicketGrantingTicket.create!(:ticket => "TGT-981276451234567890", :username => "1", :client_hostname => "127.0.0.1") end - + it "returns any ticket_granting_tickets that were created after the one stored in the session" do @second_ticket_granting_ticket = Cassy::TicketGrantingTicket.generate("1", nil, "127.0.0.1") @ticket_granting_ticket.not_the_latest_for_this_user?.should be_true end - + it "should send a request to terminate the old session" do Cassy::TicketGrantingTicket.any_instance.should_receive(:destroy_and_logout_all_service_tickets) @second_ticket_granting_ticket = Cassy::TicketGrantingTicket.generate("1", nil, "127.0.0.1") end - + end - + context "logging in with a second session and 'no_concurrent_sessions' disabled" do - + before do Cassy::TicketGrantingTicket.delete_all Cassy.config[:no_concurrent_sessions] = nil @ticket_granting_ticket = Cassy::TicketGrantingTicket.create!(:ticket => "TGT-981276451234567890", :username => "1", :client_hostname => "127.0.0.1") end - + it "should have two sessions" do Cassy::TicketGrantingTicket.any_instance.should_not_receive(:destroy_and_logout_all_service_tickets) @second_ticket_granting_ticket = Cassy::TicketGrantingTicket.generate("1", nil, "127.0.0.1") Cassy::TicketGrantingTicket.where(:username => "1").count.should == 2 end - + end - + it "returns the previous ticket for the username" do Cassy.config[:enable_single_sign_out] = true # otherwise they will be deleted @second_ticket_granting_ticket = Cassy::TicketGrantingTicket.generate("1", nil, "127.0.0.1") @second_ticket_granting_ticket.previous_ticket.should == @ticket_granting_ticket end - + end - -end \ No newline at end of file + +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d6856d0..2f736e4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,7 +3,7 @@ ENV["RAILS_ENV"] = "test" ENV["RUBYCAS_CONFIG_FILE"] = File.expand_path("default_config.yml", File.dirname(__FILE__)) -require File.expand_path("../dummy/config/environment.rb", __FILE__) +require File.expand_path("../dummy/config/application.rb", __FILE__) Rails.backtrace_cleaner.remove_silencers!