casino_core 1.0.2 → 1.0.3
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.
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/VERSION +1 -1
- data/casino_core.gemspec +5 -1
- data/lib/casino_core/helper/proxy_granting_tickets.rb +1 -1
- data/lib/casino_core/model/service_ticket.rb +1 -1
- data/lib/casino_core/model/service_ticket/single_sign_out_notifier.rb +8 -3
- data/spec/model/service_ticket/single_sign_out_notifier_spec.rb +55 -0
- data/spec/model/service_ticket_spec.rb +16 -0
- data/spec/processor/session_destroyer_spec.rb +0 -13
- data/spec/processor/ticket_validator_spec.rb +37 -2
- data/spec/spec_helper.rb +3 -1
- metadata +14 -2
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -27,6 +27,7 @@ GEM
|
|
27
27
|
rdoc
|
28
28
|
json (1.7.5)
|
29
29
|
multi_json (1.5.0)
|
30
|
+
nokogiri (1.5.6)
|
30
31
|
rake (10.0.3)
|
31
32
|
rdoc (3.12)
|
32
33
|
json (~> 1.4)
|
@@ -60,6 +61,7 @@ DEPENDENCIES
|
|
60
61
|
bundler (~> 1.2.0)
|
61
62
|
database_cleaner
|
62
63
|
jeweler (~> 1.8.4)
|
64
|
+
nokogiri
|
63
65
|
redcarpet
|
64
66
|
rspec (~> 2.12.0)
|
65
67
|
simplecov (~> 0.7.1)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.3
|
data/casino_core.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "casino_core"
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.3"
|
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"]
|
@@ -89,6 +89,7 @@ Gem::Specification.new do |s|
|
|
89
89
|
"spec/authenticator/static_spec.rb",
|
90
90
|
"spec/model/login_ticket_spec.rb",
|
91
91
|
"spec/model/proxy_ticket_spec.rb",
|
92
|
+
"spec/model/service_ticket/single_sign_out_notifier_spec.rb",
|
92
93
|
"spec/model/service_ticket_spec.rb",
|
93
94
|
"spec/model/ticket_granting_ticket_spec.rb",
|
94
95
|
"spec/processor/legacy_validator_spec.rb",
|
@@ -124,6 +125,7 @@ Gem::Specification.new do |s|
|
|
124
125
|
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
125
126
|
s.add_development_dependency(%q<database_cleaner>, [">= 0"])
|
126
127
|
s.add_development_dependency(%q<webmock>, [">= 0"])
|
128
|
+
s.add_development_dependency(%q<nokogiri>, [">= 0"])
|
127
129
|
else
|
128
130
|
s.add_dependency(%q<activerecord>, ["~> 3.2.9"])
|
129
131
|
s.add_dependency(%q<addressable>, ["~> 2.3.2"])
|
@@ -137,6 +139,7 @@ Gem::Specification.new do |s|
|
|
137
139
|
s.add_dependency(%q<sqlite3>, [">= 0"])
|
138
140
|
s.add_dependency(%q<database_cleaner>, [">= 0"])
|
139
141
|
s.add_dependency(%q<webmock>, [">= 0"])
|
142
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
140
143
|
end
|
141
144
|
else
|
142
145
|
s.add_dependency(%q<activerecord>, ["~> 3.2.9"])
|
@@ -151,6 +154,7 @@ Gem::Specification.new do |s|
|
|
151
154
|
s.add_dependency(%q<sqlite3>, [">= 0"])
|
152
155
|
s.add_dependency(%q<database_cleaner>, [">= 0"])
|
153
156
|
s.add_dependency(%q<webmock>, [">= 0"])
|
157
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
154
158
|
end
|
155
159
|
end
|
156
160
|
|
@@ -13,7 +13,7 @@ module CASinoCore
|
|
13
13
|
def acquire_proxy_granting_ticket(pgt_url, service_ticket)
|
14
14
|
begin
|
15
15
|
return contact_callback_server(pgt_url, service_ticket)
|
16
|
-
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
|
16
|
+
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
17
17
|
logger.warn "Exception while communicating with proxy-granting ticket callback server: #{e.message}"
|
18
18
|
end
|
19
19
|
nil
|
@@ -16,7 +16,7 @@ class CASinoCore::Model::ServiceTicket < ActiveRecord::Base
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.cleanup_consumed
|
19
|
-
self.destroy_all(['created_at < ? AND consumed = ?', CASinoCore::Settings.service_ticket[:lifetime_consumed].seconds.ago, true])
|
19
|
+
self.destroy_all(['(ticket_granting_ticket_id IS NULL OR created_at < ?) AND consumed = ?', CASinoCore::Settings.service_ticket[:lifetime_consumed].seconds.ago, true])
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.cleanup_consumed_hard
|
@@ -20,8 +20,13 @@ class CASinoCore::Model::ServiceTicket::SingleSignOutNotifier
|
|
20
20
|
private
|
21
21
|
def build_xml
|
22
22
|
xml = Builder::XmlMarkup.new(indent: 2)
|
23
|
-
xml.samlp :LogoutRequest,
|
24
|
-
|
23
|
+
xml.samlp :LogoutRequest,
|
24
|
+
'xmlns:samlp' => 'urn:oasis:names:tc:SAML:2.0:protocol',
|
25
|
+
'xmlns:saml' => 'urn:oasis:names:tc:SAML:2.0:assertion',
|
26
|
+
ID: SecureRandom.uuid,
|
27
|
+
Version: '2.0',
|
28
|
+
IssueInstant: Time.now do |logout_request|
|
29
|
+
logout_request.saml :NameID, '@NOT_USED@'
|
25
30
|
logout_request.samlp :SessionIndex, @service_ticket.ticket
|
26
31
|
end
|
27
32
|
xml.target!
|
@@ -49,7 +54,7 @@ class CASinoCore::Model::ServiceTicket::SingleSignOutNotifier
|
|
49
54
|
return false
|
50
55
|
end
|
51
56
|
end
|
52
|
-
rescue
|
57
|
+
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
53
58
|
logger.warn "Failed to send logout notification to service #{uri} due to #{e}"
|
54
59
|
return false
|
55
60
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
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 }
|
8
|
+
let(:notifier) { described_class.new service_ticket }
|
9
|
+
|
10
|
+
describe '#notify' do
|
11
|
+
before(:each) do
|
12
|
+
stub_request(:post, service)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'sends a valid Single Sign Out XML to the service URL' do
|
16
|
+
notifier.notify
|
17
|
+
WebMock.should have_requested(:post, service).with { |request|
|
18
|
+
post_params = CGI.parse(request.body)
|
19
|
+
post_params.should_not be_nil
|
20
|
+
xml = Nokogiri::XML post_params['logoutRequest'].first
|
21
|
+
xml.at_xpath('/samlp:LogoutRequest/samlp:SessionIndex').text.strip.should == service_ticket.ticket
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when it is a success' do
|
26
|
+
it 'returns true' do
|
27
|
+
notifier.notify.should == true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with server error' do
|
32
|
+
[404, 500].each do |status_code|
|
33
|
+
context "#{status_code}" do
|
34
|
+
before(:each) do
|
35
|
+
stub_request(:post, service).to_return status: status_code
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns false' do
|
39
|
+
notifier.notify.should == false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'connection timeout' do
|
45
|
+
before(:each) do
|
46
|
+
stub_request(:post, service).to_raise Timeout::Error
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns false' do
|
50
|
+
notifier.notify.should == false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -38,6 +38,22 @@ describe CASinoCore::Model::ServiceTicket do
|
|
38
38
|
end.should change(described_class, :count).by(-1)
|
39
39
|
described_class.find_by_ticket('ST-12345').should be_false
|
40
40
|
end
|
41
|
+
|
42
|
+
it 'deletes consumed service tickets without ticket_granting_ticket' do
|
43
|
+
consumed_ticket.ticket_granting_ticket_id = nil
|
44
|
+
consumed_ticket.save!
|
45
|
+
lambda do
|
46
|
+
described_class.cleanup_consumed
|
47
|
+
end.should change(described_class, :count).by(-1)
|
48
|
+
described_class.find_by_ticket('ST-12345').should be_false
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'does not delete unexpired service tickets' do
|
52
|
+
consumed_ticket # create the ticket
|
53
|
+
lambda do
|
54
|
+
described_class.cleanup_consumed
|
55
|
+
end.should_not change(described_class, :count)
|
56
|
+
end
|
41
57
|
end
|
42
58
|
|
43
59
|
describe '#destroy' do
|
@@ -57,19 +57,6 @@ describe CASinoCore::Processor::SessionDestroyer do
|
|
57
57
|
listener.should_receive(:ticket_deleted).with(no_args)
|
58
58
|
processor.process(params, cookies, user_agent)
|
59
59
|
end
|
60
|
-
|
61
|
-
it 'deletes the dependent service ticket' do
|
62
|
-
service_ticket.ticket # creates the service ticket
|
63
|
-
lambda {
|
64
|
-
processor.process(params, cookies, user_agent)
|
65
|
-
}.should change(CASinoCore::Model::ServiceTicket, :count).by(-1)
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'nullifies the dependent service ticket if destroying fails' do
|
69
|
-
lambda {
|
70
|
-
processor.process(params, cookies, user_agent)
|
71
|
-
}.should change { consumed_service_ticket.reload.ticket_granting_ticket_id }.to(nil)
|
72
|
-
end
|
73
60
|
end
|
74
61
|
|
75
62
|
context 'with an invalid ticket-granting ticket' do
|
@@ -83,10 +83,11 @@ require 'spec_helper'
|
|
83
83
|
end
|
84
84
|
|
85
85
|
context 'with proxy-granting ticket callback server' do
|
86
|
-
let(:
|
86
|
+
let(:pgt_url) { 'https://www.example.org' }
|
87
|
+
let(:parameters_with_pgt_url) { parameters.merge pgtUrl: pgt_url }
|
87
88
|
|
88
89
|
before(:each) do
|
89
|
-
stub_request(:get,
|
90
|
+
stub_request(:get, /#{pgt_url}\/\?pgtId=[^&]+&pgtIou=[^&]+/)
|
90
91
|
end
|
91
92
|
|
92
93
|
it 'calls the #validation_succeeded method on the listener' do
|
@@ -113,6 +114,40 @@ require 'spec_helper'
|
|
113
114
|
pgtIou: proxy_granting_ticket.iou
|
114
115
|
})
|
115
116
|
end
|
117
|
+
|
118
|
+
context 'when callback server gives an error' do
|
119
|
+
before(:each) do
|
120
|
+
stub_request(:get, /#{pgt_url}.*/).to_return status: 404
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'calls the #validation_succeeded method on the listener' do
|
124
|
+
listener.should_receive(:validation_succeeded).with(regex_success)
|
125
|
+
processor.process(parameters_with_pgt_url)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'does not create a proxy-granting ticket' do
|
129
|
+
lambda do
|
130
|
+
processor.process(parameters_with_pgt_url)
|
131
|
+
end.should_not change(service_ticket.proxy_granting_tickets, :count)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'when callback server is unreachable' do
|
136
|
+
before(:each) do
|
137
|
+
stub_request(:get, /#{pgt_url}.*/).to_raise(Timeout::Error)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'calls the #validation_succeeded method on the listener' do
|
141
|
+
listener.should_receive(:validation_succeeded).with(regex_success)
|
142
|
+
processor.process(parameters_with_pgt_url)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'does not create a proxy-granting ticket' do
|
146
|
+
lambda do
|
147
|
+
processor.process(parameters_with_pgt_url)
|
148
|
+
end.should_not change(service_ticket.proxy_granting_tickets, :count)
|
149
|
+
end
|
150
|
+
end
|
116
151
|
end
|
117
152
|
end
|
118
153
|
|
data/spec/spec_helper.rb
CHANGED
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.
|
5
|
+
version: 1.0.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Nils Caspar
|
@@ -144,6 +144,17 @@ dependencies:
|
|
144
144
|
type: :development
|
145
145
|
prerelease: false
|
146
146
|
version_requirements: *id012
|
147
|
+
- !ruby/object:Gem::Dependency
|
148
|
+
name: nokogiri
|
149
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
150
|
+
none: false
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: "0"
|
155
|
+
type: :development
|
156
|
+
prerelease: false
|
157
|
+
version_requirements: *id013
|
147
158
|
description: A CAS server core library.
|
148
159
|
email: ncaspar@me.com
|
149
160
|
executables: []
|
@@ -226,6 +237,7 @@ files:
|
|
226
237
|
- spec/authenticator/static_spec.rb
|
227
238
|
- spec/model/login_ticket_spec.rb
|
228
239
|
- spec/model/proxy_ticket_spec.rb
|
240
|
+
- spec/model/service_ticket/single_sign_out_notifier_spec.rb
|
229
241
|
- spec/model/service_ticket_spec.rb
|
230
242
|
- spec/model/ticket_granting_ticket_spec.rb
|
231
243
|
- spec/processor/legacy_validator_spec.rb
|
@@ -251,7 +263,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
251
263
|
requirements:
|
252
264
|
- - ">="
|
253
265
|
- !ruby/object:Gem::Version
|
254
|
-
hash:
|
266
|
+
hash: 1358580775161495326
|
255
267
|
segments:
|
256
268
|
- 0
|
257
269
|
version: "0"
|