bmedia-casserver 1.1.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.
Files changed (81) hide show
  1. data/CHANGELOG +325 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE +26 -0
  4. data/README.md +19 -0
  5. data/Rakefile +2 -0
  6. data/bin/rubycas-server +30 -0
  7. data/config/config.example.yml +592 -0
  8. data/config/unicorn.rb +88 -0
  9. data/config.ru +17 -0
  10. data/db/migrate/001_create_initial_structure.rb +47 -0
  11. data/lib/casserver/authenticators/active_directory_ldap.rb +19 -0
  12. data/lib/casserver/authenticators/active_resource.rb +127 -0
  13. data/lib/casserver/authenticators/authlogic_crypto_providers/aes256.rb +43 -0
  14. data/lib/casserver/authenticators/authlogic_crypto_providers/bcrypt.rb +92 -0
  15. data/lib/casserver/authenticators/authlogic_crypto_providers/md5.rb +34 -0
  16. data/lib/casserver/authenticators/authlogic_crypto_providers/sha1.rb +59 -0
  17. data/lib/casserver/authenticators/authlogic_crypto_providers/sha512.rb +50 -0
  18. data/lib/casserver/authenticators/base.rb +67 -0
  19. data/lib/casserver/authenticators/client_certificate.rb +47 -0
  20. data/lib/casserver/authenticators/google.rb +58 -0
  21. data/lib/casserver/authenticators/ldap.rb +147 -0
  22. data/lib/casserver/authenticators/ntlm.rb +88 -0
  23. data/lib/casserver/authenticators/open_id.rb +22 -0
  24. data/lib/casserver/authenticators/sql.rb +133 -0
  25. data/lib/casserver/authenticators/sql_authlogic.rb +93 -0
  26. data/lib/casserver/authenticators/sql_encrypted.rb +75 -0
  27. data/lib/casserver/authenticators/sql_md5.rb +19 -0
  28. data/lib/casserver/authenticators/sql_rest_auth.rb +82 -0
  29. data/lib/casserver/authenticators/test.rb +22 -0
  30. data/lib/casserver/cas.rb +323 -0
  31. data/lib/casserver/localization.rb +13 -0
  32. data/lib/casserver/model.rb +270 -0
  33. data/lib/casserver/server.rb +758 -0
  34. data/lib/casserver/utils.rb +32 -0
  35. data/lib/casserver/views/_login_form.erb +42 -0
  36. data/lib/casserver/views/layout.erb +18 -0
  37. data/lib/casserver/views/login.erb +30 -0
  38. data/lib/casserver/views/proxy.builder +12 -0
  39. data/lib/casserver/views/proxy_validate.builder +25 -0
  40. data/lib/casserver/views/service_validate.builder +18 -0
  41. data/lib/casserver/views/validate.erb +2 -0
  42. data/lib/casserver.rb +11 -0
  43. data/locales/de.yml +27 -0
  44. data/locales/en.yml +26 -0
  45. data/locales/es.yml +26 -0
  46. data/locales/es_ar.yml +26 -0
  47. data/locales/fr.yml +26 -0
  48. data/locales/jp.yml +26 -0
  49. data/locales/pl.yml +26 -0
  50. data/locales/pt.yml +26 -0
  51. data/locales/ru.yml +26 -0
  52. data/locales/zh.yml +26 -0
  53. data/locales/zh_tw.yml +26 -0
  54. data/public/themes/cas.css +126 -0
  55. data/public/themes/notice.png +0 -0
  56. data/public/themes/ok.png +0 -0
  57. data/public/themes/simple/bg.png +0 -0
  58. data/public/themes/simple/favicon.png +0 -0
  59. data/public/themes/simple/login_box_bg.png +0 -0
  60. data/public/themes/simple/logo.png +0 -0
  61. data/public/themes/simple/theme.css +28 -0
  62. data/public/themes/urbacon/bg.png +0 -0
  63. data/public/themes/urbacon/login_box_bg.png +0 -0
  64. data/public/themes/urbacon/logo.png +0 -0
  65. data/public/themes/urbacon/theme.css +33 -0
  66. data/public/themes/warning.png +0 -0
  67. data/resources/init.d.sh +58 -0
  68. data/setup.rb +1585 -0
  69. data/spec/alt_config.yml +50 -0
  70. data/spec/authenticators/active_resource_spec.rb +109 -0
  71. data/spec/authenticators/ldap_spec.rb +53 -0
  72. data/spec/casserver_spec.rb +156 -0
  73. data/spec/default_config.yml +50 -0
  74. data/spec/model_spec.rb +42 -0
  75. data/spec/spec.opts +4 -0
  76. data/spec/spec_helper.rb +89 -0
  77. data/spec/utils_spec.rb +53 -0
  78. data/tasks/bundler.rake +4 -0
  79. data/tasks/db/migrate.rake +12 -0
  80. data/tasks/spec.rake +10 -0
  81. metadata +308 -0
@@ -0,0 +1,50 @@
1
+ server: webrick
2
+ port: 6543
3
+ #ssl_cert: test.pem
4
+ uri_path: /test
5
+ #bind_address: 0.0.0.0
6
+
7
+ # database:
8
+ # adapter: mysql
9
+ # database: casserver
10
+ # username: root
11
+ # password:
12
+ # host: localhost
13
+ # reconnect: true
14
+ database:
15
+ adapter: sqlite3
16
+ database: spec/casserver_spec.db
17
+
18
+ disable_auto_migrations: true
19
+
20
+ quiet: true
21
+
22
+ authenticator:
23
+ class: CASServer::Authenticators::Test
24
+ password: spec_password
25
+
26
+ theme: simple
27
+
28
+ organization: "RSPEC-TEST"
29
+
30
+ infoline: "This is an rspec test."
31
+
32
+ #custom_views: /path/to/custom/views
33
+
34
+ default_locale: en
35
+
36
+ log:
37
+ file: casserver_spec.log
38
+ level: DEBUG
39
+
40
+ #db_log:
41
+ # file: casserver_spec_db.log
42
+
43
+ enable_single_sign_out: true
44
+
45
+ #maximum_unused_login_ticket_lifetime: 300
46
+ #maximum_unused_service_ticket_lifetime: 300
47
+
48
+ #maximum_session_lifetime: 172800
49
+
50
+ #downcase_username: true
@@ -0,0 +1,109 @@
1
+ # encoding: UTF-8
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ require 'casserver/authenticators/active_resource'
5
+
6
+ describe CASServer::Authenticators::Helpers::Identity do
7
+
8
+ it { should be_an ActiveResource::Base }
9
+
10
+ it "class should respond to :authenticate" do
11
+ subject.class.should respond_to :authenticate
12
+ end
13
+
14
+ it "class should have a method_name accessor" do
15
+ CASServer::Authenticators::Helpers::Identity.method_name.should == :authenticate
16
+ end
17
+
18
+ it "class should have a method_name accessor" do
19
+ CASServer::Authenticators::Helpers::Identity.method_type.should == :post
20
+ end
21
+
22
+ it "class method_type accessor should validate type" do
23
+ expect {
24
+ CASServer::Authenticators::Helpers::Identity.method_type = :foo
25
+ }.to raise_error(ArgumentError)
26
+ end
27
+
28
+ end
29
+
30
+ describe CASServer::Authenticators::ActiveResource do
31
+
32
+ describe "#setup" do
33
+
34
+ it "should configure the identity object" do
35
+ CASServer::Authenticators::Helpers::Identity.should_receive(:user=).with('httpuser').once
36
+ CASServer::Authenticators::ActiveResource.setup :site => 'http://api.example.org', :user => 'httpuser'
37
+ end
38
+
39
+ it "should configure the method_type" do
40
+ CASServer::Authenticators::Helpers::Identity.should_receive(:method_type=).with('get').once
41
+ CASServer::Authenticators::ActiveResource.setup :site => 'http://api.example.org', :method_type => 'get'
42
+ end
43
+
44
+ it "should raise if site option is missing" do
45
+ expect {
46
+ CASServer::Authenticators::ActiveResource.setup({}).should
47
+ }.to raise_error(CASServer::AuthenticatorError, /site option/)
48
+ end
49
+ end
50
+
51
+ describe "#validate" do
52
+
53
+ let(:credentials) { {:username => 'validusername',
54
+ :password => 'validpassword',
55
+ :service => 'test.service'} }
56
+
57
+ let(:auth) { CASServer::Authenticators::ActiveResource.new }
58
+
59
+ def mock_authenticate identity = nil
60
+ identity = CASServer::Authenticators::Helpers::Identity.new if identity.nil?
61
+ CASServer::Authenticators::Helpers::Identity.stub!(:authenticate).and_return(identity)
62
+ end
63
+
64
+ def sample_identity attrs = {}
65
+ identity = CASServer::Authenticators::Helpers::Identity.new
66
+ attrs.each { |k,v| identity.send "#{k}=", v }
67
+ identity
68
+ end
69
+
70
+ it "should call Identity#autenticate with the given params" do
71
+ CASServer::Authenticators::Helpers::Identity.should_receive(:authenticate).with(credentials).once
72
+ auth.validate(credentials)
73
+ end
74
+
75
+ it "should return identity object attributes as extra attributes" do
76
+ auth.configure({}.with_indifferent_access)
77
+ identity = sample_identity({:email => 'foo@example.org'})
78
+ mock_authenticate identity
79
+ auth.validate(credentials).should be_true
80
+ auth.extra_attributes.should == identity.attributes
81
+ end
82
+
83
+ it "should return false when http raises" do
84
+ CASServer::Authenticators::Helpers::Identity.stub!(:authenticate).and_raise(ActiveResource::ForbiddenAccess.new({}))
85
+ auth.validate(credentials).should be_false
86
+ end
87
+
88
+ it "should apply extra_attribute filter" do
89
+ auth.configure({ :extra_attributes => 'age'}.with_indifferent_access)
90
+ mock_authenticate sample_identity({ :email => 'foo@example.org', :age => 28 })
91
+ auth.validate(credentials).should be_true
92
+ auth.extra_attributes.should == { "age" => "28" }
93
+ end
94
+
95
+ it "should only extract not filtered attributes" do
96
+ auth.configure({ :filter_attributes => 'age'}.with_indifferent_access)
97
+ mock_authenticate sample_identity({ :email => 'foo@example.org', :age => 28 })
98
+ auth.validate(credentials).should be_true
99
+ auth.extra_attributes.should == { "email" => 'foo@example.org' }
100
+ end
101
+
102
+ it "should filter password if filter attributes is not given" do
103
+ auth.configure({}.with_indifferent_access)
104
+ mock_authenticate sample_identity({ :email => 'foo@example.org', :password => 'secret' })
105
+ auth.validate(credentials).should be_true
106
+ auth.extra_attributes.should == { "email" => 'foo@example.org' }
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: UTF-8
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ require 'casserver/authenticators/ldap'
5
+
6
+ describe CASServer::Authenticators::LDAP do
7
+ before do
8
+ @ldap_entry = mock(Net::LDAP::Entry.new)
9
+ @ldap_entry.stub!(:[]).and_return("Test")
10
+
11
+ @ldap = mock(Net::LDAP)
12
+ @ldap.stub!(:host=)
13
+ @ldap.stub!(:port=)
14
+ @ldap.stub!(:encryption)
15
+ @ldap.stub!(:bind_as).and_return(true)
16
+ @ldap.stub!(:authenticate).and_return(true)
17
+ @ldap.stub!(:search).and_return([@ldap_entry])
18
+
19
+ Net::LDAP.stub!(:new).and_return(@ldap)
20
+ end
21
+
22
+ describe '#validate' do
23
+
24
+ it 'validate with preauthentication and with extra attributes' do
25
+ auth = CASServer::Authenticators::LDAP.new
26
+
27
+ auth_config = HashWithIndifferentAccess.new(
28
+ :ldap => {
29
+ :host => "ad.example.net",
30
+ :port => 389,
31
+ :base => "dc=example,dc=net",
32
+ :filter => "(objectClass=person)",
33
+ :auth_user => "authenticator",
34
+ :auth_password => "itsasecret"
35
+ },
36
+ :extra_attributes => [:full_name, :address]
37
+ )
38
+
39
+ auth.configure(auth_config.merge('auth_index' => 0))
40
+ auth.validate(
41
+ :username => 'validusername',
42
+ :password => 'validpassword',
43
+ :service => 'test.service',
44
+ :request => {}
45
+ ).should == true
46
+
47
+ auth.extra_attributes.should == {:full_name => 'Test', :address => 'Test'}
48
+ end
49
+
50
+ end
51
+ end
52
+
53
+
@@ -0,0 +1,156 @@
1
+ # encoding: UTF-8
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+
4
+ $LOG = Logger.new(File.basename(__FILE__).gsub('.rb','.log'))
5
+
6
+ RSpec.configure do |config|
7
+ config.include Capybara::DSL
8
+ end
9
+
10
+ VALID_USERNAME = 'spec_user'
11
+ VALID_PASSWORD = 'spec_password'
12
+
13
+ ATTACK_USERNAME = '%3E%22%27%3E%3Cscript%3Ealert%2826%29%3C%2Fscript%3E&password=%3E%22%27%3E%3Cscript%3Ealert%2826%29%3C%2Fscript%3E&lt=%3E%22%27%3E%3Cscript%3Ealert%2826%29%3C%2Fscript%3E&service=%3E%22%27%3E%3Cscript%3Ealert%2826%29%3C%2Fscript%3E'
14
+ INVALID_PASSWORD = 'invalid_password'
15
+
16
+ describe 'CASServer' do
17
+
18
+ before do
19
+ @target_service = 'http://my.app.test'
20
+ end
21
+
22
+ describe "/login" do
23
+ before do
24
+ load_server(File.dirname(__FILE__) + "/default_config.yml")
25
+ reset_spec_database
26
+ end
27
+
28
+ it "logs in successfully with valid username and password without a target service" do
29
+ visit "/login"
30
+
31
+ fill_in 'username', :with => VALID_USERNAME
32
+ fill_in 'password', :with => VALID_PASSWORD
33
+ click_button 'login-submit'
34
+
35
+ page.should have_content("You have successfully logged in")
36
+ end
37
+
38
+ it "fails to log in with invalid password" do
39
+ visit "/login"
40
+ fill_in 'username', :with => VALID_USERNAME
41
+ fill_in 'password', :with => INVALID_PASSWORD
42
+ click_button 'login-submit'
43
+
44
+ page.should have_content("Incorrect username or password")
45
+ end
46
+
47
+ it "logs in successfully with valid username and password and redirects to target service" do
48
+ visit "/login?service="+CGI.escape(@target_service)
49
+
50
+ fill_in 'username', :with => VALID_USERNAME
51
+ fill_in 'password', :with => VALID_PASSWORD
52
+
53
+ click_button 'login-submit'
54
+
55
+ page.current_url.should =~ /^#{Regexp.escape(@target_service)}\/?\?ticket=ST\-[1-9rA-Z]+/
56
+ end
57
+
58
+ it "preserves target service after invalid login" do
59
+ visit "/login?service="+CGI.escape(@target_service)
60
+
61
+ fill_in 'username', :with => VALID_USERNAME
62
+ fill_in 'password', :with => INVALID_PASSWORD
63
+ click_button 'login-submit'
64
+
65
+ page.should have_content("Incorrect username or password")
66
+ page.should have_xpath('//input[@id="service"]', :value => @target_service)
67
+ end
68
+
69
+ it "uses appropriate localization based on Accept-Language header" do
70
+
71
+ page.driver.options[:headers] = {'HTTP_ACCEPT_LANGUAGE' => 'pl'}
72
+ #visit "/login?lang=pl"
73
+ visit "/login"
74
+ page.should have_content("Użytkownik")
75
+
76
+ page.driver.options[:headers] = {'HTTP_ACCEPT_LANGUAGE' => 'pt_BR'}
77
+ #visit "/login?lang=pt_BR"
78
+ visit "/login"
79
+ page.should have_content("Usuário")
80
+
81
+ page.driver.options[:headers] = {'HTTP_ACCEPT_LANGUAGE' => 'en'}
82
+ #visit "/login?lang=en"
83
+ visit "/login"
84
+ page.should have_content("Username")
85
+ end
86
+
87
+ it "is not vunerable to Cross Site Scripting" do
88
+ visit '/login?service=%22%2F%3E%3cscript%3ealert%2832%29%3c%2fscript%3e'
89
+ page.should_not have_content("alert(32)")
90
+ page.should_not have_xpath("//script")
91
+ #page.should have_xpath("<script>alert(32)</script>")
92
+ end
93
+
94
+ end # describe '/login'
95
+
96
+
97
+ describe '/logout' do
98
+
99
+ before do
100
+ load_server(File.dirname(__FILE__) + "/default_config.yml")
101
+ reset_spec_database
102
+ end
103
+
104
+ it "logs out successfully" do
105
+ visit "/logout"
106
+
107
+ page.should have_content("You have successfully logged out")
108
+ end
109
+
110
+ it "logs out successfully and redirects to target service" do
111
+ visit "/logout?gateway=true&service="+CGI.escape(@target_service)
112
+
113
+ page.current_url.should =~ /^#{Regexp.escape(@target_service)}\/?/
114
+ end
115
+
116
+ end # describe '/logout'
117
+
118
+ describe 'Configuration' do
119
+ it "uri_path value changes prefix of routes" do
120
+ load_server(File.dirname(__FILE__) + "/alt_config.yml")
121
+ @target_service = 'http://my.app.test'
122
+
123
+ visit "/test/login"
124
+ page.status_code.should_not == 404
125
+
126
+ visit "/test/logout"
127
+ page.status_code.should_not == 404
128
+ end
129
+ end
130
+
131
+ describe "proxyValidate" do
132
+ before do
133
+ load_server(File.dirname(__FILE__) + "/default_config.yml")
134
+ reset_spec_database
135
+
136
+ visit "/login?service="+CGI.escape(@target_service)
137
+
138
+ fill_in 'username', :with => VALID_USERNAME
139
+ fill_in 'password', :with => VALID_PASSWORD
140
+
141
+ click_button 'login-submit'
142
+
143
+ page.current_url.should =~ /^#{Regexp.escape(@target_service)}\/?\?ticket=ST\-[1-9rA-Z]+/
144
+ @ticket = page.current_url.match(/ticket=(.*)$/)[1]
145
+ end
146
+
147
+ it "should have extra attributes in proper format" do
148
+ visit "/serviceValidate?service=#{CGI.escape(@target_service)}&ticket=#{@ticket}"
149
+
150
+ encoded_utf_string = "&#1070;&#1090;&#1092;" # actual string is "Ютф"
151
+ page.body.should match("<test_utf_string>#{encoded_utf_string}</test_utf_string>")
152
+ page.body.should match("<test_numeric>123.45</test_numeric>")
153
+ page.body.should match("<test_utf_string>&#1070;&#1090;&#1092;</test_utf_string>")
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,50 @@
1
+ server: webrick
2
+ port: 6543
3
+ #ssl_cert: test.pem
4
+ #uri_path: /cas
5
+ #bind_address: 0.0.0.0
6
+
7
+ # database:
8
+ # adapter: mysql
9
+ # database: casserver
10
+ # username: root
11
+ # password:
12
+ # host: localhost
13
+ # reconnect: true
14
+ database:
15
+ adapter: sqlite3
16
+ database: spec/casserver_spec.db
17
+
18
+ disable_auto_migrations: true
19
+
20
+ quiet: true
21
+
22
+ authenticator:
23
+ class: CASServer::Authenticators::Test
24
+ password: spec_password
25
+
26
+ theme: simple
27
+
28
+ organization: "RSPEC-TEST"
29
+
30
+ infoline: "This is an rspec test."
31
+
32
+ #custom_views: /path/to/custom/views
33
+
34
+ default_locale: en
35
+
36
+ log:
37
+ file: casserver_spec.log
38
+ level: DEBUG
39
+
40
+ #db_log:
41
+ # file: casserver_spec_db.log
42
+
43
+ enable_single_sign_out: true
44
+
45
+ #maximum_unused_login_ticket_lifetime: 300
46
+ #maximum_unused_service_ticket_lifetime: 300
47
+
48
+ #maximum_session_lifetime: 172800
49
+
50
+ #downcase_username: true
@@ -0,0 +1,42 @@
1
+ # encoding: UTF-8
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+
4
+ module CASServer
5
+ end
6
+ require 'casserver/model'
7
+
8
+ describe CASServer::Model::LoginTicket, '.cleanup(max_lifetime, max_unconsumed_lifetime)' do
9
+ let(:max_lifetime) { -1 }
10
+ let(:max_unconsumed_lifetime) { -2 }
11
+
12
+ before do
13
+ load_server(File.dirname(__FILE__) + "/default_config.yml")
14
+ reset_spec_database
15
+
16
+ CASServer::Model::LoginTicket.create :ticket => 'test', :client_hostname => 'test.local'
17
+ end
18
+
19
+ it 'should destroy all tickets created before the max lifetime' do
20
+ expect {
21
+ CASServer::Model::LoginTicket.cleanup(max_lifetime, max_unconsumed_lifetime)
22
+ }.to change(CASServer::Model::LoginTicket, :count).by(-1)
23
+ end
24
+
25
+ it 'should destroy all unconsumed tickets not exceeding the max lifetime' do
26
+ expect {
27
+ CASServer::Model::LoginTicket.cleanup(max_lifetime, max_unconsumed_lifetime)
28
+ }.to change(CASServer::Model::LoginTicket, :count).by(-1)
29
+ end
30
+ end
31
+
32
+ describe CASServer::Model::LoginTicket, '#to_s' do
33
+ let(:ticket) { 'test' }
34
+
35
+ before do
36
+ @login_ticket = CASServer::Model::LoginTicket.new :ticket => ticket
37
+ end
38
+
39
+ it 'should delegate #to_s to #ticket' do
40
+ @login_ticket.to_s.should == ticket
41
+ end
42
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format nested
3
+ --loadby mtime
4
+ --reverse
@@ -0,0 +1,89 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+ require 'rack/test'
4
+ require 'rspec'
5
+ #require 'spec/autorun'
6
+ #require 'spec/interop/test'
7
+ require 'logger'
8
+ require 'ostruct'
9
+
10
+ require 'capybara'
11
+ require 'capybara/dsl'
12
+
13
+ # set test environment
14
+ set :environment, :test
15
+ set :run, false
16
+ set :raise_errors, true
17
+ set :logging, false
18
+
19
+
20
+ if Dir.getwd =~ /\/spec$/
21
+ # Avoid potential weirdness by changing the working directory to the CASServer root
22
+ FileUtils.cd('..')
23
+ end
24
+
25
+ def silence_warnings
26
+ old_verbose, $VERBOSE = $VERBOSE, nil
27
+ yield
28
+ ensure
29
+ $VERBOSE = old_verbose
30
+ end
31
+
32
+ # Ugly monkeypatch to allow us to test for correct redirection to
33
+ # external services.
34
+ #
35
+ # This will likely break in the future when Capybara or RackTest are upgraded.
36
+ class Capybara::RackTest::Browser
37
+ def current_url
38
+ if @redirected_to_external_url
39
+ @redirected_to_external_url
40
+ else
41
+ request.url rescue ""
42
+ end
43
+ end
44
+
45
+ def follow_redirects!
46
+ if last_response.redirect? && last_response['Location'] =~ /^http[s]?:/
47
+ puts "FOLLOWING REDIECT: #{last_response['Location']}"
48
+ @redirected_to_external_url = last_response['Location']
49
+ else
50
+ 5.times do
51
+ follow_redirect! if last_response.redirect?
52
+ end
53
+ raise Capybara::InfiniteRedirectError, "redirected more than 5 times, check for infinite redirects." if last_response.redirect?
54
+ end
55
+ end
56
+ end
57
+
58
+ # This called in specs' `before` block.
59
+ # Due to the way Sinatra applications are loaded,
60
+ # we're forced to delay loading of the server code
61
+ # until the start of each test so that certain
62
+ # configuraiton options can be changed (e.g. `uri_path`)
63
+ def load_server(config_file)
64
+ ENV['CONFIG_FILE'] = config_file
65
+
66
+ silence_warnings do
67
+ load File.dirname(__FILE__) + '/../lib/casserver/server.rb'
68
+ end
69
+
70
+ CASServer::Server.enable(:raise_errors)
71
+ CASServer::Server.disable(:show_exceptions)
72
+
73
+ #Capybara.current_driver = :selenium
74
+ Capybara.app = CASServer::Server
75
+ end
76
+
77
+ # Deletes the sqlite3 database specified in the app's config
78
+ # and runs the db:migrate rake tasks to rebuild the database schema.
79
+ def reset_spec_database
80
+ raise "Cannot reset the spec database because config[:database][:database] is not defined." unless
81
+ CASServer::Server.config[:database] && CASServer::Server.config[:database][:database]
82
+
83
+ FileUtils.rm_f(CASServer::Server.config[:database][:database])
84
+
85
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
86
+ ActiveRecord::Base.logger.level = Logger::ERROR
87
+ ActiveRecord::Migration.verbose = false
88
+ ActiveRecord::Migrator.migrate("db/migrate")
89
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: UTF-8
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+
4
+ module CASServer
5
+ end
6
+ require 'casserver/utils'
7
+
8
+ describe CASServer::Utils, '#random_string(max_length = 29)' do
9
+ before do
10
+ load_server(File.dirname(__FILE__) + "/default_config.yml")
11
+ reset_spec_database
12
+ end
13
+
14
+ context 'when max length is not passed in' do
15
+ it 'should return a random string of length 29' do
16
+ subject.random_string.length.should == 29
17
+ end
18
+ end
19
+
20
+ context 'when max length is passed in' do
21
+ it 'should return a random string of the desired length' do
22
+ subject.random_string(30).length.should == 30
23
+ end
24
+ end
25
+
26
+ it 'should include the letter r in the random string' do
27
+ subject.random_string.should include 'r'
28
+ end
29
+
30
+ it 'should return a random string' do
31
+ random_string = subject.random_string
32
+ another_random_string = subject.random_string
33
+ random_string.should_not == another_random_string
34
+ end
35
+ end
36
+
37
+ describe CASServer::Utils, '#log_controller_action(controller, params)' do
38
+ let(:params) { {} }
39
+ let(:params_with_password) { { 'password' => 'test' } }
40
+ let(:params_with_password_filtered) { { 'password' => '******' } }
41
+
42
+ it 'should log the controller action' do
43
+ $LOG.should_receive(:debug).with 'Processing application::instance_eval {}'
44
+
45
+ subject.log_controller_action('application', params)
46
+ end
47
+
48
+ it 'should filter password parameters in the log' do
49
+ $LOG.should_receive(:debug).with "Processing application::instance_eval #{params_with_password_filtered.inspect}"
50
+
51
+ subject.log_controller_action('application', params_with_password)
52
+ end
53
+ end
@@ -0,0 +1,4 @@
1
+ require 'bundler'
2
+ namespace :bundler do
3
+ Bundler::GemHelper.install_tasks
4
+ end
@@ -0,0 +1,12 @@
1
+ namespace :db do
2
+ desc "bring your CAS server database schema up to date (options CONFIG=/path/to/config.yml)"
3
+ task :migrate do |t|
4
+ $:.unshift File.dirname(__FILE__) + "/../../lib"
5
+
6
+ require 'casserver/server'
7
+
8
+ CASServer::Model::Base.logger = Logger.new(STDOUT)
9
+ ActiveRecord::Migration.verbose = true
10
+ ActiveRecord::Migrator.migrate("db/migrate")
11
+ end
12
+ end
data/tasks/spec.rake ADDED
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'rspec/core/rake_task'
3
+ desc 'Run RSpecs to confirm that all functionality is working as expected'
4
+ RSpec::Core::RakeTask.new('spec') do |t|
5
+ t.rspec_opts = ['--colour', '--format nested']
6
+ t.pattern = 'spec/**/*_spec.rb'
7
+ end
8
+ rescue LoadError
9
+ puts "Hiding spec tasks because RSpec is not available"
10
+ end