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.
@@ -1,4 +1,11 @@
1
- === 1.0.0 / 2009-01-07
1
+ === 0.0.2 / 2009-01-07
2
+
3
+ * 1 major enhancement
4
+
5
+ * Implmented renew
6
+ * Added logger
7
+
8
+ === 0.0.2 / 2009-01-07
2
9
 
3
10
  * 1 major enhancement
4
11
 
@@ -1,6 +1,6 @@
1
1
  History.txt
2
2
  Manifest.txt
3
- README.textile
3
+ README.txt
4
4
  Rakefile
5
5
  init.rb
6
6
  bin/casablanca
@@ -1,18 +1,29 @@
1
- h1. Casablanca
1
+ = Casablanca
2
2
 
3
- h2. Description
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
- sudo gem install p8-casablanca
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
- h2. Usage
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
- h2. TODO
71
+ == INSTALL:
57
72
 
58
- * Add logging
59
- * Add extra attributes returned from the server
60
- * Implement gateway and proxy
61
- * Check for single signout
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
- h2. LICENSE:
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
- # require 'metric_fu'
12
- #
13
- # MetricFu::Configuration.run do |config|
14
- # config.coverage = { :test_files => ['test/**/test_*.rb'] }
15
- # end
12
+ require 'metric_fu'
13
+
14
+ MetricFu::Configuration.run do |config|
15
+ config.coverage = { :test_files => ['test/**/test_*.rb'] }
16
+ end
@@ -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/cli.rb"
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"
@@ -1,5 +1,5 @@
1
1
  module Casablanca
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
4
4
  require 'casablanca/client'
5
5
  require 'casablanca/response_parsers'
@@ -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.get_service_ticket('admin', 'admin')
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
- C.cas_server_url = "http://example.com/cas_server"
14
- C.service_url = "http://example.com/application"
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 = @client = Casablanca::CommandLineClient.new(config)
21
+ C = Casablanca::CommandLineClient.new(config)
22
+ C.logger.level = Logger::DEBUG
19
23
 
20
24
  puts INFO
@@ -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
- response = request_validation(ticket)
19
- ticket.authenticate(response)
22
+ request_validation(ticket)
23
+ ticket.authenticate
20
24
  end
21
25
 
22
- def login_url
23
- url = "#{@cas_server_url}/login?service=#{@service_url}"
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
- def logout_url
27
- "#{@cas_server_url}/logout"
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
- post(URI.parse(login_url), {:username => username, :password => password, :service => service_url})
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 get_service_ticket(username, password)
75
- location = login(username, password)['location']
76
- query = {}
77
- URI.parse(location).query.collect{|q| k,v = q.split('='); query[k] = v }
78
- Ticket.new(query['ticket'], @service_url)
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 = 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], hash[:renew])
176
+ ticket = Ticket.new(hash[:ticket], hash[:service_url])
104
177
  ticket.user = hash[:user]
105
178
  ticket
106
179
  end
107
180
 
108
- def to_request_params
109
- params = {:service => @service_url,
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(body)
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
- def client=client
8
- @@client = client
9
- end
10
-
11
- def client
12
- @@client
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
- @@client = Client.new(config)
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
- return true if previous_ticket(controller) && !controller.params[:renew]
23
- ticket = Ticket.new(controller.params[:ticket], @@client.service_url, controller.params[:renew])
24
- if @@client.authenticate_ticket(ticket)
25
- puts "Ticket authenticated"
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[:cas_ticket] = ticket.to_hash
39
+ controller.session[:cas_renew] = nil
28
40
  return true
29
- else
30
- puts "Ticket authentication failed: #{ticket.failure_message}"
31
- controller.session[:cas_user] = nil
32
- controller.session[:cas_ticket] = nil
33
- controller.send(:redirect_to, login_url)
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
- def login_url
39
- @@client.login_url
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.send(:reset_session)
44
- controller.send(:redirect_to, @@client.logout_url)
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 previous_ticket(controller)
50
- hash = controller.session[:cas_ticket]
51
- return nil unless hash
52
- Ticket.from_hash(hash)
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
@@ -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', true)
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', true)
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://localhost:3000', @client.login_url
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
- res = @client.login('admin', 'admin')
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 61, res['location'].size
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.get_service_ticket('admin', 'admin')
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
@@ -12,22 +12,22 @@ class Test::Unit::TestCase
12
12
 
13
13
  def mock_authenticate_ticket(body)
14
14
  if MOCK_REQUESTS
15
- @client.expects(:get).returns(MockResponse.new(body, '200', :location => 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E'))
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
- @client.expects(:post).returns(MockResponse.new('', '303', :location => 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E'))
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.get_service_ticket('admin', 'admin')
30
+ cli.login('admin', 'admin')
31
31
  end
32
32
  end
33
33
 
@@ -1,73 +1,80 @@
1
1
  require File.join(File.dirname(__FILE__), 'test_helper.rb')
2
- require 'action_pack'
2
+
3
3
  class TestRailsFilter < Test::Unit::TestCase
4
4
  def setup
5
- @client = Client.new(:cas_server_url => "http://localhost:4567", :service_url => "http://localhost:3000")
6
- RailsFilter.client = @client
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://localhost:3000', RailsFilter.login_url
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
- end
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
- mock_authenticate_ticket(INVALID_TICKET)
37
- @controller.session = {}
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 test_filter_authenticated
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
- assert_session('admin', { :ticket => service_ticket.ticket, :user => 'admin', :service_url => 'http://localhost:3000' })
57
+ assert_equal 'admin', @controller.session[:cas_user]
48
58
  end
49
59
 
50
- def test_filter_same_ticket
51
- params = {:ticket => 'a'}
52
- @controller.session = { :cas_ticket => params, :cas_user => 'admin' }
53
- @controller.params = params
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
- assert_session('admin', params)
65
+ assert_equal 'admin', @controller.session[:cas_user]
56
66
  end
57
67
 
58
- def test_filter_resets_sessions_for_renew
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
- def assert_session(user, ticket)
67
- assert_equal ticket, @controller.session[:cas_ticket]
68
- assert_equal user, @controller.session[:cas_user]
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
@@ -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.authenticate(VALID_REQUEST)
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.authenticate(VALID_REQUEST)
45
+ @ticket.body = VALID_REQUEST
46
+ @ticket.authenticate
54
47
  assert_equal true, @ticket.authenticated?
55
- @ticket.authenticate(INVALID_REQUEST)
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.authenticate(INVALID_REQUEST)
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.authenticate(INVALID_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.2
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-19 00:00:00 +01:00
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.2
23
+ version: 1.8.3
24
24
  version:
25
- description: A single sign-on client for the CAS 2.0 protocol
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.textile
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: A single sign-on client for the CAS 2.0 protocol
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