casino_core 1.0.3 → 1.0.4

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.
Files changed (31) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +3 -0
  3. data/VERSION +1 -1
  4. data/casino_core.gemspec +12 -3
  5. data/config/cas.yml +10 -11
  6. data/db/migrate/20121231114141_add_authenticator_to_ticket_granting_tickets.rb +15 -0
  7. data/db/schema.rb +3 -2
  8. data/lib/casino_core/builder/ticket_validation_response.rb +0 -2
  9. data/lib/casino_core/model/ticket_granting_ticket.rb +2 -2
  10. data/lib/casino_core/processor/login_credential_acceptor.rb +11 -12
  11. data/lib/casino_core/processor/login_credential_requestor.rb +7 -2
  12. data/lib/casino_core/processor/session_overview.rb +4 -1
  13. data/lib/casino_core/settings.rb +3 -3
  14. data/spec/model/service_ticket/single_sign_out_notifier_spec.rb +3 -4
  15. data/spec/model/ticket_granting_ticket_spec.rb +6 -13
  16. data/spec/processor/legacy_validator_spec.rb +2 -12
  17. data/spec/processor/login_credential_acceptor_spec.rb +10 -1
  18. data/spec/processor/login_credential_requestor_spec.rb +26 -10
  19. data/spec/processor/logout_spec.rb +2 -9
  20. data/spec/processor/proxy_ticket_provider_spec.rb +1 -10
  21. data/spec/processor/proxy_ticket_validator_spec.rb +13 -14
  22. data/spec/processor/session_destroyer_spec.rb +6 -34
  23. data/spec/processor/session_overview_spec.rb +15 -17
  24. data/spec/processor/ticket_validator_spec.rb +16 -14
  25. data/spec/spec_helper.rb +11 -0
  26. data/spec/support/factories/login_ticket_factory.rb +16 -0
  27. data/spec/support/factories/proxy_granting_ticket_factory.rb +16 -0
  28. data/spec/support/factories/proxy_ticket_factory.rb +17 -0
  29. data/spec/support/factories/service_ticket_factory.rb +17 -0
  30. data/spec/support/factories/ticket_granting_ticket_factory.rb +13 -0
  31. metadata +20 -3
data/Gemfile CHANGED
@@ -19,6 +19,7 @@ group :development, :test do
19
19
  gem 'database_cleaner'
20
20
  gem 'webmock'
21
21
  gem 'nokogiri'
22
+ gem 'factory_girl', '~> 4.1.0'
22
23
  end
23
24
 
24
25
  gem 'activerecord', '~> 3.2.9'
@@ -18,6 +18,8 @@ GEM
18
18
  crack (0.3.1)
19
19
  database_cleaner (0.9.1)
20
20
  diff-lcs (1.1.3)
21
+ factory_girl (4.1.0)
22
+ activesupport (>= 3.0.0)
21
23
  git (1.2.5)
22
24
  i18n (0.6.1)
23
25
  jeweler (1.8.4)
@@ -60,6 +62,7 @@ DEPENDENCIES
60
62
  addressable (~> 2.3.2)
61
63
  bundler (~> 1.2.0)
62
64
  database_cleaner
65
+ factory_girl (~> 4.1.0)
63
66
  jeweler (~> 1.8.4)
64
67
  nokogiri
65
68
  redcarpet
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.3
1
+ 1.0.4
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "casino_core"
8
- s.version = "1.0.3"
8
+ s.version = "1.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nils Caspar"]
12
- s.date = "2012-12-29"
12
+ s.date = "2012-12-30"
13
13
  s.description = "A CAS server core library."
14
14
  s.email = "ncaspar@me.com"
15
15
  s.extra_rdoc_files = [
@@ -48,6 +48,7 @@ Gem::Specification.new do |s|
48
48
  "db/migrate/20121225231713_no_default_granter_type.rb",
49
49
  "db/migrate/20121226192211_fix_index_for_granter_on_proxy_granting_ticket.rb",
50
50
  "db/migrate/20121226211511_allow_service_tickets_without_ticket_granting_ticket.rb",
51
+ "db/migrate/20121231114141_add_authenticator_to_ticket_granting_tickets.rb",
51
52
  "db/schema.rb",
52
53
  "lib/casino_core.rb",
53
54
  "lib/casino_core/authenticator.rb",
@@ -101,7 +102,12 @@ Gem::Specification.new do |s|
101
102
  "spec/processor/session_destroyer_spec.rb",
102
103
  "spec/processor/session_overview_spec.rb",
103
104
  "spec/processor/ticket_validator_spec.rb",
104
- "spec/spec_helper.rb"
105
+ "spec/spec_helper.rb",
106
+ "spec/support/factories/login_ticket_factory.rb",
107
+ "spec/support/factories/proxy_granting_ticket_factory.rb",
108
+ "spec/support/factories/proxy_ticket_factory.rb",
109
+ "spec/support/factories/service_ticket_factory.rb",
110
+ "spec/support/factories/ticket_granting_ticket_factory.rb"
105
111
  ]
106
112
  s.homepage = "http://github.com/pencil/CASinoCore"
107
113
  s.licenses = ["MIT"]
@@ -126,6 +132,7 @@ Gem::Specification.new do |s|
126
132
  s.add_development_dependency(%q<database_cleaner>, [">= 0"])
127
133
  s.add_development_dependency(%q<webmock>, [">= 0"])
128
134
  s.add_development_dependency(%q<nokogiri>, [">= 0"])
135
+ s.add_development_dependency(%q<factory_girl>, ["~> 4.1.0"])
129
136
  else
130
137
  s.add_dependency(%q<activerecord>, ["~> 3.2.9"])
131
138
  s.add_dependency(%q<addressable>, ["~> 2.3.2"])
@@ -140,6 +147,7 @@ Gem::Specification.new do |s|
140
147
  s.add_dependency(%q<database_cleaner>, [">= 0"])
141
148
  s.add_dependency(%q<webmock>, [">= 0"])
142
149
  s.add_dependency(%q<nokogiri>, [">= 0"])
150
+ s.add_dependency(%q<factory_girl>, ["~> 4.1.0"])
143
151
  end
144
152
  else
145
153
  s.add_dependency(%q<activerecord>, ["~> 3.2.9"])
@@ -155,6 +163,7 @@ Gem::Specification.new do |s|
155
163
  s.add_dependency(%q<database_cleaner>, [">= 0"])
156
164
  s.add_dependency(%q<webmock>, [">= 0"])
157
165
  s.add_dependency(%q<nokogiri>, [">= 0"])
166
+ s.add_dependency(%q<factory_girl>, ["~> 4.1.0"])
158
167
  end
159
168
  end
160
169
 
@@ -7,25 +7,24 @@ defaults: &defaults
7
7
  proxy_ticket:
8
8
  lifetime_unconsumed: 300
9
9
  lifetime_consumed: 86400
10
-
11
- development:
12
- <<: *defaults
13
10
  authenticators:
14
- -
11
+ static_1:
15
12
  class: "CASinoCore::Authenticator::Static"
16
13
  options:
17
14
  users:
18
15
  testuser:
19
16
  password: "foobar123"
20
17
  name: "Test User"
21
-
22
- test:
23
- <<: *defaults
24
- authenticators:
25
- -
18
+ static_2:
26
19
  class: "CASinoCore::Authenticator::Static"
27
20
  options:
28
21
  users:
29
- testuser:
30
- password: "foobar123"
22
+ example:
23
+ password: "dito123"
31
24
  name: "Test User"
25
+
26
+ development:
27
+ <<: *defaults
28
+
29
+ test:
30
+ <<: *defaults
@@ -0,0 +1,15 @@
1
+ class AddAuthenticatorToTicketGrantingTickets < ActiveRecord::Migration
2
+ def up
3
+ add_column :ticket_granting_tickets, :authenticator, :string, null: true
4
+ CASinoCore::Model::TicketGrantingTicket.delete_all
5
+ change_column :ticket_granting_tickets, :authenticator, :string, null: false
6
+ add_index :ticket_granting_tickets, [:authenticator, :username]
7
+ remove_index :ticket_granting_tickets, :username
8
+ end
9
+
10
+ def down
11
+ remove_index :ticket_granting_tickets, [:authenticator, :username]
12
+ remove_column :ticket_granting_tickets, :authenticator
13
+ add_index :ticket_granting_tickets, :username
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 => 20121226211511) do
14
+ ActiveRecord::Schema.define(:version => 20121231114141) do
15
15
 
16
16
  create_table "login_tickets", :force => true do |t|
17
17
  t.string "ticket", :null => false
@@ -67,9 +67,10 @@ ActiveRecord::Schema.define(:version => 20121226211511) do
67
67
  t.datetime "created_at", :null => false
68
68
  t.datetime "updated_at", :null => false
69
69
  t.string "user_agent"
70
+ t.string "authenticator", :null => false
70
71
  end
71
72
 
73
+ add_index "ticket_granting_tickets", ["authenticator", "username"], :name => "index_ticket_granting_tickets_on_authenticator_and_username"
72
74
  add_index "ticket_granting_tickets", ["ticket"], :name => "index_ticket_granting_tickets_on_ticket", :unique => true
73
- add_index "ticket_granting_tickets", ["username"], :name => "index_ticket_granting_tickets_on_username"
74
75
 
75
76
  end
@@ -37,8 +37,6 @@ class CASinoCore::Builder::TicketValidationResponse < CASinoCore::Builder
37
37
  def serialize_extra_attribute(builder, key, value)
38
38
  if value.kind_of?(String) || value.kind_of?(Numeric) || value.kind_of?(Symbol)
39
39
  builder.cas key, "#{value}"
40
- elsif value.kind_of?(Numeric)
41
- builder.cas key, value.to_s
42
40
  else
43
41
  builder.cas key do |container|
44
42
  container.cdata! value.to_yaml
@@ -1,7 +1,7 @@
1
1
  require 'casino_core/model'
2
2
 
3
3
  class CASinoCore::Model::TicketGrantingTicket < ActiveRecord::Base
4
- attr_accessible :ticket, :username, :user_agent, :extra_attributes
4
+ attr_accessible :ticket, :authenticator, :username, :user_agent, :extra_attributes
5
5
  serialize :extra_attributes, Hash
6
6
  validates :ticket, uniqueness: true
7
7
  has_many :service_tickets
@@ -18,7 +18,7 @@ class CASinoCore::Model::TicketGrantingTicket < ActiveRecord::Base
18
18
  if other_ticket.nil?
19
19
  false
20
20
  else
21
- other_ticket.username == self.username
21
+ other_ticket.username == self.username && other_ticket.authenticator == self.authenticator
22
22
  end
23
23
  end
24
24
 
@@ -23,9 +23,9 @@ class CASinoCore::Processor::LoginCredentialAcceptor < CASinoCore::Processor
23
23
  params ||= {}
24
24
  cookies ||= {}
25
25
  if login_ticket_valid?(params[:lt])
26
- user_data = validate_login_credentials(params[:username], params[:password])
27
- if !user_data.nil?
28
- ticket_granting_ticket = acquire_ticket_granting_ticket(user_data, user_agent)
26
+ authentication_result = validate_login_credentials(params[:username], params[:password])
27
+ if !authentication_result.nil?
28
+ ticket_granting_ticket = acquire_ticket_granting_ticket(authentication_result, user_agent)
29
29
  url = unless params[:service].nil?
30
30
  acquire_service_ticket(ticket_granting_ticket, params[:service], true).service_with_ticket_url
31
31
  end
@@ -55,24 +55,23 @@ class CASinoCore::Processor::LoginCredentialAcceptor < CASinoCore::Processor
55
55
  end
56
56
 
57
57
  def validate_login_credentials(username, password)
58
- user_data = nil
59
- CASinoCore::Settings.authenticators.each do |authenticator|
58
+ authentication_result = nil
59
+ CASinoCore::Settings.authenticators.each do |authenticator_name, authenticator|
60
60
  data = authenticator.validate(username, password)
61
61
  if data
62
- if data[:username].nil?
63
- data[:username] = username
64
- end
65
- user_data = data
66
- logger.info("Credentials for username '#{data[:username]}' successfully validated using #{authenticator.class}")
62
+ authentication_result = { authenticator: authenticator_name, user_data: data }
63
+ logger.info("Credentials for username '#{data[:username]}' successfully validated using authenticator '#{authenticator_name}' (#{authenticator.class})")
67
64
  break
68
65
  end
69
66
  end
70
- user_data
67
+ authentication_result
71
68
  end
72
69
 
73
- def acquire_ticket_granting_ticket(user_data, user_agent = nil)
70
+ def acquire_ticket_granting_ticket(authentication_result, user_agent = nil)
71
+ user_data = authentication_result[:user_data]
74
72
  CASinoCore::Model::TicketGrantingTicket.create!({
75
73
  ticket: random_ticket_string('TGC'),
74
+ authenticator: authentication_result[:authenticator],
76
75
  username: user_data[:username],
77
76
  extra_attributes: user_data[:extra_attributes],
78
77
  user_agent: user_agent
@@ -28,8 +28,13 @@ class CASinoCore::Processor::LoginCredentialRequestor < CASinoCore::Processor
28
28
  end
29
29
  @listener.user_logged_in(service_url_with_ticket)
30
30
  else
31
- login_ticket = acquire_login_ticket
32
- @listener.user_not_logged_in(login_ticket)
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
33
38
  end
34
39
  end
35
40
  end
@@ -18,7 +18,10 @@ class CASinoCore::Processor::SessionOverview < CASinoCore::Processor
18
18
  if tgt.nil?
19
19
  @listener.user_not_logged_in
20
20
  else
21
- ticket_granting_tickets = CASinoCore::Model::TicketGrantingTicket.where(username: tgt.username).order('updated_at DESC')
21
+ ticket_granting_tickets = CASinoCore::Model::TicketGrantingTicket.where(
22
+ username: tgt.username,
23
+ authenticator: tgt.authenticator
24
+ ).order('updated_at DESC')
22
25
  @listener.ticket_granting_tickets_found(ticket_granting_tickets)
23
26
  end
24
27
  end
@@ -17,12 +17,12 @@ module CASinoCore
17
17
  end
18
18
 
19
19
  def authenticators=(authenticators)
20
- @authenticators = []
21
- authenticators.each do |authenticator|
20
+ @authenticators = {}
21
+ authenticators.each do |index, authenticator|
22
22
  unless authenticator.is_a?(CASinoCore::Authenticator)
23
23
  authenticator = authenticator[:class].constantize.new(authenticator[:options])
24
24
  end
25
- @authenticators << authenticator
25
+ @authenticators[index] = authenticator
26
26
  end
27
27
  end
28
28
  end
@@ -2,9 +2,8 @@ require 'spec_helper'
2
2
  require 'nokogiri'
3
3
 
4
4
  describe CASinoCore::Model::ServiceTicket::SingleSignOutNotifier do
5
- let(:ticket) { 'ST-123456' }
6
- let(:service) { 'http://www.example.org/' }
7
- let(:service_ticket) { CASinoCore::Model::ServiceTicket.create ticket: ticket, service: service }
5
+ let(:service_ticket) { FactoryGirl.create :service_ticket }
6
+ let(:service) { service_ticket.service }
8
7
  let(:notifier) { described_class.new service_ticket }
9
8
 
10
9
  describe '#notify' do
@@ -18,7 +17,7 @@ describe CASinoCore::Model::ServiceTicket::SingleSignOutNotifier do
18
17
  post_params = CGI.parse(request.body)
19
18
  post_params.should_not be_nil
20
19
  xml = Nokogiri::XML post_params['logoutRequest'].first
21
- xml.at_xpath('/samlp:LogoutRequest/samlp:SessionIndex').text.strip.should == service_ticket.ticket
20
+ xml.at_xpath('/samlp:LogoutRequest/samlp:SessionIndex').text.should == service_ticket.ticket
22
21
  }
23
22
  end
24
23
 
@@ -1,16 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CASinoCore::Model::TicketGrantingTicket do
4
- let(:subject) { described_class.create! ticket: 'TGT-3ep9awhy2ty5UhL8wM1xAZ', username: 'example-user' }
5
- let(:service_ticket) {
6
- subject.service_tickets.create! ticket: 'ST-12345', service: 'https://example.com/cas-service'
7
- }
8
- let(:consumed_service_ticket) {
9
- service_ticket = subject.service_tickets.create! ticket: 'ST-n9oZvDtYkVFHj5M3s59Ws5', service: 'https://example.com/cas-service'
10
- service_ticket.consumed = true
11
- service_ticket.save!
12
- service_ticket
13
- }
4
+ let(:ticket_granting_ticket) { described_class.create! ticket: 'TGT-3ep9awhy2ty5UhL8wM1xAZ', username: 'example-user', authenticator: 'test' }
5
+ let(:service_ticket) { FactoryGirl.create :service_ticket, ticket_granting_ticket: ticket_granting_ticket }
6
+ let(:consumed_service_ticket) { FactoryGirl.create :service_ticket, :consumed, ticket_granting_ticket: ticket_granting_ticket }
14
7
 
15
8
  describe '#destroy' do
16
9
  context 'when notification for a service ticket fails' do
@@ -21,14 +14,14 @@ describe CASinoCore::Model::TicketGrantingTicket do
21
14
  it 'deletes depending proxy-granting tickets' do
22
15
  consumed_service_ticket.proxy_granting_tickets.create! ticket: 'PGT-12345', iou: 'PGTIOU-12345', pgt_url: 'bla'
23
16
  lambda {
24
- subject.destroy
17
+ ticket_granting_ticket.destroy
25
18
  }.should change(CASinoCore::Model::ProxyGrantingTicket, :count).by(-1)
26
19
  end
27
20
 
28
21
  it 'nullifies depending service tickets' do
29
22
  lambda {
30
- subject.destroy
31
- }.should change { consumed_service_ticket.reload.ticket_granting_ticket_id }.from(subject.id).to(nil)
23
+ ticket_granting_ticket.destroy
24
+ }.should change { consumed_service_ticket.reload.ticket_granting_ticket_id }.from(ticket_granting_ticket.id).to(nil)
32
25
  end
33
26
  end
34
27
  end
@@ -4,18 +4,8 @@ describe CASinoCore::Processor::LegacyValidator do
4
4
  describe '#process' do
5
5
  let(:listener) { Object.new }
6
6
  let(:processor) { described_class.new(listener) }
7
- let(:user_agent) { 'TestBrowser 1.0' }
8
- let(:ticket_granting_ticket) {
9
- CASinoCore::Model::TicketGrantingTicket.create!({
10
- ticket: 'TGC-HXdkW233TsRtiqYGq4b8U7',
11
- username: 'test',
12
- extra_attributes: nil,
13
- user_agent: user_agent
14
- })
15
- }
16
- let(:service) { 'https://example.com/cas-service' }
17
- let(:service_ticket) { ticket_granting_ticket.service_tickets.create! ticket: 'ST-2nOcXx56dtPTsB069yYf0h', service: service }
18
- let(:parameters) { { service: service, ticket: service_ticket.ticket }}
7
+ let(:service_ticket) { FactoryGirl.create :service_ticket }
8
+ let(:parameters) { { service: service_ticket.service, ticket: service_ticket.ticket }}
19
9
 
20
10
  before(:each) do
21
11
  listener.stub(:validation_failed)
@@ -12,8 +12,17 @@ describe CASinoCore::Processor::LoginCredentialAcceptor do
12
12
  end
13
13
  end
14
14
 
15
+ context 'with an expired login ticket' do
16
+ let(:expired_login_ticket) { FactoryGirl.create :login_ticket, :expired }
17
+
18
+ it 'calls the #invalid_login_ticket method on the listener' do
19
+ listener.should_receive(:invalid_login_ticket).with(kind_of(CASinoCore::Model::LoginTicket))
20
+ processor.process(lt: expired_login_ticket.ticket)
21
+ end
22
+ end
23
+
15
24
  context 'with a valid login ticket' do
16
- let(:login_ticket) { CASinoCore::Model::LoginTicket.create! ticket: "LT-#{Random.rand(10000000)}" }
25
+ let(:login_ticket) { FactoryGirl.create :login_ticket }
17
26
 
18
27
  context 'with invalid credentials' do
19
28
  it 'calls the #invalid_login_credentials method on the listener' do
@@ -10,18 +10,32 @@ describe CASinoCore::Processor::LoginCredentialRequestor do
10
10
  listener.should_receive(:user_not_logged_in).with(kind_of(CASinoCore::Model::LoginTicket))
11
11
  processor.process
12
12
  end
13
+
14
+ context 'with gateway parameter' do
15
+ context 'with a service' do
16
+ let(:service) { 'http://example.com/' }
17
+ let(:params) { { service: service, gateway: 'true' } }
18
+
19
+ it 'calls the #user_logged_in method on the listener' do
20
+ listener.should_receive(:user_logged_in).with(service)
21
+ processor.process(params)
22
+ end
23
+ end
24
+
25
+ context 'without a service' do
26
+ let(:params) { { gateway: 'true' } }
27
+
28
+ it 'calls the #user_not_logged_in method on the listener' do
29
+ listener.should_receive(:user_not_logged_in).with(kind_of(CASinoCore::Model::LoginTicket))
30
+ processor.process
31
+ end
32
+ end
33
+ end
13
34
  end
14
35
 
15
36
  context 'when logged in' do
16
- let(:user_agent) { 'TestBrowser 1.0' }
17
- let(:ticket_granting_ticket) {
18
- CASinoCore::Model::TicketGrantingTicket.create!({
19
- ticket: 'TGC-9H6Vx4850i2Ksp3R8hTCwO',
20
- username: 'test',
21
- extra_attributes: nil,
22
- user_agent: user_agent
23
- })
24
- }
37
+ let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
38
+ let(:user_agent) { ticket_granting_ticket.user_agent }
25
39
  let(:cookies) { { tgt: ticket_granting_ticket.ticket } }
26
40
 
27
41
  before(:each) do
@@ -64,9 +78,11 @@ describe CASinoCore::Processor::LoginCredentialRequestor do
64
78
  end
65
79
 
66
80
  context 'with a changed browser' do
81
+ let(:user_agent) { 'FooBar 1.0' }
82
+
67
83
  it 'calls the #user_not_logged_in method on the listener' do
68
84
  listener.should_receive(:user_not_logged_in).with(kind_of(CASinoCore::Model::LoginTicket))
69
- processor.process(nil, cookies)
85
+ processor.process(nil, cookies, user_agent)
70
86
  end
71
87
  end
72
88
  end
@@ -7,22 +7,15 @@ describe CASinoCore::Processor::Logout do
7
7
  let(:cookies) { { tgt: tgt } }
8
8
  let(:url) { nil }
9
9
  let(:params) { { :url => url } unless url.nil? }
10
- let(:user_agent) { 'TestBrowser 1.0' }
11
10
 
12
11
  before(:each) do
13
12
  listener.stub(:user_logged_out)
14
13
  end
15
14
 
16
15
  context 'with an existing ticket-granting ticket' do
17
- let(:ticket_granting_ticket) {
18
- CASinoCore::Model::TicketGrantingTicket.create!({
19
- ticket: 'TGC-HXdkW233TsRtiqYGq4b8U7',
20
- username: 'test',
21
- extra_attributes: nil,
22
- user_agent: user_agent
23
- })
24
- }
16
+ let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
25
17
  let(:tgt) { ticket_granting_ticket.ticket }
18
+ let(:user_agent) { ticket_granting_ticket.user_agent }
26
19
 
27
20
  it 'deletes the ticket-granting ticket' do
28
21
  processor.process(params, cookies, user_agent)
@@ -40,16 +40,7 @@ describe CASinoCore::Processor::ProxyTicketProvider do
40
40
  end
41
41
 
42
42
  context 'with a proxy-granting ticket' do
43
- let(:ticket_granting_ticket) {
44
- CASinoCore::Model::TicketGrantingTicket.create!({
45
- ticket: 'TGC-Qu6B5IVQ7RmLc972TruM9u',
46
- username: 'test'
47
- })
48
- }
49
- let(:service_ticket) { ticket_granting_ticket.service_tickets.create! ticket: 'ST-2nOcXx56dtPTsB069yYf0h', service: 'http://www.example.com/' }
50
- let(:proxy_granting_ticket) {
51
- service_ticket.proxy_granting_tickets.create! ticket: 'PGT-OIE42ZadV3B9VcaG2xMjAf', iou: 'PGTIOU-PYg4CCPQHNyyS9s6bJF6Rg', pgt_url: 'https://www.example.com/pgtUrl'
52
- }
43
+ let(:proxy_granting_ticket) { FactoryGirl.create :proxy_granting_ticket }
53
44
  let(:params_with_valid_pgt) { params.merge(pgt: proxy_granting_ticket.ticket) }
54
45
 
55
46
  it 'calls the #request_succeeded method on the listener' do
@@ -7,21 +7,20 @@ describe CASinoCore::Processor::ProxyTicketValidator do
7
7
  describe '#process' do
8
8
  let(:regex_success) { /\A<cas:serviceResponse.*\n.*authenticationSuccess/ }
9
9
 
10
+ context 'with a login ticket' do
11
+ let(:login_ticket) { FactoryGirl.create :login_ticket }
12
+ let(:parameters) { { ticket: login_ticket.ticket, service: 'http://www.example.org/' } }
13
+
14
+ it 'calls the #validation_failed method on the listener' do
15
+ listener.should_receive(:validation_failed)
16
+ processor.process(parameters)
17
+ end
18
+ end
19
+
10
20
  context 'with an unconsumed proxy ticket' do
11
- let(:ticket_granting_ticket) {
12
- CASinoCore::Model::TicketGrantingTicket.create!({
13
- ticket: 'TGC-Qu6B5IVQ7RmLc972TruM9u',
14
- username: 'test'
15
- })
16
- }
17
- let(:service_ticket) { ticket_granting_ticket.service_tickets.create! ticket: 'ST-2nOcXx56dtPTsB069yYf0h', service: 'http://www.example.com/' }
18
- let(:proxy_granting_ticket) {
19
- service_ticket.proxy_granting_tickets.create! ticket: 'PGT-OIE42ZadV3B9VcaG2xMjAf', iou: 'PGTIOU-PYg4CCPQHNyyS9s6bJF6Rg', pgt_url: 'https://www.example.com/pgtUrl'
20
- }
21
- let(:proxy_service) { 'imaps://127.0.0.1:4578/' }
22
- let(:proxy_ticket) { proxy_granting_ticket.proxy_tickets.create! ticket: 'PT-8nA7vuxuNY7RcpVoaDvuZi', service: proxy_service }
23
- let(:parameters) { { ticket: proxy_ticket.ticket, service: proxy_service } }
24
- let(:regex_proxy) { /<cas:proxies>\s*<cas:proxy>https:\/\/www.example.com\/pgtUrl<\/cas:proxy>\s*<\/cas:proxies[>]/ }
21
+ let(:proxy_ticket) { FactoryGirl.create :proxy_ticket }
22
+ let(:parameters) { { ticket: proxy_ticket.ticket, service: proxy_ticket.service } }
23
+ let(:regex_proxy) { /<cas:proxies>\s*<cas:proxy>#{proxy_ticket.proxy_granting_ticket.pgt_url}<\/cas:proxy>\s*<\/cas:proxies>/ }
25
24
 
26
25
  it 'calls the #validation_succeeded method on the listener' do
27
26
  listener.should_receive(:validation_succeeded).with(regex_success)
@@ -4,15 +4,8 @@ describe CASinoCore::Processor::SessionDestroyer do
4
4
  describe '#process' do
5
5
  let(:listener) { Object.new }
6
6
  let(:processor) { described_class.new(listener) }
7
- let(:user_agent) { 'TestBrowser 1.0' }
8
- let(:owner_ticket_granting_ticket) {
9
- CASinoCore::Model::TicketGrantingTicket.create!({
10
- ticket: 'TGC-ocCudGzZjJtrvOXJ485mt3',
11
- username: 'test',
12
- extra_attributes: nil,
13
- user_agent: user_agent
14
- })
15
- }
7
+ let(:owner_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
8
+ let(:user_agent) { owner_ticket_granting_ticket.user_agent }
16
9
  let(:cookies) { { tgt: owner_ticket_granting_ticket.ticket } }
17
10
 
18
11
  before(:each) do
@@ -21,23 +14,9 @@ describe CASinoCore::Processor::SessionDestroyer do
21
14
  end
22
15
 
23
16
  context 'with an existing ticket-granting ticket' do
24
- let(:ticket_granting_ticket) {
25
- CASinoCore::Model::TicketGrantingTicket.create!({
26
- ticket: 'TGC-HXdkW233TsRtiqYGq4b8U7',
27
- username: 'test',
28
- extra_attributes: nil,
29
- user_agent: user_agent
30
- })
31
- }
32
- let(:service_ticket) {
33
- ticket_granting_ticket.service_tickets.create! ticket: 'ST-6NBRr5DAg2NW181H5chaHh', service: 'http://www.example.com'
34
- }
35
- let(:consumed_service_ticket) {
36
- st = ticket_granting_ticket.service_tickets.create! ticket: 'ST-6NBRr5DAg2NW181H5chaHh', service: 'http://www.example.com'
37
- st.consumed = true
38
- st.save!
39
- st
40
- }
17
+ let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
18
+ let(:service_ticket) { FactoryGirl.create :service_ticket, ticket_granting_ticket: ticket_granting_ticket }
19
+ let(:consumed_service_ticket) { FactoryGirl.create :service_ticket, :consumed, ticket_granting_ticket: ticket_granting_ticket }
41
20
  let(:params) { { id: ticket_granting_ticket.id } }
42
21
 
43
22
  it 'deletes only one ticket-granting ticket' do
@@ -75,14 +54,7 @@ describe CASinoCore::Processor::SessionDestroyer do
75
54
  end
76
55
 
77
56
  context 'when trying to delete ticket-granting ticket of another user' do
78
- let(:ticket_granting_ticket) {
79
- CASinoCore::Model::TicketGrantingTicket.create!({
80
- ticket: 'TGC-HXdkW233TsRtiqYGq4b8U7',
81
- username: 'this_is_another_user',
82
- extra_attributes: nil,
83
- user_agent: user_agent
84
- })
85
- }
57
+ let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, username: 'other_user' }
86
58
  let(:params) { { id: ticket_granting_ticket.id } }
87
59
 
88
60
  it 'does not delete a ticket-granting ticket' do
@@ -4,15 +4,8 @@ describe CASinoCore::Processor::SessionOverview do
4
4
  describe '#process' do
5
5
  let(:listener) { Object.new }
6
6
  let(:processor) { described_class.new(listener) }
7
- let(:user_agent) { 'TestBrowser 1.0' }
8
- let(:other_ticket_granting_ticket) {
9
- CASinoCore::Model::TicketGrantingTicket.create!({
10
- ticket: 'TGC-ocCudGzZjJtrvOXJ485mt3',
11
- username: 'test',
12
- extra_attributes: nil,
13
- user_agent: user_agent
14
- })
15
- }
7
+ let(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
8
+ let(:user_agent) { other_ticket_granting_ticket.user_agent }
16
9
  let(:cookies) { { tgt: tgt } }
17
10
 
18
11
  before(:each) do
@@ -22,14 +15,7 @@ describe CASinoCore::Processor::SessionOverview do
22
15
  end
23
16
 
24
17
  context 'with an existing ticket-granting ticket' do
25
- let(:ticket_granting_ticket) {
26
- CASinoCore::Model::TicketGrantingTicket.create!({
27
- ticket: 'TGC-HXdkW233TsRtiqYGq4b8U7',
28
- username: 'test',
29
- extra_attributes: nil,
30
- user_agent: user_agent
31
- })
32
- }
18
+ let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
33
19
  let(:tgt) { ticket_granting_ticket.ticket }
34
20
  it 'calls the #ticket_granting_tickets_found method on the listener' do
35
21
  listener.should_receive(:ticket_granting_tickets_found) do |tickets|
@@ -39,6 +25,18 @@ describe CASinoCore::Processor::SessionOverview do
39
25
  end
40
26
  end
41
27
 
28
+ context 'with a ticket-granting ticket with same username but different authenticator' do
29
+ let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, authenticator: 'other' }
30
+ let(:tgt) { ticket_granting_ticket.ticket }
31
+
32
+ it 'calls the #ticket_granting_tickets_found method on the listener' do
33
+ listener.should_receive(:ticket_granting_tickets_found) do |tickets|
34
+ tickets.length.should == 1
35
+ end
36
+ processor.process(cookies, user_agent)
37
+ end
38
+ end
39
+
42
40
  context 'with an invalid ticket-granting ticket' do
43
41
  let(:tgt) { 'TGT-lalala' }
44
42
  it 'calls the #user_not_logged_in method on the listener' do
@@ -5,19 +5,8 @@ require 'spec_helper'
5
5
  describe '#process' do
6
6
  let(:listener) { Object.new }
7
7
  let(:processor) { described_class.new(listener) }
8
- let(:user_agent) { 'TestBrowser 1.0' }
9
- let(:ticket_granting_ticket) {
10
- CASinoCore::Model::TicketGrantingTicket.create!({
11
- ticket: 'TGC-HXdkW233TsRtiqYGq4b8U7',
12
- username: 'test',
13
- extra_attributes: { name: "Example User", roles: ['User', 'Admin'] },
14
- user_agent: user_agent
15
- })
16
- }
17
- let(:service) { 'https://www.example.com/cas-service' }
18
- let(:service_ticket) { ticket_granting_ticket.service_tickets.create! ticket: 'ST-2nOcXx56dtPTsB069yYf0h', service: service }
19
- let(:parameters) { { service: service, ticket: service_ticket.ticket }}
20
-
8
+ let(:service_ticket) { FactoryGirl.create :service_ticket }
9
+ let(:parameters) { { service: service_ticket.service, ticket: service_ticket.ticket }}
21
10
  let(:regex_failure) { /\A\<cas\:serviceResponse.*\n.*authenticationFailure/ }
22
11
  let(:regex_success) { /\A\<cas\:serviceResponse.*\n.*authenticationSuccess/ }
23
12
 
@@ -26,6 +15,19 @@ require 'spec_helper'
26
15
  listener.stub(:validation_succeeded)
27
16
  end
28
17
 
18
+ context 'without all required parameters' do
19
+ [:ticket, :service].each do |missing_parameter|
20
+ let(:invalid_parameters) { parameters.except(missing_parameter) }
21
+
22
+ context "without '#{missing_parameter}'" do
23
+ it 'calls the #validation_failed method on the listener' do
24
+ listener.should_receive(:validation_failed).with(regex_failure)
25
+ processor.process(invalid_parameters)
26
+ end
27
+ end
28
+ end
29
+ end
30
+
29
31
  context 'with an unconsumed service ticket' do
30
32
  context 'without renew flag' do
31
33
  it 'consumes the service ticket' do
@@ -43,7 +45,7 @@ require 'spec_helper'
43
45
  context 'with empty query values' do
44
46
  it 'calls the #validation_succeeded method on the listener' do
45
47
  listener.should_receive(:validation_succeeded).with(regex_success)
46
- processor.process(parameters.merge(service: "#{service}/?"))
48
+ processor.process(parameters.merge(service: "#{service_ticket.service}/?"))
47
49
  end
48
50
  end
49
51
 
@@ -10,6 +10,11 @@ require 'simplecov'
10
10
  # loaded once.
11
11
  #
12
12
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
13
+
14
+ # Requires supporting ruby files with custom matchers and macros, etc,
15
+ # in spec/support/ and its subdirectories.
16
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
17
+
13
18
  RSpec.configure do |config|
14
19
  config.treat_symbols_as_metadata_keys_with_true_values = true
15
20
 
@@ -21,6 +26,12 @@ RSpec.configure do |config|
21
26
 
22
27
  SimpleCov.start do
23
28
  add_filter '/spec'
29
+ base_path = "#{File.dirname(__FILE__)}/../"
30
+ Dir["#{base_path}lib/casino_core/*.rb"].each do |f|
31
+ f.gsub!(/\A#{base_path}(.+)\.rb\z/, '\1')
32
+ name = File.basename(f).humanize.pluralize
33
+ add_group name, f
34
+ end
24
35
  end
25
36
 
26
37
  CASinoCore.setup 'test'
@@ -0,0 +1,16 @@
1
+ require 'factory_girl'
2
+
3
+ FactoryGirl.define do
4
+ factory :login_ticket, class: CASinoCore::Model::LoginTicket do
5
+ sequence :ticket do |n|
6
+ "LT-ticket#{n}"
7
+ end
8
+
9
+ trait :consumed do
10
+ consumed true
11
+ end
12
+ trait :expired do
13
+ created_at 601.seconds.ago
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'factory_girl'
2
+
3
+ FactoryGirl.define do
4
+ factory :proxy_granting_ticket, class: CASinoCore::Model::ProxyGrantingTicket do
5
+ association :granter, factory: :service_ticket
6
+ sequence :ticket do |n|
7
+ "PGT-ticket#{n}"
8
+ end
9
+ sequence :iou do |n|
10
+ "PGTIOU-ticket#{n}"
11
+ end
12
+ sequence :pgt_url do |n|
13
+ "https://www#{n}.example.org/pgtUrl"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ require 'factory_girl'
2
+
3
+ FactoryGirl.define do
4
+ factory :proxy_ticket, class: CASinoCore::Model::ProxyTicket do
5
+ proxy_granting_ticket
6
+ sequence :ticket do |n|
7
+ "PT-ticket#{n}"
8
+ end
9
+ sequence :service do |n|
10
+ "imaps://mail#{n}.example.org/"
11
+ end
12
+
13
+ trait :consumed do
14
+ consumed true
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'factory_girl'
2
+
3
+ FactoryGirl.define do
4
+ factory :service_ticket, class: CASinoCore::Model::ServiceTicket do
5
+ ticket_granting_ticket
6
+ sequence :ticket do |n|
7
+ "ST-ticket#{n}"
8
+ end
9
+ sequence :service do |n|
10
+ "http://www#{n}.example.org/"
11
+ end
12
+
13
+ trait :consumed do
14
+ consumed true
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ require 'factory_girl'
2
+
3
+ FactoryGirl.define do
4
+ factory :ticket_granting_ticket, class: CASinoCore::Model::TicketGrantingTicket do
5
+ sequence :ticket do |n|
6
+ "TGC-ticket#{n}"
7
+ end
8
+ authenticator 'test'
9
+ username 'test'
10
+ extra_attributes({ fullname: "Test User", age: 15, roles: [:user] })
11
+ user_agent 'TestBrowser 1.0'
12
+ end
13
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: casino_core
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.0.3
5
+ version: 1.0.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Nils Caspar
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-12-29 00:00:00 Z
13
+ date: 2012-12-30 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -155,6 +155,17 @@ dependencies:
155
155
  type: :development
156
156
  prerelease: false
157
157
  version_requirements: *id013
158
+ - !ruby/object:Gem::Dependency
159
+ name: factory_girl
160
+ requirement: &id014 !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ~>
164
+ - !ruby/object:Gem::Version
165
+ version: 4.1.0
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: *id014
158
169
  description: A CAS server core library.
159
170
  email: ncaspar@me.com
160
171
  executables: []
@@ -196,6 +207,7 @@ files:
196
207
  - db/migrate/20121225231713_no_default_granter_type.rb
197
208
  - db/migrate/20121226192211_fix_index_for_granter_on_proxy_granting_ticket.rb
198
209
  - db/migrate/20121226211511_allow_service_tickets_without_ticket_granting_ticket.rb
210
+ - db/migrate/20121231114141_add_authenticator_to_ticket_granting_tickets.rb
199
211
  - db/schema.rb
200
212
  - lib/casino_core.rb
201
213
  - lib/casino_core/authenticator.rb
@@ -250,6 +262,11 @@ files:
250
262
  - spec/processor/session_overview_spec.rb
251
263
  - spec/processor/ticket_validator_spec.rb
252
264
  - spec/spec_helper.rb
265
+ - spec/support/factories/login_ticket_factory.rb
266
+ - spec/support/factories/proxy_granting_ticket_factory.rb
267
+ - spec/support/factories/proxy_ticket_factory.rb
268
+ - spec/support/factories/service_ticket_factory.rb
269
+ - spec/support/factories/ticket_granting_ticket_factory.rb
253
270
  homepage: http://github.com/pencil/CASinoCore
254
271
  licenses:
255
272
  - MIT
@@ -263,7 +280,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
263
280
  requirements:
264
281
  - - ">="
265
282
  - !ruby/object:Gem::Version
266
- hash: 1358580775161495326
283
+ hash: -1912000289096139821
267
284
  segments:
268
285
  - 0
269
286
  version: "0"