p8-casablanca 0.0.1

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