casablanca 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +8 -1
- data/Manifest.txt +1 -1
- data/{README.textile → README.txt} +27 -13
- data/Rakefile +6 -5
- data/bin/casablanca +3 -2
- data/lib/casablanca.rb +1 -1
- data/lib/casablanca/cli.rb +9 -5
- data/lib/casablanca/client.rb +119 -35
- data/lib/casablanca/filters/rails.rb +59 -29
- data/test/test_client.rb +48 -13
- data/test/test_helper.rb +5 -5
- data/test/test_rails_filter.rb +44 -37
- data/test/test_ticket.rb +10 -14
- metadata +7 -6
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -1,18 +1,29 @@
|
|
1
|
-
|
1
|
+
= Casablanca
|
2
2
|
|
3
|
-
|
3
|
+
* http://rubyforge.org/projects/casablanca/
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
4
6
|
|
5
7
|
Casablanca is a single sign-on client for the CAS 2.0 protocol.
|
6
|
-
It can be run from the commandline and as a filter for Rails.
|
7
8
|
|
8
|
-
|
9
|
+
== FEATURES:
|
10
|
+
|
11
|
+
* Includes a commandline Client to test getting service tickets from a CAS server
|
12
|
+
* It can be run as a Rails plugin.
|
13
|
+
* Gatewaying (permitting the user to continue without authentication).
|
14
|
+
|
15
|
+
== TODO:
|
9
16
|
|
17
|
+
* Add extra attributes returned from the server
|
18
|
+
* Implement proxing
|
19
|
+
* Check for single signout
|
20
|
+
* Check for endless redirects
|
10
21
|
|
11
|
-
|
22
|
+
== SYNOPSIS:
|
12
23
|
|
13
24
|
Commandline:
|
14
25
|
|
15
|
-
casablanca
|
26
|
+
% casablanca
|
16
27
|
|
17
28
|
In IRB:
|
18
29
|
|
@@ -31,6 +42,8 @@ In a Rails project:
|
|
31
42
|
Casablanca::RailsFilter.config do |config|
|
32
43
|
config[:cas_server_url] = "http://localhost:4567"
|
33
44
|
config[:service_url] = "http://localhost:3000"
|
45
|
+
# Always require new credentials for authentication
|
46
|
+
config[:renew] = true
|
34
47
|
end
|
35
48
|
|
36
49
|
- Add the following to application.rb:
|
@@ -52,16 +65,17 @@ In a Rails project:
|
|
52
65
|
- Add the following to you logout action
|
53
66
|
|
54
67
|
Casablanca::RailsFilter.logout(self)
|
68
|
+
|
69
|
+
== REQUIREMENTS:
|
55
70
|
|
56
|
-
|
71
|
+
== INSTALL:
|
57
72
|
|
58
|
-
|
59
|
-
*
|
60
|
-
|
61
|
-
*
|
62
|
-
* Check for endless redirects
|
73
|
+
Stable version
|
74
|
+
* sudo gem install casablanca
|
75
|
+
Development version
|
76
|
+
* gem sources -a http://gems.github.com; sudo gem install p8-casablanca
|
63
77
|
|
64
|
-
|
78
|
+
== LICENSE:
|
65
79
|
|
66
80
|
(The MIT License)
|
67
81
|
|
data/Rakefile
CHANGED
@@ -6,10 +6,11 @@ require 'lib/casablanca.rb'
|
|
6
6
|
|
7
7
|
Hoe.new('casablanca', Casablanca::VERSION) do |p|
|
8
8
|
p.developer('FIX', 'FIX@example.com')
|
9
|
+
p.remote_rdoc_dir = '' # Release to root
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
require 'metric_fu'
|
13
|
+
|
14
|
+
MetricFu::Configuration.run do |config|
|
15
|
+
config.coverage = { :test_files => ['test/**/test_*.rb'] }
|
16
|
+
end
|
data/bin/casablanca
CHANGED
@@ -3,7 +3,8 @@ irb = RUBY_PLATFORM =~ /mswin32/ ? 'irb.bat' : 'irb'
|
|
3
3
|
options = { :sandbox => false, :irb => irb }
|
4
4
|
|
5
5
|
libs = " -r irb/completion"
|
6
|
-
libs << " -r #{File.dirname(__FILE__)}/../lib/casablanca.rb"
|
7
|
-
libs << " -r #{File.dirname(__FILE__)}/../lib/casablanca/
|
6
|
+
libs << " -r #{File.expand_path(File.dirname(__FILE__))}/../lib/casablanca.rb"
|
7
|
+
libs << " -r #{File.expand_path(File.dirname(__FILE__))}/../lib/casablanca/client.rb"
|
8
|
+
libs << " -r #{File.expand_path(File.dirname(__FILE__))}/../lib/casablanca/cli.rb"
|
8
9
|
|
9
10
|
exec "#{options[:irb]} #{libs} --simple-prompt"
|
data/lib/casablanca.rb
CHANGED
data/lib/casablanca/cli.rb
CHANGED
@@ -6,15 +6,19 @@ CASABLANCA CLIENT CONSOLE (#{Casablanca::VERSION})
|
|
6
6
|
Use C for a configured client (#{config.inspect})
|
7
7
|
Example:
|
8
8
|
|
9
|
-
t = C.
|
10
|
-
C.authenticate_ticket(t)
|
9
|
+
t = C.login('admin', 'admin')
|
10
|
+
C.authenticate_ticket(t)
|
11
|
+
|
12
|
+
C.logout
|
11
13
|
|
12
14
|
The configuration can be changed:
|
13
|
-
|
14
|
-
C.
|
15
|
+
|
16
|
+
C.cas_server_url = "http://example.com/cas_server"
|
17
|
+
C.service_url = "http://example.com/application"
|
15
18
|
|
16
19
|
)
|
17
20
|
|
18
|
-
C =
|
21
|
+
C = Casablanca::CommandLineClient.new(config)
|
22
|
+
C.logger.level = Logger::DEBUG
|
19
23
|
|
20
24
|
puts INFO
|
data/lib/casablanca/client.rb
CHANGED
@@ -2,9 +2,10 @@ require 'uri'
|
|
2
2
|
require 'cgi'
|
3
3
|
require 'net/https'
|
4
4
|
require 'rexml/document'
|
5
|
+
require 'logger'
|
5
6
|
|
6
7
|
module Casablanca
|
7
|
-
|
8
|
+
|
8
9
|
class Client
|
9
10
|
attr_accessor :cas_server_url, :service_url
|
10
11
|
|
@@ -14,23 +15,60 @@ module Casablanca
|
|
14
15
|
@service_url = config[:service_url]
|
15
16
|
end
|
16
17
|
|
18
|
+
##
|
19
|
+
# Validates a Ticket to the validation url of the CAS Server
|
20
|
+
# and checks if the ticket is authenticated
|
17
21
|
def authenticate_ticket(ticket)
|
18
|
-
|
19
|
-
ticket.authenticate
|
22
|
+
request_validation(ticket)
|
23
|
+
ticket.authenticate
|
20
24
|
end
|
21
25
|
|
22
|
-
|
23
|
-
|
26
|
+
##
|
27
|
+
# The login url of the Cas server. This page has the login form.
|
28
|
+
def login_url(params={})
|
29
|
+
uri = URI.parse("#{@cas_server_url}/login")
|
30
|
+
query = {:service => @service_url}
|
31
|
+
query[:renew] = 'true' if params[:renew]
|
32
|
+
uri.merge_query(query)
|
33
|
+
uri.to_s
|
24
34
|
end
|
25
35
|
|
26
|
-
|
27
|
-
|
36
|
+
##
|
37
|
+
# The logout url of the Cas server
|
38
|
+
def logout_url(params={})
|
39
|
+
uri = URI.parse("#{@cas_server_url}/logout")
|
40
|
+
query = {}
|
41
|
+
query[:url] = params[:url] if params[:url]
|
42
|
+
uri.merge_query(query)
|
43
|
+
uri.to_s
|
28
44
|
end
|
29
45
|
|
46
|
+
##
|
47
|
+
# The proxy validation url of the Cas server.
|
30
48
|
def validate_url
|
31
49
|
"#{@cas_server_url}/proxyValidate"
|
32
50
|
end
|
33
51
|
|
52
|
+
def logger
|
53
|
+
self.class.logger
|
54
|
+
end
|
55
|
+
|
56
|
+
def logger=logger
|
57
|
+
self.class.logger = logger
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.logger=logger
|
61
|
+
@logger = logger
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.logger
|
65
|
+
unless @logger
|
66
|
+
@logger = ::Logger.new($stderr)
|
67
|
+
@logger.level = Logger::WARN
|
68
|
+
end
|
69
|
+
@logger
|
70
|
+
end
|
71
|
+
|
34
72
|
private
|
35
73
|
|
36
74
|
def request_validation(ticket)
|
@@ -38,95 +76,134 @@ module Casablanca
|
|
38
76
|
uri = URI.parse(validate_url)
|
39
77
|
uri.merge_query(ticket.to_request_params)
|
40
78
|
response = get(uri)
|
41
|
-
puts "#{@cas_server_url} #{response.inspect}:\n#{response.body}"
|
42
79
|
unless response.kind_of?(Net::HTTPSuccess)
|
43
80
|
raise ResponseError, "#{response.code}, #{response.body}"
|
44
81
|
end
|
45
|
-
response.body
|
82
|
+
ticket.body = response.body
|
46
83
|
end
|
47
84
|
|
48
85
|
def get(uri)
|
49
86
|
https(uri) do |h|
|
50
|
-
h.get("#{uri.path}?#{uri.query}")
|
51
|
-
end
|
87
|
+
h.get("#{uri.path}?#{uri.query}", headers)
|
88
|
+
end
|
52
89
|
end
|
53
90
|
|
54
91
|
def https(uri)
|
55
92
|
https = Net::HTTP.new(uri.host, uri.port)
|
56
93
|
https.use_ssl = (uri.scheme == 'https')
|
57
94
|
begin
|
58
|
-
https.start do |h|
|
95
|
+
response = https.start do |h|
|
59
96
|
yield(h)
|
60
97
|
end
|
61
98
|
rescue Errno::ECONNREFUSED => error
|
62
99
|
raise CasServerException
|
63
100
|
end
|
101
|
+
logger.debug(response_log(response))
|
102
|
+
response
|
103
|
+
end
|
104
|
+
|
105
|
+
def headers
|
106
|
+
{'cookie' => @ticket_granting_ticket || ''}
|
107
|
+
end
|
108
|
+
|
109
|
+
def response_log(response)
|
110
|
+
msg = "################\n"
|
111
|
+
msg << " #{@cas_server_url} #{response.inspect}:\n"
|
112
|
+
msg << " body: #{response.body}\n"
|
113
|
+
msg << " headers:\n"
|
114
|
+
response.each_key do |k|
|
115
|
+
msg << " - #{k}: #{response[k]}\n"
|
116
|
+
end
|
117
|
+
msg
|
64
118
|
end
|
65
119
|
|
66
120
|
end
|
67
121
|
|
68
122
|
class CommandLineClient < Client
|
69
|
-
|
123
|
+
attr_reader :ticket_granting_ticket
|
124
|
+
##
|
125
|
+
# Logs in to the CAS server and returns the response
|
70
126
|
def login(username, password)
|
71
|
-
|
127
|
+
@ticket_granting_ticket = nil
|
128
|
+
response = post(URI.parse(login_url), {:username => username, :password => password, :service => service_url})
|
129
|
+
set_ticket_granting_ticket(response)
|
130
|
+
get_service_ticket(response)
|
72
131
|
end
|
73
132
|
|
74
|
-
def
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
133
|
+
def logout(follow_url=nil)
|
134
|
+
@ticket_granting_ticket = nil
|
135
|
+
uri = URI.parse(logout_url)
|
136
|
+
uri.merge_query(:url => follow_url) if follow_url
|
137
|
+
get(uri)
|
79
138
|
end
|
80
|
-
|
139
|
+
|
81
140
|
private
|
82
|
-
|
141
|
+
|
83
142
|
def post(uri, form_data)
|
84
143
|
req = Net::HTTP::Post.new(uri.path)
|
85
144
|
req.set_form_data(form_data, ';')
|
86
145
|
https(uri) do |h|
|
87
146
|
h.request(req)
|
88
147
|
end
|
89
|
-
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def get_service_ticket(response)
|
151
|
+
if (location = response['location'])
|
152
|
+
query = {}
|
153
|
+
URI.parse(location).query.collect{|q| k,v = q.split('='); query[k] = v }
|
154
|
+
Ticket.new(query['ticket'], @service_url)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def set_ticket_granting_ticket(response)
|
159
|
+
@ticket_granting_ticket = (response['set-cookie'] || '').split(/;/)[0] # tgt=TGC-1232569033r763536CC6753E6F357
|
160
|
+
end
|
90
161
|
end
|
91
162
|
|
92
163
|
class Ticket
|
93
164
|
attr_accessor :user, :failure_code, :failure_message
|
94
165
|
attr_reader :service_url, :ticket
|
95
|
-
|
166
|
+
attr_writer :body
|
96
167
|
def initialize(ticket, service_url, renew = false)
|
97
168
|
@service_url = service_url
|
98
169
|
@ticket = ticket
|
99
|
-
@renew
|
170
|
+
@renew = renew
|
100
171
|
end
|
101
172
|
|
173
|
+
##
|
174
|
+
# Create a Ticket from a Hash. Useful for unserializing
|
102
175
|
def self.from_hash(hash)
|
103
|
-
ticket = Ticket.new(hash[:ticket], hash[:service_url]
|
176
|
+
ticket = Ticket.new(hash[:ticket], hash[:service_url])
|
104
177
|
ticket.user = hash[:user]
|
105
178
|
ticket
|
106
179
|
end
|
107
180
|
|
108
|
-
|
109
|
-
|
110
|
-
:ticket => @ticket }
|
111
|
-
params[:renew] = 1 if @renew
|
112
|
-
params
|
113
|
-
end
|
114
|
-
|
181
|
+
##
|
182
|
+
# Convert a Ticket to a Hash. Useful for serializing
|
115
183
|
def to_hash
|
116
184
|
props = {}
|
117
185
|
props[:user] = @user if authenticated?
|
118
|
-
props[:renew] = @renew if @renew
|
119
186
|
props[:service_url] = @service_url
|
120
187
|
props[:ticket] = @ticket
|
121
188
|
props
|
122
189
|
end
|
190
|
+
|
191
|
+
##
|
192
|
+
# Convert the ticket to a Hash for a request
|
193
|
+
def to_request_params
|
194
|
+
params = {}
|
195
|
+
params[:service] = @service_url
|
196
|
+
params[:ticket] = @ticket if @ticket
|
197
|
+
params[:renew] = 'true' if @renew
|
198
|
+
params
|
199
|
+
end
|
123
200
|
|
124
201
|
def authenticated?
|
125
202
|
!!@user
|
126
203
|
end
|
127
204
|
|
128
|
-
def authenticate
|
129
|
-
response = CasResponseParser.parse(self, body)
|
205
|
+
def authenticate
|
206
|
+
response = CasResponseParser.parse(self, @body)
|
130
207
|
authenticated?
|
131
208
|
end
|
132
209
|
end
|
@@ -141,12 +218,19 @@ module Casablanca
|
|
141
218
|
end
|
142
219
|
end
|
143
220
|
|
221
|
+
##
|
222
|
+
# Monkey patches for URI::HTTP
|
144
223
|
class URI::HTTP
|
224
|
+
|
225
|
+
##
|
226
|
+
# Adds the hash to query
|
145
227
|
def merge_query(hash)
|
146
228
|
q = query ? query + '&' : ''
|
147
229
|
self.query = "#{q}#{hash_to_uri_array(hash)}"
|
148
230
|
end
|
149
231
|
|
232
|
+
private
|
233
|
+
|
150
234
|
def hash_to_uri_array(hash)
|
151
235
|
hash.collect do |name, value|
|
152
236
|
if value.kind_of? Array
|
@@ -1,55 +1,85 @@
|
|
1
1
|
module Casablanca
|
2
2
|
class RailsFilter
|
3
|
-
@@client = nil
|
4
3
|
|
5
4
|
class << self
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
|
5
|
+
|
6
|
+
##
|
7
|
+
# Configure the client
|
8
|
+
#
|
9
|
+
# Casablanca::RailsFilter.config do |config|
|
10
|
+
# config[:cas_server_url] = "http://localhost:4567"
|
11
|
+
# config[:service_url] = "http://localhost:3000"
|
12
|
+
# end
|
15
13
|
def config
|
16
14
|
config = {}
|
17
15
|
yield config
|
18
|
-
|
16
|
+
@cas_server_url = config[:cas_server_url]
|
17
|
+
@service_url = config[:service_url]
|
18
|
+
@renew = config[:renew] # always renew the session
|
19
|
+
# set logger to rails logger
|
20
|
+
Client.logger = ::ActionController::Base.logger
|
19
21
|
end
|
20
22
|
|
21
23
|
def filter(controller)
|
22
|
-
|
23
|
-
|
24
|
-
if
|
25
|
-
|
24
|
+
|
25
|
+
client = Client.new(:cas_server_url => @cas_server_url, :service_url => @service_url)
|
26
|
+
if !controller.session[:cas_user] && !controller.params[:ticket]
|
27
|
+
if renew?
|
28
|
+
logger.debug "Always require credentials for authentication"
|
29
|
+
else
|
30
|
+
logger.debug "Not authenticated yet. Ticket parameter required"
|
31
|
+
end
|
32
|
+
redirect_to_cas_login(controller, renew?)
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
ticket = Ticket.new(controller.params[:ticket], client.service_url, controller.session[:cas_renew])
|
36
|
+
if client.authenticate_ticket(ticket)
|
37
|
+
logger.debug "Ticket authenticated"
|
26
38
|
controller.session[:cas_user] = ticket.user
|
27
|
-
controller.session[:
|
39
|
+
controller.session[:cas_renew] = nil
|
28
40
|
return true
|
29
|
-
else
|
30
|
-
|
31
|
-
controller
|
32
|
-
|
33
|
-
controller
|
41
|
+
else
|
42
|
+
logger.warn "Ticket authentication failed: #{ticket.failure_message}"
|
43
|
+
logout(controller)
|
44
|
+
logger.debug "Renew login credentials"
|
45
|
+
redirect_to_cas_login(controller, true)
|
34
46
|
return false
|
35
47
|
end
|
36
48
|
end
|
37
49
|
|
38
|
-
|
39
|
-
|
50
|
+
##
|
51
|
+
# The login url of the Cas server. This page has the login form.
|
52
|
+
def login_url(params={})
|
53
|
+
client = Client.new(:cas_server_url => @cas_server_url, :service_url => @service_url)
|
54
|
+
client.login_url(params)
|
40
55
|
end
|
41
56
|
|
57
|
+
##
|
58
|
+
# The logout url of the Cas server.
|
59
|
+
def logout_url(params={})
|
60
|
+
client = Client.new(:cas_server_url => @cas_server_url, :service_url => @service_url)
|
61
|
+
client.logout_url(params)
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Logs out of the Cas server.
|
42
66
|
def logout(controller)
|
43
|
-
controller.
|
44
|
-
|
67
|
+
controller.session[:cas_user] = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
def logger
|
71
|
+
Client.logger
|
45
72
|
end
|
46
73
|
|
47
74
|
private
|
48
75
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
|
76
|
+
def redirect_to_cas_login(controller, renew)
|
77
|
+
controller.session[:cas_renew] = renew
|
78
|
+
controller.send(:redirect_to, login_url(:renew => renew))
|
79
|
+
end
|
80
|
+
|
81
|
+
def renew?
|
82
|
+
@renew
|
53
83
|
end
|
54
84
|
|
55
85
|
end
|
data/test/test_client.rb
CHANGED
@@ -18,7 +18,7 @@ class TestClient < Test::Unit::TestCase
|
|
18
18
|
def test_authenticate_ticket
|
19
19
|
service_ticket = get_service_ticket
|
20
20
|
@client = Client.new(:cas_server_url => "http://localhost:4567", :service_url => "http://localhost:3000")
|
21
|
-
mock_authenticate_ticket(VALID_REQUEST)
|
21
|
+
mock_authenticate_ticket(VALID_REQUEST)
|
22
22
|
@client.authenticate_ticket(service_ticket)
|
23
23
|
assert_equal 'admin', service_ticket.user
|
24
24
|
end
|
@@ -26,7 +26,7 @@ class TestClient < Test::Unit::TestCase
|
|
26
26
|
def test_validate_expired_ticket
|
27
27
|
mock_authenticate_ticket(INVALID_TICKET)
|
28
28
|
ticket = 'ST-1231341579r871C5757B79767C21E'
|
29
|
-
service_ticket = Ticket.new(ticket, 'http://localhost:3000'
|
29
|
+
service_ticket = Ticket.new(ticket, 'http://localhost:3000')
|
30
30
|
@client.authenticate_ticket(service_ticket)
|
31
31
|
assert_equal 'INVALID_TICKET', service_ticket.failure_code
|
32
32
|
#assert_equal "Ticket 'ST-1231341579r871C5757B79767C21E' has already been used up.", ticket.failure_message
|
@@ -35,7 +35,7 @@ class TestClient < Test::Unit::TestCase
|
|
35
35
|
def test_validate_invalid_ticket
|
36
36
|
mock_authenticate_ticket(INVALID_TICKET)
|
37
37
|
ticket = 'ST-1231242314r72465638160B31E8D1'
|
38
|
-
service_ticket = Ticket.new(ticket, 'http://localhost:3000'
|
38
|
+
service_ticket = Ticket.new(ticket, 'http://localhost:3000')
|
39
39
|
@client.authenticate_ticket(service_ticket)
|
40
40
|
assert_equal 'INVALID_TICKET', service_ticket.failure_code
|
41
41
|
assert_equal "Ticket ST-1231242314r72465638160B31E8D1 not recognized.", service_ticket.failure_message
|
@@ -49,13 +49,24 @@ class TestClient < Test::Unit::TestCase
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def test_login_url
|
52
|
-
assert_equal 'http://localhost:4567/login?service=http
|
52
|
+
assert_equal 'http://localhost:4567/login?service=http%3A%2F%2Flocalhost%3A3000', @client.login_url
|
53
53
|
end
|
54
54
|
|
55
|
+
def test_login_url_with_extra_params
|
56
|
+
url = @client.login_url(:renew => true)
|
57
|
+
assert_equal true, (url =~ /service\=http%3A%2F%2Flocalhost%3A3000/) > 0
|
58
|
+
assert_equal true, (url =~ /renew\=true/) > 0
|
59
|
+
end
|
60
|
+
|
55
61
|
def test_logout_url
|
56
|
-
assert_equal 'http://localhost:4567/logout', @client.logout_url
|
62
|
+
assert_equal 'http://localhost:4567/logout?', @client.logout_url
|
57
63
|
end
|
58
64
|
|
65
|
+
def test_logout_url_with_extra_params
|
66
|
+
url = @client.logout_url(:url => 'http://localhost:3000')
|
67
|
+
assert_equal true, (url =~ /url\=http%3A%2F%2Flocalhost%3A3000/) > 0
|
68
|
+
end
|
69
|
+
|
59
70
|
def test_validate_url
|
60
71
|
assert_equal 'http://localhost:4567/proxyValidate', @client.validate_url
|
61
72
|
end
|
@@ -68,17 +79,41 @@ class TestCommandLineClient < Test::Unit::TestCase
|
|
68
79
|
end
|
69
80
|
|
70
81
|
def test_login
|
71
|
-
mock_get_service_ticket
|
72
|
-
|
73
|
-
assert_equal '', res.body
|
74
|
-
assert_equal '303', res.code
|
75
|
-
assert_equal 0, res['location'] =~ /^http:\/\/localhost:3000\?ticket=ST-/
|
76
|
-
assert_equal
|
82
|
+
mock_get_service_ticket(@client)
|
83
|
+
service_ticket = @client.login('admin', 'admin')
|
84
|
+
#assert_equal '', res.body
|
85
|
+
#assert_equal '303', res.code
|
86
|
+
#assert_equal 0, res['location'] =~ /^http:\/\/localhost:3000\?ticket=ST-/
|
87
|
+
assert_equal 32, service_ticket.ticket.size
|
88
|
+
assert_equal 37, @client.ticket_granting_ticket.size
|
77
89
|
end
|
78
90
|
|
91
|
+
def test_logout
|
92
|
+
mock_get_service_ticket(@client)
|
93
|
+
service_ticket = @client.login('admin', 'admin')
|
94
|
+
assert_equal 37, @client.ticket_granting_ticket.size
|
95
|
+
# if MOCK_REQUESTS
|
96
|
+
# @client.expects(:get).returns(MockResponse.new(body, '200', :location => 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E'))
|
97
|
+
# end
|
98
|
+
service_ticket = @client.logout
|
99
|
+
assert_equal nil, @client.ticket_granting_ticket
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_logout_with_follow_url
|
103
|
+
mock_get_service_ticket(@client)
|
104
|
+
service_ticket = @client.login('admin', 'admin')
|
105
|
+
assert_equal 37, @client.ticket_granting_ticket.size
|
106
|
+
# if MOCK_REQUESTS
|
107
|
+
# @client.expects(:get).returns(MockResponse.new(body, '200', :location => 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E'))
|
108
|
+
# end
|
109
|
+
service_ticket = @client.logout('follow_url')
|
110
|
+
assert_equal nil, @client.ticket_granting_ticket
|
111
|
+
# TODO check for follow_url
|
112
|
+
end
|
113
|
+
|
79
114
|
def test_get_service_ticket
|
80
|
-
mock_get_service_ticket
|
81
|
-
ticket = @client.
|
115
|
+
mock_get_service_ticket(@client)
|
116
|
+
ticket = @client.login('admin', 'admin')
|
82
117
|
assert_equal 0, ticket.ticket =~ /^ST-/
|
83
118
|
assert_equal 32, ticket.ticket.size
|
84
119
|
end
|
data/test/test_helper.rb
CHANGED
@@ -12,22 +12,22 @@ class Test::Unit::TestCase
|
|
12
12
|
|
13
13
|
def mock_authenticate_ticket(body)
|
14
14
|
if MOCK_REQUESTS
|
15
|
-
|
15
|
+
Client.any_instance.expects(:get).returns(MockResponse.new(body, '200', :location => 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E'))
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def mock_get_service_ticket
|
19
|
+
def mock_get_service_ticket(client=Client.any_instance)
|
20
20
|
if MOCK_REQUESTS
|
21
|
-
|
21
|
+
client.expects(:post).returns(MockResponse.new('', '303', :location => 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E', :'set-cookie' => 'tgt=TGC-1232569033r763536CC6753E6F357'))
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def get_service_ticket
|
26
26
|
cli = CommandLineClient.new(:cas_server_url => "http://localhost:4567", :service_url => "http://localhost:3000")
|
27
27
|
if MOCK_REQUESTS
|
28
|
-
cli.expects(:post).returns(MockResponse.new('', '303', :location => 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E'))
|
28
|
+
cli.expects(:post).returns(MockResponse.new('', '303', {:location => 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E', :'set-cookie' => 'tgt=TGC-1232569033r763536CC6753E6F357'}))
|
29
29
|
end
|
30
|
-
cli.
|
30
|
+
cli.login('admin', 'admin')
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
data/test/test_rails_filter.rb
CHANGED
@@ -1,73 +1,80 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
2
|
-
|
2
|
+
|
3
3
|
class TestRailsFilter < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
|
6
|
-
|
5
|
+
Casablanca::RailsFilter.config do |config|
|
6
|
+
config[:cas_server_url] = "http://localhost:4567"
|
7
|
+
config[:service_url] = "http://localhost:3000"
|
8
|
+
end
|
7
9
|
@controller = Controller.new
|
8
10
|
@controller.params = {}
|
9
11
|
end
|
10
12
|
|
11
13
|
def test_login_url
|
12
|
-
assert_equal 'http://localhost:4567/login?service=http
|
14
|
+
assert_equal 'http://localhost:4567/login?service=http%3A%2F%2Flocalhost%3A3000', RailsFilter.login_url
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_login_url_with_params
|
18
|
+
url = RailsFilter.login_url(:renew => true)
|
19
|
+
assert_equal true, (url =~ /service\=http%3A%2F%2Flocalhost%3A3000/) > 0
|
20
|
+
assert_equal true, (url =~ /renew\=true/) > 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_logout_url
|
24
|
+
assert_equal 'http://localhost:4567/logout?', RailsFilter.logout_url
|
13
25
|
end
|
14
26
|
|
27
|
+
def test_logout
|
28
|
+
@controller.session = { :cas_user => 'admin' }
|
29
|
+
RailsFilter.logout(@controller)
|
30
|
+
assert_equal({:cas_user=>nil }, @controller.session)
|
31
|
+
end
|
32
|
+
|
15
33
|
def test_config
|
16
34
|
Casablanca::RailsFilter.config do |config|
|
17
35
|
config[:cas_server_url] = "http://example.com/cas_server"
|
18
36
|
config[:service_url] = "http://example.com/application"
|
19
37
|
end
|
20
|
-
assert_equal "http://example.com/cas_server", RailsFilter.client.cas_server_url
|
21
|
-
assert_equal "http://example.com/application", RailsFilter.client.service_url
|
22
|
-
|
23
|
-
# def test_filter_requires_config
|
24
|
-
# RailsFilter.config = nil
|
25
|
-
# assert_raises(RuntimeError) do
|
26
|
-
# RailsFilter.filter(Controller.new)
|
27
|
-
# end
|
28
|
-
# end
|
29
|
-
|
30
|
-
def test_logout
|
31
|
-
RailsFilter.logout(@controller)
|
32
|
-
assert_equal({}, @controller.session)
|
38
|
+
# assert_equal "http://example.com/cas_server", RailsFilter.client.cas_server_url
|
39
|
+
# assert_equal "http://example.com/application", RailsFilter.client.service_url
|
40
|
+
assert_equal 'http://example.com/cas_server/login?service=http%3A%2F%2Fexample.com%2Fapplication', RailsFilter.login_url
|
33
41
|
end
|
34
42
|
|
35
43
|
def test_filter_invalid_attempt
|
36
|
-
|
37
|
-
|
44
|
+
service_ticket = get_service_ticket
|
45
|
+
params = {:ticket => 'service_ticket.ticket'}
|
46
|
+
mock_authenticate_ticket(INVALID_REQUEST)
|
47
|
+
@controller.params = params
|
38
48
|
assert_equal false, RailsFilter.filter(@controller)
|
39
49
|
end
|
40
50
|
|
41
|
-
def
|
51
|
+
def test_filter_authenticated_with_valid_ticket_from_request
|
42
52
|
service_ticket = get_service_ticket
|
43
53
|
params = {:ticket => service_ticket.ticket}
|
44
54
|
mock_authenticate_ticket(VALID_REQUEST)
|
45
55
|
@controller.params = params
|
46
56
|
assert_equal true, RailsFilter.filter(@controller)
|
47
|
-
|
57
|
+
assert_equal 'admin', @controller.session[:cas_user]
|
48
58
|
end
|
49
59
|
|
50
|
-
def
|
51
|
-
|
52
|
-
@controller.session = {
|
53
|
-
|
60
|
+
def test_filter_already_authenticated_with_valid_ticket_from_session
|
61
|
+
service_ticket = get_service_ticket
|
62
|
+
@controller.session = {:cas_user => 'admin'}
|
63
|
+
mock_authenticate_ticket(VALID_REQUEST)
|
54
64
|
assert_equal true, RailsFilter.filter(@controller)
|
55
|
-
|
65
|
+
assert_equal 'admin', @controller.session[:cas_user]
|
56
66
|
end
|
57
67
|
|
58
|
-
|
59
|
-
mock_authenticate_ticket(INVALID_TICKET)
|
60
|
-
@controller.session[:cas_ticket] = { :ticket => 'a', :service_url => 'b' }
|
61
|
-
@controller.params = {:renew => true }
|
62
|
-
assert_equal false, RailsFilter.filter(@controller)
|
63
|
-
assert_session(nil, nil)
|
64
|
-
end
|
68
|
+
end
|
65
69
|
|
66
|
-
|
67
|
-
|
68
|
-
|
70
|
+
module ActionController
|
71
|
+
module Base
|
72
|
+
def self.logger
|
73
|
+
@logger = ::Logger.new($stderr)
|
74
|
+
@logger.level = ::Logger::ERROR
|
75
|
+
@logger
|
76
|
+
end
|
69
77
|
end
|
70
|
-
|
71
78
|
end
|
72
79
|
|
73
80
|
class Controller # < ActionController::Base
|
data/test/test_ticket.rb
CHANGED
@@ -23,7 +23,6 @@ class TestTicket < Test::Unit::TestCase
|
|
23
23
|
def test_from_hash
|
24
24
|
props = {:ticket => 'ticket',
|
25
25
|
:service_url => "http://localhost:3000",
|
26
|
-
:renew => 1,
|
27
26
|
:user => 'admin' }
|
28
27
|
ticket = Ticket.from_hash(props)
|
29
28
|
assert_equal props, ticket.to_hash
|
@@ -36,34 +35,31 @@ class TestTicket < Test::Unit::TestCase
|
|
36
35
|
assert_equal(expected, ticket.to_request_params)
|
37
36
|
end
|
38
37
|
|
39
|
-
def test_to_request_params_with_renew
|
40
|
-
ticket = Ticket.new('ticket', 'http://localhost:3000', true)
|
41
|
-
expected = {:ticket => 'ticket',
|
42
|
-
:service => "http://localhost:3000",
|
43
|
-
:renew => 1 }
|
44
|
-
assert_equal(expected, ticket.to_request_params)
|
45
|
-
end
|
46
|
-
|
47
38
|
def test_authenticate_valid_ticket
|
48
|
-
@ticket.
|
39
|
+
@ticket.body = VALID_REQUEST
|
40
|
+
@ticket.authenticate
|
49
41
|
assert_equal 'admin', @ticket.user
|
50
42
|
end
|
51
43
|
|
52
44
|
def test_authenticate_invalid_request_resets_ticket_to_unauthenticated
|
53
|
-
@ticket.
|
45
|
+
@ticket.body = VALID_REQUEST
|
46
|
+
@ticket.authenticate
|
54
47
|
assert_equal true, @ticket.authenticated?
|
55
|
-
@ticket.
|
48
|
+
@ticket.body = INVALID_REQUEST
|
49
|
+
@ticket.authenticate
|
56
50
|
assert_equal false, @ticket.authenticated?
|
57
51
|
end
|
58
52
|
|
59
53
|
def test_authenticate_invalid_request
|
60
|
-
@ticket.
|
54
|
+
@ticket.body = INVALID_REQUEST
|
55
|
+
@ticket.authenticate
|
61
56
|
assert_equal 'INVALID_REQUEST', @ticket.failure_code
|
62
57
|
assert_equal 'Ticket or service parameter was missing in the request.', @ticket.failure_message
|
63
58
|
end
|
64
59
|
|
65
60
|
def test_authenticate_invalid_ticket
|
66
|
-
@ticket.
|
61
|
+
@ticket.body = INVALID_TICKET
|
62
|
+
@ticket.authenticate
|
67
63
|
assert_equal 'INVALID_TICKET', @ticket.failure_code
|
68
64
|
assert_equal 'Ticket ST-1231242314r72465638160B31E8D1 not recognized.', @ticket.failure_message
|
69
65
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: casablanca
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- FIX
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-01-
|
12
|
+
date: 2009-01-24 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,9 +20,9 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 1.8.
|
23
|
+
version: 1.8.3
|
24
24
|
version:
|
25
|
-
description:
|
25
|
+
description: Casablanca is a single sign-on client for the CAS 2.0 protocol.
|
26
26
|
email:
|
27
27
|
- FIX@example.com
|
28
28
|
executables:
|
@@ -32,10 +32,11 @@ extensions: []
|
|
32
32
|
extra_rdoc_files:
|
33
33
|
- History.txt
|
34
34
|
- Manifest.txt
|
35
|
+
- README.txt
|
35
36
|
files:
|
36
37
|
- History.txt
|
37
38
|
- Manifest.txt
|
38
|
-
- README.
|
39
|
+
- README.txt
|
39
40
|
- Rakefile
|
40
41
|
- init.rb
|
41
42
|
- bin/casablanca
|
@@ -75,7 +76,7 @@ rubyforge_project: casablanca
|
|
75
76
|
rubygems_version: 1.2.0
|
76
77
|
signing_key:
|
77
78
|
specification_version: 2
|
78
|
-
summary:
|
79
|
+
summary: Casablanca is a single sign-on client for the CAS 2.0 protocol.
|
79
80
|
test_files:
|
80
81
|
- test/test_client.rb
|
81
82
|
- test/test_helper.rb
|