rubycas-server 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +11 -0
- data/Manifest.txt +2 -0
- data/README.txt +2 -0
- data/bin/rubycas-server +33 -2
- data/config.example.yml +2 -2
- data/lib/casserver.rb +27 -92
- data/lib/casserver/conf.rb +9 -5
- data/lib/casserver/postambles.rb +113 -0
- data/lib/casserver/version.rb +1 -1
- data/lib/casserver/views.rb +10 -12
- metadata +4 -2
data/CHANGELOG.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
=== 0.2.0 ::
|
2
|
+
|
3
|
+
* ruby-casserver now behaves more like a real command-line app, accepting
|
4
|
+
various command line arguments including -h (help), -v (version), -c (use
|
5
|
+
an alternate config.yml), and -d (daemonize, when using webrick or mongrel mode)
|
6
|
+
* special characters in CAS XML responses are now properly encoded into XML
|
7
|
+
entities
|
8
|
+
* CAS XML responses are no longer auto-indented... Markaby's indentation
|
9
|
+
seemed to be causing problems with the PHP CAS client
|
10
|
+
* Misc minor bug fixes/cleanup
|
11
|
+
|
1
12
|
=== 0.1.0 :: 2007-03-01
|
2
13
|
|
3
14
|
* First public release.
|
data/Manifest.txt
CHANGED
@@ -3,6 +3,7 @@ LICENSE.txt
|
|
3
3
|
Manifest.txt
|
4
4
|
README.txt
|
5
5
|
Rakefile
|
6
|
+
bin/rubycas-server
|
6
7
|
config.example.yml
|
7
8
|
lib/casserver.rb
|
8
9
|
lib/casserver/authenticators/active_directory_ldap.rb
|
@@ -14,6 +15,7 @@ lib/casserver/cas.rb
|
|
14
15
|
lib/casserver/conf.rb
|
15
16
|
lib/casserver/controllers.rb
|
16
17
|
lib/casserver/models.rb
|
18
|
+
lib/casserver/postambles.rb
|
17
19
|
lib/casserver/utils.rb
|
18
20
|
lib/casserver/version.rb
|
19
21
|
lib/casserver/views.rb
|
data/README.txt
CHANGED
data/bin/rubycas-server
CHANGED
@@ -1,7 +1,38 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require '
|
4
|
-
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
local_casserver = File.expand_path(File.dirname(File.expand_path(__FILE__))+'/../lib/casserver.rb')
|
6
|
+
if File.exists? local_casserver
|
7
|
+
$: << File.dirname(local_casserver)
|
8
|
+
else
|
9
|
+
require 'rubygems'
|
10
|
+
require_gem 'rubycas-server'
|
11
|
+
end
|
12
|
+
|
13
|
+
OptionParser.new do |opts|
|
14
|
+
opts.banner = "Usage: rubycas-server [options]"
|
15
|
+
|
16
|
+
opts.on("-c", "--config FILE", "Use config file (default is /etc/rubycas-server/config.yml)") do |c|
|
17
|
+
puts "Using config file #{c}"
|
18
|
+
$CONFIG_FILE = c
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on("-d", "--daemonize", "Run as a daemon (only when using webrick or mongrel)") do |c|
|
22
|
+
$DAEMONIZE = true
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
26
|
+
puts opts
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on_tail("-v", "--version", "Show version number") do
|
31
|
+
require 'casserver/version'
|
32
|
+
puts "rubycas-server-#{CASServer::VERSION::STRING}"
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
end.parse!
|
5
36
|
|
6
37
|
$RUN = true
|
7
38
|
|
data/config.example.yml
CHANGED
@@ -28,8 +28,8 @@ port: 443
|
|
28
28
|
ssl_cert: /path/to/your/ssl.pem
|
29
29
|
# ssl_key: /path/to/your/private_key.pem <-- if private key is separate from cert
|
30
30
|
|
31
|
-
### mongrel example (
|
32
|
-
###
|
31
|
+
### mongrel example (since mongrel doesn't support SSL on its own, you will have to run
|
32
|
+
### this behind an https reverse proxy)
|
33
33
|
|
34
34
|
#server: mongrel
|
35
35
|
#port: 110011
|
data/lib/casserver.rb
CHANGED
@@ -4,7 +4,8 @@
|
|
4
4
|
Dir.chdir(File.dirname(File.expand_path(__FILE__))) if __FILE__ == $0
|
5
5
|
|
6
6
|
# add current directory to load path
|
7
|
-
|
7
|
+
$CASSERVER_HOME = File.dirname(File.expand_path(__FILE__))
|
8
|
+
$: << $CASSERVER_HOME
|
8
9
|
|
9
10
|
require 'rubygems'
|
10
11
|
require_gem 'camping', '~> 1.5'
|
@@ -14,7 +15,7 @@ require 'active_support'
|
|
14
15
|
require 'yaml'
|
15
16
|
|
16
17
|
# enable xhtml source code indentation for debugging views
|
17
|
-
Markaby::Builder.set(:indent, 2)
|
18
|
+
#Markaby::Builder.set(:indent, 2)
|
18
19
|
|
19
20
|
# seed the random number generator (ruby does this by default, but it doesn't hurt to do it here just to be sure)
|
20
21
|
srand
|
@@ -23,6 +24,20 @@ srand
|
|
23
24
|
Camping.goes :CASServer
|
24
25
|
|
25
26
|
module CASServer
|
27
|
+
def init_logger
|
28
|
+
$LOG = CASServer::Utils::Logger.new(CASServer::Conf.log[:file])
|
29
|
+
$LOG.level = "CASServer::Utils::Logger::#{CASServer::Conf.log[:level]}".constantize
|
30
|
+
end
|
31
|
+
module_function :init_logger
|
32
|
+
|
33
|
+
def init_db_logger
|
34
|
+
if CASServer::Conf.db_log
|
35
|
+
CASServer::Models::Base.logger = Logger.new(CASServer::Conf.db_log[:file] || 'casserver_db.log')
|
36
|
+
CASServer::Models::Base.logger.level = "CASServer::Utils::Logger::#{CASServer::Conf.db_log[:level] || 'DEBUG'}".constantize
|
37
|
+
end
|
38
|
+
end
|
39
|
+
module_function :init_db_logger
|
40
|
+
|
26
41
|
end
|
27
42
|
|
28
43
|
require 'casserver/utils'
|
@@ -32,9 +47,7 @@ require 'casserver/conf'
|
|
32
47
|
require 'casserver/views'
|
33
48
|
require 'casserver/controllers'
|
34
49
|
|
35
|
-
|
36
|
-
$LOG = CASServer::Utils::Logger.new(CASServer::Conf.log[:file])
|
37
|
-
$LOG.level = "CASServer::Utils::Logger::#{CASServer::Conf.log[:level]}".constantize
|
50
|
+
CASServer.init_logger
|
38
51
|
|
39
52
|
# do initialization stuff
|
40
53
|
def CASServer.create
|
@@ -55,98 +68,20 @@ end
|
|
55
68
|
# this gets run if we launch directly (i.e. `ruby casserver.rb` rather than `camping casserver`)
|
56
69
|
if __FILE__ == $0 || $RUN
|
57
70
|
CASServer::Models::Base.establish_connection(CASServer::Conf.database)
|
58
|
-
|
59
|
-
CASServer::Models::Base.logger = Logger.new(CASServer::Conf.db_log[:file] || 'casserver_db.log')
|
60
|
-
CASServer::Models::Base.logger.level = "CASServer::Utils::Logger::#{CASServer::Conf.db_log[:level] || 'DEBUG'}".constantize
|
61
|
-
end
|
62
|
-
|
63
|
-
case CASServer::Conf.server
|
64
|
-
when "webrick", :webrick
|
65
|
-
require 'webrick/httpserver'
|
66
|
-
require 'webrick/https'
|
67
|
-
require 'camping/webrick'
|
68
|
-
|
69
|
-
# TODO: verify the certificate's validity
|
70
|
-
# example of how to do this is here: http://pablotron.org/download/ruri-20050331.rb
|
71
|
-
|
72
|
-
cert_path = CASServer::Conf.ssl_cert
|
73
|
-
key_path = CASServer::Conf.ssl_key || CASServer::Conf.ssl_cert
|
74
|
-
# look for the key in the ssl_cert if no ssl_key is specified
|
75
|
-
|
76
|
-
raise "'#{cert_path}' is not a valid ssl certificate. Your 'ssl_cert' configuration" +
|
77
|
-
" setting must be a path to a valid ssl certificate file." unless
|
78
|
-
File.exists? cert_path
|
79
|
-
|
80
|
-
raise "'#{key_path}' is not a valid ssl private key. Your 'ssl_key' configuration" +
|
81
|
-
" setting must be a path to a valid ssl private key file." unless
|
82
|
-
File.exists? key_path
|
83
|
-
|
84
|
-
cert = OpenSSL::X509::Certificate.new(File.read(cert_path))
|
85
|
-
key = OpenSSL::PKey::RSA.new(File.read(key_path))
|
86
|
-
|
87
|
-
begin
|
88
|
-
s = WEBrick::HTTPServer.new(
|
89
|
-
:BindAddress => "0.0.0.0",
|
90
|
-
:Port => CASServer::Conf.port,
|
91
|
-
:SSLEnable => true,
|
92
|
-
:SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
|
93
|
-
:SSLCertificate => cert,
|
94
|
-
:SSLPrivateKey => key
|
95
|
-
)
|
96
|
-
rescue Errno::EACCES
|
97
|
-
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."
|
98
|
-
exit 2
|
99
|
-
end
|
100
|
-
|
101
|
-
CASServer.create
|
102
|
-
s.mount "#{CASServer::Conf.uri_path}", WEBrick::CampingHandler, CASServer
|
103
|
-
|
104
|
-
puts "\n** CASServer is running at http://localhost:#{CASServer::Conf.port}#{CASServer::Conf.uri_path} and logging to '#{CASServer::Conf.log[:file]}'\n\n"
|
105
|
-
|
106
|
-
# This lets Ctrl+C shut down your server
|
107
|
-
trap(:INT) do
|
108
|
-
s.shutdown
|
109
|
-
end
|
71
|
+
CASServer.init_db_logger unless CASServer::Conf.server.to_s == 'mongrel'
|
110
72
|
|
111
|
-
|
112
|
-
|
113
|
-
when "mongrel", :mongrel
|
114
|
-
require 'rubygems'
|
115
|
-
require 'mongrel/camping'
|
116
|
-
|
117
|
-
# camping has fixes for mongrel currently only availabe in SVN
|
118
|
-
# ... you can install camping from svn (1.5.180) by running:
|
119
|
-
# gem install camping --source code.whytheluckystiff.net
|
120
|
-
require_gem 'camping', '~> 1.5.180'
|
121
|
-
|
122
|
-
CASServer.create
|
73
|
+
require 'casserver/postambles'
|
74
|
+
include CASServer::Postambles
|
123
75
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
exit 2
|
129
|
-
end
|
130
|
-
|
131
|
-
puts "\n** CASServer is running at http://localhost:#{CASServer::Conf.port}#{CASServer::Conf.uri_path} and logging to '#{CASServer::Conf.log[:file]}'"
|
132
|
-
server.run.join
|
133
|
-
|
134
|
-
when "fastcgi", :fastcgi
|
135
|
-
require 'camping/fastcgi'
|
136
|
-
Dir.chdir('/srv/www/camping/casserver/')
|
137
|
-
|
138
|
-
CASServer.create
|
139
|
-
Camping::FastCGI.start(CASServer)
|
140
|
-
|
141
|
-
when "cgi", :cgi
|
142
|
-
CASServer.create
|
143
|
-
puts CASServer.run
|
144
|
-
|
145
|
-
else
|
76
|
+
begin
|
77
|
+
raise NoMethodError if CASServer::Conf.server.nil?
|
78
|
+
send(CASServer::Conf.server)
|
79
|
+
rescue NoMethodError
|
146
80
|
if CASServer::Conf.server
|
147
81
|
raise "The server setting '#{CASServer::Conf.server}' in your config.yml file is invalid."
|
148
82
|
else
|
149
83
|
raise "You must have a 'server' setting in your config.yml file. Please see the RubyCAS-Server documentation."
|
150
84
|
end
|
151
85
|
end
|
152
|
-
|
86
|
+
|
87
|
+
end
|
data/lib/casserver/conf.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
# load configuration
|
2
|
-
begin
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
conf_file =
|
2
|
+
begin
|
3
|
+
if $CONFIG_FILE
|
4
|
+
conf_file = $CONFIG_FILE
|
5
|
+
else
|
6
|
+
conf_file = etc_conf = "/etc/rubycas-server/config.yml"
|
7
|
+
unless File.exists? conf_file
|
8
|
+
# can use local config.yml file in case we're running non-gem installation
|
9
|
+
conf_file = File.dirname(File.expand_path(__FILE__))+"/../../config.yml"
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
13
|
unless File.exists? conf_file
|
@@ -0,0 +1,113 @@
|
|
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
|
+
raise "'#{cert_path}' is not a valid ssl certificate. Your 'ssl_cert' configuration" +
|
17
|
+
" setting must be a path to a valid ssl certificate file." unless
|
18
|
+
File.exists? cert_path
|
19
|
+
|
20
|
+
raise "'#{key_path}' is not a valid ssl private key. Your 'ssl_key' configuration" +
|
21
|
+
" setting must be a path to a valid ssl private key file." unless
|
22
|
+
File.exists? key_path
|
23
|
+
|
24
|
+
cert = OpenSSL::X509::Certificate.new(File.read(cert_path))
|
25
|
+
key = OpenSSL::PKey::RSA.new(File.read(key_path))
|
26
|
+
|
27
|
+
begin
|
28
|
+
s = WEBrick::HTTPServer.new(
|
29
|
+
:BindAddress => "0.0.0.0",
|
30
|
+
:Port => CASServer::Conf.port,
|
31
|
+
:SSLEnable => true,
|
32
|
+
:SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
|
33
|
+
:SSLCertificate => cert,
|
34
|
+
:SSLPrivateKey => key
|
35
|
+
)
|
36
|
+
rescue Errno::EACCES
|
37
|
+
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."
|
38
|
+
exit 2
|
39
|
+
end
|
40
|
+
|
41
|
+
CASServer.create
|
42
|
+
s.mount "#{CASServer::Conf.uri_path}", WEBrick::CampingHandler, CASServer
|
43
|
+
|
44
|
+
puts "\n** CASServer is running at http://localhost:#{CASServer::Conf.port}#{CASServer::Conf.uri_path} and logging to '#{CASServer::Conf.log[:file]}'\n\n"
|
45
|
+
|
46
|
+
# This lets Ctrl+C shut down your server
|
47
|
+
trap(:INT) do
|
48
|
+
s.shutdown
|
49
|
+
end
|
50
|
+
|
51
|
+
if $DAEMONIZE
|
52
|
+
WEBrick::Daemon.start {s.start}
|
53
|
+
else
|
54
|
+
s.start
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
def mongrel
|
61
|
+
require 'rubygems'
|
62
|
+
require 'mongrel/camping'
|
63
|
+
|
64
|
+
# camping has fixes for mongrel currently only availabe in SVN
|
65
|
+
# ... you can install camping from svn (1.5.180) by running:
|
66
|
+
# gem install camping --source code.whytheluckystiff.net
|
67
|
+
require_gem 'camping', '~> 1.5.180'
|
68
|
+
|
69
|
+
CASServer.create
|
70
|
+
|
71
|
+
puts "\n** CASServer is starting. Look in '#{CASServer::Conf.log[:file]}' for further notices."
|
72
|
+
|
73
|
+
settings = {:host => "0.0.0.0", :log_file => CASServer::Conf.log[:file], :cwd => $CASSERVER_HOME}
|
74
|
+
|
75
|
+
# need to close all IOs if we daemonize
|
76
|
+
$LOG.close
|
77
|
+
|
78
|
+
config = Mongrel::Configurator.new settings do
|
79
|
+
daemonize :log_file => CASServer::Conf.log[:file], :cwd => $CASSERVER_HOME if $DAEMONIZE
|
80
|
+
|
81
|
+
listener :port => CASServer::Conf.port do
|
82
|
+
uri CASServer::Conf.uri_path, :handler => Mongrel::Camping::CampingHandler.new(CASServer)
|
83
|
+
setup_signals
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
config.run
|
88
|
+
|
89
|
+
CASServer.init_logger
|
90
|
+
CASServer.init_db_logger
|
91
|
+
|
92
|
+
puts "\n** CASServer is running at http://localhost:#{CASServer::Conf.port}#{CASServer::Conf.uri_path} and logging to '#{CASServer::Conf.log[:file]}'"
|
93
|
+
config.join
|
94
|
+
puts "\n** CASServer is stopped (#{Time.now})"
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def fastcgi
|
99
|
+
require 'camping/fastcgi'
|
100
|
+
Dir.chdir('/srv/www/camping/casserver/')
|
101
|
+
|
102
|
+
CASServer.create
|
103
|
+
Camping::FastCGI.start(CASServer)
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
def cgi
|
108
|
+
CASServer.create
|
109
|
+
puts CASServer.run
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
data/lib/casserver/version.rb
CHANGED
data/lib/casserver/views.rb
CHANGED
@@ -27,8 +27,6 @@ module CASServer::Views
|
|
27
27
|
|
28
28
|
# 2.1.3
|
29
29
|
def login
|
30
|
-
@logo =
|
31
|
-
|
32
30
|
table(:id => "login-box") do
|
33
31
|
tr do
|
34
32
|
td(:colspan => 2) do
|
@@ -104,15 +102,15 @@ module CASServer::Views
|
|
104
102
|
if @success
|
105
103
|
tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
|
106
104
|
tag!("cas:authenticationSuccess") do
|
107
|
-
tag!("cas:user") {@username}
|
105
|
+
tag!("cas:user") {@username.to_s.to_xs}
|
108
106
|
if @pgtiou
|
109
|
-
tag!("cas:proxyGrantingTicket") {@pgtiou}
|
107
|
+
tag!("cas:proxyGrantingTicket") {@pgtiou.to_s.to_xs}
|
110
108
|
end
|
111
109
|
end
|
112
110
|
end
|
113
111
|
else
|
114
112
|
tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
|
115
|
-
tag!("cas:authenticationFailure", :code => @error.code) {@error}
|
113
|
+
tag!("cas:authenticationFailure", :code => @error.code) {@error.to_s.to_xs}
|
116
114
|
end
|
117
115
|
end
|
118
116
|
end
|
@@ -123,14 +121,14 @@ module CASServer::Views
|
|
123
121
|
if @success
|
124
122
|
tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
|
125
123
|
tag!("cas:authenticationSuccess") do
|
126
|
-
tag!("cas:user") {@username}
|
124
|
+
tag!("cas:user") {@username.to_s.to_xs}
|
127
125
|
if @pgtiou
|
128
|
-
tag!("cas:proxyGrantingTicket") {@pgtiou}
|
126
|
+
tag!("cas:proxyGrantingTicket") {@pgtiou.to_s.to_xs}
|
129
127
|
end
|
130
128
|
if @proxies && !@proxies.empty?
|
131
129
|
tag!("cas:proxies") do
|
132
130
|
@proxies.each do |proxy_url|
|
133
|
-
tag!("cas:proxy") {proxy_url}
|
131
|
+
tag!("cas:proxy") {proxy_url.to_s.to_xs}
|
134
132
|
end
|
135
133
|
end
|
136
134
|
end
|
@@ -138,7 +136,7 @@ module CASServer::Views
|
|
138
136
|
end
|
139
137
|
else
|
140
138
|
tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
|
141
|
-
tag!("cas:authenticationFailure", :code => @error.code) {@error}
|
139
|
+
tag!("cas:authenticationFailure", :code => @error.code) {@error.to_s.to_xs}
|
142
140
|
end
|
143
141
|
end
|
144
142
|
end
|
@@ -149,12 +147,12 @@ module CASServer::Views
|
|
149
147
|
if @success
|
150
148
|
tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
|
151
149
|
tag!("cas:proxySuccess") do
|
152
|
-
tag!("cas:proxyTicket") {@pt}
|
150
|
+
tag!("cas:proxyTicket") {@pt.to_s.to_xs}
|
153
151
|
end
|
154
152
|
end
|
155
153
|
else
|
156
154
|
tag!("cas:serviceResponse", 'xmlns:cas' => "http://www.yale.edu/tp/cas") do
|
157
|
-
tag!("cas:proxyFailure", :code => @error.code) {@error}
|
155
|
+
tag!("cas:proxyFailure", :code => @error.code) {@error.to_s.to_xs}
|
158
156
|
end
|
159
157
|
end
|
160
158
|
end
|
@@ -182,4 +180,4 @@ module CASServer::Views
|
|
182
180
|
CASServer::Conf.infoline || ""
|
183
181
|
end
|
184
182
|
module_function :infoline
|
185
|
-
end
|
183
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rubycas-server
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-03-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2007-03-20 00:00:00 -04:00
|
8
8
|
summary: Provides single sign on for web applications using the CAS protocol.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- Manifest.txt
|
35
35
|
- README.txt
|
36
36
|
- Rakefile
|
37
|
+
- bin/rubycas-server
|
37
38
|
- config.example.yml
|
38
39
|
- lib/casserver.rb
|
39
40
|
- lib/casserver/authenticators/active_directory_ldap.rb
|
@@ -45,6 +46,7 @@ files:
|
|
45
46
|
- lib/casserver/conf.rb
|
46
47
|
- lib/casserver/controllers.rb
|
47
48
|
- lib/casserver/models.rb
|
49
|
+
- lib/casserver/postambles.rb
|
48
50
|
- lib/casserver/utils.rb
|
49
51
|
- lib/casserver/version.rb
|
50
52
|
- lib/casserver/views.rb
|