relevance-rubycas-server 0.6.99

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.
Files changed (58) hide show
  1. data/.loadpath +5 -0
  2. data/.project +17 -0
  3. data/CHANGELOG.txt +1 -0
  4. data/History.txt +223 -0
  5. data/LICENSE.txt +504 -0
  6. data/Manifest.txt +61 -0
  7. data/README.txt +25 -0
  8. data/Rakefile +60 -0
  9. data/bin/rubycas-server +26 -0
  10. data/bin/rubycas-server-ctl +22 -0
  11. data/config.example.yml +363 -0
  12. data/custom_views.example.rb +11 -0
  13. data/lib/casserver.rb +110 -0
  14. data/lib/casserver/authenticators/active_directory_ldap.rb +11 -0
  15. data/lib/casserver/authenticators/base.rb +47 -0
  16. data/lib/casserver/authenticators/ldap.rb +108 -0
  17. data/lib/casserver/authenticators/ntlm.rb +88 -0
  18. data/lib/casserver/authenticators/sql.rb +102 -0
  19. data/lib/casserver/authenticators/sql_encrypted.rb +75 -0
  20. data/lib/casserver/authenticators/test.rb +15 -0
  21. data/lib/casserver/cas.rb +307 -0
  22. data/lib/casserver/conf.rb +112 -0
  23. data/lib/casserver/controllers.rb +436 -0
  24. data/lib/casserver/environment.rb +23 -0
  25. data/lib/casserver/models.rb +218 -0
  26. data/lib/casserver/postambles.rb +174 -0
  27. data/lib/casserver/utils.rb +30 -0
  28. data/lib/casserver/version.rb +9 -0
  29. data/lib/casserver/views.rb +235 -0
  30. data/lib/rubycas-server.rb +1 -0
  31. data/lib/rubycas-server/version.rb +1 -0
  32. data/lib/themes/cas.css +121 -0
  33. data/lib/themes/notice.png +0 -0
  34. data/lib/themes/ok.png +0 -0
  35. data/lib/themes/simple/bg.png +0 -0
  36. data/lib/themes/simple/login_box_bg.png +0 -0
  37. data/lib/themes/simple/logo.png +0 -0
  38. data/lib/themes/simple/theme.css +28 -0
  39. data/lib/themes/urbacon/bg.png +0 -0
  40. data/lib/themes/urbacon/login_box_bg.png +0 -0
  41. data/lib/themes/urbacon/logo.png +0 -0
  42. data/lib/themes/urbacon/theme.css +33 -0
  43. data/lib/themes/warning.png +0 -0
  44. data/misc/basic_cas_single_signon_mechanism_diagram.png +0 -0
  45. data/misc/basic_cas_single_signon_mechanism_diagram.svg +652 -0
  46. data/resources/init.d.sh +58 -0
  47. data/setup.rb +1585 -0
  48. data/test/test_cas.rb +33 -0
  49. data/test/test_casserver.rb +125 -0
  50. data/vendor/isaac_0.9.1/LICENSE +26 -0
  51. data/vendor/isaac_0.9.1/README +78 -0
  52. data/vendor/isaac_0.9.1/TODO +3 -0
  53. data/vendor/isaac_0.9.1/VERSIONS +3 -0
  54. data/vendor/isaac_0.9.1/crypt/ISAAC.rb +171 -0
  55. data/vendor/isaac_0.9.1/isaac.gemspec +39 -0
  56. data/vendor/isaac_0.9.1/setup.rb +596 -0
  57. data/vendor/isaac_0.9.1/test/TC_ISAAC.rb +76 -0
  58. metadata +158 -0
@@ -0,0 +1,218 @@
1
+ require 'camping/db'
2
+
3
+ module CASServer::Models
4
+
5
+ module Consumable
6
+ def consume!
7
+ self.consumed = Time.now
8
+ self.save!
9
+ end
10
+ end
11
+
12
+ class Ticket < Base
13
+ def to_s
14
+ ticket
15
+ end
16
+
17
+ def self.cleanup_expired(expiry_time)
18
+ transaction do
19
+ conditions = ["created_on < ?", Time.now - expiry_time]
20
+ expired_tickets_count = count(:conditions => conditions)
21
+
22
+ $LOG.debug("Destroying #{expired_tickets_count} expired #{self.name.split('::').last}"+
23
+ "#{'s' if expired_tickets_count > 1}.") if expired_tickets_count > 0
24
+
25
+ destroy_all(conditions)
26
+ end
27
+ end
28
+ end
29
+
30
+ class LoginTicket < Ticket
31
+ set_table_name 'casserver_lt'
32
+ include Consumable
33
+ end
34
+
35
+ class ServiceTicket < Ticket
36
+ set_table_name 'casserver_st'
37
+ include Consumable
38
+
39
+ belongs_to :ticket_granting_ticket, :foreign_key => :tgt_id
40
+
41
+ def matches_service?(service)
42
+ CASServer::CAS.clean_service_url(self.service) ==
43
+ CASServer::CAS.clean_service_url(service)
44
+ end
45
+ end
46
+
47
+ class ProxyTicket < ServiceTicket
48
+ belongs_to :proxy_granting_ticket
49
+ end
50
+
51
+ class TicketGrantingTicket < Ticket
52
+ set_table_name 'casserver_tgt'
53
+
54
+ serialize :extra_attributes
55
+
56
+ has_many :service_tickets, :foreign_key => :tgt_id
57
+ end
58
+
59
+ class ProxyGrantingTicket < Ticket
60
+ set_table_name 'casserver_pgt'
61
+ belongs_to :service_ticket
62
+ has_many :proxy_tickets, :dependent => :destroy
63
+ end
64
+
65
+ class Error
66
+ attr_reader :code, :message
67
+
68
+ def initialize(code, message)
69
+ @code = code
70
+ @message = message
71
+ end
72
+
73
+ def to_s
74
+ message
75
+ end
76
+ end
77
+
78
+ class CreateCASServer < V 0.1
79
+ def self.up
80
+ if ActiveRecord::Base.connection.table_alias_length > 30
81
+ $LOG.info("Creating database with long table names...")
82
+
83
+ create_table :casserver_login_tickets, :force => true do |t|
84
+ t.column :ticket, :string, :null => false
85
+ t.column :created_on, :timestamp, :null => false
86
+ t.column :consumed, :datetime, :null => true
87
+ t.column :client_hostname, :string, :null => false
88
+ end
89
+
90
+ create_table :casserver_service_tickets, :force => true do |t|
91
+ t.column :ticket, :string, :null => false
92
+ t.column :service, :string, :null => false
93
+ t.column :created_on, :timestamp, :null => false
94
+ t.column :consumed, :datetime, :null => true
95
+ t.column :client_hostname, :string, :null => false
96
+ t.column :username, :string, :null => false
97
+ t.column :type, :string, :null => false
98
+ t.column :proxy_granting_ticket_id, :integer, :null => true
99
+ end
100
+
101
+ create_table :casserver_ticket_granting_tickets, :force => true do |t|
102
+ t.column :ticket, :string, :null => false
103
+ t.column :created_on, :timestamp, :null => false
104
+ t.column :client_hostname, :string, :null => false
105
+ t.column :username, :string, :null => false
106
+ end
107
+
108
+ create_table :casserver_proxy_granting_tickets, :force => true do |t|
109
+ t.column :ticket, :string, :null => false
110
+ t.column :created_on, :timestamp, :null => false
111
+ t.column :client_hostname, :string, :null => false
112
+ t.column :iou, :string, :null => false
113
+ t.column :service_ticket_id, :integer, :null => false
114
+ end
115
+ end
116
+ end
117
+
118
+ def self.down
119
+ if ActiveRecord::Base.connection.table_alias_length > 30
120
+ drop_table :casserver_proxy_granting_tickets
121
+ drop_table :casserver_ticket_granting_tickets
122
+ drop_table :casserver_service_tickets
123
+ drop_table :casserver_login_tickets
124
+ end
125
+ end
126
+ end
127
+
128
+ # Oracle table names cannot exceed 30 chars...
129
+ # See http://code.google.com/p/rubycas-server/issues/detail?id=15
130
+ class ShortenTableNames < V 0.5
131
+ def self.up
132
+ if ActiveRecord::Base.connection.table_alias_length > 30
133
+ $LOG.info("Shortening table names")
134
+ rename_table :casserver_login_tickets, :casserver_lt
135
+ rename_table :casserver_service_tickets, :casserver_st
136
+ rename_table :casserver_ticket_granting_tickets, :casserver_tgt
137
+ rename_table :casserver_proxy_granting_tickets, :casserver_pgt
138
+ else
139
+ create_table :casserver_lt, :force => true do |t|
140
+ t.column :ticket, :string, :null => false
141
+ t.column :created_on, :timestamp, :null => false
142
+ t.column :consumed, :datetime, :null => true
143
+ t.column :client_hostname, :string, :null => false
144
+ end
145
+
146
+ create_table :casserver_st, :force => true do |t|
147
+ t.column :ticket, :string, :null => false
148
+ t.column :service, :string, :null => false
149
+ t.column :created_on, :timestamp, :null => false
150
+ t.column :consumed, :datetime, :null => true
151
+ t.column :client_hostname, :string, :null => false
152
+ t.column :username, :string, :null => false
153
+ t.column :type, :string, :null => false
154
+ t.column :proxy_granting_ticket_id, :integer, :null => true
155
+ end
156
+
157
+ create_table :casserver_tgt, :force => true do |t|
158
+ t.column :ticket, :string, :null => false
159
+ t.column :created_on, :timestamp, :null => false
160
+ t.column :client_hostname, :string, :null => false
161
+ t.column :username, :string, :null => false
162
+ end
163
+
164
+ create_table :casserver_pgt, :force => true do |t|
165
+ t.column :ticket, :string, :null => false
166
+ t.column :created_on, :timestamp, :null => false
167
+ t.column :client_hostname, :string, :null => false
168
+ t.column :iou, :string, :null => false
169
+ t.column :service_ticket_id, :integer, :null => false
170
+ end
171
+ end
172
+ end
173
+
174
+ def self.down
175
+ if ActiveRecord::Base.connection.table_alias_length > 30
176
+ rename_table :casserver_lt, :cassserver_login_tickets
177
+ rename_table :casserver_st, :casserver_service_tickets
178
+ rename_table :casserver_tgt, :casserver_ticket_granting_tickets
179
+ rename_table :casserver_pgt, :casserver_proxy_granting_tickets
180
+ else
181
+ drop_table :casserver_pgt
182
+ drop_table :casserver_tgt
183
+ drop_table :casserver_st
184
+ drop_table :casserver_lt
185
+ end
186
+ end
187
+ end
188
+
189
+ class AddTgtToSt < V 0.7
190
+ def self.up
191
+ add_column :casserver_st, :tgt_id, :integer, :null => true
192
+ end
193
+
194
+ def self.down
195
+ remove_column :casserver_st, :tgt_id, :integer
196
+ end
197
+ end
198
+
199
+ class ChangeServiceToText < V 0.71
200
+ def self.up
201
+ change_column :casserver_st, :service, :text
202
+ end
203
+
204
+ def self.down
205
+ change_column :casserver_st, :service, :string
206
+ end
207
+ end
208
+
209
+ class AddExtraAttributes < V 0.72
210
+ def self.up
211
+ add_column :casserver_tgt, :extra_attributes, :text
212
+ end
213
+
214
+ def self.down
215
+ remove_column :casserver_tgt, :extra_attributes
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,174 @@
1
+ module CASServer
2
+ module Postambles
3
+
4
+ def webrick
5
+ require 'webrick/httpserver'
6
+ require 'webrick/https'
7
+ require 'camping/webrick'
8
+
9
+ # TODO: verify the certificate's validity
10
+ # example of how to do this is here: http://pablotron.org/download/ruri-20050331.rb
11
+
12
+ cert_path = CASServer::Conf.ssl_cert
13
+ key_path = CASServer::Conf.ssl_key || CASServer::Conf.ssl_cert
14
+ # look for the key in the ssl_cert if no ssl_key is specified
15
+
16
+ webrick_options = {:BindAddress => "0.0.0.0", :Port => CASServer::Conf.port}
17
+
18
+ unless cert_path.nil? && key_path.nil?
19
+ raise "'#{cert_path}' is not a valid ssl certificate. Your 'ssl_cert' configuration" +
20
+ " setting must be a path to a valid ssl certificate file." unless
21
+ File.exists? cert_path
22
+
23
+ raise "'#{key_path}' is not a valid ssl private key. Your 'ssl_key' configuration" +
24
+ " setting must be a path to a valid ssl private key file." unless
25
+ File.exists? key_path
26
+
27
+ cert = OpenSSL::X509::Certificate.new(File.read(cert_path))
28
+ key = OpenSSL::PKey::RSA.new(File.read(key_path))
29
+
30
+ webrick_options[:SSLEnable] = true
31
+ webrick_options[:SSLVerifyClient] = ::OpenSSL::SSL::VERIFY_NONE
32
+ webrick_options[:SSLCertificate] = cert
33
+ webrick_options[:SSLPrivateKey] = key
34
+ end
35
+
36
+ begin
37
+ s = WEBrick::HTTPServer.new(webrick_options)
38
+ rescue Errno::EACCES
39
+ puts "\nThe server could not launch. Are you running on a privileged port? (e.g. port 443) If so, you must run the server as root."
40
+ exit 2
41
+ end
42
+
43
+ CASServer.create
44
+ s.mount "#{CASServer::Conf.uri_path}", WEBrick::CampingHandler, CASServer
45
+
46
+ puts "\n** CASServer is running at http#{webrick_options[:SSLEnable] ? 's' : ''}://#{Socket.gethostname}:#{CASServer::Conf.port}#{CASServer::Conf.uri_path} and logging to '#{CASServer::Conf.log[:file]}'\n\n"
47
+
48
+ # This lets Ctrl+C shut down your server
49
+ trap(:INT) do
50
+ s.shutdown
51
+ end
52
+ trap(:TERM) do
53
+ s.shutdown
54
+ end
55
+
56
+ if $DAEMONIZE
57
+ WEBrick::Daemon.start do
58
+ write_pid_file if $PID_FILE
59
+ s.start
60
+ clear_pid_file
61
+ end
62
+ else
63
+ s.start
64
+ end
65
+ end
66
+
67
+
68
+
69
+ def mongrel
70
+ require 'rubygems'
71
+ require 'mongrel/camping'
72
+
73
+ if $DAEMONIZE
74
+ # check if log and pid are writable before daemonizing, otherwise we won't be able to notify
75
+ # the user if we run into trouble later (since once daemonized, we can't write to stdout/stderr)
76
+ check_pid_writable if $PID_FILE
77
+ check_log_writable
78
+ end
79
+
80
+ CASServer.create
81
+
82
+ puts "\n** CASServer is starting. Look in '#{CASServer::Conf.log[:file]}' for further notices."
83
+
84
+ settings = {:host => "0.0.0.0", :log_file => CASServer::Conf.log[:file], :cwd => $CASSERVER_HOME}
85
+
86
+ # need to close all IOs before daemonizing
87
+ $LOG.close if $DAEMONIZE
88
+
89
+ begin
90
+ config = Mongrel::Configurator.new settings do
91
+ daemonize :log_file => CASServer::Conf.log[:file], :cwd => $CASSERVER_HOME if $DAEMONIZE
92
+
93
+ listener :port => CASServer::Conf.port do
94
+ uri CASServer::Conf.uri_path, :handler => Mongrel::Camping::CampingHandler.new(CASServer)
95
+ setup_signals
96
+ end
97
+ end
98
+ rescue Errno::EADDRINUSE
99
+ exit 1
100
+ end
101
+
102
+ config.run
103
+
104
+ CASServer.init_logger
105
+ CASServer.init_db_logger
106
+
107
+ if $DAEMONIZE && $PID_FILE
108
+ write_pid_file
109
+ unless File.exists? $PID_FILE
110
+ $LOG.error "CASServer could not start because pid file '#{$PID_FILE}' could not be created."
111
+ exit 1
112
+ end
113
+ end
114
+
115
+ puts "\n** CASServer is running at http://localhost:#{CASServer::Conf.port}#{CASServer::Conf.uri_path} and logging to '#{CASServer::Conf.log[:file]}'"
116
+ config.join
117
+
118
+ clear_pid_file
119
+
120
+ puts "\n** CASServer is stopped (#{Time.now})"
121
+ end
122
+
123
+
124
+ def fastcgi
125
+ require 'camping/fastcgi'
126
+ Dir.chdir('/srv/www/camping/casserver/')
127
+
128
+ CASServer.create
129
+ Camping::FastCGI.start(CASServer)
130
+ end
131
+
132
+
133
+ def cgi
134
+ CASServer.create
135
+ puts CASServer.run
136
+ end
137
+
138
+ private
139
+ def check_log_writable
140
+ log_file = CASServer::Conf.log['file']
141
+ begin
142
+ f = open(log_file, 'w')
143
+ rescue
144
+ $stderr.puts "Couldn't write to log file at '#{log_file}' (#{$!})."
145
+ exit 1
146
+ end
147
+ f.close
148
+ end
149
+
150
+ def check_pid_writable
151
+ $LOG.debug "Checking if pid file '#{$PID_FILE}' is writable"
152
+ begin
153
+ f = open($PID_FILE, 'w')
154
+ rescue
155
+ $stderr.puts "Couldn't write to log at '#{$PID_FILE}' (#{$!})."
156
+ exit 1
157
+ end
158
+ f.close
159
+ end
160
+
161
+ def write_pid_file
162
+ $LOG.debug "Writing pid '#{Process.pid}' to pid file '#{$PID_FILE}'"
163
+ open($PID_FILE, "w") { |file| file.write(Process.pid) }
164
+ end
165
+
166
+ def clear_pid_file
167
+ if $PID_FILE && File.exists?($PID_FILE)
168
+ $LOG.debug "Clearing pid file '#{$PID_FILE}'"
169
+ File.unlink $PID_FILE
170
+ end
171
+ end
172
+
173
+ end
174
+ end
@@ -0,0 +1,30 @@
1
+ # Misc utility function used throughout by the RubyCAS-server.
2
+ module CASServer
3
+ module Utils
4
+ def random_string(max_length = 29)
5
+ rg = Crypt::ISAAC.new
6
+ max = 4294619050
7
+ r = "#{Time.now.to_i}r%X%X%X%X%X%X%X%X" %
8
+ [rg.rand(max), rg.rand(max), rg.rand(max), rg.rand(max),
9
+ rg.rand(max), rg.rand(max), rg.rand(max), rg.rand(max)]
10
+ r[0..max_length-1]
11
+ end
12
+ module_function :random_string
13
+
14
+ def log_controller_action(controller, params)
15
+ $LOG << "\n"
16
+
17
+ /`(.*)'/.match(caller[1])
18
+ method = $~[1]
19
+
20
+ if params.respond_to? :dup
21
+ params2 = params.dup
22
+ params2['password'] = '******' if params2['password']
23
+ else
24
+ params2 = params
25
+ end
26
+ $LOG.debug("Processing #{controller}::#{method} #{params2.inspect}")
27
+ end
28
+ module_function :log_controller_action
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ module CASServer
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 6
5
+ TINY = 99
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,235 @@
1
+ # The #.#.# comments (e.g. "2.1.3") refer to section numbers in the CAS protocol spec
2
+ # under http://www.ja-sig.org/products/cas/overview/protocol/index.html
3
+
4
+ # need auto_validation off to render CAS responses and to use the autocomplete='off' property on password field
5
+ Markaby::Builder.set(:auto_validation, false)
6
+
7
+ # disabled XML indentation because it was causing problems with mod_auth_cas
8
+ #Markaby::Builder.set(:indent, 2)
9
+
10
+ module CASServer::Views
11
+
12
+ def layout
13
+ # wrap as XHTML only when auto_validation is on, otherwise pass right through
14
+ if @use_layout
15
+ xhtml_strict do
16
+ head do
17
+ title { "#{organization} Central Login" }
18
+ link(:rel => "stylesheet", :type => "text/css", :href => "/themes/cas.css")
19
+ link(:rel => "stylesheet", :type => "text/css", :href => "/themes/#{current_theme}/theme.css")
20
+ end
21
+ body(:onload => "if (document.getElementById('username')) document.getElementById('username').focus()") do
22
+ self << yield
23
+ end
24
+ end
25
+ else
26
+ self << yield
27
+ end
28
+ end
29
+
30
+
31
+ # 2.1.3
32
+ # The full login page.
33
+ def login
34
+ @use_layout = true
35
+
36
+ table(:id => "login-box") do
37
+ tr do
38
+ td(:colspan => 2) do
39
+ div(:id => "headline-container") do
40
+ strong organization
41
+ text " Central Login"
42
+ end
43
+ end
44
+ end
45
+ if @message
46
+ tr do
47
+ td(:colspan => 2, :id => "messagebox-container") do
48
+ div(:class => "messagebox #{@message[:type]}") { @message[:message] }
49
+ end
50
+ end
51
+ end
52
+ tr do
53
+ td(:id => "logo-container") do
54
+ img(:id => "logo", :src => "/themes/#{current_theme}/logo.png")
55
+ end
56
+ td(:id => "login-form-container") do
57
+ @include_infoline = true
58
+ login_form
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ # Just the login form.
65
+ def login_form
66
+ form(:method => "post", :action => @form_action || '/login', :id => "login-form",
67
+ :onsubmit => "submitbutton = document.getElementById('login-submit'); submitbutton.value='Please wait...'; submitbutton.disabled=true; return true;") do
68
+ table(:id => "form-layout") do
69
+ tr do
70
+ td(:id => "username-label-container") do
71
+ label(:id => "username-label", :for => "username") { "Username" }
72
+ end
73
+ td(:id => "username-container") do
74
+ input(:type => "text", :id => "username", :name => "username",
75
+ :size => "32", :tabindex => "1", :accesskey => "u")
76
+ end
77
+ end
78
+ tr do
79
+ td(:id => "password-label-container") do
80
+ label(:id => "password-label", :for => "password") { "Password" }
81
+ end
82
+ td(:id => "password-container") do
83
+ input(:type => "password", :id => "password", :name => "password",
84
+ :size => "32", :tabindex => "2", :accesskey => "p", :autocomplete => "off")
85
+ end
86
+ end
87
+ tr do
88
+ td{}
89
+ td(:id => "submit-container") do
90
+ input(:type => "hidden", :id => "lt", :name => "lt", :value => @lt)
91
+ input(:type => "hidden", :id => "service", :name => "service", :value => @service)
92
+ input(:type => "hidden", :id => "warn", :name => "warn", :value => @warn)
93
+ input(:type => "submit", :class => "button", :accesskey => "l", :value => "LOGIN", :tabindex => "4", :id => "login-submit")
94
+ end
95
+ end
96
+ tr do
97
+ td(:colspan => 2, :id => "infoline") { infoline }
98
+ end if @include_infoline
99
+ end
100
+ end
101
+ end
102
+
103
+ # 2.3.2
104
+ def logout
105
+ @use_layout = true
106
+
107
+ table(:id => "login-box") do
108
+ tr do
109
+ td(:colspan => 2) do
110
+ div(:id => "headline-container") do
111
+ strong organization
112
+ text " Central Login"
113
+ end
114
+ end
115
+ end
116
+ if @message
117
+ tr do
118
+ td(:colspan => 2, :id => "messagebox-container") do
119
+ div(:class => "messagebox #{@message[:type]}") { @message[:message] }
120
+ if @continue_url
121
+ p do
122
+ a(:href => @continue_url) { @continue_url }
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ # 2.4.2
132
+ # CAS 1.0 validate response.
133
+ def validate
134
+ if @success
135
+ text "yes\n#{@username}\n"
136
+ else
137
+ text "no\n\n"
138
+ end
139
+ end
140
+
141
+ # 2.5.2
142
+ # CAS 2.0 service validate response.
143
+ def service_validate
144
+ if @success
145
+ tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
146
+ tag!("cas:authenticationSuccess") do
147
+ tag!("cas:user") {@username.to_s.to_xs}
148
+ @extra_attributes.each do |key, value|
149
+ tag!(key) {value}
150
+ end
151
+ if @pgtiou
152
+ tag!("cas:proxyGrantingTicket") {@pgtiou.to_s.to_xs}
153
+ end
154
+ end
155
+ end
156
+ else
157
+ tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
158
+ tag!("cas:authenticationFailure", :code => @error.code) {@error.to_s.to_xs}
159
+ end
160
+ end
161
+ end
162
+
163
+ # 2.6.2
164
+ # CAS 2.0 proxy validate response.
165
+ def proxy_validate
166
+ if @success
167
+ tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
168
+ tag!("cas:authenticationSuccess") do
169
+ tag!("cas:user") {@username.to_s.to_xs}
170
+ @extra_attributes.each do |key, value|
171
+ tag!(key) {value}
172
+ end
173
+ if @pgtiou
174
+ tag!("cas:proxyGrantingTicket") {@pgtiou.to_s.to_xs}
175
+ end
176
+ if @proxies && !@proxies.empty?
177
+ tag!("cas:proxies") do
178
+ @proxies.each do |proxy_url|
179
+ tag!("cas:proxy") {proxy_url.to_s.to_xs}
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+ else
186
+ tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
187
+ tag!("cas:authenticationFailure", :code => @error.code) {@error.to_s.to_xs}
188
+ end
189
+ end
190
+ end
191
+
192
+ # 2.7.2
193
+ # CAS 2.0 proxy request response.
194
+ def proxy
195
+ if @success
196
+ tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
197
+ tag!("cas:proxySuccess") do
198
+ tag!("cas:proxyTicket") {@pt.to_s.to_xs}
199
+ end
200
+ end
201
+ else
202
+ tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
203
+ tag!("cas:proxyFailure", :code => @error.code) {@error.to_s.to_xs}
204
+ end
205
+ end
206
+ end
207
+
208
+ def configure
209
+ end
210
+
211
+ protected
212
+ def themes_dir
213
+ File.dirname(File.expand_path(__FILE__))+'../themes'
214
+ end
215
+ module_function :themes_dir
216
+
217
+ def current_theme
218
+ CASServer::Conf.theme || "simple"
219
+ end
220
+ module_function :current_theme
221
+
222
+ def organization
223
+ CASServer::Conf.organization || ""
224
+ end
225
+ module_function :organization
226
+
227
+ def infoline
228
+ CASServer::Conf.infoline || ""
229
+ end
230
+ module_function :infoline
231
+ end
232
+
233
+ if CASServer::Conf.custom_views_file
234
+ require CASServer::Conf.custom_views_file
235
+ end