casino_core 1.0.12 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|