casablanca 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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