casino_core 1.2.0 → 1.3.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 +7 -1
- data/UPGRADE.md +15 -3
- data/casino_core.gemspec +2 -0
- data/config/cas.yml +1 -7
- data/db/migrate/20130202210100_create_users.rb +0 -6
- data/db/migrate/20130203100015_create_two_factor_authenticators.rb +12 -0
- data/db/migrate/20130203101351_add_active_to_two_factor_authenticators.rb +5 -0
- data/db/migrate/20130203155008_add_awaiting_two_factor_authentication_to_ticket_granting_tickets.rb +5 -0
- data/db/schema.rb +16 -5
- data/lib/casino_core/helper.rb +1 -0
- data/lib/casino_core/helper/proxy_granting_tickets.rb +26 -31
- data/lib/casino_core/helper/proxy_tickets.rb +1 -5
- data/lib/casino_core/helper/ticket_granting_tickets.rb +3 -2
- data/lib/casino_core/helper/two_factor_authenticators.rb +22 -0
- data/lib/casino_core/model.rb +2 -0
- data/lib/casino_core/model/service_ticket/single_sign_out_notifier.rb +13 -30
- data/lib/casino_core/model/ticket_granting_ticket.rb +1 -1
- data/lib/casino_core/model/two_factor_authenticator.rb +19 -0
- data/lib/casino_core/model/user.rb +5 -0
- data/lib/casino_core/model/validation_result.rb +7 -0
- data/lib/casino_core/processor.rb +5 -0
- data/lib/casino_core/processor/login_credential_acceptor.rb +12 -7
- data/lib/casino_core/processor/second_factor_authentication_acceptor.rb +46 -0
- data/lib/casino_core/processor/session_overview.rb +1 -1
- data/lib/casino_core/processor/two_factor_authenticator_activator.rb +46 -0
- data/lib/casino_core/processor/two_factor_authenticator_destroyer.rb +38 -0
- data/lib/casino_core/processor/two_factor_authenticator_overview.rb +24 -0
- data/lib/casino_core/processor/two_factor_authenticator_registrator.rb +27 -0
- data/lib/casino_core/settings.rb +20 -2
- data/lib/casino_core/tasks/cleanup.rake +7 -1
- data/lib/casino_core/version.rb +1 -1
- data/spec/model/two_factor_authenticator_spec.rb +31 -0
- data/spec/processor/login_credential_acceptor_spec.rb +10 -0
- data/spec/processor/login_credential_requestor_spec.rb +9 -0
- data/spec/processor/second_factor_authenticaton_acceptor_spec.rb +83 -0
- data/spec/processor/ticket_validator_spec.rb +15 -0
- data/spec/processor/two_factor_authenticator_activator_spec.rb +122 -0
- data/spec/processor/two_factor_authenticator_destroyer_spec.rb +71 -0
- data/spec/processor/two_factor_authenticator_overview_spec.rb +56 -0
- data/spec/processor/two_factor_authenticator_registrator_spec.rb +48 -0
- data/spec/settings_spec.rb +9 -0
- data/spec/support/factories/ticket_granting_ticket_factory.rb +4 -0
- data/spec/support/factories/two_factor_authenticator_factory.rb +16 -0
- metadata +61 -4
- metadata.gz.sig +1 -3
data.tar.gz.sig
CHANGED
Binary file
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
casino_core (1.
|
4
|
+
casino_core (1.3.0)
|
5
5
|
activerecord (~> 3.2.9)
|
6
6
|
addressable (~> 2.3)
|
7
|
+
faraday (~> 0.8)
|
8
|
+
rotp (~> 1.4)
|
7
9
|
terminal-table (~> 1.4)
|
8
10
|
useragent (~> 0.4)
|
9
11
|
|
@@ -29,10 +31,14 @@ GEM
|
|
29
31
|
diff-lcs (1.1.3)
|
30
32
|
factory_girl (4.2.0)
|
31
33
|
activesupport (>= 3.0.0)
|
34
|
+
faraday (0.8.5)
|
35
|
+
multipart-post (~> 1.1)
|
32
36
|
i18n (0.6.1)
|
33
37
|
multi_json (1.5.0)
|
38
|
+
multipart-post (1.1.5)
|
34
39
|
nokogiri (1.5.6)
|
35
40
|
rake (10.0.3)
|
41
|
+
rotp (1.4.1)
|
36
42
|
rspec (2.12.0)
|
37
43
|
rspec-core (~> 2.12.0)
|
38
44
|
rspec-expectations (~> 2.12.0)
|
data/UPGRADE.md
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
|
3
3
|
Here is a list of backward-incompatible changes that were introduced.
|
4
4
|
|
5
|
+
## 1.x.y
|
6
|
+
|
7
|
+
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
|
+
|
9
|
+
If you would like to support two-factor authentication in your web application, please have a look at the corresponding processors: `SecondFactorAuthenticationAcceptor`, `TwoFactorAuthenticatorActivator`, `TwoFactorAuthenticatorDestroyer`, `TwoFactorAuthenticatorOverview`, `TwoFactorAuthenticatorRegistrator`
|
10
|
+
|
11
|
+
New callbacks:
|
12
|
+
|
13
|
+
* `LoginCredentialAcceptor`: calls `#two_factor_authentication_pending` on the listener, when two-factor authentication is enabled for this user.
|
14
|
+
|
15
|
+
If you don't want to support two-factor authentication, nothing has to be changed.
|
16
|
+
|
5
17
|
## 1.2.0
|
6
18
|
|
7
19
|
API changes:
|
@@ -12,9 +24,9 @@ API changes:
|
|
12
24
|
|
13
25
|
API changes:
|
14
26
|
|
15
|
-
* `
|
27
|
+
* `LoginCredentialAcceptor`: The parameters of `#process` changed from `params, cookies, user_agent` to just `params, user_agent`
|
16
28
|
|
17
29
|
New callbacks:
|
18
30
|
|
19
|
-
* `
|
20
|
-
* `
|
31
|
+
* `LoginCredentialRequestor` and `LoginCredentialAcceptor` call `#service_not_allowed` on the listener, when a service is not in the service whitelist.
|
32
|
+
* `API::ServiceTicketProvider` calls `#service_not_allowed_via_api` on the listener, when a service is not in the service whitelist.
|
data/casino_core.gemspec
CHANGED
@@ -34,5 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.add_runtime_dependency 'addressable', '~> 2.3'
|
35
35
|
s.add_runtime_dependency 'terminal-table', '~> 1.4'
|
36
36
|
s.add_runtime_dependency 'useragent', '~> 0.4'
|
37
|
+
s.add_runtime_dependency 'faraday', '~> 0.8'
|
38
|
+
s.add_runtime_dependency 'rotp', '~> 1.4'
|
37
39
|
end
|
38
40
|
|
data/config/cas.yml
CHANGED
@@ -1,12 +1,6 @@
|
|
1
1
|
defaults: &defaults
|
2
|
-
login_ticket:
|
3
|
-
lifetime: 600
|
4
2
|
service_ticket:
|
5
|
-
lifetime_unconsumed:
|
6
|
-
lifetime_consumed: 86400
|
7
|
-
proxy_ticket:
|
8
|
-
lifetime_unconsumed: 300
|
9
|
-
lifetime_consumed: 86400
|
3
|
+
lifetime_unconsumed: 299
|
10
4
|
authenticators:
|
11
5
|
static_1:
|
12
6
|
class: "CASinoCore::Authenticator::Static"
|
@@ -1,11 +1,5 @@
|
|
1
1
|
class CreateUsers < ActiveRecord::Migration
|
2
2
|
def up
|
3
|
-
tgt = CASinoCore::Model::TicketGrantingTicket.new
|
4
|
-
tgt.authenticator = 'foo'
|
5
|
-
tgt.username = 'bar'
|
6
|
-
tgt.ticket = 'TGT-bla'
|
7
|
-
tgt.save!
|
8
|
-
|
9
3
|
create_table :users do |t|
|
10
4
|
t.string :authenticator, null: false
|
11
5
|
t.string :username, null: false
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateTwoFactorAuthenticators < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :two_factor_authenticators do |t|
|
4
|
+
t.integer :user_id, null: false
|
5
|
+
t.string :secret, null: false
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :two_factor_authenticators, :user_id
|
11
|
+
end
|
12
|
+
end
|
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 => 20130203155008) do
|
15
15
|
|
16
16
|
create_table "login_tickets", :force => true do |t|
|
17
17
|
t.string "ticket", :null => false
|
@@ -73,15 +73,26 @@ ActiveRecord::Schema.define(:version => 20130202210100) do
|
|
73
73
|
add_index "service_tickets", ["ticket_granting_ticket_id"], :name => "index_service_tickets_on_ticket_granting_ticket_id"
|
74
74
|
|
75
75
|
create_table "ticket_granting_tickets", :force => true do |t|
|
76
|
-
t.string "ticket",
|
77
|
-
t.datetime "created_at",
|
78
|
-
t.datetime "updated_at",
|
76
|
+
t.string "ticket", :null => false
|
77
|
+
t.datetime "created_at", :null => false
|
78
|
+
t.datetime "updated_at", :null => false
|
79
79
|
t.string "user_agent"
|
80
|
-
t.integer "user_id",
|
80
|
+
t.integer "user_id", :null => false
|
81
|
+
t.boolean "awaiting_two_factor_authentication", :default => false, :null => false
|
81
82
|
end
|
82
83
|
|
83
84
|
add_index "ticket_granting_tickets", ["ticket"], :name => "index_ticket_granting_tickets_on_ticket", :unique => true
|
84
85
|
|
86
|
+
create_table "two_factor_authenticators", :force => true do |t|
|
87
|
+
t.integer "user_id", :null => false
|
88
|
+
t.string "secret", :null => false
|
89
|
+
t.datetime "created_at", :null => false
|
90
|
+
t.datetime "updated_at", :null => false
|
91
|
+
t.boolean "active", :default => false, :null => false
|
92
|
+
end
|
93
|
+
|
94
|
+
add_index "two_factor_authenticators", ["user_id"], :name => "index_two_factor_authenticators_on_user_id"
|
95
|
+
|
85
96
|
create_table "users", :force => true do |t|
|
86
97
|
t.string "authenticator", :null => false
|
87
98
|
t.string "username", :null => false
|
data/lib/casino_core/helper.rb
CHANGED
@@ -12,5 +12,6 @@ module CASinoCore
|
|
12
12
|
autoload :ServiceTickets, 'casino_core/helper/service_tickets.rb'
|
13
13
|
autoload :Tickets, 'casino_core/helper/tickets.rb'
|
14
14
|
autoload :TicketGrantingTickets, 'casino_core/helper/ticket_granting_tickets.rb'
|
15
|
+
autoload :TwoFactorAuthenticators, 'casino_core/helper/two_factor_authenticators.rb'
|
15
16
|
end
|
16
17
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'addressable/uri'
|
2
|
-
require '
|
2
|
+
require 'faraday'
|
3
3
|
|
4
4
|
require 'casino_core/helper/logger'
|
5
5
|
require 'casino_core/helper/tickets'
|
@@ -11,41 +11,36 @@ module CASinoCore
|
|
11
11
|
include CASinoCore::Helper::Tickets
|
12
12
|
|
13
13
|
def acquire_proxy_granting_ticket(pgt_url, service_ticket)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
callback_uri = Addressable::URI.parse(pgt_url)
|
15
|
+
if callback_uri.scheme != 'https'
|
16
|
+
logger.warn "Proxy tickets can only be granted to callback servers using HTTPS."
|
17
|
+
nil
|
18
|
+
else
|
19
|
+
contact_callback_server(callback_uri, service_ticket)
|
18
20
|
end
|
19
|
-
nil
|
20
21
|
end
|
21
22
|
|
22
23
|
private
|
23
|
-
def contact_callback_server(
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
response
|
38
|
-
|
39
|
-
if "#{response.code}" == "200"
|
40
|
-
# 3.4 (proxy-granting ticket IOU)
|
41
|
-
pgt.save!
|
42
|
-
logger.debug "Proxy-granting ticket generated for service '#{service_ticket.service}': #{pgt.inspect}"
|
43
|
-
pgt
|
44
|
-
else
|
45
|
-
logger.warn "Proxy-granting ticket callback server responded with a bad result code '#{response.code}'. PGT will not be stored."
|
46
|
-
nil
|
47
|
-
end
|
24
|
+
def contact_callback_server(callback_uri, service_ticket)
|
25
|
+
pgt = service_ticket.proxy_granting_tickets.new({
|
26
|
+
ticket: random_ticket_string('PGT'),
|
27
|
+
iou: random_ticket_string('PGTIOU'),
|
28
|
+
pgt_url: "#{callback_uri}"
|
29
|
+
})
|
30
|
+
callback_uri.query_values = (callback_uri.query_values || {}).merge(pgtId: pgt.ticket, pgtIou: pgt.iou)
|
31
|
+
response = Faraday.get "#{callback_uri}"
|
32
|
+
# TODO: does this follow redirects? CAS specification says that redirects MAY be followed (2.5.4)
|
33
|
+
if response.success?
|
34
|
+
pgt.save!
|
35
|
+
logger.debug "Proxy-granting ticket generated for service '#{service_ticket.service}': #{pgt.inspect}"
|
36
|
+
pgt
|
37
|
+
else
|
38
|
+
logger.warn "Proxy-granting ticket callback server responded with a bad result code '#{response.status}'. PGT will not be stored."
|
39
|
+
nil
|
48
40
|
end
|
41
|
+
rescue Faraday::Error::ClientError => error
|
42
|
+
logger.warn "Exception while communicating with proxy-granting ticket callback server: #{error.message}"
|
43
|
+
nil
|
49
44
|
end
|
50
45
|
end
|
51
46
|
end
|
@@ -2,11 +2,7 @@ module CASinoCore
|
|
2
2
|
module Helper
|
3
3
|
module ProxyTickets
|
4
4
|
|
5
|
-
class ValidationResult <
|
6
|
-
def success?
|
7
|
-
self.error_code.nil?
|
8
|
-
end
|
9
|
-
end
|
5
|
+
class ValidationResult < CASinoCore::Model::ValidationResult; end
|
10
6
|
|
11
7
|
include CASinoCore::Helper::Logger
|
12
8
|
include CASinoCore::Helper::Tickets
|
@@ -7,9 +7,9 @@ module CASinoCore
|
|
7
7
|
include CASinoCore::Helper::Browser
|
8
8
|
include CASinoCore::Helper::Logger
|
9
9
|
|
10
|
-
def find_valid_ticket_granting_ticket(tgt, user_agent)
|
10
|
+
def find_valid_ticket_granting_ticket(tgt, user_agent, ignore_two_factor = false)
|
11
11
|
ticket_granting_ticket = CASinoCore::Model::TicketGrantingTicket.where(ticket: tgt).first
|
12
|
-
unless ticket_granting_ticket.nil?
|
12
|
+
unless ticket_granting_ticket.nil? || (!ignore_two_factor && ticket_granting_ticket.awaiting_two_factor_authentication?)
|
13
13
|
if same_browser?(ticket_granting_ticket.user_agent, user_agent)
|
14
14
|
ticket_granting_ticket.user_agent = user_agent
|
15
15
|
ticket_granting_ticket.touch
|
@@ -27,6 +27,7 @@ module CASinoCore
|
|
27
27
|
user = load_or_initialize_user(authentication_result[:authenticator], user_data[:username], user_data[:extra_attributes])
|
28
28
|
user.ticket_granting_tickets.create!({
|
29
29
|
ticket: random_ticket_string('TGC'),
|
30
|
+
awaiting_two_factor_authentication: !user.active_two_factor_authenticator.nil?,
|
30
31
|
user_agent: user_agent
|
31
32
|
})
|
32
33
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
module CASinoCore
|
4
|
+
module Helper
|
5
|
+
module TwoFactorAuthenticators
|
6
|
+
class ValidationResult < CASinoCore::Model::ValidationResult; end
|
7
|
+
|
8
|
+
def validate_one_time_password(otp, authenticator)
|
9
|
+
if authenticator.nil? || authenticator.expired?
|
10
|
+
ValidationResult.new 'INVALID_AUTHENTICATOR', 'Authenticator does not exist or expired', :warn
|
11
|
+
else
|
12
|
+
totp = ROTP::TOTP.new(authenticator.secret)
|
13
|
+
if totp.verify_with_drift(otp, CASinoCore::Settings.two_factor_authenticator[:drift])
|
14
|
+
ValidationResult.new
|
15
|
+
else
|
16
|
+
ValidationResult.new 'INVALID_OTP', 'One-time password not valid', :warn
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/casino_core/model.rb
CHANGED
@@ -8,6 +8,8 @@ module CASinoCore
|
|
8
8
|
autoload :ProxyGrantingTicket, 'casino_core/model/proxy_granting_ticket.rb'
|
9
9
|
autoload :ProxyTicket, 'casino_core/model/proxy_ticket.rb'
|
10
10
|
autoload :TicketGrantingTicket, 'casino_core/model/ticket_granting_ticket.rb'
|
11
|
+
autoload :TwoFactorAuthenticator, 'casino_core/model/two_factor_authenticator.rb'
|
11
12
|
autoload :User, 'casino_core/model/user.rb'
|
13
|
+
autoload :ValidationResult, 'casino_core/model/validation_result.rb'
|
12
14
|
end
|
13
15
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'builder'
|
2
|
-
require '
|
2
|
+
require 'faraday'
|
3
3
|
require 'casino_core/model/service_ticket'
|
4
|
-
require 'addressable/uri'
|
5
4
|
|
6
5
|
class CASinoCore::Model::ServiceTicket::SingleSignOutNotifier
|
7
6
|
include CASinoCore::Helper::Logger
|
@@ -11,10 +10,7 @@ class CASinoCore::Model::ServiceTicket::SingleSignOutNotifier
|
|
11
10
|
end
|
12
11
|
|
13
12
|
def notify
|
14
|
-
|
15
|
-
uri = Addressable::URI.parse(@service_ticket.service)
|
16
|
-
request = build_request(uri, xml)
|
17
|
-
send_notification(uri, request)
|
13
|
+
send_notification @service_ticket.service, build_xml
|
18
14
|
end
|
19
15
|
|
20
16
|
private
|
@@ -32,31 +28,18 @@ class CASinoCore::Model::ServiceTicket::SingleSignOutNotifier
|
|
32
28
|
xml.target!
|
33
29
|
end
|
34
30
|
|
35
|
-
def
|
36
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
37
|
-
request.set_form_data(logoutRequest: xml)
|
38
|
-
return request
|
39
|
-
end
|
40
|
-
|
41
|
-
def send_notification(uri, request)
|
31
|
+
def send_notification(url, xml)
|
42
32
|
logger.info "Sending Single Sign Out notification for ticket '#{@service_ticket.ticket}'"
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
logger.info "Logout notification successfully posted to #{uri}."
|
51
|
-
return true
|
52
|
-
else
|
53
|
-
logger.warn "Service #{uri} responed to logout notification with code '#{response.code}'!"
|
54
|
-
return false
|
55
|
-
end
|
56
|
-
end
|
57
|
-
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
58
|
-
logger.warn "Failed to send logout notification to service #{uri} due to #{e}"
|
59
|
-
return false
|
33
|
+
result = Faraday.post(url, logoutRequest: xml)
|
34
|
+
if result.success?
|
35
|
+
logger.info "Logout notification successfully posted to #{url}."
|
36
|
+
true
|
37
|
+
else
|
38
|
+
logger.warn "Service #{url} responed to logout notification with code '#{result.status}'!"
|
39
|
+
false
|
60
40
|
end
|
41
|
+
rescue Faraday::Error::ClientError => error
|
42
|
+
logger.warn "Failed to send logout notification to service #{url} due to #{error}"
|
43
|
+
false
|
61
44
|
end
|
62
45
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'casino_core/model'
|
2
2
|
|
3
3
|
class CASinoCore::Model::TicketGrantingTicket < ActiveRecord::Base
|
4
|
-
attr_accessible :ticket, :user_agent
|
4
|
+
attr_accessible :ticket, :user_agent, :awaiting_two_factor_authentication
|
5
5
|
validates :ticket, uniqueness: true
|
6
6
|
|
7
7
|
belongs_to :user
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'casino_core/model'
|
2
|
+
|
3
|
+
class CASinoCore::Model::TwoFactorAuthenticator < ActiveRecord::Base
|
4
|
+
attr_accessible :secret
|
5
|
+
|
6
|
+
belongs_to :user
|
7
|
+
|
8
|
+
def self.cleanup
|
9
|
+
self.delete_all(['(created_at < ?) AND active = ?', self.lifetime.ago, false])
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.lifetime
|
13
|
+
CASinoCore::Settings.two_factor_authenticator[:lifetime_inactive].seconds
|
14
|
+
end
|
15
|
+
|
16
|
+
def expired?
|
17
|
+
!self.active? && (Time.now - (self.created_at || Time.now)) > self.class.lifetime
|
18
|
+
end
|
19
|
+
end
|
@@ -5,4 +5,9 @@ class CASinoCore::Model::User < ActiveRecord::Base
|
|
5
5
|
serialize :extra_attributes, Hash
|
6
6
|
|
7
7
|
has_many :ticket_granting_tickets
|
8
|
+
has_many :two_factor_authenticators
|
9
|
+
|
10
|
+
def active_two_factor_authenticator
|
11
|
+
self.two_factor_authenticators.where(active: true).first
|
12
|
+
end
|
8
13
|
end
|
@@ -8,9 +8,14 @@ module CASinoCore
|
|
8
8
|
autoload :Logout, 'casino_core/processor/logout.rb'
|
9
9
|
autoload :ProxyTicketProvider, 'casino_core/processor/proxy_ticket_provider.rb'
|
10
10
|
autoload :ProxyTicketValidator, 'casino_core/processor/proxy_ticket_validator.rb'
|
11
|
+
autoload :SecondFactorAuthenticationAcceptor, 'casino_core/processor/second_factor_authentication_acceptor.rb'
|
11
12
|
autoload :ServiceTicketValidator, 'casino_core/processor/service_ticket_validator.rb'
|
12
13
|
autoload :SessionDestroyer, 'casino_core/processor/session_destroyer.rb'
|
13
14
|
autoload :SessionOverview, 'casino_core/processor/session_overview.rb'
|
15
|
+
autoload :TwoFactorAuthenticatorActivator, 'casino_core/processor/two_factor_authenticator_activator.rb'
|
16
|
+
autoload :TwoFactorAuthenticatorDestroyer, 'casino_core/processor/two_factor_authenticator_destroyer.rb'
|
17
|
+
autoload :TwoFactorAuthenticatorOverview, 'casino_core/processor/two_factor_authenticator_overview.rb'
|
18
|
+
autoload :TwoFactorAuthenticatorRegistrator, 'casino_core/processor/two_factor_authenticator_registrator.rb'
|
14
19
|
|
15
20
|
autoload :API, 'casino_core/processor/api.rb'
|
16
21
|
|
@@ -18,6 +18,7 @@ class CASinoCore::Processor::LoginCredentialAcceptor < CASinoCore::Processor
|
|
18
18
|
# * `#invalid_login_ticket` and `#invalid_login_credentials`: The first argument is a LoginTicket.
|
19
19
|
# See {CASinoCore::Processor::LoginCredentialRequestor} for details.
|
20
20
|
# * `#service_not_allowed`: The user tried to access a service that this CAS server is not allowed to serve.
|
21
|
+
# * `#two_factor_authentication_pending`: The user should be asked to enter his OTP. The first argument (String) is the ticket-granting ticket. The ticket-granting ticket is not active yet. Use SecondFactorAuthenticatonAcceptor to activate it.
|
21
22
|
#
|
22
23
|
# @param [Hash] params parameters supplied by user
|
23
24
|
# @param [String] user_agent user-agent delivered by the client
|
@@ -42,14 +43,18 @@ class CASinoCore::Processor::LoginCredentialAcceptor < CASinoCore::Processor
|
|
42
43
|
end
|
43
44
|
|
44
45
|
def user_logged_in(authentication_result)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
ticket_granting_ticket = acquire_ticket_granting_ticket(authentication_result, @user_agent)
|
47
|
+
if ticket_granting_ticket.awaiting_two_factor_authentication?
|
48
|
+
@listener.two_factor_authentication_pending(ticket_granting_ticket.ticket)
|
49
|
+
else
|
50
|
+
begin
|
51
|
+
url = unless @params[:service].blank?
|
52
|
+
acquire_service_ticket(ticket_granting_ticket, @params[:service], true).service_with_ticket_url
|
53
|
+
end
|
54
|
+
@listener.user_logged_in(url, ticket_granting_ticket.ticket)
|
55
|
+
rescue ServiceNotAllowedError => e
|
56
|
+
@listener.service_not_allowed(clean_service_url @params[:service])
|
49
57
|
end
|
50
|
-
@listener.user_logged_in(url, ticket_granting_ticket.ticket)
|
51
|
-
rescue ServiceNotAllowedError => e
|
52
|
-
@listener.service_not_allowed(clean_service_url @params[:service])
|
53
58
|
end
|
54
59
|
end
|
55
60
|
end
|