devise_ldap_authenticatable 0.4.9 → 0.4.10

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -140,9 +140,9 @@ All unit and functional tests are part of a sample rails application under test/
140
140
  Build / Start Instructions for Test LDAP Server
141
141
  -----------------------------------------------
142
142
 
143
- Make sure that directories test/ldap/openldap-data and test/ldap/openldap-data/run exist.
143
+ These instructions require the current directory context to be the `test/ldap` directory relative to the project root.
144
144
 
145
- 1. To start the server, run `./run_server.sh`
145
+ 1. To start the server, run `./run-server.sh`
146
146
  2. Add the basic structure: `ldapadd -x -h localhost -p 3389 -x -D "cn=admin,dc=test,dc=com" -w secret -f base.ldif`
147
147
  * this creates the users / passwords:
148
148
  * cn=admin,dc=test,com / secret
@@ -151,7 +151,7 @@ Make sure that directories test/ldap/openldap-data and test/ldap/openldap-data/r
151
151
 
152
152
  _For a LDAP server running SSL_
153
153
 
154
- 1. To start the server, run: `./run_server.sh --ssl`
154
+ 1. To start the server, run: `./run-server.sh --ssl`
155
155
  2. Add the basic structure: `ldapadd -x -H ldaps://localhost:3389 -x -D "cn=admin,dc=test,dc=com" -w secret -f base.ldif`
156
156
  * this creates the users / passwords:
157
157
  * cn=admin,dc=test,com / secret
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.9
1
+ 0.4.10
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{devise_ldap_authenticatable}
8
- s.version = "0.4.9"
8
+ s.version = "0.4.10"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Curtis Schiewek", "Daniel McNevin"]
12
- s.date = %q{2011-07-06}
11
+ s.authors = ["Curtis Schiewek", "Daniel McNevin", "Steven Xu"]
12
+ s.date = %q{2011-10-17}
13
13
  s.description = %q{LDAP authentication module for Devise}
14
14
  s.email = %q{curtis.schiewek@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -34,6 +34,9 @@ module Devise
34
34
 
35
35
  mattr_accessor :ldap_auth_username_builder
36
36
  @@ldap_auth_username_builder = Proc.new() {|attribute, login, ldap| "#{attribute}=#{login},#{ldap.base}" }
37
+
38
+ mattr_accessor :ldap_ad_group_check
39
+ @@ldap_ad_group_check = false
37
40
  end
38
41
 
39
42
  # Add ldap_authenticatable strategy to defaults.
@@ -13,6 +13,14 @@ module Devise
13
13
  resource = LdapConnect.new(options)
14
14
  resource.authorized?
15
15
  end
16
+
17
+ def self.valid_login?(login)
18
+ options = {:login => login,
19
+ :ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
20
+ :admin => ::Devise.ldap_use_admin_to_bind}
21
+ resource = LdapConnect.new(options)
22
+ resource.valid_login?
23
+ end
16
24
 
17
25
  def self.update_password(login, new_password)
18
26
  options = {:login => login,
@@ -56,7 +64,8 @@ module Devise
56
64
  def initialize(params = {})
57
65
  ldap_config = YAML.load(ERB.new(File.read(::Devise.ldap_config || "#{Rails.root}/config/ldap.yml")).result)[Rails.env]
58
66
  ldap_options = params
59
- ldap_options[:encryption] = :simple_tls if ldap_config["ssl"]
67
+ ldap_config["ssl"] = :simple_tls if ldap_config["ssl"] === true
68
+ ldap_options[:encryption] = ldap_config["ssl"].to_sym if ldap_config["ssl"]
60
69
 
61
70
  @ldap = Net::LDAP.new(ldap_options)
62
71
  @ldap.host = ldap_config["host"]
@@ -77,10 +86,8 @@ module Devise
77
86
  end
78
87
 
79
88
  def dn
80
- DeviseLdapAuthenticatable::Logger.send("LDAP search: #{@attribute}=#{@login}")
81
- filter = Net::LDAP::Filter.eq(@attribute.to_s, @login.to_s)
82
- ldap_entry = nil
83
- @ldap.search(:filter => filter) {|entry| ldap_entry = entry}
89
+ DeviseLdapAuthenticatable::Logger.send("LDAP dn lookup: #{@attribute}=#{@login}")
90
+ ldap_entry = search_for_login
84
91
  if ldap_entry.nil?
85
92
  @ldap_auth_username_builder.call(@attribute,@login,@ldap)
86
93
  else
@@ -94,7 +101,7 @@ module Devise
94
101
  @ldap.search(:filter => filter) {|entry| ldap_entry = entry}
95
102
 
96
103
  DeviseLdapAuthenticatable::Logger.send("Requested param #{param} has value #{ldap_entry.send(param)}")
97
- ldap_entry.send(param).to_s
104
+ ldap_entry.send(param)
98
105
  end
99
106
 
100
107
  def authenticate!
@@ -130,14 +137,27 @@ module Devise
130
137
  group_attribute = "uniqueMember"
131
138
  group_name = group
132
139
  end
133
- admin_ldap.search(:base => group_name, :scope => Net::LDAP::SearchScope_BaseObject) do |entry|
134
- unless entry[group_attribute].include? dn
140
+ unless ::Devise.ldap_ad_group_check
141
+ admin_ldap.search(:base => group_name, :scope => Net::LDAP::SearchScope_BaseObject) do |entry|
142
+ unless entry[group_attribute].include? dn
143
+ DeviseLdapAuthenticatable::Logger.send("User #{dn} is not in group: #{group_name }")
144
+ return false
145
+ end
146
+ end
147
+ else
148
+ # AD optimization - extension will recursively check sub-groups with one query
149
+ # "(memberof:1.2.840.113556.1.4.1941:=group_name)"
150
+ search_result = admin_ldap.search(:base => dn,
151
+ :filter => Net::LDAP::Filter.ex("memberof:1.2.840.113556.1.4.1941", group_name),
152
+ :scope => Net::LDAP::SearchScope_BaseObject)
153
+ # Will return the user entry if belongs to group otherwise nothing
154
+ unless search_result.length == 1 && search_result[0].dn.eql?(dn)
135
155
  DeviseLdapAuthenticatable::Logger.send("User #{dn} is not in group: #{group_name }")
136
156
  return false
137
157
  end
138
158
  end
139
159
  end
140
-
160
+
141
161
  return true
142
162
  end
143
163
 
@@ -165,6 +185,10 @@ module Devise
165
185
  filter = Net::LDAP::Filter.eq("uniqueMember", dn)
166
186
  admin_ldap.search(:filter => filter, :base => @group_base).collect(&:dn)
167
187
  end
188
+
189
+ def valid_login?
190
+ !search_for_login.nil?
191
+ end
168
192
 
169
193
  private
170
194
 
@@ -183,6 +207,17 @@ module Devise
183
207
  DeviseLdapAuthenticatable::Logger.send("Finding user: #{dn}")
184
208
  ldap.search(:base => dn, :scope => Net::LDAP::SearchScope_BaseObject).try(:first)
185
209
  end
210
+
211
+ # Searches the LDAP for the login
212
+ #
213
+ # @return [Object] the LDAP entry found; nil if not found
214
+ def search_for_login
215
+ DeviseLdapAuthenticatable::Logger.send("LDAP search for login: #{@attribute}=#{@login}")
216
+ filter = Net::LDAP::Filter.eq(@attribute.to_s, @login.to_s)
217
+ ldap_entry = nil
218
+ @ldap.search(:filter => filter) {|entry| ldap_entry = entry}
219
+ ldap_entry
220
+ end
186
221
 
187
222
  def update_ldap(ops)
188
223
  operations = []
@@ -18,7 +18,8 @@ module Devise
18
18
  end
19
19
 
20
20
  def login_with
21
- self[::Devise.authentication_keys.first]
21
+ @login_with ||= Devise.mappings[self.class.to_s.underscore.to_sym].to.authentication_keys.first
22
+ self[@login_with]
22
23
  end
23
24
 
24
25
  def reset_password!(new_password, new_password_confirmation)
@@ -54,25 +55,36 @@ module Devise
54
55
  Devise::LdapAdapter.get_ldap_param(login_with,param)
55
56
  end
56
57
 
58
+ #
59
+ # callbacks
60
+ #
61
+
62
+ # # Called before the ldap record is saved automatically
63
+ # def ldap_before_save
64
+ # end
65
+
57
66
 
58
67
  module ClassMethods
59
68
  # Authenticate a user based on configured attribute keys. Returns the
60
69
  # authenticated user if it's valid or nil.
61
70
  def authenticate_with_ldap(attributes={})
62
- @login_with = ::Devise.authentication_keys.first
63
- return nil unless attributes[@login_with].present?
64
-
71
+ auth_key = self.authentication_keys.first
72
+ return nil unless attributes[auth_key].present?
73
+
65
74
  # resource = find_for_ldap_authentication(conditions)
66
- resource = where(@login_with => attributes[@login_with]).first
75
+ resource = where(auth_key => attributes[auth_key]).first
67
76
 
68
77
  if (resource.blank? and ::Devise.ldap_create_user)
69
78
  resource = new
70
- resource[@login_with] = attributes[@login_with]
79
+ resource[auth_key] = attributes[auth_key]
71
80
  resource.password = attributes[:password]
72
81
  end
73
82
 
74
83
  if resource.try(:valid_ldap_authentication?, attributes[:password])
75
- resource.save if resource.new_record?
84
+ if resource.new_record?
85
+ resource.ldap_before_save if resource.respond_to?(:ldap_before_save)
86
+ resource.save
87
+ end
76
88
  return resource
77
89
  else
78
90
  return nil
@@ -36,6 +36,7 @@ module DeviseLdapAuthenticatable
36
36
  # config.ldap_check_group_membership = false
37
37
  # config.ldap_check_attributes = false
38
38
  # config.ldap_use_admin_to_bind = false
39
+ # config.ldap_ad_group_check = false
39
40
 
40
41
  eof
41
42
  if options.advanced?
@@ -37,7 +37,7 @@ test:
37
37
  base: ou=people,dc=test,dc=com
38
38
  admin_user: cn=admin,dc=test,dc=com
39
39
  admin_password: admin_password
40
- ssl: false
40
+ ssl: simple_tls
41
41
  # <<: *AUTHORIZATIONS
42
42
 
43
43
  production:
@@ -47,5 +47,5 @@ production:
47
47
  base: ou=people,dc=test,dc=com
48
48
  admin_user: cn=admin,dc=test,dc=com
49
49
  admin_password: admin_password
50
- ssl: true
51
- # <<: *AUTHORIZATIONS
50
+ ssl: start_tls
51
+ # <<: *AUTHORIZATIONS
@@ -3,7 +3,7 @@ source 'http://rubygems.org'
3
3
  gem 'rails', '3.0.0'
4
4
  gem 'sqlite3-ruby', :require => 'sqlite3'
5
5
 
6
- gem "devise", "1.1.2"
6
+ gem "devise", "~> 1.4.0"
7
7
  gem "devise_ldap_authenticatable", :path => "../../"
8
8
 
9
9
  group :test do
@@ -1,9 +1,9 @@
1
1
  PATH
2
- remote: /Users/dpmcnevin/Rails/devise_ldap_authenticatable
2
+ remote: ../../
3
3
  specs:
4
- devise_ldap_authenticatable (0.4.5)
5
- devise (= 1.1.2)
6
- net-ldap (= 0.1.1)
4
+ devise_ldap_authenticatable (0.4.9)
5
+ devise (~> 1.4.0)
6
+ net-ldap (~> 0.2.2)
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
@@ -43,7 +43,7 @@ GEM
43
43
  autotest (>= 4.2.4)
44
44
  autotest-rails (4.1.0)
45
45
  ZenTest
46
- bcrypt-ruby (2.1.2)
46
+ bcrypt-ruby (3.0.1)
47
47
  builder (2.1.2)
48
48
  capybara (0.3.9)
49
49
  culerity (>= 0.2.4)
@@ -64,9 +64,10 @@ GEM
64
64
  cucumber (>= 0.8.0)
65
65
  culerity (0.2.12)
66
66
  database_cleaner (0.5.2)
67
- devise (1.1.2)
68
- bcrypt-ruby (~> 2.1.2)
69
- warden (~> 0.10.7)
67
+ devise (1.4.7)
68
+ bcrypt-ruby (~> 3.0)
69
+ orm_adapter (~> 0.0.3)
70
+ warden (~> 1.0.3)
70
71
  diff-lcs (1.1.2)
71
72
  erubis (2.6.6)
72
73
  abstract (>= 1.0.0)
@@ -91,8 +92,9 @@ GEM
91
92
  mime-types (1.16)
92
93
  mocha (0.9.8)
93
94
  rake
94
- net-ldap (0.1.1)
95
+ net-ldap (0.2.2)
95
96
  nokogiri (1.4.3.1)
97
+ orm_adapter (0.0.5)
96
98
  polyglot (0.3.1)
97
99
  rack (1.2.1)
98
100
  rack-mount (0.6.12)
@@ -132,8 +134,8 @@ GEM
132
134
  polyglot (>= 0.3.1)
133
135
  trollop (1.16.2)
134
136
  tzinfo (0.3.23)
135
- warden (0.10.7)
136
- rack (>= 1.0.0)
137
+ warden (1.0.5)
138
+ rack (>= 1.0)
137
139
 
138
140
  PLATFORMS
139
141
  ruby
@@ -145,7 +147,7 @@ DEPENDENCIES
145
147
  capybara
146
148
  cucumber-rails
147
149
  database_cleaner
148
- devise (= 1.1.2)
150
+ devise (~> 1.4.0)
149
151
  devise_ldap_authenticatable!
150
152
  factory_girl_rails
151
153
  launchy
@@ -1,8 +1,8 @@
1
- # This file is auto-generated from the current state of the database. Instead
1
+ # This file is auto-generated from the current state of the database. Instead
2
2
  # of editing this file, please use the migrations feature of Active Record to
3
3
  # incrementally modify your database, and then regenerate this schema definition.
4
4
  #
5
- # Note that this schema.rb definition is the authoritative source for your
5
+ # Note that this schema.rb definition is the authoritative source for your
6
6
  # database schema. If you need to create the application database on another
7
7
  # system, you should be using db:schema:load, not running all the migrations
8
8
  # from scratch. The latter is a flawed and unsustainable approach (the more migrations
@@ -22,7 +22,6 @@ ActiveRecord::Schema.define(:version => 20100708120448) do
22
22
  create_table "users", :force => true do |t|
23
23
  t.string "email", :default => "", :null => false
24
24
  t.string "encrypted_password", :limit => 128, :default => "", :null => false
25
- t.string "password_salt", :default => "", :null => false
26
25
  t.string "reset_password_token"
27
26
  t.string "remember_token"
28
27
  t.datetime "remember_created_at"
@@ -15,6 +15,16 @@ class UserTest < ActiveSupport::TestCase
15
15
  default_devise_settings!
16
16
  reset_ldap_server!
17
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
18
28
 
19
29
  context "create a basic user" do
20
30
  setup do
@@ -170,6 +180,25 @@ class UserTest < ActiveSupport::TestCase
170
180
  assert_equal(User.all.size, 1)
171
181
  assert_contains(User.all.collect(&:uid), "example_user", "user not in database")
172
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
173
202
  end
174
203
  end
175
204
 
@@ -192,6 +221,20 @@ class UserTest < ActiveSupport::TestCase
192
221
  end
193
222
  end
194
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
195
238
 
196
239
  context "use username builder" do
197
240
  setup do
metadata CHANGED
@@ -1,65 +1,47 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: devise_ldap_authenticatable
3
- version: !ruby/object:Gem::Version
4
- hash: 29
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.10
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 4
9
- - 9
10
- version: 0.4.9
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Curtis Schiewek
14
9
  - Daniel McNevin
10
+ - Steven Xu
15
11
  autorequire:
16
12
  bindir: bin
17
13
  cert_chain: []
18
-
19
- date: 2011-07-06 00:00:00 -04:00
20
- default_executable:
21
- dependencies:
22
- - !ruby/object:Gem::Dependency
14
+ date: 2011-10-17 00:00:00.000000000Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
23
17
  name: devise
24
- prerelease: false
25
- requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirement: &14061140 !ruby/object:Gem::Requirement
26
19
  none: false
27
- requirements:
20
+ requirements:
28
21
  - - ~>
29
- - !ruby/object:Gem::Version
30
- hash: 7
31
- segments:
32
- - 1
33
- - 4
34
- - 0
22
+ - !ruby/object:Gem::Version
35
23
  version: 1.4.0
36
24
  type: :runtime
37
- version_requirements: *id001
38
- - !ruby/object:Gem::Dependency
39
- name: net-ldap
40
25
  prerelease: false
41
- requirement: &id002 !ruby/object:Gem::Requirement
26
+ version_requirements: *14061140
27
+ - !ruby/object:Gem::Dependency
28
+ name: net-ldap
29
+ requirement: &14060660 !ruby/object:Gem::Requirement
42
30
  none: false
43
- requirements:
31
+ requirements:
44
32
  - - ~>
45
- - !ruby/object:Gem::Version
46
- hash: 19
47
- segments:
48
- - 0
49
- - 2
50
- - 2
33
+ - !ruby/object:Gem::Version
51
34
  version: 0.2.2
52
35
  type: :runtime
53
- version_requirements: *id002
36
+ prerelease: false
37
+ version_requirements: *14060660
54
38
  description: LDAP authentication module for Devise
55
39
  email: curtis.schiewek@gmail.com
56
40
  executables: []
57
-
58
41
  extensions: []
59
-
60
- extra_rdoc_files:
42
+ extra_rdoc_files:
61
43
  - README.md
62
- files:
44
+ files:
63
45
  - MIT-LICENSE
64
46
  - README.md
65
47
  - Rakefile
@@ -152,39 +134,28 @@ files:
152
134
  - test/rails_app/test/unit/post_test.rb
153
135
  - test/rails_app/test/unit/user_test.rb
154
136
  - test/test_helper.rb
155
- has_rdoc: true
156
137
  homepage: http://github.com/cschiewek/devise_ldap_authenticatable
157
138
  licenses: []
158
-
159
139
  post_install_message:
160
140
  rdoc_options: []
161
-
162
- require_paths:
141
+ require_paths:
163
142
  - lib
164
- required_ruby_version: !ruby/object:Gem::Requirement
143
+ required_ruby_version: !ruby/object:Gem::Requirement
165
144
  none: false
166
- requirements:
167
- - - ">="
168
- - !ruby/object:Gem::Version
169
- hash: 3
170
- segments:
171
- - 0
172
- version: "0"
173
- required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ! '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
150
  none: false
175
- requirements:
176
- - - ">="
177
- - !ruby/object:Gem::Version
178
- hash: 3
179
- segments:
180
- - 0
181
- version: "0"
151
+ requirements:
152
+ - - ! '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
182
155
  requirements: []
183
-
184
156
  rubyforge_project:
185
- rubygems_version: 1.5.2
157
+ rubygems_version: 1.8.10
186
158
  signing_key:
187
159
  specification_version: 3
188
160
  summary: LDAP authentication module for Devise
189
161
  test_files: []
190
-