casino_core 1.3.5 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/Gemfile.lock +1 -1
- data/UPGRADE.md +10 -1
- data/db/migrate/20130323111208_add_long_term_to_ticket_granting_tickets.rb +5 -0
- data/db/schema.rb +2 -1
- data/lib/casino_core/builder/ticket_validation_response.rb +16 -6
- data/lib/casino_core/helper/ticket_granting_tickets.rb +3 -2
- data/lib/casino_core/model/service_ticket.rb +1 -0
- data/lib/casino_core/model/ticket_granting_ticket.rb +13 -25
- data/lib/casino_core/processor/login_credential_acceptor.rb +9 -2
- data/lib/casino_core/processor/logout.rb +5 -1
- data/lib/casino_core/settings.rb +3 -2
- data/lib/casino_core/version.rb +1 -1
- data/spec/model/service_ticket/single_sign_out_notifier_spec.rb +1 -1
- data/spec/model/service_ticket_spec.rb +2 -2
- data/spec/model/ticket_granting_ticket_spec.rb +49 -3
- data/spec/processor/login_credential_acceptor_spec.rb +15 -0
- data/spec/processor/logout_spec.rb +23 -0
- data/spec/processor/ticket_validator_spec.rb +15 -0
- metadata +10 -3
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/Gemfile.lock
CHANGED
data/UPGRADE.md
CHANGED
@@ -2,7 +2,16 @@
|
|
2
2
|
|
3
3
|
Here is a list of backward-incompatible changes that were introduced.
|
4
4
|
|
5
|
-
## 1.
|
5
|
+
## 1.4.0
|
6
|
+
|
7
|
+
This release changed some database structure. Be sure to advise users to migrate the database using `bundle exec rake casino_core:db:migrate`.
|
8
|
+
|
9
|
+
API changes:
|
10
|
+
|
11
|
+
* `LoginCredentialAcceptor`: `user_logged_in` may receive a third argument (`Time`, optional, default = `nil`) which represents the expiry date of the cookie. If it is `nil`, the cookie should be a session cookie.
|
12
|
+
* `Logout`: `user_logged_out` may receive a second argument (`boolean`, optional, default = `false`). When it is `true`, the user should be redirected immediately.
|
13
|
+
|
14
|
+
## 1.3.0
|
6
15
|
|
7
16
|
This release adds support for two-factor authentication using a [TOTP](http://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm) (time-based one-time password) which can be generated with applications like [Google Authenticator](http://support.google.com/a/bin/answer.py?hl=en&answer=1037451) (iPhone, Android, BlackBerry) or gadgets such as the [YubiKey](http://www.yubico.com/products/yubikey-hardware/yubikey/).
|
8
17
|
|
data/db/schema.rb
CHANGED
@@ -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 =>
|
14
|
+
ActiveRecord::Schema.define(:version => 20130323111208) do
|
15
15
|
|
16
16
|
create_table "login_tickets", :force => true do |t|
|
17
17
|
t.string "ticket", :null => false
|
@@ -79,6 +79,7 @@ ActiveRecord::Schema.define(:version => 20130203155008) do
|
|
79
79
|
t.string "user_agent"
|
80
80
|
t.integer "user_id", :null => false
|
81
81
|
t.boolean "awaiting_two_factor_authentication", :default => false, :null => false
|
82
|
+
t.boolean "long_term", :default => false, :null => false
|
82
83
|
end
|
83
84
|
|
84
85
|
add_index "ticket_granting_tickets", ["ticket"], :name => "index_ticket_granting_tickets_on_ticket", :unique => true
|
@@ -14,18 +14,19 @@ class CASinoCore::Builder::TicketValidationResponse < CASinoCore::Builder
|
|
14
14
|
ticket = @options[:ticket]
|
15
15
|
if ticket.is_a?(CASinoCore::Model::ProxyTicket)
|
16
16
|
proxies = []
|
17
|
-
|
18
|
-
while
|
17
|
+
service_ticket = ticket
|
18
|
+
while service_ticket.is_a?(CASinoCore::Model::ProxyTicket)
|
19
19
|
proxy_granting_ticket = ticket.proxy_granting_ticket
|
20
20
|
proxies << proxy_granting_ticket.pgt_url
|
21
|
-
|
21
|
+
service_ticket = proxy_granting_ticket.granter
|
22
22
|
end
|
23
|
-
ticket_granting_ticket =
|
23
|
+
ticket_granting_ticket = service_ticket.ticket_granting_ticket
|
24
24
|
else
|
25
|
+
service_ticket = ticket
|
25
26
|
ticket_granting_ticket = ticket.ticket_granting_ticket
|
26
27
|
end
|
27
28
|
|
28
|
-
build_success_xml(service_response, ticket, ticket_granting_ticket, proxies)
|
29
|
+
build_success_xml(service_response, ticket, service_ticket, ticket_granting_ticket, proxies)
|
29
30
|
else
|
30
31
|
build_failure_xml(service_response)
|
31
32
|
end
|
@@ -44,12 +45,21 @@ class CASinoCore::Builder::TicketValidationResponse < CASinoCore::Builder
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
|
-
def build_success_xml(service_response, ticket, ticket_granting_ticket, proxies)
|
48
|
+
def build_success_xml(service_response, ticket, service_ticket, ticket_granting_ticket, proxies)
|
48
49
|
user = ticket_granting_ticket.user
|
49
50
|
service_response.cas :authenticationSuccess do |authentication_success|
|
50
51
|
authentication_success.cas :user, user.username
|
51
52
|
unless user.extra_attributes.blank?
|
52
53
|
authentication_success.cas :attributes do |attributes|
|
54
|
+
attributes.cas :authenticationDate, ticket_granting_ticket.created_at.iso8601
|
55
|
+
attributes.cas :longTermAuthenticationRequestTokenUsed, ticket_granting_ticket.long_term?
|
56
|
+
attributes.cas :isFromNewLogin, service_ticket.issued_from_credentials?
|
57
|
+
# This would probably be the correct way, but current clients do not support this:
|
58
|
+
# attributes.cas :userAttributes do |user_attributes|
|
59
|
+
# user.extra_attributes.each do |key, value|
|
60
|
+
# serialize_extra_attribute(user_attributes, key, value)
|
61
|
+
# end
|
62
|
+
# end
|
53
63
|
user.extra_attributes.each do |key, value|
|
54
64
|
serialize_extra_attribute(attributes, key, value)
|
55
65
|
end
|
@@ -29,14 +29,15 @@ module CASinoCore
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def acquire_ticket_granting_ticket(authentication_result, user_agent = nil)
|
32
|
+
def acquire_ticket_granting_ticket(authentication_result, user_agent = nil, long_term = nil)
|
33
33
|
user_data = authentication_result[:user_data]
|
34
34
|
user = load_or_initialize_user(authentication_result[:authenticator], user_data[:username], user_data[:extra_attributes])
|
35
35
|
cleanup_expired_ticket_granting_tickets(user)
|
36
36
|
user.ticket_granting_tickets.create!({
|
37
37
|
ticket: random_ticket_string('TGC'),
|
38
38
|
awaiting_two_factor_authentication: !user.active_two_factor_authenticator.nil?,
|
39
|
-
user_agent: user_agent
|
39
|
+
user_agent: user_agent,
|
40
|
+
long_term: !!long_term
|
40
41
|
})
|
41
42
|
end
|
42
43
|
|
@@ -1,17 +1,19 @@
|
|
1
1
|
require 'casino_core/model'
|
2
2
|
|
3
3
|
class CASinoCore::Model::TicketGrantingTicket < ActiveRecord::Base
|
4
|
-
attr_accessible :ticket, :user_agent, :awaiting_two_factor_authentication
|
4
|
+
attr_accessible :ticket, :user_agent, :awaiting_two_factor_authentication, :long_term
|
5
5
|
validates :ticket, uniqueness: true
|
6
6
|
|
7
7
|
belongs_to :user
|
8
|
-
has_many :service_tickets
|
9
|
-
|
10
|
-
before_destroy :destroy_service_tickets
|
11
|
-
after_destroy :destroy_proxy_granting_tickets
|
8
|
+
has_many :service_tickets, dependent: :destroy
|
12
9
|
|
13
10
|
def self.cleanup
|
14
|
-
self.destroy_all([
|
11
|
+
self.destroy_all([
|
12
|
+
'(created_at < ? AND long_term = ?) OR created_at < ?',
|
13
|
+
CASinoCore::Settings.ticket_granting_ticket[:lifetime].seconds.ago,
|
14
|
+
false,
|
15
|
+
CASinoCore::Settings.ticket_granting_ticket[:lifetime_long_term].seconds.ago
|
16
|
+
])
|
15
17
|
end
|
16
18
|
|
17
19
|
def browser_info
|
@@ -34,25 +36,11 @@ class CASinoCore::Model::TicketGrantingTicket < ActiveRecord::Base
|
|
34
36
|
end
|
35
37
|
|
36
38
|
def expired?
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
private
|
42
|
-
def destroy_service_tickets
|
43
|
-
self.service_tickets.each do |service_ticket|
|
44
|
-
unless service_ticket.destroy
|
45
|
-
service_ticket.ticket_granting_ticket_id = nil
|
46
|
-
service_ticket.save
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# Deletes proxy-granting tickets of service tickets that
|
52
|
-
# could not be deleted (see #destroy_service_tickets)
|
53
|
-
def destroy_proxy_granting_tickets
|
54
|
-
self.service_tickets.each do |service_ticket|
|
55
|
-
service_ticket.proxy_granting_tickets.destroy_all
|
39
|
+
if long_term?
|
40
|
+
lifetime = CASinoCore::Settings.ticket_granting_ticket[:lifetime_long_term]
|
41
|
+
else
|
42
|
+
lifetime = CASinoCore::Settings.ticket_granting_ticket[:lifetime]
|
56
43
|
end
|
44
|
+
(Time.now - (self.created_at || Time.now)) > lifetime
|
57
45
|
end
|
58
46
|
end
|
@@ -15,6 +15,8 @@ class CASinoCore::Processor::LoginCredentialAcceptor < CASinoCore::Processor
|
|
15
15
|
# The method will call one of the following methods on the listener:
|
16
16
|
# * `#user_logged_in`: The first argument (String) is the URL (if any), the user should be redirected to.
|
17
17
|
# The second argument (String) is the ticket-granting ticket. It should be stored in a cookie named "tgt".
|
18
|
+
# The third argument (Time, optional, default = nil) is for "Remember Me" functionality.
|
19
|
+
# This is the cookies expiration date. If it is `nil`, the cookie should be a session cookie.
|
18
20
|
# * `#invalid_login_ticket` and `#invalid_login_credentials`: The first argument is a LoginTicket.
|
19
21
|
# See {CASinoCore::Processor::LoginCredentialRequestor} for details.
|
20
22
|
# * `#service_not_allowed`: The user tried to access a service that this CAS server is not allowed to serve.
|
@@ -43,7 +45,8 @@ class CASinoCore::Processor::LoginCredentialAcceptor < CASinoCore::Processor
|
|
43
45
|
end
|
44
46
|
|
45
47
|
def user_logged_in(authentication_result)
|
46
|
-
|
48
|
+
long_term = @params[:rememberMe]
|
49
|
+
ticket_granting_ticket = acquire_ticket_granting_ticket(authentication_result, @user_agent, long_term)
|
47
50
|
if ticket_granting_ticket.awaiting_two_factor_authentication?
|
48
51
|
@listener.two_factor_authentication_pending(ticket_granting_ticket.ticket)
|
49
52
|
else
|
@@ -51,7 +54,11 @@ class CASinoCore::Processor::LoginCredentialAcceptor < CASinoCore::Processor
|
|
51
54
|
url = unless @params[:service].blank?
|
52
55
|
acquire_service_ticket(ticket_granting_ticket, @params[:service], true).service_with_ticket_url
|
53
56
|
end
|
54
|
-
|
57
|
+
if long_term
|
58
|
+
@listener.user_logged_in(url, ticket_granting_ticket.ticket, CASinoCore::Settings.ticket_granting_ticket[:lifetime_long_term].seconds.from_now)
|
59
|
+
else
|
60
|
+
@listener.user_logged_in(url, ticket_granting_ticket.ticket)
|
61
|
+
end
|
55
62
|
rescue ServiceNotAllowedError => e
|
56
63
|
@listener.service_not_allowed(clean_service_url @params[:service])
|
57
64
|
end
|
@@ -18,6 +18,10 @@ class CASinoCore::Processor::Logout < CASinoCore::Processor
|
|
18
18
|
params ||= {}
|
19
19
|
cookies ||= {}
|
20
20
|
remove_ticket_granting_ticket(cookies[:tgt], user_agent)
|
21
|
-
|
21
|
+
if params[:service] && CASinoCore::Model::ServiceRule.allowed?(params[:service])
|
22
|
+
@listener.user_logged_out(params[:service], true)
|
23
|
+
else
|
24
|
+
@listener.user_logged_out(params[:url])
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
data/lib/casino_core/settings.rb
CHANGED
@@ -9,13 +9,14 @@ module CASinoCore
|
|
9
9
|
lifetime: 600
|
10
10
|
},
|
11
11
|
ticket_granting_ticket: {
|
12
|
-
lifetime: 86400
|
12
|
+
lifetime: 86400,
|
13
|
+
lifetime_long_term: 864000
|
13
14
|
},
|
14
15
|
service_ticket: {
|
15
16
|
lifetime_unconsumed: 300,
|
16
17
|
lifetime_consumed: 86400,
|
17
18
|
single_sign_out_notification: {
|
18
|
-
timeout:
|
19
|
+
timeout: 5
|
19
20
|
}
|
20
21
|
},
|
21
22
|
proxy_ticket: {
|
data/lib/casino_core/version.rb
CHANGED
@@ -23,7 +23,7 @@ describe CASinoCore::Model::ServiceTicket::SingleSignOutNotifier do
|
|
23
23
|
|
24
24
|
it 'sets the timeout values' do
|
25
25
|
[:read_timeout=, :open_timeout=].each do |timeout|
|
26
|
-
Net::HTTP.any_instance.should_receive(timeout).with(
|
26
|
+
Net::HTTP.any_instance.should_receive(timeout).with(CASinoCore::Settings.service_ticket[:single_sign_out_notification][:timeout])
|
27
27
|
end
|
28
28
|
notifier.notify
|
29
29
|
end
|
@@ -106,11 +106,11 @@ describe CASinoCore::Model::ServiceTicket do
|
|
106
106
|
described_class::SingleSignOutNotifier.any_instance.stub(:notify).and_return(false)
|
107
107
|
end
|
108
108
|
|
109
|
-
it 'does
|
109
|
+
it 'does delete the service ticket anyway' do
|
110
110
|
consumed_ticket
|
111
111
|
lambda {
|
112
112
|
consumed_ticket.destroy
|
113
|
-
}.
|
113
|
+
}.should change(CASinoCore::Model::ServiceTicket, :count).by(-1)
|
114
114
|
end
|
115
115
|
end
|
116
116
|
end
|
@@ -4,9 +4,10 @@ require 'useragent'
|
|
4
4
|
describe CASinoCore::Model::TicketGrantingTicket do
|
5
5
|
let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
|
6
6
|
let(:service_ticket) { FactoryGirl.create :service_ticket, ticket_granting_ticket: ticket_granting_ticket }
|
7
|
-
let(:consumed_service_ticket) { FactoryGirl.create :service_ticket, :consumed, ticket_granting_ticket: ticket_granting_ticket }
|
8
7
|
|
9
8
|
describe '#destroy' do
|
9
|
+
let!(:consumed_service_ticket) { FactoryGirl.create :service_ticket, :consumed, ticket_granting_ticket: ticket_granting_ticket }
|
10
|
+
|
10
11
|
context 'when notification for a service ticket fails' do
|
11
12
|
before(:each) do
|
12
13
|
CASinoCore::Model::ServiceTicket::SingleSignOutNotifier.any_instance.stub(:notify).and_return(false)
|
@@ -19,10 +20,10 @@ describe CASinoCore::Model::TicketGrantingTicket do
|
|
19
20
|
}.should change(CASinoCore::Model::ProxyGrantingTicket, :count).by(-1)
|
20
21
|
end
|
21
22
|
|
22
|
-
it '
|
23
|
+
it 'deletes depending service tickets' do
|
23
24
|
lambda {
|
24
25
|
ticket_granting_ticket.destroy
|
25
|
-
}.should change
|
26
|
+
}.should change(CASinoCore::Model::ServiceTicket, :count).by(-1)
|
26
27
|
end
|
27
28
|
end
|
28
29
|
end
|
@@ -82,6 +83,32 @@ describe CASinoCore::Model::TicketGrantingTicket do
|
|
82
83
|
end
|
83
84
|
|
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
|
+
|
85
112
|
context 'with an expired ticket' do
|
86
113
|
before(:each) do
|
87
114
|
ticket_granting_ticket.created_at = 25.hours.ago
|
@@ -111,5 +138,24 @@ describe CASinoCore::Model::TicketGrantingTicket do
|
|
111
138
|
end.should change(described_class, :count).by(-1)
|
112
139
|
described_class.find_by_ticket(ticket_granting_ticket.ticket).should be_false
|
113
140
|
end
|
141
|
+
|
142
|
+
it 'does not delete almost expired long-term ticket-granting tickets' do
|
143
|
+
ticket_granting_ticket.created_at = 9.days.ago
|
144
|
+
ticket_granting_ticket.long_term = true
|
145
|
+
ticket_granting_ticket.save!
|
146
|
+
lambda do
|
147
|
+
described_class.cleanup
|
148
|
+
end.should_not change(described_class, :count)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'does delete expired long-term ticket-granting tickets' do
|
152
|
+
ticket_granting_ticket.created_at = 30.days.ago
|
153
|
+
ticket_granting_ticket.long_term = true
|
154
|
+
ticket_granting_ticket.save!
|
155
|
+
lambda do
|
156
|
+
described_class.cleanup
|
157
|
+
end.should change(described_class, :count).by(-1)
|
158
|
+
described_class.find_by_ticket(ticket_granting_ticket.ticket).should be_false
|
159
|
+
end
|
114
160
|
end
|
115
161
|
end
|
@@ -41,6 +41,21 @@ describe CASinoCore::Processor::LoginCredentialAcceptor do
|
|
41
41
|
listener.stub(:user_logged_in)
|
42
42
|
end
|
43
43
|
|
44
|
+
context 'with rememberMe set' do
|
45
|
+
let(:login_data_with_remember_me) { login_data.merge(rememberMe: true) }
|
46
|
+
|
47
|
+
it 'calls the #user_logged_in method on the listener with an expiration date set' do
|
48
|
+
listener.should_receive(:user_logged_in).with(/^#{service}\/\?ticket=ST\-/, /^TGC\-/, kind_of(Time))
|
49
|
+
processor.process(login_data_with_remember_me)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'creates a long-term ticket-granting ticket' do
|
53
|
+
processor.process(login_data_with_remember_me)
|
54
|
+
tgt = CASinoCore::Model::TicketGrantingTicket.last
|
55
|
+
tgt.long_term.should == true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
44
59
|
context 'with two-factor authentication enabled' do
|
45
60
|
let(:user) { CASinoCore::Model::User.create! username: username, authenticator: authenticator }
|
46
61
|
let!(:two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator, user: user }
|
@@ -35,6 +35,29 @@ describe CASinoCore::Processor::Logout do
|
|
35
35
|
processor.process(params, cookies, user_agent)
|
36
36
|
end
|
37
37
|
end
|
38
|
+
|
39
|
+
context 'with a service' do
|
40
|
+
let(:params) { { :service => url } }
|
41
|
+
let(:url) { 'http://www.example.org' }
|
42
|
+
|
43
|
+
context '(whitelisted)' do
|
44
|
+
it 'calls the #user_logged_out method on the listener and passes the URL and the redirect_immediate flag' do
|
45
|
+
listener.should_receive(:user_logged_out).with(url, true)
|
46
|
+
processor.process(params, cookies, user_agent)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context '(not whitelisted)' do
|
51
|
+
before(:each) do
|
52
|
+
FactoryGirl.create :service_rule, :regex, url: '^https://.*'
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'calls the #user_logged_out method on the listener and passes no URL' do
|
56
|
+
listener.should_receive(:user_logged_out).with(nil)
|
57
|
+
processor.process(params, cookies, user_agent)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
38
61
|
end
|
39
62
|
|
40
63
|
context 'with an invlaid ticket-granting ticket' do
|
@@ -29,6 +29,21 @@ require 'spec_helper'
|
|
29
29
|
end
|
30
30
|
|
31
31
|
context 'with an unconsumed service ticket' do
|
32
|
+
context 'issued from a long_term ticket-granting ticket' do
|
33
|
+
before(:each) do
|
34
|
+
tgt = service_ticket.ticket_granting_ticket
|
35
|
+
tgt.long_term = true
|
36
|
+
tgt.save!
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'calls the #validation_succeeded method on the listener' do
|
40
|
+
listener.should_receive(:validation_succeeded).with(
|
41
|
+
/<cas\:longTermAuthenticationRequestTokenUsed>true<\/cas\:longTermAuthenticationRequestTokenUsed>/
|
42
|
+
)
|
43
|
+
processor.process(parameters)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
32
47
|
context 'without renew flag' do
|
33
48
|
it 'consumes the service ticket' do
|
34
49
|
processor.process(parameters)
|
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.
|
4
|
+
version: 1.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
b1VSdnUwRzgvWXlIVUFtSVUvV0tyanIxYmdjZjFWUnYKUjRLRDFNblVWL3Y1
|
37
37
|
MDJwaU1sWG1qeE9XZGJLOHl2UUVIa3N1L3pqYkNqU3UrTTJrd0ZtV0dzeDVu
|
38
38
|
eCtWZHc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
39
|
-
date: 2013-03-
|
39
|
+
date: 2013-03-24 00:00:00.000000000 Z
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
@@ -342,6 +342,7 @@ files:
|
|
342
342
|
- db/migrate/20130203100015_create_two_factor_authenticators.rb
|
343
343
|
- db/migrate/20130203101351_add_active_to_two_factor_authenticators.rb
|
344
344
|
- db/migrate/20130203155008_add_awaiting_two_factor_authentication_to_ticket_granting_tickets.rb
|
345
|
+
- db/migrate/20130323111208_add_long_term_to_ticket_granting_tickets.rb
|
345
346
|
- db/schema.rb
|
346
347
|
- lib/casino_core.rb
|
347
348
|
- lib/casino_core/authenticator.rb
|
@@ -447,15 +448,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
447
448
|
- - ! '>='
|
448
449
|
- !ruby/object:Gem::Version
|
449
450
|
version: '0'
|
451
|
+
segments:
|
452
|
+
- 0
|
453
|
+
hash: -3391276428784871857
|
450
454
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
451
455
|
none: false
|
452
456
|
requirements:
|
453
457
|
- - ! '>='
|
454
458
|
- !ruby/object:Gem::Version
|
455
459
|
version: '0'
|
460
|
+
segments:
|
461
|
+
- 0
|
462
|
+
hash: -3391276428784871857
|
456
463
|
requirements: []
|
457
464
|
rubyforge_project:
|
458
|
-
rubygems_version: 1.8.
|
465
|
+
rubygems_version: 1.8.25
|
459
466
|
signing_key:
|
460
467
|
specification_version: 3
|
461
468
|
summary: A CAS server core library.
|
metadata.gz.sig
CHANGED
Binary file
|