casino 1.3.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.gitignore +3 -0
  3. data/.travis.yml +1 -1
  4. data/README.md +1 -8
  5. data/Rakefile +0 -2
  6. data/app/assets/javascripts/casino/application.js +1 -0
  7. data/app/assets/javascripts/casino/index.js +0 -2
  8. data/app/assets/javascripts/casino/sessions.js +32 -0
  9. data/app/authenticators/casino/static_authenticator.rb +23 -0
  10. data/app/builders/casino/ticket_validation_response_builder.rb +84 -0
  11. data/app/controllers/casino/api/v1/tickets_controller.rb +7 -4
  12. data/app/controllers/casino/application_controller.rb +2 -3
  13. data/{lib/casino/listener/legacy_validator.rb → app/listeners/casino/legacy_validator_listener.rb} +2 -2
  14. data/app/listeners/casino/listener.rb +16 -0
  15. data/{lib/casino/listener/login_credential_acceptor.rb → app/listeners/casino/login_credential_acceptor_listener.rb} +2 -2
  16. data/{lib/casino/listener/login_credential_requestor.rb → app/listeners/casino/login_credential_requestor_listener.rb} +2 -2
  17. data/{lib/casino/listener/logout.rb → app/listeners/casino/logout_listener.rb} +2 -2
  18. data/{lib/casino/listener/other_sessions_destroyer.rb → app/listeners/casino/other_sessions_destroyer_listener.rb} +2 -2
  19. data/{lib/casino/listener/proxy_ticket_provider.rb → app/listeners/casino/proxy_ticket_provider_listener.rb} +2 -2
  20. data/{lib/casino/listener/second_factor_authentication_acceptor.rb → app/listeners/casino/second_factor_authentication_acceptor_listener.rb} +2 -2
  21. data/{lib/casino/listener/session_destroyer.rb → app/listeners/casino/session_destroyer_listener.rb} +2 -2
  22. data/{lib/casino/listener/session_overview.rb → app/listeners/casino/session_overview_listener.rb} +2 -2
  23. data/{lib/casino/listener/ticket_validator.rb → app/listeners/casino/ticket_validator_listener.rb} +2 -2
  24. data/{lib/casino/listener/two_factor_authenticator_activator.rb → app/listeners/casino/two_factor_authenticator_activator_listener.rb} +2 -2
  25. data/{lib/casino/listener/two_factor_authenticator_destroyer.rb → app/listeners/casino/two_factor_authenticator_destroyer_listener.rb} +2 -2
  26. data/{lib/casino/listener/two_factor_authenticator_overview.rb → app/listeners/casino/two_factor_authenticator_overview_listener.rb} +2 -2
  27. data/{lib/casino/listener/two_factor_authenticator_registrator.rb → app/listeners/casino/two_factor_authenticator_registrator_listener.rb} +2 -2
  28. data/app/models/casino/login_ticket.rb +12 -0
  29. data/app/models/casino/proxy_granting_ticket.rb +8 -0
  30. data/app/models/casino/proxy_ticket.rb +25 -0
  31. data/app/models/casino/service_rule.rb +27 -0
  32. data/app/models/casino/service_ticket.rb +43 -0
  33. data/app/models/casino/service_ticket/single_sign_out_notifier.rb +44 -0
  34. data/app/models/casino/ticket_granting_ticket.rb +57 -0
  35. data/app/models/casino/two_factor_authenticator.rb +18 -0
  36. data/app/models/casino/user.rb +12 -0
  37. data/app/models/casino/validation_result.rb +5 -0
  38. data/app/processors/casino/api/login_credential_acceptor_processor.rb +46 -0
  39. data/app/processors/casino/api/logout_processor.rb +17 -0
  40. data/app/processors/casino/api/service_ticket_provider_processor.rb +69 -0
  41. data/app/processors/casino/legacy_validator_processor.rb +19 -0
  42. data/app/processors/casino/login_credential_acceptor_processor.rb +63 -0
  43. data/app/processors/casino/login_credential_requestor_processor.rb +66 -0
  44. data/app/processors/casino/logout_processor.rb +23 -0
  45. data/app/processors/casino/other_sessions_destroyer_processor.rb +26 -0
  46. data/app/processors/casino/processor.rb +5 -0
  47. data/app/processors/casino/processor_concern/authentication.rb +87 -0
  48. data/app/processors/casino/processor_concern/browser.rb +14 -0
  49. data/app/processors/casino/processor_concern/login_tickets.rb +28 -0
  50. data/app/processors/casino/processor_concern/proxy_granting_tickets.rb +43 -0
  51. data/app/processors/casino/processor_concern/proxy_tickets.rb +56 -0
  52. data/app/processors/casino/processor_concern/service_tickets.rb +50 -0
  53. data/app/processors/casino/processor_concern/ticket_granting_tickets.rb +65 -0
  54. data/app/processors/casino/processor_concern/tickets.rb +17 -0
  55. data/app/processors/casino/processor_concern/two_factor_authenticators.rb +22 -0
  56. data/app/processors/casino/proxy_ticket_provider_processor.rb +41 -0
  57. data/app/processors/casino/proxy_ticket_validator_processor.rb +22 -0
  58. data/app/processors/casino/second_factor_authentication_acceptor_processor.rb +45 -0
  59. data/app/processors/casino/service_ticket_validator_processor.rb +46 -0
  60. data/app/processors/casino/session_destroyer_processor.rb +25 -0
  61. data/app/processors/casino/session_overview_processor.rb +21 -0
  62. data/app/processors/casino/two_factor_authenticator_activator_processor.rb +41 -0
  63. data/app/processors/casino/two_factor_authenticator_destroyer_processor.rb +33 -0
  64. data/app/processors/casino/two_factor_authenticator_overview_processor.rb +20 -0
  65. data/app/processors/casino/two_factor_authenticator_registrator_processor.rb +24 -0
  66. data/app/views/casino/application/_footer.html.erb +1 -1
  67. data/app/views/casino/sessions/new.html.erb +2 -1
  68. data/app/views/casino/sessions/validate_otp.html.erb +1 -1
  69. data/app/views/casino/two_factor_authenticators/new.html.erb +2 -2
  70. data/app/views/layouts/application.html.erb +1 -1
  71. data/casino.gemspec +9 -4
  72. data/db/migrate/20130809135400_create_core_schema.rb +117 -0
  73. data/db/migrate/20130809135401_rename_base_models.rb +101 -0
  74. data/db/migrate/20131022110146_cleanup_indexes.rb +27 -0
  75. data/db/migrate/20131022110246_fix_long_index_names.rb +12 -0
  76. data/db/migrate/20131022110346_change_service_to_text.rb +6 -0
  77. data/lib/casino.rb +47 -3
  78. data/lib/casino/authenticator.rb +9 -0
  79. data/lib/casino/engine.rb +26 -0
  80. data/lib/casino/inflections.rb +7 -0
  81. data/lib/casino/tasks.rb +1 -0
  82. data/lib/casino/tasks/cleanup.rake +59 -0
  83. data/lib/casino/tasks/service_rule.rake +49 -0
  84. data/lib/casino/version.rb +1 -1
  85. data/lib/generators/casino/install/USAGE +13 -0
  86. data/lib/generators/casino/install/install_generator.rb +47 -0
  87. data/lib/generators/casino/{templates → install/templates}/README +3 -4
  88. data/lib/generators/casino/{templates → install/templates}/cas.yml +2 -2
  89. data/lib/generators/casino/{templates → install/templates}/casino_and_overrides.scss +0 -0
  90. data/lib/generators/casino/templates/casino_core.rb +1 -1
  91. data/spec/authenticator/base_spec.rb +13 -0
  92. data/spec/authenticator/static_spec.rb +42 -0
  93. data/spec/controllers/api/v1/tickets_controller_spec.rb +15 -15
  94. data/spec/controllers/listener/legacy_validator_spec.rb +1 -1
  95. data/spec/controllers/listener/login_credential_acceptor_spec.rb +1 -1
  96. data/spec/controllers/listener/login_credential_requestor_spec.rb +1 -1
  97. data/spec/controllers/listener/logout_spec.rb +1 -1
  98. data/spec/controllers/listener/other_sessions_destroyer_spec.rb +1 -1
  99. data/spec/controllers/listener/proxy_ticket_provider_spec.rb +1 -1
  100. data/spec/controllers/listener/second_factor_authentication_acceptor_spec.rb +1 -1
  101. data/spec/controllers/listener/session_destroyer_spec.rb +1 -1
  102. data/spec/controllers/listener/session_overview_spec.rb +1 -1
  103. data/spec/controllers/listener/ticket_validator_spec.rb +1 -1
  104. data/spec/controllers/listener/two_factor_authenticator_activator_spec.rb +1 -1
  105. data/spec/controllers/listener/two_factor_authenticator_destroyer_spec.rb +1 -1
  106. data/spec/controllers/listener/two_factor_authenticator_overview_spec.rb +1 -1
  107. data/spec/controllers/listener/two_factor_authenticator_registrator_spec.rb +1 -1
  108. data/spec/controllers/proxy_tickets_controller_spec.rb +4 -4
  109. data/spec/controllers/service_tickets_controller_spec.rb +4 -4
  110. data/spec/controllers/sessions_controller_spec.rb +15 -15
  111. data/spec/controllers/two_factor_authenticators_controller_spec.rb +6 -6
  112. data/spec/dummy/app/assets/stylesheets/casino_and_overrides.scss +13 -0
  113. data/spec/dummy/config/cas.yml +11 -11
  114. data/spec/dummy/config/routes.rb +1 -2
  115. data/spec/dummy/db/migrate/20130910094259_create_base_models.casino.rb +95 -0
  116. data/spec/dummy/db/schema.rb +107 -0
  117. data/spec/model/login_ticket_spec.rb +23 -0
  118. data/spec/model/proxy_ticket_spec.rb +63 -0
  119. data/spec/model/service_rule_spec.rb +65 -0
  120. data/spec/model/service_ticket/single_sign_out_notifier_spec.rb +61 -0
  121. data/spec/model/service_ticket_spec.rb +124 -0
  122. data/spec/model/ticket_granting_ticket_spec.rb +204 -0
  123. data/spec/model/two_factor_authenticator_spec.rb +31 -0
  124. data/spec/processor/api/login_credential_acceptor_spec.rb +52 -0
  125. data/spec/processor/api/logout_spec.rb +34 -0
  126. data/spec/processor/api/service_ticket_provider_spec.rb +61 -0
  127. data/spec/processor/legacy_validator_spec.rb +78 -0
  128. data/spec/processor/login_credential_acceptor_spec.rb +164 -0
  129. data/spec/processor/login_credential_requestor_spec.rb +135 -0
  130. data/spec/processor/logout_other_sessions_spec.rb +53 -0
  131. data/spec/processor/logout_spec.rb +72 -0
  132. data/spec/processor/processor_concern/service_tickets_spec.rb +49 -0
  133. data/spec/processor/proxy_ticket_provider_spec.rb +66 -0
  134. data/spec/processor/proxy_ticket_validator_spec.rb +65 -0
  135. data/spec/processor/second_factor_authenticaton_acceptor_spec.rb +94 -0
  136. data/spec/processor/session_destroyer_spec.rb +75 -0
  137. data/spec/processor/session_overview_spec.rb +49 -0
  138. data/spec/processor/ticket_validator_spec.rb +199 -0
  139. data/spec/processor/two_factor_authenticator_activator_spec.rb +122 -0
  140. data/spec/processor/two_factor_authenticator_destroyer_spec.rb +71 -0
  141. data/spec/processor/two_factor_authenticator_overview_spec.rb +56 -0
  142. data/spec/processor/two_factor_authenticator_registrator_spec.rb +48 -0
  143. data/spec/spec_helper.rb +8 -19
  144. data/spec/support/casino.rb +12 -0
  145. data/spec/support/factories/login_ticket_factory.rb +16 -0
  146. data/spec/support/factories/proxy_granting_ticket_factory.rb +16 -0
  147. data/spec/support/factories/proxy_ticket_factory.rb +17 -0
  148. data/spec/support/factories/service_rule_factory.rb +16 -0
  149. data/spec/support/factories/service_ticket_factory.rb +17 -0
  150. data/spec/support/factories/ticket_granting_ticket_factory.rb +15 -0
  151. data/spec/support/factories/two_factor_authenticator_factory.rb +16 -0
  152. data/spec/support/factories/user_factory.rb +11 -0
  153. data/spec/support/rspec.rb +8 -0
  154. data/spec/support/sqlite3.rb +4 -0
  155. metadata +284 -48
  156. metadata.gz.sig +2 -0
  157. data/.powrc +0 -4
  158. data/Gemfile.lock +0 -149
  159. data/app/assets/javascripts/casino/application.js.coffee +0 -5
  160. data/app/assets/javascripts/casino/sessions.js.coffee +0 -15
  161. data/config/initializers/frontend_config.rb +0 -9
  162. data/config/initializers/inflections.rb +0 -19
  163. data/config/initializers/yaml.rb +0 -1
  164. data/lib/casino/listener.rb +0 -31
  165. data/lib/generators/casino/install_generator.rb +0 -35
  166. data/spec/dummy/config/initializers/casino_core.rb +0 -1
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require 'nokogiri'
3
+
4
+ describe CASino::ServiceTicket::SingleSignOutNotifier do
5
+ let(:service_ticket) { FactoryGirl.create :service_ticket }
6
+ let(:service) { service_ticket.service }
7
+ let(:notifier) { described_class.new service_ticket }
8
+
9
+ describe '#notify' do
10
+ before(:each) do
11
+ stub_request(:post, service)
12
+ end
13
+
14
+ it 'sends a valid Single Sign Out XML to the service URL' do
15
+ notifier.notify
16
+ WebMock.should have_requested(:post, service).with { |request|
17
+ post_params = CGI.parse(request.body)
18
+ post_params.should_not be_nil
19
+ xml = Nokogiri::XML post_params['logoutRequest'].first
20
+ xml.at_xpath('/samlp:LogoutRequest/samlp:SessionIndex').text.should == service_ticket.ticket
21
+ }
22
+ end
23
+
24
+ it 'sets the timeout values' do
25
+ [:read_timeout=, :open_timeout=].each do |timeout|
26
+ Net::HTTP.any_instance.should_receive(timeout).with(CASino.config.service_ticket[:single_sign_out_notification][:timeout])
27
+ end
28
+ notifier.notify
29
+ end
30
+
31
+ context 'when it is a success' do
32
+ it 'returns true' do
33
+ notifier.notify.should == true
34
+ end
35
+ end
36
+
37
+ context 'with server error' do
38
+ [404, 500].each do |status_code|
39
+ context "#{status_code}" do
40
+ before(:each) do
41
+ stub_request(:post, service).to_return status: status_code
42
+ end
43
+
44
+ it 'returns false' do
45
+ notifier.notify.should == false
46
+ end
47
+ end
48
+ end
49
+
50
+ context 'connection timeout' do
51
+ before(:each) do
52
+ stub_request(:post, service).to_raise Timeout::Error
53
+ end
54
+
55
+ it 'returns false' do
56
+ notifier.notify.should == false
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,124 @@
1
+ require 'spec_helper'
2
+
3
+ describe CASino::ServiceTicket do
4
+ let(:unconsumed_ticket) {
5
+ ticket = described_class.new ticket: 'ST-12345', service: 'https://example.com/cas-service'
6
+ ticket.ticket_granting_ticket_id = 1
7
+ ticket
8
+ }
9
+ let(:consumed_ticket) {
10
+ ticket = described_class.new ticket: 'ST-54321', service: 'https://example.com/cas-service'
11
+ ticket.ticket_granting_ticket_id = 1
12
+ ticket.consumed = true
13
+ ticket.save!
14
+ ticket
15
+ }
16
+
17
+ describe '#expired?' do
18
+ [:unconsumed, :consumed].each do |state|
19
+ context "with an #{state} ticket" do
20
+ let(:ticket) { send("#{state}_ticket") }
21
+
22
+ context 'with an expired ticket' do
23
+ before(:each) do
24
+ ticket.created_at = (CASino.config.service_ticket[:"lifetime_#{state}"].seconds + 1).ago
25
+ ticket.save!
26
+ end
27
+
28
+ it 'returns true' do
29
+ ticket.expired?.should == true
30
+ end
31
+ end
32
+
33
+ context 'with an unexpired ticket' do
34
+ it 'returns false' do
35
+ ticket.expired?.should == false
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '.cleanup_unconsumed' do
43
+ it 'deletes expired unconsumed service tickets' do
44
+ unconsumed_ticket.created_at = 10.hours.ago
45
+ unconsumed_ticket.save!
46
+ lambda do
47
+ described_class.cleanup_unconsumed
48
+ end.should change(described_class, :count).by(-1)
49
+ described_class.find_by_ticket('ST-12345').should be_false
50
+ end
51
+ end
52
+
53
+ describe '.cleanup_consumed_hard' do
54
+ before(:each) do
55
+ described_class::SingleSignOutNotifier.any_instance.stub(:notify).and_return(false)
56
+ end
57
+
58
+ it 'deletes consumed service tickets with an unreachable Single Sign Out callback server' do
59
+ consumed_ticket.created_at = 10.days.ago
60
+ consumed_ticket.save!
61
+ lambda do
62
+ described_class.cleanup_consumed_hard
63
+ end.should change(described_class, :count).by(-1)
64
+ end
65
+ end
66
+
67
+ describe '.cleanup_consumed' do
68
+ before(:each) do
69
+ described_class::SingleSignOutNotifier.any_instance.stub(:notify).and_return(true)
70
+ end
71
+
72
+ it 'deletes expired consumed service tickets' do
73
+ consumed_ticket.created_at = 10.days.ago
74
+ consumed_ticket.save!
75
+ lambda do
76
+ described_class.cleanup_consumed
77
+ end.should change(described_class, :count).by(-1)
78
+ described_class.find_by_ticket('ST-12345').should be_false
79
+ end
80
+
81
+ it 'deletes consumed service tickets without ticket_granting_ticket' do
82
+ consumed_ticket.ticket_granting_ticket_id = nil
83
+ consumed_ticket.save!
84
+ lambda do
85
+ described_class.cleanup_consumed
86
+ end.should change(described_class, :count).by(-1)
87
+ described_class.find_by_ticket('ST-12345').should be_false
88
+ end
89
+
90
+ it 'does not delete unexpired service tickets' do
91
+ consumed_ticket # create the ticket
92
+ lambda do
93
+ described_class.cleanup_consumed
94
+ end.should_not change(described_class, :count)
95
+ end
96
+ end
97
+
98
+ describe '#destroy' do
99
+ it 'sends out a single sign out notification' do
100
+ described_class::SingleSignOutNotifier.any_instance.should_receive(:notify).and_return(true)
101
+ consumed_ticket.destroy
102
+ end
103
+
104
+ context 'when notification fails' do
105
+ before(:each) do
106
+ described_class::SingleSignOutNotifier.any_instance.stub(:notify).and_return(false)
107
+ end
108
+
109
+ it 'does delete the service ticket anyway' do
110
+ consumed_ticket
111
+ lambda {
112
+ consumed_ticket.destroy
113
+ }.should change(CASino::ServiceTicket, :count).by(-1)
114
+ end
115
+ end
116
+ end
117
+
118
+ describe '#service_with_ticket_url' do
119
+ it 'does not escape the url from the database' do
120
+ unconsumed_ticket.service = 'https://host.example.org/test.php?t=other&other=testing'
121
+ unconsumed_ticket.service_with_ticket_url.should eq('https://host.example.org/test.php?t=other&other=testing&ticket=ST-12345')
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,204 @@
1
+ require 'spec_helper'
2
+ require 'useragent'
3
+
4
+ describe CASino::TicketGrantingTicket do
5
+ let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
6
+ let(:service_ticket) { FactoryGirl.create :service_ticket, ticket_granting_ticket: ticket_granting_ticket }
7
+
8
+ describe '#destroy' do
9
+ let!(:consumed_service_ticket) { FactoryGirl.create :service_ticket, :consumed, ticket_granting_ticket: ticket_granting_ticket }
10
+
11
+ context 'when notification for a service ticket fails' do
12
+ before(:each) do
13
+ CASino::ServiceTicket::SingleSignOutNotifier.any_instance.stub(:notify).and_return(false)
14
+ end
15
+
16
+ it 'deletes depending proxy-granting tickets' do
17
+ consumed_service_ticket.proxy_granting_tickets.create! ticket: 'PGT-12345', iou: 'PGTIOU-12345', pgt_url: 'bla'
18
+ lambda {
19
+ ticket_granting_ticket.destroy
20
+ }.should change(CASino::ProxyGrantingTicket, :count).by(-1)
21
+ end
22
+
23
+ it 'deletes depending service tickets' do
24
+ lambda {
25
+ ticket_granting_ticket.destroy
26
+ }.should change(CASino::ServiceTicket, :count).by(-1)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe '#browser_info' do
32
+ let(:user_agent) { Object.new }
33
+ before(:each) do
34
+ user_agent.stub(:browser).and_return('TestBrowser')
35
+ UserAgent.stub(:parse).and_return(user_agent)
36
+ end
37
+
38
+ context 'without platform' do
39
+ before(:each) do
40
+ user_agent.stub(:platform).and_return(nil)
41
+ end
42
+
43
+ it 'returns the browser name' do
44
+ ticket_granting_ticket.browser_info.should == 'TestBrowser'
45
+ end
46
+ end
47
+
48
+ context 'with a platform' do
49
+ before(:each) do
50
+ user_agent.stub(:platform).and_return('Linux')
51
+ end
52
+
53
+ it 'returns the browser name' do
54
+ ticket_granting_ticket.browser_info.should == 'TestBrowser (Linux)'
55
+ end
56
+ end
57
+ end
58
+
59
+ describe '#same_user?' do
60
+ context 'with a nil value' do
61
+ let(:other_ticket_granting_ticket) { nil }
62
+
63
+ it 'should return false' do
64
+ ticket_granting_ticket.same_user?(other_ticket_granting_ticket).should == false
65
+ end
66
+ end
67
+
68
+ context 'with a ticket from another user' do
69
+ let(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
70
+
71
+ it 'should return false' do
72
+ ticket_granting_ticket.same_user?(other_ticket_granting_ticket).should == false
73
+ end
74
+ end
75
+
76
+ context 'with a ticket from the same user' do
77
+ let(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, user: ticket_granting_ticket.user }
78
+
79
+ it 'should return true' do
80
+ ticket_granting_ticket.same_user?(other_ticket_granting_ticket).should == true
81
+ end
82
+ end
83
+ end
84
+
85
+ describe '#expired?' do
86
+ context 'with a long-term ticket' do
87
+ context 'when almost expired' do
88
+ before(:each) do
89
+ ticket_granting_ticket.created_at = 9.days.ago
90
+ ticket_granting_ticket.long_term = true
91
+ ticket_granting_ticket.save!
92
+ end
93
+
94
+ it 'returns false' do
95
+ ticket_granting_ticket.expired?.should == false
96
+ end
97
+ end
98
+
99
+ context 'when expired' do
100
+ before(:each) do
101
+ ticket_granting_ticket.created_at = 30.days.ago
102
+ ticket_granting_ticket.long_term = true
103
+ ticket_granting_ticket.save!
104
+ end
105
+
106
+ it 'returns true' do
107
+ ticket_granting_ticket.expired?.should == true
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'with an expired ticket' do
113
+ before(:each) do
114
+ ticket_granting_ticket.created_at = 25.hours.ago
115
+ ticket_granting_ticket.save!
116
+ end
117
+
118
+ it 'returns true' do
119
+ ticket_granting_ticket.expired?.should == true
120
+ end
121
+ end
122
+
123
+ context 'with an unexpired ticket' do
124
+ it 'returns false' do
125
+ ticket_granting_ticket.expired?.should == false
126
+ end
127
+ end
128
+
129
+ context 'with pending two-factor authentication' do
130
+ before(:each) do
131
+ ticket_granting_ticket.awaiting_two_factor_authentication = true
132
+ ticket_granting_ticket.save!
133
+ end
134
+
135
+ context 'with an expired ticket' do
136
+ before(:each) do
137
+ ticket_granting_ticket.created_at = 10.minutes.ago
138
+ ticket_granting_ticket.save!
139
+ end
140
+
141
+ it 'returns true' do
142
+ ticket_granting_ticket.expired?.should == true
143
+ end
144
+ end
145
+
146
+ context 'with an unexpired ticket' do
147
+ it 'returns false' do
148
+ ticket_granting_ticket.expired?.should == false
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ describe '.cleanup' do
155
+ let!(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
156
+
157
+ it 'deletes expired ticket-granting tickets' do
158
+ ticket_granting_ticket.created_at = 25.hours.ago
159
+ ticket_granting_ticket.save!
160
+ lambda do
161
+ described_class.cleanup
162
+ end.should change(described_class, :count).by(-1)
163
+ described_class.find_by_ticket(ticket_granting_ticket.ticket).should be_false
164
+ end
165
+
166
+ it 'does not delete almost expired long-term ticket-granting tickets' do
167
+ ticket_granting_ticket.created_at = 9.days.ago
168
+ ticket_granting_ticket.long_term = true
169
+ ticket_granting_ticket.save!
170
+ lambda do
171
+ described_class.cleanup
172
+ end.should_not change(described_class, :count)
173
+ end
174
+
175
+ it 'does delete expired long-term ticket-granting tickets' do
176
+ ticket_granting_ticket.created_at = 30.days.ago
177
+ ticket_granting_ticket.long_term = true
178
+ ticket_granting_ticket.save!
179
+ lambda do
180
+ described_class.cleanup
181
+ end.should change(described_class, :count).by(-1)
182
+ described_class.find_by_ticket(ticket_granting_ticket.ticket).should be_false
183
+ end
184
+
185
+ it 'does not delete almost expired ticket-granting tickets with pending two-factor authentication' do
186
+ ticket_granting_ticket.created_at = 2.minutes.ago
187
+ ticket_granting_ticket.awaiting_two_factor_authentication = true
188
+ ticket_granting_ticket.save!
189
+ lambda do
190
+ described_class.cleanup
191
+ end.should_not change(described_class, :count)
192
+ end
193
+
194
+ it 'does delete expired ticket-granting tickets with pending two-factor authentication' do
195
+ ticket_granting_ticket.created_at = 20.minutes.ago
196
+ ticket_granting_ticket.awaiting_two_factor_authentication = true
197
+ ticket_granting_ticket.save!
198
+ lambda do
199
+ described_class.cleanup
200
+ end.should change(described_class, :count).by(-1)
201
+ described_class.find_by_ticket(ticket_granting_ticket.ticket).should be_false
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe CASino::TwoFactorAuthenticator do
4
+ describe '.cleanup' do
5
+ it 'deletes expired inactive two-factor authenticators' do
6
+ authenticator = FactoryGirl.create :two_factor_authenticator, :inactive
7
+ authenticator.created_at = 10.hours.ago
8
+ authenticator.save!
9
+ lambda do
10
+ described_class.cleanup
11
+ end.should change(described_class, :count).by(-1)
12
+ end
13
+
14
+ it 'does not delete not expired inactive two-factor authenticators' do
15
+ authenticator = FactoryGirl.create :two_factor_authenticator, :inactive
16
+ authenticator.created_at = (CASino.config.two_factor_authenticator[:lifetime_inactive].seconds - 5).ago
17
+ lambda do
18
+ described_class.cleanup
19
+ end.should_not change(described_class, :count)
20
+ end
21
+
22
+ it 'does not delete active two-factor authenticators' do
23
+ authenticator = FactoryGirl.create :two_factor_authenticator
24
+ authenticator.created_at = 10.hours.ago
25
+ authenticator.save!
26
+ lambda do
27
+ described_class.cleanup
28
+ end.should_not change(described_class, :count)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe CASino::API::LoginCredentialAcceptorProcessor do
4
+ describe '#process' do
5
+ let(:listener) { Object.new }
6
+ let(:processor) { described_class.new(listener) }
7
+ let(:user_agent) { 'ThisIsATestBrwoser 1.0' }
8
+
9
+ context 'with invalid credentials' do
10
+ let(:login_data) { { username: 'testuser', password: 'wrong' } }
11
+
12
+ before(:each) do
13
+ listener.stub(:invalid_login_credentials_via_api)
14
+ end
15
+
16
+ it 'calls the #invalid_login_credentials_via_api method on the listener' do
17
+ listener.should_receive(:invalid_login_credentials_via_api)
18
+ processor.process(login_data, user_agent).should be_false
19
+ end
20
+
21
+ it 'does not generate a ticket-granting ticket' do
22
+ expect {
23
+ processor.process(login_data, user_agent)
24
+ }.to_not change(CASino::TicketGrantingTicket, :count)
25
+ end
26
+ end
27
+
28
+ context 'with valid credentials' do
29
+ let(:login_data) { { username: 'testuser', password: 'foobar123' } }
30
+
31
+ before(:each) do
32
+ listener.stub(:user_logged_in_via_api)
33
+ end
34
+
35
+ it 'calls the #user_logged_in_via_api method on the listener' do
36
+ listener.should_receive(:user_logged_in_via_api).with(/^TGC\-/)
37
+ processor.process(login_data, user_agent)
38
+ end
39
+
40
+ it 'generates a ticket-granting ticket' do
41
+ expect {
42
+ processor.process(login_data, user_agent)
43
+ }.to change(CASino::TicketGrantingTicket, :count).by(1)
44
+ end
45
+
46
+ it 'sets the user-agent in the ticket-granting ticket' do
47
+ processor.process(login_data, user_agent)
48
+ CASino::TicketGrantingTicket.last.user_agent.should == user_agent
49
+ end
50
+ end
51
+ end
52
+ end