bmedia-casserver 1.1.1

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