devise_ldap_authenticatable 0.8.1 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 83f8abeb23a6a4f7ba011a20858268cc9bc1b0f8
4
- data.tar.gz: dca093640944a95c13037086cc74c94a39f9af02
3
+ metadata.gz: 2b851a53df509e6cf0d16292aa9192e06dfff3e7
4
+ data.tar.gz: 532280a974b9cf4bf52d34ff5a57b49cd33e6304
5
5
  SHA512:
6
- metadata.gz: 65d9174c9f3d1231a895da94b731662a1fc5f4b3018b7626c95e71c94d739520d2737dd3ce27a999e60d9f64503b95fb3c68224fcdcb3da842570ec18fd43af6
7
- data.tar.gz: 7cf26b625215614e7527745d3a32f449e592b56f7957cbad0a40cc253de4ccd63f6ef419d6854dcf8be28a555d25dd03c5de38eccef1e8279a56d9ece833099a
6
+ metadata.gz: dce1145454333fc039cab36e9c9c0c36178402fac1eff6f4d9bd552d3ac2eaa04fb8cf80e75750ed7c69e19fe93abe4a697288fb646f70481084114133c76725
7
+ data.tar.gz: c5084e9417909665e9aecb7591dad2fbaa42543498ad179a9ca7ce8fc75315c3c278c36ce5a4ddf74c7f202f64d34089bc17d828bff451e896ca116d5aa1338d
data/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  Devise LDAP Authenticatable
2
2
  ===========================
3
+
4
+ Why this fork?
5
+ --------------
6
+ This fork changes a few lines to allow the admin binding to be set to the user trying to log in.
7
+
3
8
  [![Gem Version](https://badge.fury.io/rb/devise_ldap_authenticatable.png)](http://badge.fury.io/rb/devise_ldap_authenticatable)
4
9
  [![Code Climate](https://codeclimate.com/github/cschiewek/devise_ldap_authenticatable.png)](https://codeclimate.com/github/cschiewek/devise_ldap_authenticatable)
5
10
  [![Dependency Status](https://gemnasium.com/cschiewek/devise_ldap_authenticatable.png)](https://gemnasium.com/cschiewek/devise_ldap_authenticatable)
@@ -41,7 +46,7 @@ Run the rails generator for `devise_ldap_authenticatable`
41
46
 
42
47
  rails generate devise_ldap_authenticatable:install [options]
43
48
 
44
- This will install the sample.yml, update the devise.rb initializer, and update your user model. There are some options you can pass to it:
49
+ This will install the ldap.yml, update the devise.rb initializer, and update your user model. There are some options you can pass to it:
45
50
 
46
51
  Options:
47
52
 
@@ -57,12 +62,10 @@ Querying LDAP
57
62
  -------------
58
63
  Given that `ldap_create_user` is set to true and you are authenticating with username, you can query an LDAP server for other attributes.
59
64
 
60
- in your user model:
65
+ in your user model you have to simply define `ldap_before_save` method:
61
66
 
62
- before_save :get_ldap_email
63
-
64
- def get_ldap_email
65
- self.email = Devise::LdapAdapter.get_ldap_param(self.username,"mail")
67
+ def ldap_before_save
68
+ self.email = Devise::LDAP::Adapter.get_ldap_param(self.username,"mail").first
66
69
  end
67
70
 
68
71
  Configuration
@@ -71,25 +74,20 @@ In initializer `config/initializers/devise.rb` :
71
74
 
72
75
  * `ldap_logger` _(default: true)_
73
76
  * If set to true, will log LDAP queries to the Rails logger.
74
-
75
77
  * `ldap_create_user` _(default: false)_
76
- * If set to true, all valid LDAP users will be allowed to login and an appropriate user record will be created.
77
- If set to false, you will have to create the user record before they will be allowed to login.
78
-
78
+ * If set to true, all valid LDAP users will be allowed to login and an appropriate user record will be created. If set to false, you will have to create the user record before they will be allowed to login.
79
79
  * `ldap_config` _(default: #{Rails.root}/config/ldap.yml)_
80
- * Where to find the LDAP config file. Commented out to use the default, change if needed.
81
-
80
+ * Where to find the LDAP config file. Commented out to use the default, change if needed.
82
81
  * `ldap_update_password` _(default: true)_
83
82
  * When doing password resets, if true will update the LDAP server. Requires admin password in the ldap.yml
84
-
85
83
  * `ldap_check_group_membership` _(default: false)_
86
84
  * When set to true, the user trying to login will be checked to make sure they are in all of groups specified in the ldap.yml file.
87
-
88
85
  * `ldap_check_attributes` _(default: false)_
89
86
  * When set to true, the user trying to login will be checked to make sure they have all of the attributes in the ldap.yml file.
90
-
91
87
  * `ldap_use_admin_to_bind` _(default: false)_
92
88
  * When set to true, the admin user will be used to bind to the LDAP server during authentication.
89
+ * `ldap_check_group_membership_without_admin` _(default: false)_
90
+ * When set to true, the group membership check is done with the user's own credentials rather than with admin credentials. Since these credentials are only available to the Devise user model during the login flow, the group check function will not work if a group check is performed when this option is true outside of the login flow (e.g., before particular actions).
93
91
 
94
92
  Advanced Configuration
95
93
  ----------------------
@@ -97,10 +95,12 @@ These parameters will be added to `config/initializers/devise.rb` when you pass
97
95
 
98
96
  * `ldap_auth_username_builder` _(default: `Proc.new() {|attribute, login, ldap| "#{attribute}=#{login},#{ldap.base}" }`)_
99
97
  * You can pass a proc to the username option to explicitly specify the format that you search for a users' DN on your LDAP server.
98
+ * `ldap_auth_password_build` _(default: `Proc.new() {|new_password| Net::LDAP::Password.generate(:sha, new_password) }`)_
99
+ * Optionally you can define a proc to create custom password encrption when user reset password
100
100
 
101
101
  Troubleshooting
102
102
  --------------
103
- **Using a "username" instead of an "email":** The field that is used for logins is the first key that's configured in the `config/devise.rb` file under `config.authentication_keys`, which by default is email. For help changing this, please see the [Railscast](http://railscasts.com/episodes/210-customizing-devise) that goes through how to customize Devise.
103
+ **Using a "username" instead of an "email":** The field that is used for logins is the first key that's configured in the `config/initializers/devise.rb` file under `config.authentication_keys`, which by default is email. For help changing this, please see the [Railscast](http://railscasts.com/episodes/210-customizing-devise) that goes through how to customize Devise. Also, this [documentation](https://github.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-sign-in-using-their-username-or-email-address) from Devise can very helpful.
104
104
 
105
105
  **SSL certificate invalid:** If you're using a test LDAP server running a self-signed SSL certificate, make sure the appropriate root certificate is installed on your system. Alternately, you may temporarily disable certificate checking for SSL by modifying your system LDAP configuration (e.g., `/etc/openldap/ldap.conf` or `/etc/ldap/ldap.conf`) to read `TLS_REQCERT never`.
106
106
 
@@ -111,11 +111,12 @@ For additional support, questions or discussions, please see the discussion foru
111
111
 
112
112
  Development guide
113
113
  ------------
114
- To contribute to `devise_ldap_authentication`, you should be able to run a test OpenLDAP server. Specifically, you need the `slapd`, `ldapadd`, and `ldapmodify` binaries.
115
114
 
116
- This seems to come out of the box with Mac OS X 10.6.
115
+ Devise LDAP Authenticatable uses a running OpenLDAP server to do automated acceptance tests. You'll need the executables `slapd`, `ldapadd`, and `ldapmodify`.
116
+
117
+ On OS X, this is available out of the box.
117
118
 
118
- On Ubuntu (tested on 12.04 and 12.10), you can run `sudo apt-get install slapd ldap-utils`. You will also likely have to add the `spec/ldap` directory of your local git clone to the slapd [apparmor](https://wiki.ubuntu.com/DebuggingApparmor) profile `/etc/apparmor.d/usr.sbin.slapd` if you get permissions errors. Something like this should do:
119
+ On Ubuntu, you can install OpenLDAP with `sudo apt-get install slapd ldap-utils`. If slapd runs under AppArmor, add an exception like this to `/etc/apparmor.d/local/usr.sbin.slapd` to let slapd read our configs.
119
120
 
120
121
  /path/to/devise_ldap_authenticatable/spec/ldap/** rw,$
121
122
 
@@ -16,6 +16,8 @@ module Devise
16
16
  mattr_accessor :ldap_create_user
17
17
  @@ldap_create_user = false
18
18
 
19
+ # A path to YAML config file or a Proc that returns a
20
+ # configuration hash
19
21
  mattr_accessor :ldap_config
20
22
  # @@ldap_config = "#{Rails.root}/config/ldap.yml"
21
23
 
@@ -44,4 +46,4 @@ Devise.add_module(:ldap_authenticatable,
44
46
  :route => :session, ## This will add the routes, rather than in the routes.rb
45
47
  :strategy => true,
46
48
  :controller => :sessions,
47
- :model => 'devise_ldap_authenticatable/model')
49
+ :model => 'devise_ldap_authenticatable/model')
@@ -26,7 +26,7 @@ module Devise
26
26
  end
27
27
 
28
28
  def self.update_own_password(login, new_password, current_password)
29
- set_ldap_param(login, :userpassword, Net::LDAP::Password.generate(:sha, new_password), current_password)
29
+ set_ldap_param(login, :userPassword, ::Devise.ldap_auth_password_builder.call(new_password), current_password)
30
30
  end
31
31
 
32
32
  def self.ldap_connect(login)
@@ -84,4 +84,4 @@ module Devise
84
84
 
85
85
  end
86
86
 
87
- end
87
+ end
@@ -4,7 +4,11 @@ module Devise
4
4
  attr_reader :ldap, :login
5
5
 
6
6
  def initialize(params = {})
7
- ldap_config = YAML.load(ERB.new(File.read(::Devise.ldap_config || "#{Rails.root}/config/ldap.yml")).result)[Rails.env]
7
+ if ::Devise.ldap_config.is_a?(Proc)
8
+ ldap_config = ::Devise.ldap_config.call
9
+ else
10
+ ldap_config = YAML.load(ERB.new(File.read(::Devise.ldap_config || "#{Rails.root}/config/ldap.yml")).result)[Rails.env]
11
+ end
8
12
  ldap_options = params
9
13
  ldap_config["ssl"] = :simple_tls if ldap_config["ssl"] === true
10
14
  ldap_options[:encryption] = ldap_config["ssl"].to_sym if ldap_config["ssl"]
@@ -14,6 +18,8 @@ module Devise
14
18
  @ldap.port = ldap_config["port"]
15
19
  @ldap.base = ldap_config["base"]
16
20
  @attribute = ldap_config["attribute"]
21
+ @allow_unauthenticated_bind = ldap_config["allow_unauthenticated_bind"]
22
+
17
23
  @ldap_auth_username_builder = params[:ldap_auth_username_builder]
18
24
 
19
25
  @group_base = ldap_config["group_base"]
@@ -22,6 +28,7 @@ module Devise
22
28
  @required_attributes = ldap_config["require_attribute"]
23
29
 
24
30
  @ldap.auth ldap_config["admin_user"], ldap_config["admin_password"] if params[:admin]
31
+ @ldap.auth params[:login], params[:password] if ldap_config["admin_as_user"]
25
32
 
26
33
  @login = params[:login]
27
34
  @password = params[:password]
@@ -37,19 +44,19 @@ module Devise
37
44
  end
38
45
 
39
46
  def dn
40
- DeviseLdapAuthenticatable::Logger.send("LDAP dn lookup: #{@attribute}=#{@login}")
41
- ldap_entry = search_for_login
42
- if ldap_entry.nil?
43
- @ldap_auth_username_builder.call(@attribute,@login,@ldap)
44
- else
45
- ldap_entry.dn
47
+ @dn ||= begin
48
+ DeviseLdapAuthenticatable::Logger.send("LDAP dn lookup: #{@attribute}=#{@login}")
49
+ ldap_entry = search_for_login
50
+ if ldap_entry.nil?
51
+ @ldap_auth_username_builder.call(@attribute,@login,@ldap)
52
+ else
53
+ ldap_entry.dn
54
+ end
46
55
  end
47
56
  end
48
57
 
49
58
  def ldap_param_value(param)
50
- filter = Net::LDAP::Filter.eq(@attribute.to_s, @login.to_s)
51
- ldap_entry = nil
52
- @ldap.search(:filter => filter) {|entry| ldap_entry = entry}
59
+ ldap_entry = search_for_login
53
60
 
54
61
  if ldap_entry
55
62
  unless ldap_entry[param].empty?
@@ -67,6 +74,7 @@ module Devise
67
74
  end
68
75
 
69
76
  def authenticate!
77
+ return false unless (@password.present? || @allow_unauthenticated_bind)
70
78
  @ldap.auth(dn, @password)
71
79
  @ldap.bind
72
80
  end
@@ -174,13 +182,15 @@ module Devise
174
182
  #
175
183
  # @return [Object] the LDAP entry found; nil if not found
176
184
  def search_for_login
177
- DeviseLdapAuthenticatable::Logger.send("LDAP search for login: #{@attribute}=#{@login}")
178
- filter = Net::LDAP::Filter.eq(@attribute.to_s, @login.to_s)
179
- ldap_entry = nil
180
- match_count = 0
181
- @ldap.search(:filter => filter) {|entry| ldap_entry = entry; match_count+=1}
182
- DeviseLdapAuthenticatable::Logger.send("LDAP search yielded #{match_count} matches")
183
- ldap_entry
185
+ @login_ldap_entry ||= begin
186
+ DeviseLdapAuthenticatable::Logger.send("LDAP search for login: #{@attribute}=#{@login}")
187
+ filter = Net::LDAP::Filter.eq(@attribute.to_s, @login.to_s)
188
+ ldap_entry = nil
189
+ match_count = 0
190
+ @ldap.search(:filter => filter) {|entry| ldap_entry = entry; match_count+=1}
191
+ DeviseLdapAuthenticatable::Logger.send("LDAP search yielded #{match_count} matches")
192
+ ldap_entry
193
+ end
184
194
  end
185
195
 
186
196
  private
@@ -223,4 +233,4 @@ module Devise
223
233
  end
224
234
  end
225
235
  end
226
- end
236
+ end
@@ -1,4 +1,4 @@
1
- require 'devise_ldap_authenticatable/strategy'
1
+ require 'devise_ldap_authenticatable/strategy'
2
2
 
3
3
  module Devise
4
4
  module Models
@@ -18,7 +18,7 @@ module Devise
18
18
  end
19
19
 
20
20
  def login_with
21
- @login_with ||= Devise.mappings[self.class.to_s.underscore.to_sym].to.authentication_keys.first
21
+ @login_with ||= Devise.mappings.find {|k,v| v.class_name == self.class.name}.last.to.authentication_keys.first
22
22
  self[@login_with]
23
23
  end
24
24
 
@@ -45,11 +45,11 @@ module Devise
45
45
 
46
46
  # Checks if a resource is valid upon authentication.
47
47
  def valid_ldap_authentication?(password)
48
- if Devise::LDAP::Adapter.valid_credentials?(login_with, password)
49
- return true
50
- else
51
- return false
52
- end
48
+ Devise::LDAP::Adapter.valid_credentials?(login_with, password)
49
+ end
50
+
51
+ def ldap_entry
52
+ @ldap_entry ||= Devise::LDAP::Adapter.get_ldap_entry(login_with)
53
53
  end
54
54
 
55
55
  def ldap_groups
@@ -61,11 +61,15 @@ module Devise
61
61
  end
62
62
 
63
63
  def ldap_dn
64
- Devise::LDAP::Adapter.get_dn(login_with)
64
+ ldap_entry ? ldap_entry.dn : nil
65
65
  end
66
66
 
67
- def ldap_get_param(login_with, param)
68
- Devise::LDAP::Adapter.get_ldap_param(login_with,param)
67
+ def ldap_get_param(param)
68
+ if ldap_entry && !ldap_entry[param].empty?
69
+ value = ldap_entry.send(param)
70
+ else
71
+ nil
72
+ end
69
73
  end
70
74
 
71
75
  #
@@ -76,34 +80,34 @@ module Devise
76
80
  # def ldap_before_save
77
81
  # end
78
82
 
83
+ # Called after a successful LDAP authentication
84
+ def after_ldap_authentication
85
+ end
86
+
79
87
 
80
88
  module ClassMethods
81
- # Authenticate a user based on configured attribute keys. Returns the
82
- # authenticated user if it's valid or nil.
83
- def authenticate_with_ldap(attributes={})
89
+ # Find a user for ldap authentication.
90
+ def find_for_ldap_authentication(attributes={})
84
91
  auth_key = self.authentication_keys.first
85
92
  return nil unless attributes[auth_key].present?
86
93
 
87
94
  auth_key_value = (self.case_insensitive_keys || []).include?(auth_key) ? attributes[auth_key].downcase : attributes[auth_key]
95
+ auth_key_value = (self.strip_whitespace_keys || []).include?(auth_key) ? auth_key_value.strip : auth_key_value
88
96
 
89
- # resource = find_for_ldap_authentication(conditions)
90
97
  resource = where(auth_key => auth_key_value).first
91
98
 
92
- if (resource.blank? and ::Devise.ldap_create_user)
99
+ if resource.blank?
93
100
  resource = new
94
101
  resource[auth_key] = auth_key_value
95
102
  resource.password = attributes[:password]
96
103
  end
97
104
 
98
- if resource.try(:valid_ldap_authentication?, attributes[:password])
99
- if resource.new_record?
100
- resource.ldap_before_save if resource.respond_to?(:ldap_before_save)
101
- resource.save!
102
- end
103
- return resource
104
- else
105
- return nil
105
+ if ::Devise.ldap_create_user && resource.new_record? && resource.valid_ldap_authentication?(attributes[:password])
106
+ resource.ldap_before_save if resource.respond_to?(:ldap_before_save)
107
+ resource.save!
106
108
  end
109
+
110
+ resource
107
111
  end
108
112
 
109
113
  def update_with_password(resource)
@@ -3,16 +3,35 @@ require 'devise/strategies/authenticatable'
3
3
  module Devise
4
4
  module Strategies
5
5
  class LdapAuthenticatable < Authenticatable
6
+
7
+ # Tests whether the returned resource exists in the database and the
8
+ # credentials are valid. If the resource is in the database and the credentials
9
+ # are valid, the user is authenticated. Otherwise failure messages are returned
10
+ # indicating whether the resource is not found in the database or the credentials
11
+ # are invalid.
6
12
  def authenticate!
7
- resource = valid_password? && mapping.to.authenticate_with_ldap(authentication_hash.merge(password: password))
8
- return fail(:invalid) unless resource
13
+ resource = mapping.to.find_for_ldap_authentication(authentication_hash.merge(password: password))
14
+
15
+ if resource.persisted?
16
+ if validate(resource) { resource.valid_ldap_authentication?(password) }
17
+ remember_me(resource)
18
+ resource.after_ldap_authentication
19
+ success!(resource)
20
+ else
21
+ return fail(:invalid) # Invalid credentials
22
+ end
23
+ end
9
24
 
10
- if validate(resource)
11
- success!(resource)
25
+ if resource.new_record?
26
+ if validate(resource) { resource.valid_ldap_authentication?(password) }
27
+ return fail(:not_found_in_database) # Valid credentials
28
+ else
29
+ return fail(:invalid) # Invalid credentials
30
+ end
12
31
  end
13
32
  end
14
33
  end
15
34
  end
16
35
  end
17
36
 
18
- Warden::Strategies.add(:ldap_authenticatable, Devise::Strategies::LdapAuthenticatable)
37
+ Warden::Strategies.add(:ldap_authenticatable, Devise::Strategies::LdapAuthenticatable)
@@ -1,3 +1,3 @@
1
1
  module DeviseLdapAuthenticatable
2
- VERSION = "0.8.1".freeze
2
+ VERSION = "0.8.3".freeze
3
3
  end
@@ -1,31 +1,31 @@
1
1
  module DeviseLdapAuthenticatable
2
2
  class InstallGenerator < Rails::Generators::Base
3
3
  source_root File.expand_path("../templates", __FILE__)
4
-
4
+
5
5
  class_option :user_model, :type => :string, :default => "user", :desc => "Model to update"
6
6
  class_option :update_model, :type => :boolean, :default => true, :desc => "Update model to change from database_authenticatable to ldap_authenticatable"
7
7
  class_option :add_rescue, :type => :boolean, :default => true, :desc => "Update Application Controller with resuce_from for DeviseLdapAuthenticatable::LdapException"
8
8
  class_option :advanced, :type => :boolean, :desc => "Add advanced config options to the devise initializer"
9
-
10
-
9
+
10
+
11
11
  def create_ldap_config
12
12
  copy_file "ldap.yml", "config/ldap.yml"
13
13
  end
14
-
14
+
15
15
  def create_default_devise_settings
16
16
  inject_into_file "config/initializers/devise.rb", default_devise_settings, :after => "Devise.setup do |config|\n"
17
17
  end
18
-
18
+
19
19
  def update_user_model
20
20
  gsub_file "app/models/#{options.user_model}.rb", /:database_authenticatable/, ":ldap_authenticatable" if options.update_model?
21
21
  end
22
-
22
+
23
23
  def update_application_controller
24
24
  inject_into_class "app/controllers/application_controller.rb", ApplicationController, rescue_from_exception if options.add_rescue?
25
25
  end
26
-
26
+
27
27
  private
28
-
28
+
29
29
  def default_devise_settings
30
30
  settings = <<-eof
31
31
  # ==> LDAP Configuration
@@ -34,22 +34,23 @@ module DeviseLdapAuthenticatable
34
34
  # config.ldap_update_password = true
35
35
  # config.ldap_config = "\#{Rails.root}/config/ldap.yml"
36
36
  # config.ldap_check_group_membership = false
37
+ # config.ldap_check_group_membership_without_admin = false
37
38
  # config.ldap_check_attributes = false
38
39
  # config.ldap_use_admin_to_bind = false
39
40
  # config.ldap_ad_group_check = false
40
-
41
+
41
42
  eof
42
43
  if options.advanced?
43
44
  settings << <<-eof
44
45
  # ==> Advanced LDAP Configuration
45
46
  # config.ldap_auth_username_builder = Proc.new() {|attribute, login, ldap| "\#{attribute}=\#{login},\#{ldap.base}" }
46
-
47
+
47
48
  eof
48
49
  end
49
-
50
+
50
51
  settings
51
52
  end
52
-
53
+
53
54
  def rescue_from_exception
54
55
  <<-eof
55
56
  rescue_from DeviseLdapAuthenticatable::LdapException do |exception|
@@ -57,6 +58,6 @@ module DeviseLdapAuthenticatable
57
58
  end
58
59
  eof
59
60
  end
60
-
61
+
61
62
  end
62
63
  end
@@ -3,6 +3,7 @@
3
3
  # You can also just copy and paste the tree (do not include the "authorizations") to each
4
4
  # environment if you need something different per enviornment.
5
5
  authorizations: &AUTHORIZATIONS
6
+ allow_unauthenticated_bind: false
6
7
  group_base: ou=groups,dc=test,dc=com
7
8
  ## Requires config.ldap_check_group_membership in devise.rb be true
8
9
  # Can have multiple values, must match all to be authorized
@@ -16,6 +16,11 @@ Devise.setup do |config|
16
16
  # note that it will be overwritten if you use your own mailer class with default "from" parameter.
17
17
  config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com"
18
18
 
19
+
20
+ if ::Devise.respond_to?(:secret_key)
21
+ ::Devise.secret_key = '012a16191a7f61e84e55704e34b73db991a23ba396b6b7760596a3e80073e4464c55421c42a1a34327dee44828bec6745c48eba10cc0866799ec95c09ea27ada'
22
+ end
23
+
19
24
  # Configure the class responsible to send e-mails.
20
25
  # config.mailer = "Devise::Mailer"
21
26
 
@@ -17,6 +17,7 @@ en:
17
17
  unauthenticated: 'You need to sign in or sign up before continuing.'
18
18
  unconfirmed: 'You have to confirm your account before continuing.'
19
19
  locked: 'Your account is locked.'
20
+ not_found_in_database: "Your account is not present in this application's database."
20
21
  invalid: 'Invalid email or password.'
21
22
  invalid_token: 'Invalid authentication token.'
22
23
  timeout: 'Your session expired, please sign in again to continue.'
@@ -5,6 +5,14 @@ require 'rspec/rails'
5
5
  require 'rspec/autorun'
6
6
  require 'factory_girl' # not sure why this is not already required
7
7
 
8
+ # Rails 4.1 and RSpec are a bit on different pages on who should run migrations
9
+ # on the test db and when.
10
+ #
11
+ # https://github.com/rspec/rspec-rails/issues/936
12
+ if defined?(ActiveRecord::Migration) && ActiveRecord::Migration.respond_to?(:maintain_test_schema!)
13
+ ActiveRecord::Migration.maintain_test_schema!
14
+ end
15
+
8
16
  Dir[File.expand_path("support/**/*.rb", File.dirname(__FILE__))].each {|f| require f}
9
17
 
10
18
  RSpec.configure do |config|
@@ -0,0 +1,14 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ describe 'Connection' do
4
+ it 'accepts a proc for ldap_config' do
5
+ ::Devise.ldap_config = Proc.new() {{
6
+ 'host' => 'localhost',
7
+ 'port' => 3389,
8
+ 'base' => 'ou=testbase,dc=test,dc=com',
9
+ 'attribute' => 'cn',
10
+ }}
11
+ connection = Devise::LDAP::Connection.new()
12
+ expect(connection.ldap.base).to eq('ou=testbase,dc=test,dc=com')
13
+ end
14
+ end
@@ -66,9 +66,10 @@ describe 'Users' do
66
66
  assert(User.all.blank?, "There shouldn't be any users in the database")
67
67
  end
68
68
 
69
- it "should don't create user in the database" do
70
- @user = User.authenticate_with_ldap(:email => "example.user@test.com", :password => "secret")
69
+ it "should not create user in the database" do
70
+ @user = User.find_for_ldap_authentication(:email => "example.user@test.com", :password => "secret")
71
71
  assert(User.all.blank?)
72
+ assert(@user.new_record?)
72
73
  end
73
74
 
74
75
  describe "creating users is enabled" do
@@ -77,18 +78,19 @@ describe 'Users' do
77
78
  end
78
79
 
79
80
  it "should create a user in the database" do
80
- @user = User.authenticate_with_ldap(:email => "example.user@test.com", :password => "secret")
81
+ @user = User.find_for_ldap_authentication(:email => "example.user@test.com", :password => "secret")
81
82
  assert_equal(User.all.size, 1)
82
83
  User.all.collect(&:email).should include("example.user@test.com")
84
+ assert(@user.persisted?)
83
85
  end
84
86
 
85
87
  it "should not create a user in the database if the password is wrong_secret" do
86
- @user = User.authenticate_with_ldap(:email => "example.user", :password => "wrong_secret")
88
+ @user = User.find_for_ldap_authentication(:email => "example.user", :password => "wrong_secret")
87
89
  assert(User.all.blank?, "There's users in the database")
88
90
  end
89
91
 
90
- it "should create a user if the user is not in LDAP" do
91
- @user = User.authenticate_with_ldap(:email => "wrong_secret.user@test.com", :password => "wrong_secret")
92
+ it "should not create a user if the user is not in LDAP" do
93
+ @user = User.find_for_ldap_authentication(:email => "wrong_secret.user@test.com", :password => "wrong_secret")
92
94
  assert(User.all.blank?, "There's users in the database")
93
95
  end
94
96
 
@@ -97,7 +99,7 @@ describe 'Users' do
97
99
  @user = Factory.create(:user)
98
100
 
99
101
  expect do
100
- User.authenticate_with_ldap(:email => "EXAMPLE.user@test.com", :password => "secret")
102
+ User.find_for_ldap_authentication(:email => "EXAMPLE.user@test.com", :password => "secret")
101
103
  end.to change { User.count }.by(1)
102
104
  end
103
105
 
@@ -106,14 +108,14 @@ describe 'Users' do
106
108
  @user = Factory.create(:user)
107
109
 
108
110
  expect do
109
- User.authenticate_with_ldap(:email => "EXAMPLE.user@test.com", :password => "secret")
111
+ User.find_for_ldap_authentication(:email => "EXAMPLE.user@test.com", :password => "secret")
110
112
  end.to_not change { User.count }
111
113
  end
112
114
 
113
115
  it "should create a user with downcased email in the database if case insensitivity matters" do
114
116
  ::Devise.case_insensitive_keys = [:email]
115
117
 
116
- @user = User.authenticate_with_ldap(:email => "EXAMPLE.user@test.com", :password => "secret")
118
+ @user = User.find_for_ldap_authentication(:email => "EXAMPLE.user@test.com", :password => "secret")
117
119
  User.all.collect(&:email).should include("example.user@test.com")
118
120
  end
119
121
  end
@@ -167,7 +169,37 @@ describe 'Users' do
167
169
  assert_equal false, @user.in_ldap_group?('cn=thisgroupdoesnotexist,ou=groups,dc=test,dc=com')
168
170
  end
169
171
  end
170
-
172
+
173
+ describe "check group membership w/out admin bind" do
174
+ before do
175
+ @user = Factory.create(:user)
176
+ ::Devise.ldap_check_group_membership_without_admin = true
177
+ end
178
+
179
+ after do
180
+ ::Devise.ldap_check_group_membership_without_admin = false
181
+ end
182
+
183
+ it "should return true for user being in the users group" do
184
+ assert_equal true, @user.in_ldap_group?('cn=users,ou=groups,dc=test,dc=com')
185
+ end
186
+
187
+ it "should return false for user being in the admins group" do
188
+ assert_equal false, @user.in_ldap_group?('cn=admins,ou=groups,dc=test,dc=com')
189
+ end
190
+
191
+ it "should return false for a user being in a nonexistent group" do
192
+ assert_equal false, @user.in_ldap_group?('cn=thisgroupdoesnotexist,ou=groups,dc=test,dc=com')
193
+ end
194
+
195
+ # TODO: add a test that confirms the user's own binding is used rather
196
+ # than the admin binding by creating an LDAP user who can't do group
197
+ # lookups perhaps?
198
+
199
+ # TODO: add a test to demonstrate this function won't work on a user
200
+ # after the initial login request if the password isn't available. This
201
+ # might have to be more of a full stack test.
202
+ end
171
203
 
172
204
  describe "use role attribute for authorization" do
173
205
  before do
@@ -225,7 +257,7 @@ describe 'Users' do
225
257
  end
226
258
 
227
259
  it "should create a user in the database" do
228
- @user = User.authenticate_with_ldap(:uid => "example_user", :password => "secret")
260
+ @user = User.find_for_ldap_authentication(:uid => "example_user", :password => "secret")
229
261
  assert_equal(User.all.size, 1)
230
262
  User.all.collect(&:uid).should include("example_user")
231
263
  end
@@ -236,7 +268,7 @@ describe 'Users' do
236
268
  @foobar = 'foobar'
237
269
  end
238
270
  end
239
- user = User.authenticate_with_ldap(:uid => "example_user", :password => "secret")
271
+ user = User.find_for_ldap_authentication(:uid => "example_user", :password => "secret")
240
272
  assert_equal 'foobar', user.instance_variable_get(:"@foobar")
241
273
  User.class_eval do
242
274
  undef ldap_before_save
@@ -244,9 +276,7 @@ describe 'Users' do
244
276
  end
245
277
 
246
278
  it "should not call ldap_before_save hook if not defined" do
247
- assert_nothing_raised do
248
- should_be_validated Factory.create(:user, :uid => "example_user"), "secret"
249
- end
279
+ should_be_validated Factory.create(:user, :uid => "example_user"), "secret"
250
280
  end
251
281
  end
252
282
  end
@@ -279,9 +309,7 @@ describe 'Users' do
279
309
  end
280
310
 
281
311
  it "should not fail if config file has ssl: true" do
282
- assert_nothing_raised do
283
- Devise::LDAP::Connection.new
284
- end
312
+ Devise::LDAP::Connection.new
285
313
  end
286
314
  end
287
315
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_ldap_authenticatable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Curtis Schiewek
@@ -10,180 +10,180 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-07-24 00:00:00.000000000 Z
13
+ date: 2015-03-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: devise
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - '>='
19
+ - - ">="
20
20
  - !ruby/object:Gem::Version
21
21
  version: '3.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - '>='
26
+ - - ">="
27
27
  - !ruby/object:Gem::Version
28
28
  version: '3.0'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: net-ldap
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - '>='
33
+ - - ">="
34
34
  - !ruby/object:Gem::Version
35
35
  version: 0.3.1
36
- - - <
36
+ - - "<"
37
37
  - !ruby/object:Gem::Version
38
38
  version: 0.6.0
39
39
  type: :runtime
40
40
  prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
42
42
  requirements:
43
- - - '>='
43
+ - - ">="
44
44
  - !ruby/object:Gem::Version
45
45
  version: 0.3.1
46
- - - <
46
+ - - "<"
47
47
  - !ruby/object:Gem::Version
48
48
  version: 0.6.0
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: rake
51
51
  requirement: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - '>='
53
+ - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0.9'
56
56
  type: :development
57
57
  prerelease: false
58
58
  version_requirements: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - '>='
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0.9'
63
63
  - !ruby/object:Gem::Dependency
64
64
  name: rdoc
65
65
  requirement: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - '>='
67
+ - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '3'
70
70
  type: :development
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - '>='
74
+ - - ">="
75
75
  - !ruby/object:Gem::Version
76
76
  version: '3'
77
77
  - !ruby/object:Gem::Dependency
78
78
  name: rails
79
79
  requirement: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - '>='
81
+ - - ">="
82
82
  - !ruby/object:Gem::Version
83
83
  version: '4.0'
84
84
  type: :development
85
85
  prerelease: false
86
86
  version_requirements: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - '>='
88
+ - - ">="
89
89
  - !ruby/object:Gem::Version
90
90
  version: '4.0'
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: sqlite3
93
93
  requirement: !ruby/object:Gem::Requirement
94
94
  requirements:
95
- - - '>='
95
+ - - ">="
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
98
  type: :development
99
99
  prerelease: false
100
100
  version_requirements: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - '>='
102
+ - - ">="
103
103
  - !ruby/object:Gem::Version
104
104
  version: '0'
105
105
  - !ruby/object:Gem::Dependency
106
106
  name: factory_girl_rails
107
107
  requirement: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - ~>
109
+ - - "~>"
110
110
  - !ruby/object:Gem::Version
111
111
  version: '1.0'
112
112
  type: :development
113
113
  prerelease: false
114
114
  version_requirements: !ruby/object:Gem::Requirement
115
115
  requirements:
116
- - - ~>
116
+ - - "~>"
117
117
  - !ruby/object:Gem::Version
118
118
  version: '1.0'
119
119
  - !ruby/object:Gem::Dependency
120
120
  name: factory_girl
121
121
  requirement: !ruby/object:Gem::Requirement
122
122
  requirements:
123
- - - ~>
123
+ - - "~>"
124
124
  - !ruby/object:Gem::Version
125
125
  version: '2.0'
126
126
  type: :development
127
127
  prerelease: false
128
128
  version_requirements: !ruby/object:Gem::Requirement
129
129
  requirements:
130
- - - ~>
130
+ - - "~>"
131
131
  - !ruby/object:Gem::Version
132
132
  version: '2.0'
133
133
  - !ruby/object:Gem::Dependency
134
134
  name: rspec-rails
135
135
  requirement: !ruby/object:Gem::Requirement
136
136
  requirements:
137
- - - '>='
137
+ - - ">="
138
138
  - !ruby/object:Gem::Version
139
139
  version: '0'
140
140
  type: :development
141
141
  prerelease: false
142
142
  version_requirements: !ruby/object:Gem::Requirement
143
143
  requirements:
144
- - - '>='
144
+ - - ">="
145
145
  - !ruby/object:Gem::Version
146
146
  version: '0'
147
147
  - !ruby/object:Gem::Dependency
148
148
  name: database_cleaner
149
149
  requirement: !ruby/object:Gem::Requirement
150
150
  requirements:
151
- - - '>='
151
+ - - ">="
152
152
  - !ruby/object:Gem::Version
153
153
  version: '0'
154
154
  type: :development
155
155
  prerelease: false
156
156
  version_requirements: !ruby/object:Gem::Requirement
157
157
  requirements:
158
- - - '>='
158
+ - - ">="
159
159
  - !ruby/object:Gem::Version
160
160
  version: '0'
161
161
  - !ruby/object:Gem::Dependency
162
162
  name: capybara
163
163
  requirement: !ruby/object:Gem::Requirement
164
164
  requirements:
165
- - - '>='
165
+ - - ">="
166
166
  - !ruby/object:Gem::Version
167
167
  version: '0'
168
168
  type: :development
169
169
  prerelease: false
170
170
  version_requirements: !ruby/object:Gem::Requirement
171
171
  requirements:
172
- - - '>='
172
+ - - ">="
173
173
  - !ruby/object:Gem::Version
174
174
  version: '0'
175
175
  - !ruby/object:Gem::Dependency
176
176
  name: launchy
177
177
  requirement: !ruby/object:Gem::Requirement
178
178
  requirements:
179
- - - '>='
179
+ - - ">="
180
180
  - !ruby/object:Gem::Version
181
181
  version: '0'
182
182
  type: :development
183
183
  prerelease: false
184
184
  version_requirements: !ruby/object:Gem::Requirement
185
185
  requirements:
186
- - - '>='
186
+ - - ">="
187
187
  - !ruby/object:Gem::Version
188
188
  version: '0'
189
189
  description: Devise extension to allow authentication via LDAP
@@ -192,7 +192,7 @@ executables: []
192
192
  extensions: []
193
193
  extra_rdoc_files: []
194
194
  files:
195
- - .gitignore
195
+ - ".gitignore"
196
196
  - CHANGELOG.md
197
197
  - Gemfile
198
198
  - MIT-LICENSE
@@ -277,6 +277,7 @@ files:
277
277
  - spec/rails_app/script/rails
278
278
  - spec/spec_helper.rb
279
279
  - spec/support/factories.rb
280
+ - spec/unit/connection_spec.rb
280
281
  - spec/unit/user_spec.rb
281
282
  homepage: https://github.com/cschiewek/devise_ldap_authenticatable
282
283
  licenses:
@@ -288,18 +289,89 @@ require_paths:
288
289
  - lib
289
290
  required_ruby_version: !ruby/object:Gem::Requirement
290
291
  requirements:
291
- - - '>='
292
+ - - ">="
292
293
  - !ruby/object:Gem::Version
293
294
  version: '0'
294
295
  required_rubygems_version: !ruby/object:Gem::Requirement
295
296
  requirements:
296
- - - '>='
297
+ - - ">="
297
298
  - !ruby/object:Gem::Version
298
299
  version: '0'
299
300
  requirements: []
300
301
  rubyforge_project:
301
- rubygems_version: 2.0.3
302
+ rubygems_version: 2.2.2
302
303
  signing_key:
303
304
  specification_version: 4
304
305
  summary: Devise extension to allow authentication via LDAP
305
- test_files: []
306
+ test_files:
307
+ - spec/ldap/.gitignore
308
+ - spec/ldap/base.ldif
309
+ - spec/ldap/clear.ldif
310
+ - spec/ldap/local.schema
311
+ - spec/ldap/openldap-data/.gitignore
312
+ - spec/ldap/openldap-data/run/.gitignore
313
+ - spec/ldap/openldap-data/run/.gitkeep
314
+ - spec/ldap/run-server
315
+ - spec/ldap/server.pem
316
+ - spec/ldap/slapd-test.conf.erb
317
+ - spec/rails_app/Rakefile
318
+ - spec/rails_app/app/controllers/application_controller.rb
319
+ - spec/rails_app/app/controllers/posts_controller.rb
320
+ - spec/rails_app/app/helpers/application_helper.rb
321
+ - spec/rails_app/app/helpers/posts_helper.rb
322
+ - spec/rails_app/app/models/post.rb
323
+ - spec/rails_app/app/models/user.rb
324
+ - spec/rails_app/app/views/layouts/application.html.erb
325
+ - spec/rails_app/app/views/posts/index.html.erb
326
+ - spec/rails_app/config.ru
327
+ - spec/rails_app/config/application.rb
328
+ - spec/rails_app/config/boot.rb
329
+ - spec/rails_app/config/cucumber.yml
330
+ - spec/rails_app/config/database.yml
331
+ - spec/rails_app/config/environment.rb
332
+ - spec/rails_app/config/environments/development.rb
333
+ - spec/rails_app/config/environments/production.rb
334
+ - spec/rails_app/config/environments/test.rb
335
+ - spec/rails_app/config/initializers/backtrace_silencers.rb
336
+ - spec/rails_app/config/initializers/devise.rb
337
+ - spec/rails_app/config/initializers/inflections.rb
338
+ - spec/rails_app/config/initializers/mime_types.rb
339
+ - spec/rails_app/config/initializers/secret_token.rb
340
+ - spec/rails_app/config/initializers/session_store.rb
341
+ - spec/rails_app/config/ldap.yml
342
+ - spec/rails_app/config/ldap_with_boolean_ssl.yml
343
+ - spec/rails_app/config/ldap_with_erb.yml
344
+ - spec/rails_app/config/ldap_with_uid.yml
345
+ - spec/rails_app/config/locales/devise.en.yml
346
+ - spec/rails_app/config/locales/en.yml
347
+ - spec/rails_app/config/routes.rb
348
+ - spec/rails_app/config/ssl_ldap.yml
349
+ - spec/rails_app/config/ssl_ldap_with_erb.yml
350
+ - spec/rails_app/config/ssl_ldap_with_uid.yml
351
+ - spec/rails_app/db/migrate/20100708120448_devise_create_users.rb
352
+ - spec/rails_app/db/schema.rb
353
+ - spec/rails_app/features/manage_logins.feature
354
+ - spec/rails_app/features/step_definitions/login_steps.rb
355
+ - spec/rails_app/features/step_definitions/web_steps.rb
356
+ - spec/rails_app/features/support/env.rb
357
+ - spec/rails_app/features/support/paths.rb
358
+ - spec/rails_app/lib/tasks/.gitkeep
359
+ - spec/rails_app/lib/tasks/cucumber.rake
360
+ - spec/rails_app/public/404.html
361
+ - spec/rails_app/public/422.html
362
+ - spec/rails_app/public/500.html
363
+ - spec/rails_app/public/images/rails.png
364
+ - spec/rails_app/public/javascripts/application.js
365
+ - spec/rails_app/public/javascripts/controls.js
366
+ - spec/rails_app/public/javascripts/dragdrop.js
367
+ - spec/rails_app/public/javascripts/effects.js
368
+ - spec/rails_app/public/javascripts/prototype.js
369
+ - spec/rails_app/public/javascripts/rails.js
370
+ - spec/rails_app/public/stylesheets/.gitkeep
371
+ - spec/rails_app/script/cucumber
372
+ - spec/rails_app/script/rails
373
+ - spec/spec_helper.rb
374
+ - spec/support/factories.rb
375
+ - spec/unit/connection_spec.rb
376
+ - spec/unit/user_spec.rb
377
+ has_rdoc: