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.
- data/.loadpath +5 -0
- data/.project +17 -0
- data/CHANGELOG.txt +1 -0
- data/History.txt +223 -0
- data/LICENSE.txt +504 -0
- data/Manifest.txt +61 -0
- data/README.txt +25 -0
- data/Rakefile +60 -0
- data/bin/rubycas-server +26 -0
- data/bin/rubycas-server-ctl +22 -0
- data/config.example.yml +363 -0
- data/custom_views.example.rb +11 -0
- data/lib/casserver.rb +110 -0
- data/lib/casserver/authenticators/active_directory_ldap.rb +11 -0
- data/lib/casserver/authenticators/base.rb +47 -0
- data/lib/casserver/authenticators/ldap.rb +108 -0
- data/lib/casserver/authenticators/ntlm.rb +88 -0
- data/lib/casserver/authenticators/sql.rb +102 -0
- data/lib/casserver/authenticators/sql_encrypted.rb +75 -0
- data/lib/casserver/authenticators/test.rb +15 -0
- data/lib/casserver/cas.rb +307 -0
- data/lib/casserver/conf.rb +112 -0
- data/lib/casserver/controllers.rb +436 -0
- data/lib/casserver/environment.rb +23 -0
- data/lib/casserver/models.rb +218 -0
- data/lib/casserver/postambles.rb +174 -0
- data/lib/casserver/utils.rb +30 -0
- data/lib/casserver/version.rb +9 -0
- data/lib/casserver/views.rb +235 -0
- data/lib/rubycas-server.rb +1 -0
- data/lib/rubycas-server/version.rb +1 -0
- data/lib/themes/cas.css +121 -0
- data/lib/themes/notice.png +0 -0
- data/lib/themes/ok.png +0 -0
- data/lib/themes/simple/bg.png +0 -0
- data/lib/themes/simple/login_box_bg.png +0 -0
- data/lib/themes/simple/logo.png +0 -0
- data/lib/themes/simple/theme.css +28 -0
- data/lib/themes/urbacon/bg.png +0 -0
- data/lib/themes/urbacon/login_box_bg.png +0 -0
- data/lib/themes/urbacon/logo.png +0 -0
- data/lib/themes/urbacon/theme.css +33 -0
- data/lib/themes/warning.png +0 -0
- data/misc/basic_cas_single_signon_mechanism_diagram.png +0 -0
- data/misc/basic_cas_single_signon_mechanism_diagram.svg +652 -0
- data/resources/init.d.sh +58 -0
- data/setup.rb +1585 -0
- data/test/test_cas.rb +33 -0
- data/test/test_casserver.rb +125 -0
- data/vendor/isaac_0.9.1/LICENSE +26 -0
- data/vendor/isaac_0.9.1/README +78 -0
- data/vendor/isaac_0.9.1/TODO +3 -0
- data/vendor/isaac_0.9.1/VERSIONS +3 -0
- data/vendor/isaac_0.9.1/crypt/ISAAC.rb +171 -0
- data/vendor/isaac_0.9.1/isaac.gemspec +39 -0
- data/vendor/isaac_0.9.1/setup.rb +596 -0
- data/vendor/isaac_0.9.1/test/TC_ISAAC.rb +76 -0
- 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,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
|