casino_core 1.0.12 → 1.1.0
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.lock +14 -12
- data/UPGRADE.md +14 -0
- data/casino_core.gemspec +1 -0
- data/db/migrate/20130105152327_create_service_rules.rb +15 -0
- data/db/schema.rb +13 -1
- data/lib/casino_core/helper/login_tickets.rb +15 -0
- data/lib/casino_core/helper/service_tickets.rb +13 -4
- data/lib/casino_core/model.rb +1 -0
- data/lib/casino_core/model/service_rule.rb +28 -0
- data/lib/casino_core/processor/api/service_ticket_provider.rb +11 -2
- data/lib/casino_core/processor/login_credential_acceptor.rb +22 -26
- data/lib/casino_core/processor/login_credential_requestor.rb +45 -15
- data/lib/casino_core/rake_tasks.rb +1 -0
- data/lib/casino_core/tasks/service_rule.rake +52 -0
- data/lib/casino_core/version.rb +1 -1
- data/spec/model/service_rule_spec.rb +65 -0
- data/spec/processor/api/service_ticket_provider_spec.rb +14 -1
- data/spec/processor/login_credential_acceptor_spec.rb +13 -1
- data/spec/processor/login_credential_requestor_spec.rb +13 -0
- data/spec/support/factories/service_rule_factory.rb +16 -0
- metadata +28 -4
data/Gemfile.lock
CHANGED
@@ -1,32 +1,33 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
casino_core (1.0
|
4
|
+
casino_core (1.1.0)
|
5
5
|
activerecord (~> 3.2.9)
|
6
6
|
addressable (~> 2.3)
|
7
|
+
terminal-table (~> 1.4)
|
7
8
|
useragent (~> 0.4)
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: http://rubygems.org/
|
11
12
|
specs:
|
12
|
-
activemodel (3.2.
|
13
|
-
activesupport (= 3.2.
|
13
|
+
activemodel (3.2.11)
|
14
|
+
activesupport (= 3.2.11)
|
14
15
|
builder (~> 3.0.0)
|
15
|
-
activerecord (3.2.
|
16
|
-
activemodel (= 3.2.
|
17
|
-
activesupport (= 3.2.
|
16
|
+
activerecord (3.2.11)
|
17
|
+
activemodel (= 3.2.11)
|
18
|
+
activesupport (= 3.2.11)
|
18
19
|
arel (~> 3.0.2)
|
19
20
|
tzinfo (~> 0.3.29)
|
20
|
-
activesupport (3.2.
|
21
|
+
activesupport (3.2.11)
|
21
22
|
i18n (~> 0.6)
|
22
23
|
multi_json (~> 1.0)
|
23
24
|
addressable (2.3.2)
|
24
25
|
arel (3.0.2)
|
25
26
|
builder (3.0.4)
|
26
|
-
crack (0.3.
|
27
|
+
crack (0.3.2)
|
27
28
|
database_cleaner (0.9.1)
|
28
29
|
diff-lcs (1.1.3)
|
29
|
-
factory_girl (4.
|
30
|
+
factory_girl (4.2.0)
|
30
31
|
activesupport (>= 3.0.0)
|
31
32
|
i18n (0.6.1)
|
32
33
|
multi_json (1.5.0)
|
@@ -39,14 +40,15 @@ GEM
|
|
39
40
|
rspec-core (2.12.2)
|
40
41
|
rspec-expectations (2.12.1)
|
41
42
|
diff-lcs (~> 1.1.3)
|
42
|
-
rspec-mocks (2.12.
|
43
|
+
rspec-mocks (2.12.2)
|
43
44
|
simplecov (0.7.1)
|
44
45
|
multi_json (~> 1.0)
|
45
46
|
simplecov-html (~> 0.7.1)
|
46
47
|
simplecov-html (0.7.1)
|
47
|
-
sqlite3 (1.3.
|
48
|
+
sqlite3 (1.3.7)
|
49
|
+
terminal-table (1.4.5)
|
48
50
|
tzinfo (0.3.35)
|
49
|
-
useragent (0.4.
|
51
|
+
useragent (0.4.16)
|
50
52
|
webmock (1.9.0)
|
51
53
|
addressable (>= 2.2.7)
|
52
54
|
crack (>= 0.1.7)
|
data/UPGRADE.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Upgrade CASinoCore
|
2
|
+
|
3
|
+
Here is a list of backward-incompatible changes that were introduced.
|
4
|
+
|
5
|
+
## 1.1.0
|
6
|
+
|
7
|
+
API changes:
|
8
|
+
|
9
|
+
* `login_credential_acceptor`: The parameters of `#process` changed from `params, cookies, user_agent` to just `params, user_agent`
|
10
|
+
|
11
|
+
New callbacks:
|
12
|
+
|
13
|
+
* `login_credential_requestor` calls `#service_not_allowed` on the listener, when a service is not in the service whitelist.
|
14
|
+
* `api/service_ticket_provider` calls `#service_not_allowed_via_api` on the listener, when a service is not in the service whitelist.
|
data/casino_core.gemspec
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateServiceRules < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :service_rules do |t|
|
4
|
+
t.boolean :enabled, null: false, default: true
|
5
|
+
t.integer :order, null: false, default: 10
|
6
|
+
t.string :name, null: false
|
7
|
+
t.string :url, null: false
|
8
|
+
t.boolean :regex, null: false, default: false
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :service_rules, :url, unique: true
|
14
|
+
end
|
15
|
+
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 => 20130105152327) do
|
15
15
|
|
16
16
|
create_table "login_tickets", :force => true do |t|
|
17
17
|
t.string "ticket", :null => false
|
@@ -47,6 +47,18 @@ ActiveRecord::Schema.define(:version => 20121231114141) do
|
|
47
47
|
add_index "proxy_tickets", ["proxy_granting_ticket_id"], :name => "index_proxy_tickets_on_proxy_granting_ticket_id"
|
48
48
|
add_index "proxy_tickets", ["ticket"], :name => "index_proxy_tickets_on_ticket", :unique => true
|
49
49
|
|
50
|
+
create_table "service_rules", :force => true do |t|
|
51
|
+
t.boolean "enabled", :default => true, :null => false
|
52
|
+
t.integer "order", :default => 10, :null => false
|
53
|
+
t.string "name", :null => false
|
54
|
+
t.string "url", :null => false
|
55
|
+
t.boolean "regex", :default => false, :null => false
|
56
|
+
t.datetime "created_at", :null => false
|
57
|
+
t.datetime "updated_at", :null => false
|
58
|
+
end
|
59
|
+
|
60
|
+
add_index "service_rules", ["url"], :name => "index_service_rules_on_url", :unique => true
|
61
|
+
|
50
62
|
create_table "service_tickets", :force => true do |t|
|
51
63
|
t.string "ticket", :null => false
|
52
64
|
t.string "service", :null => false
|
@@ -9,6 +9,21 @@ module CASinoCore
|
|
9
9
|
logger.debug "Created login ticket '#{ticket.ticket}'"
|
10
10
|
ticket
|
11
11
|
end
|
12
|
+
|
13
|
+
def login_ticket_valid?(lt)
|
14
|
+
ticket = CASinoCore::Model::LoginTicket.find_by_ticket lt
|
15
|
+
if ticket.nil?
|
16
|
+
logger.info "Login ticket '#{lt}' not found"
|
17
|
+
false
|
18
|
+
elsif ticket.created_at < CASinoCore::Settings.login_ticket[:lifetime].seconds.ago
|
19
|
+
logger.info "Login ticket '#{ticket.ticket}' expired"
|
20
|
+
false
|
21
|
+
else
|
22
|
+
logger.debug "Login ticket '#{ticket.ticket}' successfully validated"
|
23
|
+
ticket.delete
|
24
|
+
true
|
25
|
+
end
|
26
|
+
end
|
12
27
|
end
|
13
28
|
end
|
14
29
|
end
|
@@ -7,10 +7,18 @@ module CASinoCore
|
|
7
7
|
include CASinoCore::Helper::Tickets
|
8
8
|
include CASinoCore::Helper::ProxyTickets
|
9
9
|
|
10
|
+
class ServiceNotAllowedError < StandardError; end
|
11
|
+
|
10
12
|
def acquire_service_ticket(ticket_granting_ticket, service, credentials_supplied = nil)
|
13
|
+
service_url = clean_service_url(service)
|
14
|
+
unless CASinoCore::Model::ServiceRule.allowed?(service_url)
|
15
|
+
message = "#{service_url} is not in the list of allowed URLs"
|
16
|
+
logger.error message
|
17
|
+
raise ServiceNotAllowedError, message
|
18
|
+
end
|
11
19
|
ticket_granting_ticket.service_tickets.create!({
|
12
20
|
ticket: random_ticket_string('ST'),
|
13
|
-
service:
|
21
|
+
service: service_url,
|
14
22
|
issued_from_credentials: !!credentials_supplied
|
15
23
|
})
|
16
24
|
end
|
@@ -24,9 +32,10 @@ module CASinoCore
|
|
24
32
|
if service_uri.query_values.blank?
|
25
33
|
service_uri.query_values = nil
|
26
34
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
35
|
+
|
36
|
+
service_uri.path = (service_uri.path || '').gsub(/\/+\z/, '')
|
37
|
+
service_uri.path = '/' if service_uri.path.blank?
|
38
|
+
|
30
39
|
clean_service = service_uri.to_s
|
31
40
|
|
32
41
|
logger.debug("Cleaned dirty service URL '#{dirty_service}' to '#{clean_service}'") if dirty_service != clean_service
|
data/lib/casino_core/model.rb
CHANGED
@@ -3,6 +3,7 @@ require 'active_record'
|
|
3
3
|
module CASinoCore
|
4
4
|
module Model
|
5
5
|
autoload :LoginTicket, 'casino_core/model/login_ticket.rb'
|
6
|
+
autoload :ServiceRule, 'casino_core/model/service_rule.rb'
|
6
7
|
autoload :ServiceTicket, 'casino_core/model/service_ticket.rb'
|
7
8
|
autoload :ProxyGrantingTicket, 'casino_core/model/proxy_granting_ticket.rb'
|
8
9
|
autoload :ProxyTicket, 'casino_core/model/proxy_ticket.rb'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'casino_core/model'
|
2
|
+
|
3
|
+
class CASinoCore::Model::ServiceRule < ActiveRecord::Base
|
4
|
+
attr_accessible :enabled, :order, :name, :url, :regex
|
5
|
+
validates :name, presence: true
|
6
|
+
validates :url, uniqueness: true, presence: true
|
7
|
+
|
8
|
+
def self.allowed?(service_url)
|
9
|
+
rules = self.where(enabled: true)
|
10
|
+
if rules.empty?
|
11
|
+
true
|
12
|
+
else
|
13
|
+
rules.any? { |rule| rule.allows?(service_url) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def allows?(service_url)
|
18
|
+
if self.regex?
|
19
|
+
regex = Regexp.new self.url, true
|
20
|
+
if regex =~ service_url
|
21
|
+
return true
|
22
|
+
end
|
23
|
+
elsif self.url == service_url
|
24
|
+
return true
|
25
|
+
end
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
@@ -15,6 +15,7 @@ class CASinoCore::Processor::API::ServiceTicketProvider < CASinoCore::Processor
|
|
15
15
|
# The service ticket (and nothing else) should be displayed.
|
16
16
|
# * `#invalid_ticket_granting_ticket_via_api`: No argument. The application should respond with status "400 Bad Request"
|
17
17
|
# * `#no_service_provided_via_api`: No argument. The application should respond with status "400 Bad Request"
|
18
|
+
# * `#service_not_allowed_via_api`: The user tried to access a service that this CAS server is not allowed to serve.
|
18
19
|
#
|
19
20
|
# @param [String] ticket_granting_ticket ticket_granting_ticket supplied by the user in the URL
|
20
21
|
# @param [Hash] parameters parameters supplied by user (`service` in particular)
|
@@ -37,8 +38,12 @@ class CASinoCore::Processor::API::ServiceTicketProvider < CASinoCore::Processor
|
|
37
38
|
def handle_ticket_granting_ticket
|
38
39
|
case
|
39
40
|
when (@service_url and @ticket_granting_ticket)
|
40
|
-
|
41
|
-
|
41
|
+
begin
|
42
|
+
create_service_ticket
|
43
|
+
callback_granted_service_ticket
|
44
|
+
rescue ServiceNotAllowedError
|
45
|
+
callback_service_not_allowed
|
46
|
+
end
|
42
47
|
when (@service_url and not @ticket_granting_ticket)
|
43
48
|
callback_invalid_tgt
|
44
49
|
when (not @service_url and @ticket_granting_ticket)
|
@@ -62,4 +67,8 @@ class CASinoCore::Processor::API::ServiceTicketProvider < CASinoCore::Processor
|
|
62
67
|
@listener.no_service_provided_via_api
|
63
68
|
end
|
64
69
|
|
70
|
+
def callback_service_not_allowed
|
71
|
+
@listener.service_not_allowed_via_api(clean_service_url @service_url)
|
72
|
+
end
|
73
|
+
|
65
74
|
end
|
@@ -17,43 +17,39 @@ class CASinoCore::Processor::LoginCredentialAcceptor < CASinoCore::Processor
|
|
17
17
|
# The second argument (String) is the ticket-granting ticket. It should be stored in a cookie named "tgt".
|
18
18
|
# * `#invalid_login_ticket` and `#invalid_login_credentials`: The first argument is a LoginTicket.
|
19
19
|
# See {CASinoCore::Processor::LoginCredentialRequestor} for details.
|
20
|
+
# * `#service_not_allowed`: The user tried to access a service that this CAS server is not allowed to serve.
|
20
21
|
#
|
21
22
|
# @param [Hash] params parameters supplied by user
|
22
|
-
# @param [Hash] cookies cookies supplied by user
|
23
23
|
# @param [String] user_agent user-agent delivered by the client
|
24
|
-
def process(params = nil,
|
25
|
-
params
|
26
|
-
|
27
|
-
if login_ticket_valid?(params[:lt])
|
28
|
-
|
29
|
-
if !authentication_result.nil?
|
30
|
-
ticket_granting_ticket = acquire_ticket_granting_ticket(authentication_result, user_agent)
|
31
|
-
url = unless params[:service].nil?
|
32
|
-
acquire_service_ticket(ticket_granting_ticket, params[:service], true).service_with_ticket_url
|
33
|
-
end
|
34
|
-
@listener.user_logged_in(url, ticket_granting_ticket.ticket)
|
35
|
-
else
|
36
|
-
@listener.invalid_login_credentials(acquire_login_ticket)
|
37
|
-
end
|
24
|
+
def process(params = nil, user_agent = nil)
|
25
|
+
@params = params || {}
|
26
|
+
@user_agent = user_agent
|
27
|
+
if login_ticket_valid?(@params[:lt])
|
28
|
+
authenticate_user
|
38
29
|
else
|
39
30
|
@listener.invalid_login_ticket(acquire_login_ticket)
|
40
31
|
end
|
41
32
|
end
|
42
33
|
|
43
34
|
private
|
44
|
-
def
|
45
|
-
|
46
|
-
if
|
47
|
-
|
48
|
-
false
|
49
|
-
elsif ticket.created_at < CASinoCore::Settings.login_ticket[:lifetime].seconds.ago
|
50
|
-
logger.info "Login ticket '#{ticket.ticket}' expired"
|
51
|
-
false
|
35
|
+
def authenticate_user
|
36
|
+
authentication_result = validate_login_credentials(@params[:username], @params[:password])
|
37
|
+
if !authentication_result.nil?
|
38
|
+
user_logged_in(authentication_result)
|
52
39
|
else
|
53
|
-
|
54
|
-
ticket.delete
|
55
|
-
true
|
40
|
+
@listener.invalid_login_credentials(acquire_login_ticket)
|
56
41
|
end
|
57
42
|
end
|
58
43
|
|
44
|
+
def user_logged_in(authentication_result)
|
45
|
+
begin
|
46
|
+
ticket_granting_ticket = acquire_ticket_granting_ticket(authentication_result, @user_agent)
|
47
|
+
url = unless @params[:service].nil?
|
48
|
+
acquire_service_ticket(ticket_granting_ticket, @params[:service], true).service_with_ticket_url
|
49
|
+
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
|
+
end
|
54
|
+
end
|
59
55
|
end
|
@@ -14,27 +14,57 @@ class CASinoCore::Processor::LoginCredentialRequestor < CASinoCore::Processor
|
|
14
14
|
# The method will call one of the following methods on the listener:
|
15
15
|
# * `#user_logged_in`: The first argument (String) is the URL (if any), the user should be redirected to.
|
16
16
|
# * `#user_not_logged_in`: The first argument is a LoginTicket. It should be stored in a hidden field with name "lt".
|
17
|
+
# * `#service_not_allowed`: The user tried to access a service that this CAS server is not allowed to serve.
|
17
18
|
#
|
18
19
|
# @param [Hash] params parameters supplied by user
|
19
20
|
# @param [Hash] cookies cookies supplied by user
|
20
21
|
# @param [String] user_agent user-agent delivered by the client
|
21
22
|
def process(params = nil, cookies = nil, user_agent = nil)
|
22
|
-
params
|
23
|
-
cookies
|
24
|
-
|
25
|
-
if
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
@params = params || {}
|
24
|
+
@cookies = cookies || {}
|
25
|
+
@user_agent = user_agent || {}
|
26
|
+
if check_service_allowed
|
27
|
+
handle_allowed_service
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def handle_allowed_service
|
33
|
+
if !@params[:renew] && (@ticket_granting_ticket = find_valid_ticket_granting_ticket(@cookies[:tgt], @user_agent))
|
34
|
+
handle_logged_in
|
35
|
+
else
|
36
|
+
handle_not_logged_in
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def handle_logged_in
|
41
|
+
service_url_with_ticket = unless @params[:service].nil?
|
42
|
+
acquire_service_ticket(@ticket_granting_ticket, @params[:service], true).service_with_ticket_url
|
43
|
+
end
|
44
|
+
@listener.user_logged_in(service_url_with_ticket)
|
45
|
+
end
|
46
|
+
|
47
|
+
def handle_not_logged_in
|
48
|
+
if gateway_request?
|
49
|
+
# we actually lie to the listener to simplify things
|
50
|
+
@listener.user_logged_in(@params[:service])
|
51
|
+
else
|
52
|
+
login_ticket = acquire_login_ticket
|
53
|
+
@listener.user_not_logged_in(login_ticket)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def check_service_allowed
|
58
|
+
service_url = clean_service_url(@params[:service]) unless @params[:service].nil?
|
59
|
+
if service_url.nil? || CASinoCore::Model::ServiceRule.allowed?(service_url)
|
60
|
+
true
|
30
61
|
else
|
31
|
-
|
32
|
-
|
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
|
62
|
+
@listener.service_not_allowed(service_url)
|
63
|
+
false
|
38
64
|
end
|
39
65
|
end
|
66
|
+
|
67
|
+
def gateway_request?
|
68
|
+
@params[:gateway] == 'true' && @params[:service]
|
69
|
+
end
|
40
70
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'terminal-table'
|
2
|
+
require 'casino_core/model'
|
3
|
+
require 'casino_core/helper/service_tickets'
|
4
|
+
|
5
|
+
namespace :casino_core do
|
6
|
+
namespace :service_rule do
|
7
|
+
include CASinoCore::Helper::ServiceTickets
|
8
|
+
|
9
|
+
desc 'Add a service rule (prefix the url parameter with "regex:" to add a regular expression)'
|
10
|
+
task :add, [:name, :url] => 'casino_core:db:configure_connection' do |task, args|
|
11
|
+
service_rule = CASinoCore::Model::ServiceRule.new name: args[:name]
|
12
|
+
match = /^regex:(.*)/.match(args[:url])
|
13
|
+
if match.nil?
|
14
|
+
service_rule.url = clean_service_url(args[:url])
|
15
|
+
else
|
16
|
+
service_rule.url = match[1]
|
17
|
+
service_rule.regex = true
|
18
|
+
end
|
19
|
+
if !service_rule.save
|
20
|
+
fail service_rule.errors.full_messages.join("\n")
|
21
|
+
elsif service_rule.regex && service_rule.url[0] != '^'
|
22
|
+
puts 'Warning: Potentially unsafe regex! Use ^ to match the beginning of the URL. Example: ^https://'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Remove a servcice rule.'
|
27
|
+
task :delete, [:id] => 'casino_core:db:configure_connection' do |task, args|
|
28
|
+
CASinoCore::Model::ServiceRule.find(args[:id]).delete
|
29
|
+
puts "Successfully deleted service rule ##{args[:id]}."
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'Delete all servcice rules.'
|
33
|
+
task :flush => 'casino_core:db:configure_connection' do |task, args|
|
34
|
+
CASinoCore::Model::ServiceRule.delete_all
|
35
|
+
puts 'Successfully deleted all service rules.'
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'List all service rules.'
|
39
|
+
task list: 'casino_core:db:configure_connection' do
|
40
|
+
table = Terminal::Table.new :headings => ['Enabled', 'ID', 'Name', 'URL'] do |t|
|
41
|
+
CASinoCore::Model::ServiceRule.all.each do |service_rule|
|
42
|
+
url = service_rule.url
|
43
|
+
if service_rule.regex?
|
44
|
+
url += " (Regex)"
|
45
|
+
end
|
46
|
+
t.add_row [service_rule.enabled, service_rule.id, service_rule.name, url]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
puts table
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/casino_core/version.rb
CHANGED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CASinoCore::Model::ServiceRule do
|
4
|
+
describe '.allowed?' do
|
5
|
+
context 'with an empty table' do
|
6
|
+
['https://www.example.org/', 'http://www.google.com/'].each do |service_url|
|
7
|
+
it "allows access to #{service_url}" do
|
8
|
+
described_class.allowed?(service_url).should == true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'with a regex rule' do
|
14
|
+
before(:each) do
|
15
|
+
FactoryGirl.create :service_rule, :regex, url: '^https://.*'
|
16
|
+
end
|
17
|
+
|
18
|
+
['https://www.example.org/', 'https://www.google.com/'].each do |service_url|
|
19
|
+
it "allows access to #{service_url}" do
|
20
|
+
described_class.allowed?(service_url).should == true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
['http://www.example.org/', 'http://www.google.com/'].each do |service_url|
|
25
|
+
it "does not allow access to #{service_url}" do
|
26
|
+
described_class.allowed?(service_url).should == false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with many regex rules' do
|
32
|
+
before(:each) do
|
33
|
+
100.times do |counter|
|
34
|
+
FactoryGirl.create :service_rule, :regex, url: "^https://www#{counter}.example.com"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
let(:service_url) { 'https://www111.example.com/bla' }
|
39
|
+
|
40
|
+
it 'does not take too long to check a denied service' do
|
41
|
+
start = Time.now
|
42
|
+
described_class.allowed?(service_url).should == false
|
43
|
+
(Time.now - start).should < 0.1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with a non-regex rule' do
|
48
|
+
before(:each) do
|
49
|
+
FactoryGirl.create :service_rule, url: 'https://www.google.com/foo'
|
50
|
+
end
|
51
|
+
|
52
|
+
['https://www.google.com/foo'].each do |service_url|
|
53
|
+
it "allows access to #{service_url}" do
|
54
|
+
described_class.allowed?(service_url).should == true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
['https://www.example.org/', 'http://www.example.org/', 'https://www.google.com/test'].each do |service_url|
|
59
|
+
it "does not allow access to #{service_url}" do
|
60
|
+
described_class.allowed?(service_url).should == false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -5,7 +5,8 @@ describe CASinoCore::Processor::API::ServiceTicketProvider do
|
|
5
5
|
let(:listener) { Object.new }
|
6
6
|
let(:processor) { described_class.new(listener) }
|
7
7
|
|
8
|
-
let(:
|
8
|
+
let(:service) { 'http://example.org/' }
|
9
|
+
let(:parameters) { { service: service } }
|
9
10
|
|
10
11
|
context 'with an invalid ticket-granting ticket' do
|
11
12
|
let(:ticket_granting_ticket) { 'TGT-INVALID' }
|
@@ -21,6 +22,18 @@ describe CASinoCore::Processor::API::ServiceTicketProvider do
|
|
21
22
|
let(:ticket) { ticket_granting_ticket.ticket }
|
22
23
|
let(:user_agent) { ticket_granting_ticket.user_agent }
|
23
24
|
|
25
|
+
context 'with a not allowed service' do
|
26
|
+
before(:each) do
|
27
|
+
FactoryGirl.create :service_rule, :regex, url: '^https://.*'
|
28
|
+
end
|
29
|
+
let(:service) { 'http://www.example.org/' }
|
30
|
+
|
31
|
+
it 'calls the #service_not_allowed method on the listener' do
|
32
|
+
listener.should_receive(:service_not_allowed_via_api).with(service)
|
33
|
+
processor.process(ticket, parameters, user_agent)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
24
37
|
it 'calls the #granted_service_ticket_via_api method on the listener' do
|
25
38
|
listener.should_receive(:granted_service_ticket_via_api).with(/^ST\-/)
|
26
39
|
processor.process(ticket, parameters, user_agent)
|
@@ -39,6 +39,18 @@ describe CASinoCore::Processor::LoginCredentialAcceptor do
|
|
39
39
|
listener.stub(:user_logged_in)
|
40
40
|
end
|
41
41
|
|
42
|
+
context 'with a not allowed service' do
|
43
|
+
before(:each) do
|
44
|
+
FactoryGirl.create :service_rule, :regex, url: '^https://.*'
|
45
|
+
end
|
46
|
+
let(:service) { 'http://www.example.org/' }
|
47
|
+
|
48
|
+
it 'calls the #service_not_allowed method on the listener' do
|
49
|
+
listener.should_receive(:service_not_allowed).with(service)
|
50
|
+
processor.process(login_data)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
42
54
|
context 'when all authenticators raise an error' do
|
43
55
|
before(:each) do
|
44
56
|
CASinoCore::Authenticator::Static.any_instance.stub(:validate) do
|
@@ -71,7 +83,7 @@ describe CASinoCore::Processor::LoginCredentialAcceptor do
|
|
71
83
|
let(:service) { 'https://www.example.com' }
|
72
84
|
|
73
85
|
it 'calls the #user_logged_in method on the listener' do
|
74
|
-
listener.should_receive(:user_logged_in).with(/^#{service}
|
86
|
+
listener.should_receive(:user_logged_in).with(/^#{service}\/\?ticket=ST\-/, /^TGC\-/)
|
75
87
|
processor.process(login_data)
|
76
88
|
end
|
77
89
|
|
@@ -5,6 +5,19 @@ describe CASinoCore::Processor::LoginCredentialRequestor do
|
|
5
5
|
let(:listener) { Object.new }
|
6
6
|
let(:processor) { described_class.new(listener) }
|
7
7
|
|
8
|
+
context 'with a not allowed service' do
|
9
|
+
before(:each) do
|
10
|
+
FactoryGirl.create :service_rule, :regex, url: '^https://.*'
|
11
|
+
end
|
12
|
+
let(:service) { 'http://www.example.org/' }
|
13
|
+
let(:params) { { service: service } }
|
14
|
+
|
15
|
+
it 'calls the #service_not_allowed method on the listener' do
|
16
|
+
listener.should_receive(:service_not_allowed).with(service)
|
17
|
+
processor.process(params)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
8
21
|
context 'when logged out' do
|
9
22
|
it 'calls the #user_not_logged_in method on the listener' do
|
10
23
|
listener.should_receive(:user_not_logged_in).with(kind_of(CASinoCore::Model::LoginTicket))
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'factory_girl'
|
2
|
+
|
3
|
+
FactoryGirl.define do
|
4
|
+
factory :service_rule, class: CASinoCore::Model::ServiceRule do
|
5
|
+
sequence :order do |n|
|
6
|
+
n
|
7
|
+
end
|
8
|
+
sequence :name do |n|
|
9
|
+
"Rule #{n}"
|
10
|
+
end
|
11
|
+
|
12
|
+
trait :regex do
|
13
|
+
regex true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
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.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -187,6 +187,22 @@ dependencies:
|
|
187
187
|
- - ~>
|
188
188
|
- !ruby/object:Gem::Version
|
189
189
|
version: '2.3'
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: terminal-table
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ~>
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '1.4'
|
198
|
+
type: :runtime
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ~>
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '1.4'
|
190
206
|
- !ruby/object:Gem::Dependency
|
191
207
|
name: useragent
|
192
208
|
requirement: !ruby/object:Gem::Requirement
|
@@ -221,6 +237,7 @@ files:
|
|
221
237
|
- LICENSE.txt
|
222
238
|
- README.md
|
223
239
|
- Rakefile
|
240
|
+
- UPGRADE.md
|
224
241
|
- VERSION
|
225
242
|
- casino_core.gemspec
|
226
243
|
- config/cas.yml
|
@@ -244,6 +261,7 @@ files:
|
|
244
261
|
- db/migrate/20121226192211_fix_index_for_granter_on_proxy_granting_ticket.rb
|
245
262
|
- db/migrate/20121226211511_allow_service_tickets_without_ticket_granting_ticket.rb
|
246
263
|
- db/migrate/20121231114141_add_authenticator_to_ticket_granting_tickets.rb
|
264
|
+
- db/migrate/20130105152327_create_service_rules.rb
|
247
265
|
- db/schema.rb
|
248
266
|
- lib/casino_core.rb
|
249
267
|
- lib/casino_core/authenticator.rb
|
@@ -264,6 +282,7 @@ files:
|
|
264
282
|
- lib/casino_core/model/login_ticket.rb
|
265
283
|
- lib/casino_core/model/proxy_granting_ticket.rb
|
266
284
|
- lib/casino_core/model/proxy_ticket.rb
|
285
|
+
- lib/casino_core/model/service_rule.rb
|
267
286
|
- lib/casino_core/model/service_ticket.rb
|
268
287
|
- lib/casino_core/model/service_ticket/single_sign_out_notifier.rb
|
269
288
|
- lib/casino_core/model/ticket_granting_ticket.rb
|
@@ -286,11 +305,13 @@ files:
|
|
286
305
|
- lib/casino_core/settings.rb
|
287
306
|
- lib/casino_core/tasks/cleanup.rake
|
288
307
|
- lib/casino_core/tasks/database.rake
|
308
|
+
- lib/casino_core/tasks/service_rule.rake
|
289
309
|
- lib/casino_core/version.rb
|
290
310
|
- spec/authenticator/base_spec.rb
|
291
311
|
- spec/authenticator/static_spec.rb
|
292
312
|
- spec/model/login_ticket_spec.rb
|
293
313
|
- spec/model/proxy_ticket_spec.rb
|
314
|
+
- spec/model/service_rule_spec.rb
|
294
315
|
- spec/model/service_ticket/single_sign_out_notifier_spec.rb
|
295
316
|
- spec/model/service_ticket_spec.rb
|
296
317
|
- spec/model/ticket_granting_ticket_spec.rb
|
@@ -311,6 +332,7 @@ files:
|
|
311
332
|
- spec/support/factories/login_ticket_factory.rb
|
312
333
|
- spec/support/factories/proxy_granting_ticket_factory.rb
|
313
334
|
- spec/support/factories/proxy_ticket_factory.rb
|
335
|
+
- spec/support/factories/service_rule_factory.rb
|
314
336
|
- spec/support/factories/service_ticket_factory.rb
|
315
337
|
- spec/support/factories/ticket_granting_ticket_factory.rb
|
316
338
|
homepage: http://rbcas.org/
|
@@ -328,7 +350,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
328
350
|
version: '0'
|
329
351
|
segments:
|
330
352
|
- 0
|
331
|
-
hash:
|
353
|
+
hash: 4552405534502231272
|
332
354
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
333
355
|
none: false
|
334
356
|
requirements:
|
@@ -337,7 +359,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
337
359
|
version: '0'
|
338
360
|
segments:
|
339
361
|
- 0
|
340
|
-
hash:
|
362
|
+
hash: 4552405534502231272
|
341
363
|
requirements: []
|
342
364
|
rubyforge_project:
|
343
365
|
rubygems_version: 1.8.24
|
@@ -349,6 +371,7 @@ test_files:
|
|
349
371
|
- spec/authenticator/static_spec.rb
|
350
372
|
- spec/model/login_ticket_spec.rb
|
351
373
|
- spec/model/proxy_ticket_spec.rb
|
374
|
+
- spec/model/service_rule_spec.rb
|
352
375
|
- spec/model/service_ticket/single_sign_out_notifier_spec.rb
|
353
376
|
- spec/model/service_ticket_spec.rb
|
354
377
|
- spec/model/ticket_granting_ticket_spec.rb
|
@@ -369,6 +392,7 @@ test_files:
|
|
369
392
|
- spec/support/factories/login_ticket_factory.rb
|
370
393
|
- spec/support/factories/proxy_granting_ticket_factory.rb
|
371
394
|
- spec/support/factories/proxy_ticket_factory.rb
|
395
|
+
- spec/support/factories/service_rule_factory.rb
|
372
396
|
- spec/support/factories/service_ticket_factory.rb
|
373
397
|
- spec/support/factories/ticket_granting_ticket_factory.rb
|
374
398
|
has_rdoc:
|