p8-casablanca 0.0.1

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 ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2009-01-07
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,17 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.textile
4
+ Rakefile
5
+ init.rb
6
+ bin/casablanca
7
+ lib/casablanca.rb
8
+ lib/casablanca/cli.rb
9
+ lib/casablanca/client.rb
10
+ lib/casablanca/filters/rails.rb
11
+ lib/casablanca/response_parsers.rb
12
+ lib/casablanca/version.rb
13
+ test/test_client.rb
14
+ test/test_helper.rb
15
+ test/test_parser.rb
16
+ test/test_rails_filter.rb
17
+ test/test_ticket.rb
data/README.textile ADDED
@@ -0,0 +1,79 @@
1
+ h1. Casablanca
2
+
3
+ h2. Description
4
+
5
+ A single sign-on client based on the CAS 2.0 protocol.
6
+ Has a filter for Rails so it can be used as a Rails plugin.
7
+
8
+ sudo gem install p8-casablanca
9
+
10
+ h2. TODO
11
+
12
+ * Add flag to turn on/off mock request
13
+ * Add extra attributes
14
+ * Implement gateway and proxy
15
+ * Check for single signout
16
+ * Check for endless redirects
17
+
18
+ h2. Usage
19
+
20
+ In IRB:
21
+
22
+ require 'casablanca'
23
+
24
+ C = Casablanca::CommandLineClient.new({ :cas_server_url => "http://localhost:4567",
25
+ :service_url => "http://localhost:3000" })
26
+
27
+ ticket = C.get_service_ticket('admin', 'admin')
28
+ C.authenticate_ticket(ticket)
29
+
30
+
31
+ In a Rails project:
32
+ - environment.rb:
33
+
34
+ Casablanca::RailsFilter.client = Casablanca::Client.new(:cas_server_url => "http://localhost:4567", :service_url => "http://localhost:3000")
35
+
36
+ - Add the following to application.rb:
37
+
38
+ before_filter Casablanca::RailsFilter
39
+
40
+ def current_person
41
+ @current_person ||= login_from_cas unless @current_person == false
42
+ end
43
+
44
+ def login_from_cas
45
+ if session[:cas_user]
46
+ person = Person.find_by_name(session[:cas_user])
47
+ logout_killing_session! unless person
48
+ person
49
+ end
50
+ end
51
+
52
+ - Add the following to you logout action
53
+
54
+ Casablanca::RailsFilter.logout(self)
55
+
56
+ h2. LICENSE:
57
+
58
+ (The MIT License)
59
+
60
+ Copyright (c) 2009 Petrik de Heus
61
+
62
+ Permission is hereby granted, free of charge, to any person obtaining
63
+ a copy of this software and associated documentation files (the
64
+ 'Software'), to deal in the Software without restriction, including
65
+ without limitation the rights to use, copy, modify, merge, publish,
66
+ distribute, sublicense, and/or sell copies of the Software, and to
67
+ permit persons to whom the Software is furnished to do so, subject to
68
+ the following conditions:
69
+
70
+ The above copyright notice and this permission notice shall be
71
+ included in all copies or substantial portions of the Software.
72
+
73
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
74
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
75
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
76
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
77
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
78
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
79
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require 'lib/casablanca/version'
6
+
7
+ Hoe.new('casablanca', Casablanca::VERSION) do |p|
8
+ p.developer('FIX', 'FIX@example.com')
9
+ end
10
+
11
+ require 'metric_fu'
12
+
13
+ MetricFu::Configuration.run do |config|
14
+ config.coverage = { :test_files => ['test/**/test_*.rb'] }
15
+ end
data/bin/casablanca ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ irb = RUBY_PLATFORM =~ /mswin32/ ? 'irb.bat' : 'irb'
3
+ options = { :sandbox => false, :irb => irb }
4
+
5
+ libs = " -r irb/completion"
6
+ libs << " -r #{File.dirname(__FILE__)}/../lib/casablanca/client.rb"
7
+ libs << " -r #{File.dirname(__FILE__)}/../lib/casablanca/cli.rb"
8
+ libs << " -r #{File.dirname(__FILE__)}/../lib/casablanca/response_parsers.rb"
9
+
10
+ exec "#{options[:irb]} #{libs} --simple-prompt"
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ $: << File.expand_path(File.dirname(__FILE__))+'/lib'
2
+ require 'casablanca'
3
+ require 'casablanca/filters/rails'
data/lib/casablanca.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'casablanca/version'
2
+ require 'casablanca/client'
3
+ require 'casablanca/response_parsers'
@@ -0,0 +1,19 @@
1
+ config = { :cas_server_url => "http://localhost:4567", :service_url => "http://localhost:3000" }
2
+ INFO = %(
3
+ =====================================================
4
+ CASABLANCA CLIENT CONSOLE
5
+
6
+ Use C for a configured client (#{config.inspect})
7
+ Example:
8
+
9
+ t = C.get_service_ticket('admin', 'admin')
10
+ C.authenticate_ticket(t)
11
+
12
+ C.cas_server_url = "http://example.com/cas_server"
13
+ C.service_url = "http://example.com/application"
14
+
15
+ )
16
+
17
+ C = @client = Casablanca::CommandLineClient.new(config)
18
+
19
+ puts INFO
@@ -0,0 +1,162 @@
1
+ require 'uri'
2
+ require 'cgi'
3
+ require 'net/https'
4
+ require 'rexml/document'
5
+
6
+ module Casablanca
7
+
8
+ class Client
9
+ attr_reader :service_url
10
+ def initialize(config)
11
+ raise ":cas_server_url is required" unless config[:cas_server_url]
12
+ @cas_server_url = config[:cas_server_url]
13
+ @service_url = config[:service_url]
14
+ end
15
+
16
+ def authenticate_ticket(ticket)
17
+ response = request_validation(ticket)
18
+ ticket.authenticate(response)
19
+ end
20
+
21
+ def login_url
22
+ url = "#{@cas_server_url}/login?service=#{@service_url}"
23
+ end
24
+
25
+ def logout_url
26
+ "#{@cas_server_url}/logout"
27
+ end
28
+
29
+ def validate_url
30
+ "#{@cas_server_url}/proxyValidate"
31
+ end
32
+
33
+ private
34
+
35
+ def request_validation(ticket)
36
+ raise "ticket.service_url cannot be empty" if ticket.service_url.nil? || ticket.service_url.strip == ""
37
+ uri = URI.parse(validate_url)
38
+ uri.merge_query(ticket.to_request_params)
39
+ response = get(uri)
40
+ puts "#{@cas_server_url} #{response.inspect}:\n#{response.body}"
41
+ unless response.kind_of?(Net::HTTPSuccess)
42
+ raise ResponseError, "#{response.code}, #{response.body}"
43
+ end
44
+ response.body
45
+ end
46
+
47
+ def get(uri)
48
+ https(uri) do |h|
49
+ h.get("#{uri.path}?#{uri.query}")
50
+ end
51
+ end
52
+
53
+ def https(uri)
54
+ https = Net::HTTP.new(uri.host, uri.port)
55
+ https.use_ssl = (uri.scheme == 'https')
56
+ begin
57
+ https.start do |h|
58
+ yield(h)
59
+ end
60
+ rescue Errno::ECONNREFUSED => error
61
+ raise CasServerException
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ class CommandLineClient < Client
68
+ attr_accessor :cas_server_url, :service_url
69
+ def login(username, password)
70
+ post(URI.parse(login_url), {:username => username, :password => password, :service => service_url})
71
+ end
72
+
73
+ def get_service_ticket(username, password)
74
+ location = login(username, password)['location']
75
+ query = {}
76
+ URI.parse(location).query.collect{|q| k,v = q.split('='); query[k] = v }
77
+ Ticket.new(query['ticket'], @service_url)
78
+ end
79
+
80
+ private
81
+
82
+ def post(uri, form_data)
83
+ req = Net::HTTP::Post.new(uri.path)
84
+ req.set_form_data(form_data, ';')
85
+ https(uri) do |h|
86
+ h.request(req)
87
+ end
88
+ end
89
+ end
90
+
91
+ class Ticket
92
+ attr_accessor :user, :failure_code, :failure_message
93
+ attr_reader :service_url
94
+
95
+ def initialize(ticket, service_url, renew = false)
96
+ @service_url = service_url
97
+ @ticket = ticket
98
+ @renew = renew
99
+ end
100
+
101
+ def self.from_hash(hash)
102
+ ticket = Ticket.new(hash[:ticket], hash[:service_url], hash[:renew])
103
+ ticket.user = hash[:user]
104
+ ticket
105
+ end
106
+
107
+ def to_request_params
108
+ params = {:service => @service_url,
109
+ :ticket => @ticket }
110
+ params[:renew] = 1 if @renew
111
+ params
112
+ end
113
+
114
+ def to_hash
115
+ props = {}
116
+ props[:user] = @user if authenticated?
117
+ props[:renew] = @renew if @renew
118
+ props[:service_url] = @service_url
119
+ props[:ticket] = @ticket
120
+ props
121
+ end
122
+
123
+ def authenticated?
124
+ !!@user
125
+ end
126
+
127
+ def authenticate(body)
128
+ response = CasResponseParser.parse(self, body)
129
+ authenticated?
130
+ end
131
+ end
132
+
133
+ class ResponseError < Exception
134
+ end
135
+
136
+ class CasServerException < Exception
137
+ end
138
+
139
+ class UnknownTicketType < Exception
140
+ end
141
+ end
142
+
143
+ class URI::HTTP
144
+ def merge_query(hash)
145
+ q = query ? query + '&' : ''
146
+ self.query = "#{q}#{hash_to_uri_array(hash)}"
147
+ end
148
+
149
+ def hash_to_uri_array(hash)
150
+ hash.collect do |name, value|
151
+ if value.kind_of? Array
152
+ value.map {|v| stringify_param(name, v) }
153
+ else
154
+ stringify_param(name, value)
155
+ end
156
+ end.join('&')
157
+ end
158
+
159
+ def stringify_param(name, value)
160
+ "#{CGI::escape(name.to_s)}=#{CGI::escape(value.to_s)}"
161
+ end
162
+ end
@@ -0,0 +1,48 @@
1
+ module Casablanca
2
+ class RailsFilter
3
+ @@client = nil
4
+
5
+ class << self
6
+
7
+ def client=client
8
+ @@client = client
9
+ end
10
+
11
+ def filter(controller)
12
+ return true if previous_ticket(controller) && !controller.params[:renew]
13
+ ticket = Ticket.new(controller.params[:ticket], @@client.service_url, controller.params[:renew])
14
+ if @@client.authenticate_ticket(ticket)
15
+ puts "Ticket authenticated #{ticket.failure_message}"
16
+ controller.session[:cas_user] = ticket.user
17
+ controller.session[:cas_ticket] = ticket.to_hash
18
+ return true
19
+ else
20
+ puts "Ticket authentication failed: #{ticket.failure_message}"
21
+ controller.session[:cas_user] = nil
22
+ controller.session[:cas_ticket] = nil
23
+ controller.send(:redirect_to, login_url)
24
+ return false
25
+ end
26
+ end
27
+
28
+ def login_url
29
+ @@client.login_url
30
+ end
31
+
32
+ def logout(controller)
33
+ controller.send(:reset_session)
34
+ controller.send(:redirect_to, @@client.logout_url)
35
+ end
36
+
37
+ private
38
+
39
+ def previous_ticket(controller)
40
+ hash = controller.session[:cas_ticket]
41
+ return nil unless hash
42
+ Ticket.from_hash(hash)
43
+ end
44
+
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,50 @@
1
+ module Casablanca
2
+
3
+ class CasResponseParser
4
+ def protocol
5
+ self.class.to_s.gsub(/(Casablanca::Cas_|_ResponseParser)/, '').gsub('_', '.').to_f
6
+ end
7
+
8
+ def self.parse(ticket, body)
9
+ raise ResponseError, "Response body is empty" if body.nil? || body.strip == ""
10
+ #return Cas_1_0_Parser.new(body) if ?
11
+ response = Cas_2_0_ResponseParser.new(body)
12
+ ticket.user = response.user
13
+ unless response.authenticated?
14
+ ticket.failure_code = response.failure_code
15
+ ticket.failure_message = response.failure_message
16
+ end
17
+ end
18
+ end
19
+
20
+ class Cas_2_0_ResponseParser < CasResponseParser
21
+ def initialize(xml)
22
+ doc = REXML::Document.new(xml)
23
+ @xml = doc.elements['cas:serviceResponse'].elements[1]
24
+ end
25
+
26
+ def user
27
+ strip_text(@xml.elements['cas:user'])
28
+ end
29
+
30
+ def authenticated?
31
+ @xml.name == 'authenticationSuccess'
32
+ end
33
+
34
+ def failure_code
35
+ @xml.elements['//cas:authenticationFailure'].attributes['code']
36
+ end
37
+
38
+ def failure_message
39
+ strip_text(@xml.elements['//cas:authenticationFailure'])
40
+ end
41
+
42
+ private
43
+
44
+ def strip_text(tag)
45
+ tag.text.strip if tag
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,3 @@
1
+ module Casablanca
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,96 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper.rb')
2
+
3
+ class TestClient < Test::Unit::TestCase
4
+ def setup
5
+ @client = Client.new(:cas_server_url => "http://localhost:4567", :service_url => "http://localhost:3000")
6
+ end
7
+
8
+ def test_config
9
+ assert_equal @client.service_url, "http://localhost:3000"
10
+ end
11
+
12
+ def test_config_requires_cas_server_url
13
+ assert_raises(RuntimeError) do
14
+ @client = Client.new({})
15
+ end
16
+ end
17
+
18
+ def test_authenticate_ticket
19
+ cli = CommandLineClient.new(:cas_server_url => "http://localhost:4567", :service_url => "http://localhost:3000")
20
+ ticket = cli.login_ticket('admin', 'admin') #'ST-1231341579r871C5757B79767C21E'
21
+ service_ticket = Ticket.new(ticket, 'http://localhost:3000', true)
22
+ @client.authenticate_ticket(service_ticket)
23
+ assert_equal 'admin', service_ticket.user
24
+ end
25
+
26
+ def test_validate_expired_ticket
27
+ ticket = 'ST-1231341579r871C5757B79767C21E'
28
+ service_ticket = Ticket.new(ticket, 'http://localhost:3000', true)
29
+ @client.authenticate_ticket(service_ticket)
30
+ assert_equal 'INVALID_TICKET', service_ticket.failure_code
31
+ #assert_equal "Ticket 'ST-1231341579r871C5757B79767C21E' has already been used up.", ticket.failure_message
32
+ end
33
+
34
+ def test_validate_invalid_ticket
35
+ ticket = '1231341579r871C5757B79767C21E'
36
+ service_ticket = Ticket.new(ticket, 'http://localhost:3000', true)
37
+ @client.authenticate_ticket(service_ticket)
38
+ assert_equal 'INVALID_TICKET', service_ticket.failure_code
39
+ assert_equal "Ticket 1231341579r871C5757B79767C21E not recognized.", service_ticket.failure_message
40
+ end
41
+
42
+ def test_authenticate_ticket_with_empty_service_url
43
+ service_ticket = Ticket.new('ticket', nil)
44
+ assert_raises(RuntimeError) do
45
+ @client.authenticate_ticket(service_ticket)
46
+ end
47
+ end
48
+
49
+ def test_login_url
50
+ assert_equal 'http://localhost:4567/login?service=http://localhost:3000', @client.login_url
51
+ end
52
+
53
+ def test_logout_url
54
+ assert_equal 'http://localhost:4567/logout', @client.logout_url
55
+ end
56
+
57
+ def test_validate_url
58
+ assert_equal 'http://localhost:4567/proxyValidate', @client.validate_url
59
+ end
60
+
61
+ end
62
+
63
+ class TestCommandLineClient < Test::Unit::TestCase
64
+ def setup
65
+ @client = CommandLineClient.new(:cas_server_url => "http://localhost:4567", :service_url => "http://localhost:3000")
66
+ end
67
+
68
+ def test_login
69
+ @client.expects(:post).returns(MockResponse.new('', '303', :location => 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E'))
70
+ res = @client.login('admin', 'admin')
71
+ assert_equal '', res.body
72
+ assert_equal '303', res.code
73
+ assert_equal 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E', res['location']
74
+ end
75
+
76
+ def test_get_service_ticket
77
+ @client.expects(:post).returns(MockResponse.new('', '303', :location => 'http://localhost:3000?ticket=ST-1231341579r871C5757B79767C21E'))
78
+ ticket = @client.get_login_ticket('admin', 'admin')
79
+ assert_equal 'ST-1231341579r871C5757B79767C21E', ticket
80
+ end
81
+
82
+ end
83
+
84
+ class TestURIHTTP < Test::Unit::TestCase
85
+ def test_merge_query
86
+ uri = URI.parse('http://localhost:4567/login')
87
+ uri.merge_query({:order_by => ['1', '2']})
88
+ assert_equal 'order_by=1&order_by=2', uri.query
89
+ end
90
+
91
+ def test_merge_query_with_existing_query
92
+ uri = URI.parse('http://localhost:4567/login?search=ah')
93
+ uri.merge_query({:order_by => ['1', '2']})
94
+ assert_equal 'search=ah&order_by=1&order_by=2', uri.query
95
+ end
96
+ end
@@ -0,0 +1,54 @@
1
+ require(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'casablanca.rb')))
2
+ require(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'casablanca', 'filters', 'rails.rb')))
3
+ require 'test/unit'
4
+ require 'rubygems'
5
+ require 'mocha'
6
+
7
+ class Test::Unit::TestCase
8
+ include Casablanca
9
+ end
10
+
11
+ class MockResponse < Net::HTTPResponse
12
+ attr_accessor :body, :code
13
+ def initialize(body, code=200, header={})
14
+ @body, @code, @header = body, code, header
15
+ end
16
+
17
+ def []= key, value
18
+ @header[key.to_sym] = value
19
+ end
20
+
21
+ def [] key
22
+ @header[key.to_sym]
23
+ end
24
+
25
+ def kind_of?(klass)
26
+ if klass == Net::HTTPSuccess
27
+ code.to_i == 200
28
+ end
29
+ end
30
+ end
31
+
32
+ VALID_REQUEST = %(
33
+ <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
34
+ <cas:authenticationSuccess>
35
+ <cas:user>admin</cas:user>
36
+ </cas:authenticationSuccess>
37
+ </cas:serviceResponse>
38
+ )
39
+
40
+ INVALID_REQUEST = %(
41
+ <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
42
+ <cas:authenticationFailure code="INVALID_REQUEST">
43
+ Ticket or service parameter was missing in the request.
44
+ </cas:authenticationFailure>
45
+ </cas:serviceResponse>
46
+ )
47
+
48
+ INVALID_TICKET = %(
49
+ <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
50
+ <cas:authenticationFailure code="INVALID_TICKET">
51
+ Ticket ST-1231242314r72465638160B31E8D1 not recognized.
52
+ </cas:authenticationFailure>
53
+ </cas:serviceResponse>
54
+ )
@@ -0,0 +1,22 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper.rb')
2
+
3
+ class TestCas_2_0_ResponseParser < Test::Unit::TestCase
4
+ def test_parse_valid_ticket
5
+ response = Cas_2_0_ResponseParser.new(VALID_REQUEST)
6
+ assert_equal 'admin', response.user
7
+ assert_equal 2.0, response.protocol
8
+ end
9
+
10
+ def test_parse_invalid_request
11
+ response = Cas_2_0_ResponseParser.new(INVALID_REQUEST)
12
+ assert_equal 'INVALID_REQUEST', response.failure_code
13
+ assert_equal 'Ticket or service parameter was missing in the request.', response.failure_message
14
+ end
15
+
16
+ def test_parse_invalid_ticket
17
+ response = Cas_2_0_ResponseParser.new(INVALID_TICKET)
18
+ assert_equal 'INVALID_TICKET', response.failure_code
19
+ assert_equal 'Ticket ST-1231242314r72465638160B31E8D1 not recognized.', response.failure_message
20
+ end
21
+
22
+ end
@@ -0,0 +1,92 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper.rb')
2
+ require 'action_pack'
3
+ class TestRailsFilter < Test::Unit::TestCase
4
+ def setup
5
+ @client = Client.new(:cas_server_url => "http://localhost:4567", :service_url => "http://localhost:3000")
6
+ RailsFilter.client = @client
7
+ @controller = Controller.new
8
+ @controller.params = {}
9
+ end
10
+
11
+ def test_login_url
12
+ assert_equal 'http://localhost:4567/login?service=http://localhost:3000', RailsFilter.login_url
13
+ end
14
+
15
+ # def test_filter_requires_config
16
+ # RailsFilter.config = nil
17
+ # assert_raises(RuntimeError) do
18
+ # RailsFilter.filter(Controller.new)
19
+ # end
20
+ # end
21
+
22
+ def test_logout
23
+ RailsFilter.logout(@controller)
24
+ assert_equal({}, @controller.session)
25
+ end
26
+
27
+ def test_filter_invalid_attempt
28
+ @controller.session = {}
29
+ assert_equal false, RailsFilter.filter(@controller)
30
+ end
31
+
32
+ def test_filter_authenticated
33
+ params = {:ticket => 'a'}
34
+ @client.expects(:authenticate_ticket).returns(true)
35
+ @controller.params = params
36
+ assert_equal true, RailsFilter.filter(@controller)
37
+ assert_session(nil, { :ticket => 'a', :service_url => 'http://localhost:3000' })
38
+ end
39
+
40
+ def test_filter_same_ticket
41
+ params = {:ticket => 'a'}
42
+ @controller.session = { :cas_ticket => params, :cas_user => 'admin' }
43
+ @controller.params = params
44
+ assert_equal true, RailsFilter.filter(@controller)
45
+ assert_session('admin', params)
46
+ end
47
+
48
+ def test_filter_resets_sessions_for_renew
49
+ @controller.session[:cas_ticket] = { :ticket => 'a', :service_url => 'b' }
50
+ @controller.params = {:renew => true }
51
+ assert_equal false, RailsFilter.filter(@controller)
52
+ assert_session(nil, nil)
53
+ end
54
+
55
+ def assert_session(user, ticket)
56
+ assert_equal ticket, @controller.session[:cas_ticket]
57
+ assert_equal user, @controller.session[:cas_user]
58
+ end
59
+
60
+ end
61
+
62
+ class Controller # < ActionController::Base
63
+ attr_accessor :params, :session
64
+ def initialize
65
+ @session = {}
66
+ end
67
+
68
+ def request
69
+ Request.new
70
+ end
71
+
72
+ def url_for(url)
73
+ url
74
+ end
75
+
76
+ def redirect_to(url)
77
+ end
78
+
79
+ private
80
+
81
+ def reset_session
82
+ @session = {}
83
+ end
84
+ end
85
+
86
+ class Request
87
+ def headers
88
+ {}
89
+ end
90
+ def post?
91
+ end
92
+ end
@@ -0,0 +1,71 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper.rb')
2
+
3
+ class TestTicket < Test::Unit::TestCase
4
+ def setup
5
+ @ticket = Ticket.new('ST-1231242314r72465638160B31E8D1', 'http://localhost:3000')
6
+ end
7
+
8
+ def test_create_service_ticket
9
+ ticket = Ticket.new('ST-1231242314r72465638160B31E8D1', 'http://localhost:3000')
10
+ assert_equal 'ST-1231242314r72465638160B31E8D1', ticket.to_hash[:ticket]
11
+ end
12
+
13
+ def test_create_proxy_ticket
14
+ ticket = Ticket.new('PT-1231242314r72465638160B31E8D1', 'http://localhost:3000')
15
+ assert_equal 'PT-1231242314r72465638160B31E8D1', ticket.to_hash[:ticket]
16
+ end
17
+
18
+ def test_to_hash
19
+ ticket = Ticket.new('ST-1231242314r72465638160B31E8D1', 'http://localhost:3000')
20
+ assert_equal 'ST-1231242314r72465638160B31E8D1', ticket.to_hash[:ticket]
21
+ end
22
+
23
+ def test_from_hash
24
+ props = {:ticket => 'ticket',
25
+ :service_url => "http://localhost:3000",
26
+ :renew => 1,
27
+ :user => 'admin' }
28
+ ticket = Ticket.from_hash(props)
29
+ assert_equal props, ticket.to_hash
30
+ end
31
+
32
+ def test_to_request_params
33
+ ticket = Ticket.new('ticket', 'http://localhost:3000')
34
+ expected = {:ticket => 'ticket',
35
+ :service => "http://localhost:3000" }
36
+ assert_equal(expected, ticket.to_request_params)
37
+ end
38
+
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
+ def test_authenticate_valid_ticket
48
+ @ticket.authenticate(VALID_REQUEST)
49
+ assert_equal 'admin', @ticket.user
50
+ end
51
+
52
+ def test_authenticate_invalid_request_resets_ticket_to_unauthenticated
53
+ @ticket.authenticate(VALID_REQUEST)
54
+ assert_equal true, @ticket.authenticated?
55
+ @ticket.authenticate(INVALID_REQUEST)
56
+ assert_equal false, @ticket.authenticated?
57
+ end
58
+
59
+ def test_authenticate_invalid_request
60
+ @ticket.authenticate(INVALID_REQUEST)
61
+ assert_equal 'INVALID_REQUEST', @ticket.failure_code
62
+ assert_equal 'Ticket or service parameter was missing in the request.', @ticket.failure_message
63
+ end
64
+
65
+ def test_authenticate_invalid_ticket
66
+ @ticket.authenticate(INVALID_TICKET)
67
+ assert_equal 'INVALID_TICKET', @ticket.failure_code
68
+ assert_equal 'Ticket ST-1231242314r72465638160B31E8D1 not recognized.', @ticket.failure_message
69
+ end
70
+
71
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: p8-casablanca
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Petrik de Heus
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-17 00:00:00 -08:00
13
+ default_executable: casablanca
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.8.2
23
+ version:
24
+ description:
25
+ email:
26
+ - FIX@example.com
27
+ executables:
28
+ - casablanca
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.textile
35
+ files:
36
+ - History.txt
37
+ - Manifest.txt
38
+ - Rakefile
39
+ - init.rb
40
+ - bin/casablanca
41
+ - lib/casablanca.rb
42
+ - lib/casablanca/cli.rb
43
+ - lib/casablanca/client.rb
44
+ - lib/casablanca/filters/rails.rb
45
+ - lib/casablanca/response_parsers.rb
46
+ - lib/casablanca/version.rb
47
+ - test/test_client.rb
48
+ - test/test_helper.rb
49
+ - test/test_parser.rb
50
+ - test/test_rails_filter.rb
51
+ - test/test_ticket.rb
52
+ - README.textile
53
+ has_rdoc: true
54
+ homepage:
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --main
58
+ - README.txt
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ requirements: []
74
+
75
+ rubyforge_project: casablanca
76
+ rubygems_version: 1.2.0
77
+ signing_key:
78
+ specification_version: 2
79
+ summary: A single sign-on client based on the CAS 2.0 protocol.
80
+ test_files:
81
+ - test/test_client.rb
82
+ - test/test_helper.rb
83
+ - test/test_parser.rb
84
+ - test/test_rails_filter.rb
85
+ - test/test_ticket.rb