casino_core 1.0.12 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,32 +1,33 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- casino_core (1.0.12)
4
+ casino_core (1.1.0)
5
5
  activerecord (~> 3.2.9)
6
6
  addressable (~> 2.3)
7
+ terminal-table (~> 1.4)
7
8
  useragent (~> 0.4)
8
9
 
9
10
  GEM
10
11
  remote: http://rubygems.org/
11
12
  specs:
12
- activemodel (3.2.9)
13
- activesupport (= 3.2.9)
13
+ activemodel (3.2.11)
14
+ activesupport (= 3.2.11)
14
15
  builder (~> 3.0.0)
15
- activerecord (3.2.9)
16
- activemodel (= 3.2.9)
17
- activesupport (= 3.2.9)
16
+ activerecord (3.2.11)
17
+ activemodel (= 3.2.11)
18
+ activesupport (= 3.2.11)
18
19
  arel (~> 3.0.2)
19
20
  tzinfo (~> 0.3.29)
20
- activesupport (3.2.9)
21
+ activesupport (3.2.11)
21
22
  i18n (~> 0.6)
22
23
  multi_json (~> 1.0)
23
24
  addressable (2.3.2)
24
25
  arel (3.0.2)
25
26
  builder (3.0.4)
26
- crack (0.3.1)
27
+ crack (0.3.2)
27
28
  database_cleaner (0.9.1)
28
29
  diff-lcs (1.1.3)
29
- factory_girl (4.1.0)
30
+ factory_girl (4.2.0)
30
31
  activesupport (>= 3.0.0)
31
32
  i18n (0.6.1)
32
33
  multi_json (1.5.0)
@@ -39,14 +40,15 @@ GEM
39
40
  rspec-core (2.12.2)
40
41
  rspec-expectations (2.12.1)
41
42
  diff-lcs (~> 1.1.3)
42
- rspec-mocks (2.12.1)
43
+ rspec-mocks (2.12.2)
43
44
  simplecov (0.7.1)
44
45
  multi_json (~> 1.0)
45
46
  simplecov-html (~> 0.7.1)
46
47
  simplecov-html (0.7.1)
47
- sqlite3 (1.3.6)
48
+ sqlite3 (1.3.7)
49
+ terminal-table (1.4.5)
48
50
  tzinfo (0.3.35)
49
- useragent (0.4.15)
51
+ useragent (0.4.16)
50
52
  webmock (1.9.0)
51
53
  addressable (>= 2.2.7)
52
54
  crack (>= 0.1.7)
@@ -0,0 +1,14 @@
1
+ # Upgrade CASinoCore
2
+
3
+ Here is a list of backward-incompatible changes that were introduced.
4
+
5
+ ## 1.1.0
6
+
7
+ API changes:
8
+
9
+ * `login_credential_acceptor`: The parameters of `#process` changed from `params, cookies, user_agent` to just `params, user_agent`
10
+
11
+ New callbacks:
12
+
13
+ * `login_credential_requestor` calls `#service_not_allowed` on the listener, when a service is not in the service whitelist.
14
+ * `api/service_ticket_provider` calls `#service_not_allowed_via_api` on the listener, when a service is not in the service whitelist.
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
29
29
 
30
30
  s.add_runtime_dependency 'activerecord', '~> 3.2.9'
31
31
  s.add_runtime_dependency 'addressable', '~> 2.3'
32
+ s.add_runtime_dependency 'terminal-table', '~> 1.4'
32
33
  s.add_runtime_dependency 'useragent', '~> 0.4'
33
34
  end
34
35
 
@@ -0,0 +1,15 @@
1
+ class CreateServiceRules < ActiveRecord::Migration
2
+ def change
3
+ create_table :service_rules do |t|
4
+ t.boolean :enabled, null: false, default: true
5
+ t.integer :order, null: false, default: 10
6
+ t.string :name, null: false
7
+ t.string :url, null: false
8
+ t.boolean :regex, null: false, default: false
9
+
10
+ t.timestamps
11
+ end
12
+
13
+ add_index :service_rules, :url, unique: true
14
+ end
15
+ end
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended to check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(:version => 20121231114141) do
14
+ ActiveRecord::Schema.define(:version => 20130105152327) do
15
15
 
16
16
  create_table "login_tickets", :force => true do |t|
17
17
  t.string "ticket", :null => false
@@ -47,6 +47,18 @@ ActiveRecord::Schema.define(:version => 20121231114141) do
47
47
  add_index "proxy_tickets", ["proxy_granting_ticket_id"], :name => "index_proxy_tickets_on_proxy_granting_ticket_id"
48
48
  add_index "proxy_tickets", ["ticket"], :name => "index_proxy_tickets_on_ticket", :unique => true
49
49
 
50
+ create_table "service_rules", :force => true do |t|
51
+ t.boolean "enabled", :default => true, :null => false
52
+ t.integer "order", :default => 10, :null => false
53
+ t.string "name", :null => false
54
+ t.string "url", :null => false
55
+ t.boolean "regex", :default => false, :null => false
56
+ t.datetime "created_at", :null => false
57
+ t.datetime "updated_at", :null => false
58
+ end
59
+
60
+ add_index "service_rules", ["url"], :name => "index_service_rules_on_url", :unique => true
61
+
50
62
  create_table "service_tickets", :force => true do |t|
51
63
  t.string "ticket", :null => false
52
64
  t.string "service", :null => false
@@ -9,6 +9,21 @@ module CASinoCore
9
9
  logger.debug "Created login ticket '#{ticket.ticket}'"
10
10
  ticket
11
11
  end
12
+
13
+ def login_ticket_valid?(lt)
14
+ ticket = CASinoCore::Model::LoginTicket.find_by_ticket lt
15
+ if ticket.nil?
16
+ logger.info "Login ticket '#{lt}' not found"
17
+ false
18
+ elsif ticket.created_at < CASinoCore::Settings.login_ticket[:lifetime].seconds.ago
19
+ logger.info "Login ticket '#{ticket.ticket}' expired"
20
+ false
21
+ else
22
+ logger.debug "Login ticket '#{ticket.ticket}' successfully validated"
23
+ ticket.delete
24
+ true
25
+ end
26
+ end
12
27
  end
13
28
  end
14
29
  end
@@ -7,10 +7,18 @@ module CASinoCore
7
7
  include CASinoCore::Helper::Tickets
8
8
  include CASinoCore::Helper::ProxyTickets
9
9
 
10
+ class ServiceNotAllowedError < StandardError; end
11
+
10
12
  def acquire_service_ticket(ticket_granting_ticket, service, credentials_supplied = nil)
13
+ service_url = clean_service_url(service)
14
+ unless CASinoCore::Model::ServiceRule.allowed?(service_url)
15
+ message = "#{service_url} is not in the list of allowed URLs"
16
+ logger.error message
17
+ raise ServiceNotAllowedError, message
18
+ end
11
19
  ticket_granting_ticket.service_tickets.create!({
12
20
  ticket: random_ticket_string('ST'),
13
- service: clean_service_url(service),
21
+ service: service_url,
14
22
  issued_from_credentials: !!credentials_supplied
15
23
  })
16
24
  end
@@ -24,9 +32,10 @@ module CASinoCore
24
32
  if service_uri.query_values.blank?
25
33
  service_uri.query_values = nil
26
34
  end
27
- if "#{service_uri.path}".length > 1
28
- service_uri.path = service_uri.path.gsub(/\/\z/, '')
29
- end
35
+
36
+ service_uri.path = (service_uri.path || '').gsub(/\/+\z/, '')
37
+ service_uri.path = '/' if service_uri.path.blank?
38
+
30
39
  clean_service = service_uri.to_s
31
40
 
32
41
  logger.debug("Cleaned dirty service URL '#{dirty_service}' to '#{clean_service}'") if dirty_service != clean_service
@@ -3,6 +3,7 @@ require 'active_record'
3
3
  module CASinoCore
4
4
  module Model
5
5
  autoload :LoginTicket, 'casino_core/model/login_ticket.rb'
6
+ autoload :ServiceRule, 'casino_core/model/service_rule.rb'
6
7
  autoload :ServiceTicket, 'casino_core/model/service_ticket.rb'
7
8
  autoload :ProxyGrantingTicket, 'casino_core/model/proxy_granting_ticket.rb'
8
9
  autoload :ProxyTicket, 'casino_core/model/proxy_ticket.rb'
@@ -0,0 +1,28 @@
1
+ require 'casino_core/model'
2
+
3
+ class CASinoCore::Model::ServiceRule < ActiveRecord::Base
4
+ attr_accessible :enabled, :order, :name, :url, :regex
5
+ validates :name, presence: true
6
+ validates :url, uniqueness: true, presence: true
7
+
8
+ def self.allowed?(service_url)
9
+ rules = self.where(enabled: true)
10
+ if rules.empty?
11
+ true
12
+ else
13
+ rules.any? { |rule| rule.allows?(service_url) }
14
+ end
15
+ end
16
+
17
+ def allows?(service_url)
18
+ if self.regex?
19
+ regex = Regexp.new self.url, true
20
+ if regex =~ service_url
21
+ return true
22
+ end
23
+ elsif self.url == service_url
24
+ return true
25
+ end
26
+ false
27
+ end
28
+ end
@@ -15,6 +15,7 @@ class CASinoCore::Processor::API::ServiceTicketProvider < CASinoCore::Processor
15
15
  # The service ticket (and nothing else) should be displayed.
16
16
  # * `#invalid_ticket_granting_ticket_via_api`: No argument. The application should respond with status "400 Bad Request"
17
17
  # * `#no_service_provided_via_api`: No argument. The application should respond with status "400 Bad Request"
18
+ # * `#service_not_allowed_via_api`: The user tried to access a service that this CAS server is not allowed to serve.
18
19
  #
19
20
  # @param [String] ticket_granting_ticket ticket_granting_ticket supplied by the user in the URL
20
21
  # @param [Hash] parameters parameters supplied by user (`service` in particular)
@@ -37,8 +38,12 @@ class CASinoCore::Processor::API::ServiceTicketProvider < CASinoCore::Processor
37
38
  def handle_ticket_granting_ticket
38
39
  case
39
40
  when (@service_url and @ticket_granting_ticket)
40
- create_service_ticket
41
- callback_granted_service_ticket
41
+ begin
42
+ create_service_ticket
43
+ callback_granted_service_ticket
44
+ rescue ServiceNotAllowedError
45
+ callback_service_not_allowed
46
+ end
42
47
  when (@service_url and not @ticket_granting_ticket)
43
48
  callback_invalid_tgt
44
49
  when (not @service_url and @ticket_granting_ticket)
@@ -62,4 +67,8 @@ class CASinoCore::Processor::API::ServiceTicketProvider < CASinoCore::Processor
62
67
  @listener.no_service_provided_via_api
63
68
  end
64
69
 
70
+ def callback_service_not_allowed
71
+ @listener.service_not_allowed_via_api(clean_service_url @service_url)
72
+ end
73
+
65
74
  end
@@ -17,43 +17,39 @@ class CASinoCore::Processor::LoginCredentialAcceptor < CASinoCore::Processor
17
17
  # The second argument (String) is the ticket-granting ticket. It should be stored in a cookie named "tgt".
18
18
  # * `#invalid_login_ticket` and `#invalid_login_credentials`: The first argument is a LoginTicket.
19
19
  # See {CASinoCore::Processor::LoginCredentialRequestor} for details.
20
+ # * `#service_not_allowed`: The user tried to access a service that this CAS server is not allowed to serve.
20
21
  #
21
22
  # @param [Hash] params parameters supplied by user
22
- # @param [Hash] cookies cookies supplied by user
23
23
  # @param [String] user_agent user-agent delivered by the client
24
- def process(params = nil, cookies = nil, user_agent = nil)
25
- params ||= {}
26
- cookies ||= {}
27
- if login_ticket_valid?(params[:lt])
28
- authentication_result = validate_login_credentials(params[:username], params[:password])
29
- if !authentication_result.nil?
30
- ticket_granting_ticket = acquire_ticket_granting_ticket(authentication_result, user_agent)
31
- url = unless params[:service].nil?
32
- acquire_service_ticket(ticket_granting_ticket, params[:service], true).service_with_ticket_url
33
- end
34
- @listener.user_logged_in(url, ticket_granting_ticket.ticket)
35
- else
36
- @listener.invalid_login_credentials(acquire_login_ticket)
37
- end
24
+ def process(params = nil, user_agent = nil)
25
+ @params = params || {}
26
+ @user_agent = user_agent
27
+ if login_ticket_valid?(@params[:lt])
28
+ authenticate_user
38
29
  else
39
30
  @listener.invalid_login_ticket(acquire_login_ticket)
40
31
  end
41
32
  end
42
33
 
43
34
  private
44
- def login_ticket_valid?(lt)
45
- ticket = CASinoCore::Model::LoginTicket.find_by_ticket lt
46
- if ticket.nil?
47
- logger.info "Login ticket '#{lt}' not found"
48
- false
49
- elsif ticket.created_at < CASinoCore::Settings.login_ticket[:lifetime].seconds.ago
50
- logger.info "Login ticket '#{ticket.ticket}' expired"
51
- false
35
+ def authenticate_user
36
+ authentication_result = validate_login_credentials(@params[:username], @params[:password])
37
+ if !authentication_result.nil?
38
+ user_logged_in(authentication_result)
52
39
  else
53
- logger.debug "Login ticket '#{ticket.ticket}' successfully validated"
54
- ticket.delete
55
- true
40
+ @listener.invalid_login_credentials(acquire_login_ticket)
56
41
  end
57
42
  end
58
43
 
44
+ def user_logged_in(authentication_result)
45
+ begin
46
+ ticket_granting_ticket = acquire_ticket_granting_ticket(authentication_result, @user_agent)
47
+ url = unless @params[:service].nil?
48
+ acquire_service_ticket(ticket_granting_ticket, @params[:service], true).service_with_ticket_url
49
+ end
50
+ @listener.user_logged_in(url, ticket_granting_ticket.ticket)
51
+ rescue ServiceNotAllowedError => e
52
+ @listener.service_not_allowed(clean_service_url @params[:service])
53
+ end
54
+ end
59
55
  end
@@ -14,27 +14,57 @@ class CASinoCore::Processor::LoginCredentialRequestor < CASinoCore::Processor
14
14
  # The method will call one of the following methods on the listener:
15
15
  # * `#user_logged_in`: The first argument (String) is the URL (if any), the user should be redirected to.
16
16
  # * `#user_not_logged_in`: The first argument is a LoginTicket. It should be stored in a hidden field with name "lt".
17
+ # * `#service_not_allowed`: The user tried to access a service that this CAS server is not allowed to serve.
17
18
  #
18
19
  # @param [Hash] params parameters supplied by user
19
20
  # @param [Hash] cookies cookies supplied by user
20
21
  # @param [String] user_agent user-agent delivered by the client
21
22
  def process(params = nil, cookies = nil, user_agent = nil)
22
- params ||= {}
23
- cookies ||= {}
24
- request_env ||= {}
25
- if !params[:renew] && (ticket_granting_ticket = find_valid_ticket_granting_ticket(cookies[:tgt], user_agent))
26
- service_url_with_ticket = unless params[:service].nil?
27
- acquire_service_ticket(ticket_granting_ticket, params[:service], true).service_with_ticket_url
28
- end
29
- @listener.user_logged_in(service_url_with_ticket)
23
+ @params = params || {}
24
+ @cookies = cookies || {}
25
+ @user_agent = user_agent || {}
26
+ if check_service_allowed
27
+ handle_allowed_service
28
+ end
29
+ end
30
+
31
+ private
32
+ def handle_allowed_service
33
+ if !@params[:renew] && (@ticket_granting_ticket = find_valid_ticket_granting_ticket(@cookies[:tgt], @user_agent))
34
+ handle_logged_in
35
+ else
36
+ handle_not_logged_in
37
+ end
38
+ end
39
+
40
+ def handle_logged_in
41
+ service_url_with_ticket = unless @params[:service].nil?
42
+ acquire_service_ticket(@ticket_granting_ticket, @params[:service], true).service_with_ticket_url
43
+ end
44
+ @listener.user_logged_in(service_url_with_ticket)
45
+ end
46
+
47
+ def handle_not_logged_in
48
+ if gateway_request?
49
+ # we actually lie to the listener to simplify things
50
+ @listener.user_logged_in(@params[:service])
51
+ else
52
+ login_ticket = acquire_login_ticket
53
+ @listener.user_not_logged_in(login_ticket)
54
+ end
55
+ end
56
+
57
+ def check_service_allowed
58
+ service_url = clean_service_url(@params[:service]) unless @params[:service].nil?
59
+ if service_url.nil? || CASinoCore::Model::ServiceRule.allowed?(service_url)
60
+ true
30
61
  else
31
- if params[:gateway] == 'true' && params[:service]
32
- # we actually lie to the listener to simplify things
33
- @listener.user_logged_in(params[:service])
34
- else
35
- login_ticket = acquire_login_ticket
36
- @listener.user_not_logged_in(login_ticket)
37
- end
62
+ @listener.service_not_allowed(service_url)
63
+ false
38
64
  end
39
65
  end
66
+
67
+ def gateway_request?
68
+ @params[:gateway] == 'true' && @params[:service]
69
+ end
40
70
  end
@@ -5,6 +5,7 @@ module CASinoCore
5
5
  %w(
6
6
  database
7
7
  cleanup
8
+ service_rule
8
9
  ).each do |task|
9
10
  load "casino_core/tasks/#{task}.rake"
10
11
  end
@@ -0,0 +1,52 @@
1
+ require 'terminal-table'
2
+ require 'casino_core/model'
3
+ require 'casino_core/helper/service_tickets'
4
+
5
+ namespace :casino_core do
6
+ namespace :service_rule do
7
+ include CASinoCore::Helper::ServiceTickets
8
+
9
+ desc 'Add a service rule (prefix the url parameter with "regex:" to add a regular expression)'
10
+ task :add, [:name, :url] => 'casino_core:db:configure_connection' do |task, args|
11
+ service_rule = CASinoCore::Model::ServiceRule.new name: args[:name]
12
+ match = /^regex:(.*)/.match(args[:url])
13
+ if match.nil?
14
+ service_rule.url = clean_service_url(args[:url])
15
+ else
16
+ service_rule.url = match[1]
17
+ service_rule.regex = true
18
+ end
19
+ if !service_rule.save
20
+ fail service_rule.errors.full_messages.join("\n")
21
+ elsif service_rule.regex && service_rule.url[0] != '^'
22
+ puts 'Warning: Potentially unsafe regex! Use ^ to match the beginning of the URL. Example: ^https://'
23
+ end
24
+ end
25
+
26
+ desc 'Remove a servcice rule.'
27
+ task :delete, [:id] => 'casino_core:db:configure_connection' do |task, args|
28
+ CASinoCore::Model::ServiceRule.find(args[:id]).delete
29
+ puts "Successfully deleted service rule ##{args[:id]}."
30
+ end
31
+
32
+ desc 'Delete all servcice rules.'
33
+ task :flush => 'casino_core:db:configure_connection' do |task, args|
34
+ CASinoCore::Model::ServiceRule.delete_all
35
+ puts 'Successfully deleted all service rules.'
36
+ end
37
+
38
+ desc 'List all service rules.'
39
+ task list: 'casino_core:db:configure_connection' do
40
+ table = Terminal::Table.new :headings => ['Enabled', 'ID', 'Name', 'URL'] do |t|
41
+ CASinoCore::Model::ServiceRule.all.each do |service_rule|
42
+ url = service_rule.url
43
+ if service_rule.regex?
44
+ url += " (Regex)"
45
+ end
46
+ t.add_row [service_rule.enabled, service_rule.id, service_rule.name, url]
47
+ end
48
+ end
49
+ puts table
50
+ end
51
+ end
52
+ end
@@ -1,3 +1,3 @@
1
1
  module CASinoCore
2
- VERSION = '1.0.12'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe CASinoCore::Model::ServiceRule do
4
+ describe '.allowed?' do
5
+ context 'with an empty table' do
6
+ ['https://www.example.org/', 'http://www.google.com/'].each do |service_url|
7
+ it "allows access to #{service_url}" do
8
+ described_class.allowed?(service_url).should == true
9
+ end
10
+ end
11
+ end
12
+
13
+ context 'with a regex rule' do
14
+ before(:each) do
15
+ FactoryGirl.create :service_rule, :regex, url: '^https://.*'
16
+ end
17
+
18
+ ['https://www.example.org/', 'https://www.google.com/'].each do |service_url|
19
+ it "allows access to #{service_url}" do
20
+ described_class.allowed?(service_url).should == true
21
+ end
22
+ end
23
+
24
+ ['http://www.example.org/', 'http://www.google.com/'].each do |service_url|
25
+ it "does not allow access to #{service_url}" do
26
+ described_class.allowed?(service_url).should == false
27
+ end
28
+ end
29
+ end
30
+
31
+ context 'with many regex rules' do
32
+ before(:each) do
33
+ 100.times do |counter|
34
+ FactoryGirl.create :service_rule, :regex, url: "^https://www#{counter}.example.com"
35
+ end
36
+ end
37
+
38
+ let(:service_url) { 'https://www111.example.com/bla' }
39
+
40
+ it 'does not take too long to check a denied service' do
41
+ start = Time.now
42
+ described_class.allowed?(service_url).should == false
43
+ (Time.now - start).should < 0.1
44
+ end
45
+ end
46
+
47
+ context 'with a non-regex rule' do
48
+ before(:each) do
49
+ FactoryGirl.create :service_rule, url: 'https://www.google.com/foo'
50
+ end
51
+
52
+ ['https://www.google.com/foo'].each do |service_url|
53
+ it "allows access to #{service_url}" do
54
+ described_class.allowed?(service_url).should == true
55
+ end
56
+ end
57
+
58
+ ['https://www.example.org/', 'http://www.example.org/', 'https://www.google.com/test'].each do |service_url|
59
+ it "does not allow access to #{service_url}" do
60
+ described_class.allowed?(service_url).should == false
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -5,7 +5,8 @@ describe CASinoCore::Processor::API::ServiceTicketProvider do
5
5
  let(:listener) { Object.new }
6
6
  let(:processor) { described_class.new(listener) }
7
7
 
8
- let(:parameters) { { service: 'http://example.org/' } }
8
+ let(:service) { 'http://example.org/' }
9
+ let(:parameters) { { service: service } }
9
10
 
10
11
  context 'with an invalid ticket-granting ticket' do
11
12
  let(:ticket_granting_ticket) { 'TGT-INVALID' }
@@ -21,6 +22,18 @@ describe CASinoCore::Processor::API::ServiceTicketProvider do
21
22
  let(:ticket) { ticket_granting_ticket.ticket }
22
23
  let(:user_agent) { ticket_granting_ticket.user_agent }
23
24
 
25
+ context 'with a not allowed service' do
26
+ before(:each) do
27
+ FactoryGirl.create :service_rule, :regex, url: '^https://.*'
28
+ end
29
+ let(:service) { 'http://www.example.org/' }
30
+
31
+ it 'calls the #service_not_allowed method on the listener' do
32
+ listener.should_receive(:service_not_allowed_via_api).with(service)
33
+ processor.process(ticket, parameters, user_agent)
34
+ end
35
+ end
36
+
24
37
  it 'calls the #granted_service_ticket_via_api method on the listener' do
25
38
  listener.should_receive(:granted_service_ticket_via_api).with(/^ST\-/)
26
39
  processor.process(ticket, parameters, user_agent)
@@ -39,6 +39,18 @@ describe CASinoCore::Processor::LoginCredentialAcceptor do
39
39
  listener.stub(:user_logged_in)
40
40
  end
41
41
 
42
+ context 'with a not allowed service' do
43
+ before(:each) do
44
+ FactoryGirl.create :service_rule, :regex, url: '^https://.*'
45
+ end
46
+ let(:service) { 'http://www.example.org/' }
47
+
48
+ it 'calls the #service_not_allowed method on the listener' do
49
+ listener.should_receive(:service_not_allowed).with(service)
50
+ processor.process(login_data)
51
+ end
52
+ end
53
+
42
54
  context 'when all authenticators raise an error' do
43
55
  before(:each) do
44
56
  CASinoCore::Authenticator::Static.any_instance.stub(:validate) do
@@ -71,7 +83,7 @@ describe CASinoCore::Processor::LoginCredentialAcceptor do
71
83
  let(:service) { 'https://www.example.com' }
72
84
 
73
85
  it 'calls the #user_logged_in method on the listener' do
74
- listener.should_receive(:user_logged_in).with(/^#{service}\?ticket=ST\-/, /^TGC\-/)
86
+ listener.should_receive(:user_logged_in).with(/^#{service}\/\?ticket=ST\-/, /^TGC\-/)
75
87
  processor.process(login_data)
76
88
  end
77
89
 
@@ -5,6 +5,19 @@ describe CASinoCore::Processor::LoginCredentialRequestor do
5
5
  let(:listener) { Object.new }
6
6
  let(:processor) { described_class.new(listener) }
7
7
 
8
+ context 'with a not allowed service' do
9
+ before(:each) do
10
+ FactoryGirl.create :service_rule, :regex, url: '^https://.*'
11
+ end
12
+ let(:service) { 'http://www.example.org/' }
13
+ let(:params) { { service: service } }
14
+
15
+ it 'calls the #service_not_allowed method on the listener' do
16
+ listener.should_receive(:service_not_allowed).with(service)
17
+ processor.process(params)
18
+ end
19
+ end
20
+
8
21
  context 'when logged out' do
9
22
  it 'calls the #user_not_logged_in method on the listener' do
10
23
  listener.should_receive(:user_not_logged_in).with(kind_of(CASinoCore::Model::LoginTicket))
@@ -0,0 +1,16 @@
1
+ require 'factory_girl'
2
+
3
+ FactoryGirl.define do
4
+ factory :service_rule, class: CASinoCore::Model::ServiceRule do
5
+ sequence :order do |n|
6
+ n
7
+ end
8
+ sequence :name do |n|
9
+ "Rule #{n}"
10
+ end
11
+
12
+ trait :regex do
13
+ regex true
14
+ end
15
+ end
16
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: casino_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.12
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-02 00:00:00.000000000 Z
12
+ date: 2013-02-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -187,6 +187,22 @@ dependencies:
187
187
  - - ~>
188
188
  - !ruby/object:Gem::Version
189
189
  version: '2.3'
190
+ - !ruby/object:Gem::Dependency
191
+ name: terminal-table
192
+ requirement: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ~>
196
+ - !ruby/object:Gem::Version
197
+ version: '1.4'
198
+ type: :runtime
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ~>
204
+ - !ruby/object:Gem::Version
205
+ version: '1.4'
190
206
  - !ruby/object:Gem::Dependency
191
207
  name: useragent
192
208
  requirement: !ruby/object:Gem::Requirement
@@ -221,6 +237,7 @@ files:
221
237
  - LICENSE.txt
222
238
  - README.md
223
239
  - Rakefile
240
+ - UPGRADE.md
224
241
  - VERSION
225
242
  - casino_core.gemspec
226
243
  - config/cas.yml
@@ -244,6 +261,7 @@ files:
244
261
  - db/migrate/20121226192211_fix_index_for_granter_on_proxy_granting_ticket.rb
245
262
  - db/migrate/20121226211511_allow_service_tickets_without_ticket_granting_ticket.rb
246
263
  - db/migrate/20121231114141_add_authenticator_to_ticket_granting_tickets.rb
264
+ - db/migrate/20130105152327_create_service_rules.rb
247
265
  - db/schema.rb
248
266
  - lib/casino_core.rb
249
267
  - lib/casino_core/authenticator.rb
@@ -264,6 +282,7 @@ files:
264
282
  - lib/casino_core/model/login_ticket.rb
265
283
  - lib/casino_core/model/proxy_granting_ticket.rb
266
284
  - lib/casino_core/model/proxy_ticket.rb
285
+ - lib/casino_core/model/service_rule.rb
267
286
  - lib/casino_core/model/service_ticket.rb
268
287
  - lib/casino_core/model/service_ticket/single_sign_out_notifier.rb
269
288
  - lib/casino_core/model/ticket_granting_ticket.rb
@@ -286,11 +305,13 @@ files:
286
305
  - lib/casino_core/settings.rb
287
306
  - lib/casino_core/tasks/cleanup.rake
288
307
  - lib/casino_core/tasks/database.rake
308
+ - lib/casino_core/tasks/service_rule.rake
289
309
  - lib/casino_core/version.rb
290
310
  - spec/authenticator/base_spec.rb
291
311
  - spec/authenticator/static_spec.rb
292
312
  - spec/model/login_ticket_spec.rb
293
313
  - spec/model/proxy_ticket_spec.rb
314
+ - spec/model/service_rule_spec.rb
294
315
  - spec/model/service_ticket/single_sign_out_notifier_spec.rb
295
316
  - spec/model/service_ticket_spec.rb
296
317
  - spec/model/ticket_granting_ticket_spec.rb
@@ -311,6 +332,7 @@ files:
311
332
  - spec/support/factories/login_ticket_factory.rb
312
333
  - spec/support/factories/proxy_granting_ticket_factory.rb
313
334
  - spec/support/factories/proxy_ticket_factory.rb
335
+ - spec/support/factories/service_rule_factory.rb
314
336
  - spec/support/factories/service_ticket_factory.rb
315
337
  - spec/support/factories/ticket_granting_ticket_factory.rb
316
338
  homepage: http://rbcas.org/
@@ -328,7 +350,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
328
350
  version: '0'
329
351
  segments:
330
352
  - 0
331
- hash: 1278753813307290410
353
+ hash: 4552405534502231272
332
354
  required_rubygems_version: !ruby/object:Gem::Requirement
333
355
  none: false
334
356
  requirements:
@@ -337,7 +359,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
337
359
  version: '0'
338
360
  segments:
339
361
  - 0
340
- hash: 1278753813307290410
362
+ hash: 4552405534502231272
341
363
  requirements: []
342
364
  rubyforge_project:
343
365
  rubygems_version: 1.8.24
@@ -349,6 +371,7 @@ test_files:
349
371
  - spec/authenticator/static_spec.rb
350
372
  - spec/model/login_ticket_spec.rb
351
373
  - spec/model/proxy_ticket_spec.rb
374
+ - spec/model/service_rule_spec.rb
352
375
  - spec/model/service_ticket/single_sign_out_notifier_spec.rb
353
376
  - spec/model/service_ticket_spec.rb
354
377
  - spec/model/ticket_granting_ticket_spec.rb
@@ -369,6 +392,7 @@ test_files:
369
392
  - spec/support/factories/login_ticket_factory.rb
370
393
  - spec/support/factories/proxy_granting_ticket_factory.rb
371
394
  - spec/support/factories/proxy_ticket_factory.rb
395
+ - spec/support/factories/service_rule_factory.rb
372
396
  - spec/support/factories/service_ticket_factory.rb
373
397
  - spec/support/factories/ticket_granting_ticket_factory.rb
374
398
  has_rdoc: