prathe_devise_ldap_authenticatable 0.4.10

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 (93) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +187 -0
  3. data/Rakefile +52 -0
  4. data/VERSION +1 -0
  5. data/devise_ldap_authenticatable.gemspec +133 -0
  6. data/lib/devise_ldap_authenticatable.rb +48 -0
  7. data/lib/devise_ldap_authenticatable/exception.rb +6 -0
  8. data/lib/devise_ldap_authenticatable/ldap_adapter.rb +242 -0
  9. data/lib/devise_ldap_authenticatable/logger.rb +11 -0
  10. data/lib/devise_ldap_authenticatable/model.rb +101 -0
  11. data/lib/devise_ldap_authenticatable/routes.rb +8 -0
  12. data/lib/devise_ldap_authenticatable/schema.rb +14 -0
  13. data/lib/devise_ldap_authenticatable/strategy.rb +36 -0
  14. data/lib/devise_ldap_authenticatable/version.rb +4 -0
  15. data/lib/generators/devise_ldap_authenticatable/install_generator.rb +62 -0
  16. data/lib/generators/devise_ldap_authenticatable/templates/ldap.yml +51 -0
  17. data/rails/init.rb +2 -0
  18. data/test/devise_ldap_authenticatable_test.rb +8 -0
  19. data/test/ldap/base.ldif +73 -0
  20. data/test/ldap/clear.ldif +26 -0
  21. data/test/ldap/local.schema +6 -0
  22. data/test/ldap/run-server.sh +10 -0
  23. data/test/ldap/server.pem +38 -0
  24. data/test/ldap/slapd-ssl-test.conf +107 -0
  25. data/test/ldap/slapd-test.conf +107 -0
  26. data/test/rails_app/Gemfile +22 -0
  27. data/test/rails_app/Gemfile.lock +159 -0
  28. data/test/rails_app/Rakefile +7 -0
  29. data/test/rails_app/app/controllers/application_controller.rb +4 -0
  30. data/test/rails_app/app/controllers/posts_controller.rb +15 -0
  31. data/test/rails_app/app/helpers/application_helper.rb +2 -0
  32. data/test/rails_app/app/helpers/posts_helper.rb +2 -0
  33. data/test/rails_app/app/models/post.rb +2 -0
  34. data/test/rails_app/app/models/user.rb +10 -0
  35. data/test/rails_app/app/views/layouts/application.html.erb +26 -0
  36. data/test/rails_app/app/views/posts/index.html.erb +2 -0
  37. data/test/rails_app/config.ru +4 -0
  38. data/test/rails_app/config/application.rb +46 -0
  39. data/test/rails_app/config/boot.rb +13 -0
  40. data/test/rails_app/config/cucumber.yml +8 -0
  41. data/test/rails_app/config/database.yml +25 -0
  42. data/test/rails_app/config/environment.rb +5 -0
  43. data/test/rails_app/config/environments/development.rb +22 -0
  44. data/test/rails_app/config/environments/production.rb +46 -0
  45. data/test/rails_app/config/environments/test.rb +34 -0
  46. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  47. data/test/rails_app/config/initializers/devise.rb +140 -0
  48. data/test/rails_app/config/initializers/inflections.rb +10 -0
  49. data/test/rails_app/config/initializers/mime_types.rb +5 -0
  50. data/test/rails_app/config/initializers/secret_token.rb +7 -0
  51. data/test/rails_app/config/initializers/session_store.rb +8 -0
  52. data/test/rails_app/config/ldap.yml +22 -0
  53. data/test/rails_app/config/ldap_with_erb.yml +23 -0
  54. data/test/rails_app/config/ldap_with_uid.yml +18 -0
  55. data/test/rails_app/config/locales/devise.en.yml +39 -0
  56. data/test/rails_app/config/locales/en.yml +5 -0
  57. data/test/rails_app/config/routes.rb +64 -0
  58. data/test/rails_app/config/ssl_ldap.yml +21 -0
  59. data/test/rails_app/config/ssl_ldap_with_erb.yml +23 -0
  60. data/test/rails_app/config/ssl_ldap_with_uid.yml +18 -0
  61. data/test/rails_app/db/migrate/20100708120302_create_posts.rb +14 -0
  62. data/test/rails_app/db/migrate/20100708120448_devise_create_users.rb +26 -0
  63. data/test/rails_app/db/schema.rb +41 -0
  64. data/test/rails_app/db/seeds.rb +7 -0
  65. data/test/rails_app/features/manage_logins.feature +35 -0
  66. data/test/rails_app/features/step_definitions/login_steps.rb +21 -0
  67. data/test/rails_app/features/step_definitions/web_steps.rb +219 -0
  68. data/test/rails_app/features/support/env.rb +58 -0
  69. data/test/rails_app/features/support/paths.rb +38 -0
  70. data/test/rails_app/lib/tasks/.gitkeep +0 -0
  71. data/test/rails_app/lib/tasks/cucumber.rake +53 -0
  72. data/test/rails_app/public/404.html +26 -0
  73. data/test/rails_app/public/422.html +26 -0
  74. data/test/rails_app/public/500.html +26 -0
  75. data/test/rails_app/public/images/rails.png +0 -0
  76. data/test/rails_app/public/javascripts/application.js +2 -0
  77. data/test/rails_app/public/javascripts/controls.js +965 -0
  78. data/test/rails_app/public/javascripts/dragdrop.js +974 -0
  79. data/test/rails_app/public/javascripts/effects.js +1123 -0
  80. data/test/rails_app/public/javascripts/prototype.js +4874 -0
  81. data/test/rails_app/public/javascripts/rails.js +118 -0
  82. data/test/rails_app/public/stylesheets/.gitkeep +0 -0
  83. data/test/rails_app/script/cucumber +10 -0
  84. data/test/rails_app/script/rails +6 -0
  85. data/test/rails_app/test/factories/users.rb +14 -0
  86. data/test/rails_app/test/functional/posts_controller_test.rb +58 -0
  87. data/test/rails_app/test/performance/browsing_test.rb +9 -0
  88. data/test/rails_app/test/test_helper.rb +36 -0
  89. data/test/rails_app/test/unit/helpers/posts_helper_test.rb +4 -0
  90. data/test/rails_app/test/unit/post_test.rb +4 -0
  91. data/test/rails_app/test/unit/user_test.rb +254 -0
  92. data/test/test_helper.rb +3 -0
  93. metadata +161 -0
@@ -0,0 +1,118 @@
1
+ document.observe("dom:loaded", function() {
2
+ function handleRemote(element) {
3
+ var method, url, params;
4
+
5
+ if (element.tagName.toLowerCase() === 'form') {
6
+ method = element.readAttribute('method') || 'post';
7
+ url = element.readAttribute('action');
8
+ params = element.serialize(true);
9
+ } else {
10
+ method = element.readAttribute('data-method') || 'get';
11
+ url = element.readAttribute('href');
12
+ params = {};
13
+ }
14
+
15
+ var event = element.fire("ajax:before");
16
+ if (event.stopped) return false;
17
+
18
+ new Ajax.Request(url, {
19
+ method: method,
20
+ parameters: params,
21
+ asynchronous: true,
22
+ evalScripts: true,
23
+
24
+ onLoading: function(request) { element.fire("ajax:loading", {request: request}); },
25
+ onLoaded: function(request) { element.fire("ajax:loaded", {request: request}); },
26
+ onInteractive: function(request) { element.fire("ajax:interactive", {request: request}); },
27
+ onComplete: function(request) { element.fire("ajax:complete", {request: request}); },
28
+ onSuccess: function(request) { element.fire("ajax:success", {request: request}); },
29
+ onFailure: function(request) { element.fire("ajax:failure", {request: request}); }
30
+ });
31
+
32
+ element.fire("ajax:after");
33
+ }
34
+
35
+ function handleMethod(element) {
36
+ var method, url, token_name, token;
37
+
38
+ method = element.readAttribute('data-method');
39
+ url = element.readAttribute('href');
40
+ csrf_param = $$('meta[name=csrf-param]').first();
41
+ csrf_token = $$('meta[name=csrf-token]').first();
42
+
43
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
44
+ element.parentNode.appendChild(form);
45
+
46
+ if (method != 'post') {
47
+ var field = new Element('input', { type: 'hidden', name: '_method', value: method });
48
+ form.appendChild(field);
49
+ }
50
+
51
+ if (csrf_param) {
52
+ var param = csrf_param.readAttribute('content');
53
+ var token = csrf_token.readAttribute('content');
54
+ var field = new Element('input', { type: 'hidden', name: param, value: token });
55
+ form.appendChild(field);
56
+ }
57
+
58
+ form.submit();
59
+ }
60
+
61
+ $(document.body).observe("click", function(event) {
62
+ var message = event.findElement().readAttribute('data-confirm');
63
+ if (message && !confirm(message)) {
64
+ event.stop();
65
+ return false;
66
+ }
67
+
68
+ var element = event.findElement("a[data-remote]");
69
+ if (element) {
70
+ handleRemote(element);
71
+ event.stop();
72
+ return true;
73
+ }
74
+
75
+ var element = event.findElement("a[data-method]");
76
+ if (element) {
77
+ handleMethod(element);
78
+ event.stop();
79
+ return true;
80
+ }
81
+ });
82
+
83
+ // TODO: I don't think submit bubbles in IE
84
+ $(document.body).observe("submit", function(event) {
85
+ var element = event.findElement(),
86
+ message = element.readAttribute('data-confirm');
87
+ if (message && !confirm(message)) {
88
+ event.stop();
89
+ return false;
90
+ }
91
+
92
+ var inputs = element.select("input[type=submit][data-disable-with]");
93
+ inputs.each(function(input) {
94
+ input.disabled = true;
95
+ input.writeAttribute('data-original-value', input.value);
96
+ input.value = input.readAttribute('data-disable-with');
97
+ });
98
+
99
+ var element = event.findElement("form[data-remote]");
100
+ if (element) {
101
+ handleRemote(element);
102
+ event.stop();
103
+ }
104
+ });
105
+
106
+ $(document.body).observe("ajax:after", function(event) {
107
+ var element = event.findElement();
108
+
109
+ if (element.tagName.toLowerCase() === 'form') {
110
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
111
+ inputs.each(function(input) {
112
+ input.value = input.readAttribute('data-original-value');
113
+ input.writeAttribute('data-original-value', null);
114
+ input.disabled = false;
115
+ });
116
+ }
117
+ });
118
+ });
File without changes
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
4
+ if vendored_cucumber_bin
5
+ load File.expand_path(vendored_cucumber_bin)
6
+ else
7
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
8
+ require 'cucumber'
9
+ load Cucumber::BINARY
10
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,14 @@
1
+ Factory.define :user do |f|
2
+ f.email "example.user@test.com"
3
+ f.password "secret"
4
+ end
5
+
6
+ Factory.define :admin, :class => "user" do |f|
7
+ f.email "example.admin@test.com"
8
+ f.password "admin_secret"
9
+ end
10
+
11
+ Factory.define :other, :class => "user" do |f|
12
+ f.email "other.user@test.com"
13
+ f.password "other_secret"
14
+ end
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+
3
+ class PostsControllerTest < ActionController::TestCase
4
+
5
+ include Devise::TestHelpers
6
+
7
+ context "not logged in" do
8
+ should "should get INDEX" do
9
+ get :index
10
+ assert_response :success
11
+ assert_equal(response.body, "posts#index")
12
+ end
13
+
14
+ context "go to NEW page" do
15
+ setup do
16
+ get :new
17
+ end
18
+
19
+ should "not get NEW" do
20
+ assert_response :redirect
21
+ end
22
+ end
23
+ end
24
+
25
+ context "logged in" do
26
+ setup do
27
+ @user = Factory(:user)
28
+ sign_in(@user)
29
+ end
30
+
31
+ context "get NEW action" do
32
+ setup do
33
+ get :new
34
+ end
35
+
36
+ should "get the NEW action" do
37
+ assert_response :success
38
+ assert_equal(response.body, "posts#new")
39
+ end
40
+ end
41
+
42
+ context "log out user" do
43
+ setup do
44
+ sign_out(@user)
45
+ get :new
46
+ end
47
+
48
+ should "get redirected to the login page" do
49
+ assert_response :redirect
50
+ end
51
+ end
52
+
53
+
54
+ end
55
+
56
+
57
+
58
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+ require 'rails/performance_test_help'
3
+
4
+ # Profiling results for each test method are written to tmp/performance.
5
+ class BrowsingTest < ActionDispatch::PerformanceTest
6
+ def test_homepage
7
+ get '/'
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path('../../config/environment', __FILE__)
3
+ require 'rails/test_help'
4
+
5
+ class ActiveSupport::TestCase
6
+
7
+ def ldap_connect_string
8
+ if ENV["LDAP_SSL"]
9
+ "-x -H ldaps://localhost:3389 -D 'cn=admin,dc=test,dc=com' -w secret"
10
+ else
11
+ "-x -h localhost -p 3389 -D 'cn=admin,dc=test,dc=com' -w secret"
12
+ end
13
+ end
14
+
15
+ def reset_ldap_server!
16
+ if ENV["LDAP_SSL"]
17
+ `ldapmodify #{ldap_connect_string} -f ../ldap/clear.ldif`
18
+ `ldapadd #{ldap_connect_string} -f ../ldap/base.ldif`
19
+ else
20
+ `ldapmodify #{ldap_connect_string} -f ../ldap/clear.ldif`
21
+ `ldapadd #{ldap_connect_string} -f ../ldap/base.ldif`
22
+ end
23
+ end
24
+
25
+ def default_devise_settings!
26
+ ::Devise.ldap_logger = true
27
+ ::Devise.ldap_create_user = false
28
+ ::Devise.ldap_update_password = true
29
+ ::Devise.ldap_config = "#{Rails.root}/config/#{"ssl_" if ENV["LDAP_SSL"]}ldap.yml"
30
+ ::Devise.ldap_check_group_membership = false
31
+ ::Devise.ldap_check_attributes = false
32
+ ::Devise.ldap_auth_username_builder = Proc.new() {|attribute, login, ldap| "#{attribute}=#{login},#{ldap.base}" }
33
+ ::Devise.authentication_keys = [:email]
34
+ end
35
+
36
+ end
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class PostsHelperTest < ActionView::TestCase
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class PostTest < ActiveSupport::TestCase
4
+ end
@@ -0,0 +1,254 @@
1
+ require 'test_helper'
2
+
3
+ class UserTest < ActiveSupport::TestCase
4
+
5
+ def should_be_validated(user, password, message = "Password is invalid")
6
+ assert(user.valid_ldap_authentication?(password), message)
7
+ end
8
+
9
+ def should_not_be_validated(user, password, message = "Password is not properly set")
10
+ assert(!user.valid_ldap_authentication?(password), message)
11
+ end
12
+
13
+ context "With default settings" do
14
+ setup do
15
+ default_devise_settings!
16
+ reset_ldap_server!
17
+ end
18
+
19
+ context "look up and ldap user" do
20
+ should "return true for a user that does exist in LDAP" do
21
+ assert_equal true, ::Devise::LdapAdapter.valid_login?('example.user@test.com')
22
+ end
23
+
24
+ should "return false for a user that doesn't exist in LDAP" do
25
+ assert_equal false, ::Devise::LdapAdapter.valid_login?('barneystinson')
26
+ end
27
+ end
28
+
29
+ context "create a basic user" do
30
+ setup do
31
+ @user = Factory(:user)
32
+ end
33
+
34
+ should "check for password validation" do
35
+ assert_equal(@user.email, "example.user@test.com")
36
+ should_be_validated @user, "secret"
37
+ should_not_be_validated @user, "wrong_secret"
38
+ should_not_be_validated @user, "Secret"
39
+ end
40
+ end
41
+
42
+ context "change a LDAP password" do
43
+ setup do
44
+ @user = Factory(:user)
45
+ end
46
+
47
+ should "change password" do
48
+ should_be_validated @user, "secret"
49
+ @user.reset_password!("changed","changed")
50
+ should_be_validated @user, "changed", "password was not changed properly on the LDAP sevrer"
51
+ end
52
+
53
+ should "not allow to change password if setting is false" do
54
+ should_be_validated @user, "secret"
55
+ ::Devise.ldap_update_password = false
56
+ @user.reset_password!("wrong_secret", "wrong_secret")
57
+ should_not_be_validated @user, "wrong_secret"
58
+ should_be_validated @user, "secret"
59
+ end
60
+ end
61
+
62
+ context "create new local user if user is in LDAP" do
63
+
64
+ setup do
65
+ assert(User.all.blank?, "There shouldn't be any users in the database")
66
+ end
67
+
68
+ should "don't create user in the database" do
69
+ @user = User.authenticate_with_ldap(:email => "example.user@test.com", :password => "secret")
70
+ assert(User.all.blank?)
71
+ end
72
+
73
+ context "creating users is enabled" do
74
+ setup do
75
+ ::Devise.ldap_create_user = true
76
+ end
77
+
78
+ should "create a user in the database" do
79
+ @user = User.authenticate_with_ldap(:email => "example.user@test.com", :password => "secret")
80
+ assert_equal(User.all.size, 1)
81
+ assert_contains(User.all.collect(&:email), "example.user@test.com", "user not in database")
82
+ end
83
+
84
+ should "not create a user in the database if the password is wrong_secret" do
85
+ @user = User.authenticate_with_ldap(:email => "example.user", :password => "wrong_secret")
86
+ assert(User.all.blank?, "There's users in the database")
87
+ end
88
+
89
+ should "create a user if the user is not in LDAP" do
90
+ @user = User.authenticate_with_ldap(:email => "wrong_secret.user@test.com", :password => "wrong_secret")
91
+ assert(User.all.blank?, "There's users in the database")
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ context "use groups for authorization" do
98
+ setup do
99
+ @admin = Factory(:admin)
100
+ @user = Factory(:user)
101
+ ::Devise.authentication_keys = [:email]
102
+ ::Devise.ldap_check_group_membership = true
103
+ end
104
+
105
+ should "admin should be allowed in" do
106
+ should_be_validated @admin, "admin_secret"
107
+ end
108
+
109
+ should "admin should have the proper groups set" do
110
+ assert_contains(@admin.ldap_groups, /cn=admins/, "groups attribute not being set properly")
111
+ end
112
+
113
+ should "user should not be allowed in" do
114
+ should_not_be_validated @user, "secret"
115
+ end
116
+
117
+ should "not be validated if group with different attribute is removed" do
118
+ `ldapmodify #{ldap_connect_string} -f ../ldap/delete_authorization_role.ldif`
119
+ should_not_be_validated @admin, "admin_secret"
120
+ end
121
+ end
122
+
123
+ context "use role attribute for authorization" do
124
+ setup do
125
+ @admin = Factory(:admin)
126
+ @user = Factory(:user)
127
+ ::Devise.ldap_check_attributes = true
128
+ end
129
+
130
+ should "admin should be allowed in" do
131
+ should_be_validated @admin, "admin_secret"
132
+ end
133
+
134
+ should "user should not be allowed in" do
135
+ should_not_be_validated @user, "secret"
136
+ end
137
+ end
138
+
139
+ context "use admin setting to bind" do
140
+ setup do
141
+ @admin = Factory(:admin)
142
+ @user = Factory(:user)
143
+ ::Devise.ldap_use_admin_to_bind = true
144
+ end
145
+
146
+ should "description" do
147
+ should_be_validated @admin, "admin_secret"
148
+ end
149
+ end
150
+
151
+ end
152
+
153
+ context "use uid for login" do
154
+ setup do
155
+ default_devise_settings!
156
+ reset_ldap_server!
157
+ ::Devise.ldap_config = "#{Rails.root}/config/#{"ssl_" if ENV["LDAP_SSL"]}ldap_with_uid.yml"
158
+ ::Devise.authentication_keys = [:uid]
159
+ end
160
+
161
+ context "description" do
162
+ setup do
163
+ @admin = Factory(:admin)
164
+ @user = Factory(:user, :uid => "example_user")
165
+ end
166
+
167
+ should "be able to authenticate using uid" do
168
+ should_be_validated @user, "secret"
169
+ should_not_be_validated @admin, "admin_secret"
170
+ end
171
+ end
172
+
173
+ context "create user" do
174
+ setup do
175
+ ::Devise.ldap_create_user = true
176
+ end
177
+
178
+ should "create a user in the database" do
179
+ @user = User.authenticate_with_ldap(:uid => "example_user", :password => "secret")
180
+ assert_equal(User.all.size, 1)
181
+ assert_contains(User.all.collect(&:uid), "example_user", "user not in database")
182
+ end
183
+
184
+ should "call ldap_before_save hooks" do
185
+ User.class_eval do
186
+ def ldap_before_save
187
+ @foobar = 'foobar'
188
+ end
189
+ end
190
+ user = User.authenticate_with_ldap(:uid => "example_user", :password => "secret")
191
+ assert_equal 'foobar', user.instance_variable_get(:"@foobar")
192
+ User.class_eval do
193
+ undef ldap_before_save
194
+ end
195
+ end
196
+
197
+ should "not call ldap_before_save hook if not defined" do
198
+ assert_nothing_raised do
199
+ should_be_validated Factory(:user, :uid => "example_user"), "secret"
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ context "using ERB in the config file" do
206
+ setup do
207
+ default_devise_settings!
208
+ reset_ldap_server!
209
+ ::Devise.ldap_config = "#{Rails.root}/config/#{"ssl_" if ENV["LDAP_SSL"]}ldap_with_erb.yml"
210
+ end
211
+
212
+ context "authenticate" do
213
+ setup do
214
+ @admin = Factory(:admin)
215
+ @user = Factory(:user)
216
+ end
217
+
218
+ should "be able to authenticate" do
219
+ should_be_validated @user, "secret"
220
+ should_be_validated @admin, "admin_secret"
221
+ end
222
+ end
223
+ end
224
+
225
+ context "using variants in the config file" do
226
+ setup do
227
+ default_devise_settings!
228
+ reset_ldap_server!
229
+ ::Devise.ldap_config = Rails.root.join 'config', 'ldap_with_boolean_ssl.yml'
230
+ end
231
+
232
+ should "not fail if config file has ssl: true" do
233
+ assert_nothing_raised do
234
+ Devise::LdapAdapter::LdapConnect.new
235
+ end
236
+ end
237
+ end
238
+
239
+ context "use username builder" do
240
+ setup do
241
+ default_devise_settings!
242
+ reset_ldap_server!
243
+ ::Devise.ldap_auth_username_builder = Proc.new() do |attribute, login, ldap|
244
+ "#{attribute}=#{login},ou=others,dc=test,dc=com"
245
+ end
246
+ @other = Factory(:other)
247
+ end
248
+
249
+ should "be able to authenticate" do
250
+ should_be_validated @other, "other_secret"
251
+ end
252
+ end
253
+
254
+ end