Hello community,

here is the log from the commit of package rubygem-devise_ldap_authenticatable 
for openSUSE:Factory checked in at 2018-03-08 10:56:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-devise_ldap_authenticatable (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-devise_ldap_authenticatable.new 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-devise_ldap_authenticatable"

Thu Mar  8 10:56:55 2018 rev:2 rq:577156 version:0.8.6

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/rubygem-devise_ldap_authenticatable/rubygem-devise_ldap_authenticatable.changes
  2018-01-10 23:30:45.352446313 +0100
+++ 
/work/SRC/openSUSE:Factory/.rubygem-devise_ldap_authenticatable.new/rubygem-devise_ldap_authenticatable.changes
     2018-03-08 10:56:57.654500505 +0100
@@ -1,0 +2,6 @@
+Wed Feb 14 05:28:56 UTC 2018 - factory-a...@kulow.org
+
+- updated to version 0.8.6
+ see installed CHANGELOG.md
+
+-------------------------------------------------------------------

Old:
----
  devise_ldap_authenticatable-0.8.5.gem

New:
----
  devise_ldap_authenticatable-0.8.6.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-devise_ldap_authenticatable.spec ++++++
--- /var/tmp/diff_new_pack.FgR2k7/_old  2018-03-08 10:56:58.690463213 +0100
+++ /var/tmp/diff_new_pack.FgR2k7/_new  2018-03-08 10:56:58.694463069 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package rubygem-devise_ldap_authenticatable
 #
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -24,16 +24,16 @@
 #
 
 Name:           rubygem-devise_ldap_authenticatable
-Version:        0.8.5
+Version:        0.8.6
 Release:        0
 %define mod_name devise_ldap_authenticatable
 %define mod_full_name %{mod_name}-%{version}
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
-BuildRequires:  ruby-macros >= 5
-BuildRequires:  %{ruby}
 BuildRequires:  %{rubygem gem2rpm}
+BuildRequires:  %{ruby}
+BuildRequires:  ruby-macros >= 5
 Url:            https://github.com/cschiewek/devise_ldap_authenticatable
-Source:         http://rubygems.org/gems/%{mod_full_name}.gem
+Source:         https://rubygems.org/gems/%{mod_full_name}.gem
 Source1:        gem2rpm.yml
 Summary:        Devise extension to allow authentication via LDAP
 License:        MIT

++++++ devise_ldap_authenticatable-0.8.5.gem -> 
devise_ldap_authenticatable-0.8.6.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      2015-06-19 18:22:40.000000000 +0200
+++ new/.gitignore      2018-02-13 19:06:27.000000000 +0100
@@ -7,4 +7,5 @@
 test/ldap/openldap-data/run/slapd.*
 test/rails_app/tmp
 pkg/*
-*.gem
\ No newline at end of file
+*.gem
+.vscode
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2015-06-19 18:22:40.000000000 +0200
+++ new/README.md       2018-02-13 19:06:27.000000000 +0100
@@ -1,10 +1,5 @@
 Devise LDAP Authenticatable
 ===========================
-
-Why this fork?
---------------
-This fork changes a few lines to allow the admin binding to be set to the user 
trying to log in.
-
 [![Gem 
Version](https://badge.fury.io/rb/devise_ldap_authenticatable.png)](http://badge.fury.io/rb/devise_ldap_authenticatable)
 [![Code 
Climate](https://codeclimate.com/github/cschiewek/devise_ldap_authenticatable.png)](https://codeclimate.com/github/cschiewek/devise_ldap_authenticatable)
 [![Dependency 
Status](https://gemnasium.com/cschiewek/devise_ldap_authenticatable.png)](https://gemnasium.com/cschiewek/devise_ldap_authenticatable)
@@ -15,7 +10,7 @@
 
 Devise LDAP Authenticatable works in replacement of Database Authenticatable. 
This devise plugin has not been tested with DatabaseAuthenticatable enabled at 
the same time. This is meant as a drop in replacement for 
DatabaseAuthenticatable allowing for a semi single sign on approach.
 
-For a screencast with an example application, please visit: 
[http://random-rails.blogspot.com/2010/07/ldap-authentication-with-devise.html](http://random-rails.blogspot.com/2010/07/ldap-authentication-with-devise.html)
+For a screencast with an example application, please visit: 
[http://corrupt.net/2010/07/05/LDAP-Authentication-With-Devise/](http://corrupt.net/2010/07/05/LDAP-Authentication-With-Devise/)
 
 Prerequisites
 -------------
@@ -24,6 +19,8 @@
 
 Note: Rails 3.x / Devise 2.x has been moved to the 0.7 branch.  All 0.7.x gems 
will support Rails 3, where as 0.8.x will support Rails 4.
 
+If you are transitioning from having Devise manage your users' passwords in 
the database to using LDAP auth, you may have to update your `users` table to 
make `encrypted_password` nullable, or else the LDAP user insert will fail.
+
 Usage
 -----
 In the Gemfile for your application:
@@ -83,7 +80,9 @@
 * `ldap_check_group_membership` _(default: false)_
   * 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.
 * `ldap_check_attributes` _(default: false)_
-  * 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.
+  * When set to true, the user trying to login will be checked to make sure 
their attributes match those specified in the ldap.yml file.
+* `ldap_check_attributes_presence` _(default: false)_
+  * When set to true, the user trying to login will be checked against all 
`require_attribute_presence` attributes in the ldap.yml file, either present 
_(attr: true)_,or not present _(attr: false)_.
 * `ldap_use_admin_to_bind` _(default: false)_
   * When set to true, the admin user will be used to bind to the LDAP server 
during authentication.
 * `ldap_check_group_membership_without_admin` _(default: false)_
@@ -116,9 +115,9 @@
 
 On OS X, this is available out of the box.
 
-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.
+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 (reload 
using `sudo service apparmor reload` afterwards).
 
-    /path/to/devise_ldap_authenticatable/spec/ldap/** rw,$
+    /path/to/devise_ldap_authenticatable/spec/ldap/** rw,
 
 To start hacking on `devise_ldap_authentication`, clone the github repository, 
start the test LDAP server, and run the rake test task:
 
@@ -129,7 +128,7 @@
     # in a separate console or backgrounded
     ./spec/ldap/run-server
 
-    bundle exec rake db:migrate # first time only
+    RAILS_ENV=test bundle exec rake db:migrate # first time only
     bundle exec rake spec
 
 References
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devise_ldap_authenticatable.gemspec 
new/devise_ldap_authenticatable.gemspec
--- old/devise_ldap_authenticatable.gemspec     2015-06-19 18:22:40.000000000 
+0200
+++ new/devise_ldap_authenticatable.gemspec     2018-02-13 19:06:27.000000000 
+0100
@@ -18,16 +18,16 @@
   s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| 
File.basename(f) }
   s.require_paths = ["lib"]
 
-  s.add_dependency('devise', '>= 3.4.1')
-  s.add_dependency('net-ldap', '>= 0.6.0', '<= 0.11')
+  s.add_dependency 'devise', '>= 3.4.1'
+  s.add_dependency 'net-ldap', '>= 0.16.0'
 
-  s.add_development_dependency('rake', '>= 0.9')
-  s.add_development_dependency('rdoc', '>= 3')
-  s.add_development_dependency('rails', '>= 4.0')
-  s.add_development_dependency('sqlite3')
-  s.add_development_dependency('factory_girl_rails', '~> 1.0')
-  s.add_development_dependency('factory_girl', '~> 2.0')
-  s.add_development_dependency('rspec-rails')
+  s.add_development_dependency 'rake', '>= 0.9'
+  s.add_development_dependency 'rdoc', '>= 3'
+  s.add_development_dependency 'rails', '>= 4.0'
+  s.add_development_dependency 'sqlite3'
+  s.add_development_dependency 'factory_girl_rails', '~> 1.0'
+  s.add_development_dependency 'factory_girl', '~> 2.0'
+  s.add_development_dependency 'rspec-rails'
 
   %w{database_cleaner capybara launchy}.each do |dep|
     s.add_development_dependency(dep)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/devise_ldap_authenticatable/ldap/adapter.rb 
new/lib/devise_ldap_authenticatable/ldap/adapter.rb
--- old/lib/devise_ldap_authenticatable/ldap/adapter.rb 2015-06-19 
18:22:40.000000000 +0200
+++ new/lib/devise_ldap_authenticatable/ldap/adapter.rb 2018-02-13 
19:06:27.000000000 +0100
@@ -15,6 +15,16 @@
         resource.authorized?
       end
 
+      def self.expired_valid_credentials?(login, password_plaintext)
+        options = {:login => login,
+                   :password => password_plaintext,
+                   :ldap_auth_username_builder => 
::Devise.ldap_auth_username_builder,
+                   :admin => ::Devise.ldap_use_admin_to_bind}
+
+        resource = Devise::LDAP::Connection.new(options)
+        resource.expired_valid_credentials?
+      end
+
       def self.update_password(login, new_password)
         options = {:login => login,
                    :new_password => new_password,
@@ -34,7 +44,7 @@
                    :ldap_auth_username_builder => 
::Devise.ldap_auth_username_builder,
                    :admin => ::Devise.ldap_use_admin_to_bind}
 
-        resource = Devise::LDAP::Connection.new(options)
+        Devise::LDAP::Connection.new(options)
       end
 
       def self.valid_login?(login)
@@ -54,18 +64,18 @@
       end
 
       def self.set_ldap_param(login, param, new_value, password = nil)
-        options = { :login => login,
-                    :ldap_auth_username_builder => 
::Devise.ldap_auth_username_builder,
-                    :password => password }
+        options = {:login => login,
+                   :ldap_auth_username_builder => 
::Devise.ldap_auth_username_builder,
+                   :password => password }
 
         resource = Devise::LDAP::Connection.new(options)
         resource.set_param(param, new_value)
       end
 
       def self.delete_ldap_param(login, param, password = nil)
-        options = { :login => login,
-                    :ldap_auth_username_builder => 
::Devise.ldap_auth_username_builder,
-                    :password => password }
+        options = {:login => login,
+                   :ldap_auth_username_builder => 
::Devise.ldap_auth_username_builder,
+                   :password => password }
 
         resource = Devise::LDAP::Connection.new(options)
         resource.delete_param(param)
@@ -79,9 +89,6 @@
       def self.get_ldap_entry(login)
         self.ldap_connect(login).search_for_login
       end
-
     end
-
   end
-
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/devise_ldap_authenticatable/ldap/connection.rb 
new/lib/devise_ldap_authenticatable/ldap/connection.rb
--- old/lib/devise_ldap_authenticatable/ldap/connection.rb      2015-06-19 
18:22:40.000000000 +0200
+++ new/lib/devise_ldap_authenticatable/ldap/connection.rb      2018-02-13 
19:06:27.000000000 +0100
@@ -24,11 +24,13 @@
 
         @group_base = ldap_config["group_base"]
         @check_group_membership = 
ldap_config.has_key?("check_group_membership") ? 
ldap_config["check_group_membership"] : ::Devise.ldap_check_group_membership
+        @check_group_membership_without_admin = 
ldap_config.has_key?("check_group_membership_without_admin") ? 
ldap_config["check_group_membership_without_admin"] : 
::Devise.ldap_check_group_membership_without_admin
         @required_groups = ldap_config["required_groups"]
+        @group_membership_attribute = 
ldap_config.has_key?("group_membership_attribute") ? 
ldap_config["group_membership_attribute"] : "uniqueMember"
         @required_attributes = ldap_config["require_attribute"]
+        @required_attributes_presence = 
ldap_config["require_attribute_presence"]
 
         @ldap.auth ldap_config["admin_user"], ldap_config["admin_password"] if 
params[:admin]
-        @ldap.auth params[:login], params[:password] if 
ldap_config["admin_as_user"]
 
         @login = params[:login]
         @password = params[:password]
@@ -83,10 +85,25 @@
         authenticate!
       end
 
+      def last_message_bad_credentials?
+        @ldap.get_operation_result.error_message.to_s.include? 
'AcceptSecurityContext error, data 52e'
+      end
+
+      def last_message_expired_credentials?
+        @ldap.get_operation_result.error_message.to_s.include? 
'AcceptSecurityContext error, data 773'
+      end
+
       def authorized?
         DeviseLdapAuthenticatable::Logger.send("Authorizing user #{dn}")
         if !authenticated?
-          DeviseLdapAuthenticatable::Logger.send("Not authorized because not 
authenticated.")
+          if last_message_bad_credentials?
+            DeviseLdapAuthenticatable::Logger.send("Not authorized because of 
invalid credentials.")
+          elsif last_message_expired_credentials?
+            DeviseLdapAuthenticatable::Logger.send("Not authorized because of 
expired credentials.")
+          else
+            DeviseLdapAuthenticatable::Logger.send("Not authorized because not 
authenticated.")
+          end
+
           return false
         elsif !in_required_groups?
           DeviseLdapAuthenticatable::Logger.send("Not authorized because not 
in required groups.")
@@ -94,17 +111,26 @@
         elsif !has_required_attribute?
           DeviseLdapAuthenticatable::Logger.send("Not authorized because does 
not have required attribute.")
           return false
+        elsif !has_required_attribute_presence?
+          DeviseLdapAuthenticatable::Logger.send("Not authorized because does 
not have required attribute present.")
+          return false
         else
           return true
         end
       end
 
+      def expired_valid_credentials?
+        DeviseLdapAuthenticatable::Logger.send("Authorizing user #{dn}")
+
+        !authenticated? && last_message_expired_credentials?
+      end
+
       def change_password!
-        update_ldap(:userpassword => Net::LDAP::Password.generate(:sha, 
@new_password))
+        update_ldap(:userPassword => 
::Devise.ldap_auth_password_builder.call(@new_password))
       end
 
       def in_required_groups?
-        return true unless @check_group_membership
+        return true unless @check_group_membership || 
@check_group_membership_without_admin
 
         ## FIXME set errors here, the ldap.yml isn't set properly.
         return false if @required_groups.nil?
@@ -122,23 +148,29 @@
       def in_group?(group_name, group_attribute = 
LDAP::DEFAULT_GROUP_UNIQUE_MEMBER_LIST_KEY)
         in_group = false
 
-        admin_ldap = Connection.admin
+        if @check_group_membership_without_admin
+          group_checking_ldap = @ldap
+        else
+          group_checking_ldap = Connection.admin
+        end
 
         unless ::Devise.ldap_ad_group_check
-          admin_ldap.search(:base => group_name, :scope => 
Net::LDAP::SearchScope_BaseObject) do |entry|
+          group_checking_ldap.search(:base => group_name, :scope => 
Net::LDAP::SearchScope_BaseObject) do |entry|
             if entry[group_attribute].include? dn
               in_group = true
+              DeviseLdapAuthenticatable::Logger.send("User #{dn} IS included 
in group: #{group_name}")
             end
           end
         else
           # AD optimization - extension will recursively check sub-groups with 
one query
           # "(memberof:1.2.840.113556.1.4.1941:=group_name)"
-          search_result = admin_ldap.search(:base => dn,
+          search_result = group_checking_ldap.search(:base => dn,
                             :filter => 
Net::LDAP::Filter.ex("memberof:1.2.840.113556.1.4.1941", group_name),
                             :scope => Net::LDAP::SearchScope_BaseObject)
           # Will return  the user entry if belongs to group otherwise nothing
           if search_result.length == 1 && search_result[0].dn.eql?(dn)
             in_group = true
+            DeviseLdapAuthenticatable::Logger.send("User #{dn} IS included in 
group: #{group_name}")
           end
         end
 
@@ -153,11 +185,11 @@
         return true unless ::Devise.ldap_check_attributes
 
         admin_ldap = Connection.admin
-
         user = find_ldap_user(admin_ldap)
 
         @required_attributes.each do |key,val|
-          unless user[key].include? val
+          matching_attributes = user[key] & Array(val)
+          unless (matching_attributes).any?
             DeviseLdapAuthenticatable::Logger.send("User #{dn} did not match 
attribute #{key}:#{val}")
             return false
           end
@@ -166,11 +198,28 @@
         return true
       end
 
+      def has_required_attribute_presence?
+        return true unless ::Devise.ldap_check_attributes_presence
+
+        user = search_for_login
+
+        @required_attributes_presence.each do |key,val|
+          if val && !user.attribute_names.include?(key.to_sym)
+            DeviseLdapAuthenticatable::Logger.send("User #{dn} doesn't include 
attribute #{key}")
+            return false
+          elsif !val && user.attribute_names.include?(key.to_sym)
+            DeviseLdapAuthenticatable::Logger.send("User #{dn} includes 
attribute #{key}")
+            return false
+          end
+        end
+
+        return true
+      end
+
       def user_groups
         admin_ldap = Connection.admin
-
         DeviseLdapAuthenticatable::Logger.send("Getting groups for #{dn}")
-        filter = Net::LDAP::Filter.eq("uniqueMember", dn)
+        filter = Net::LDAP::Filter.eq(@group_membership_attribute, dn)
         admin_ldap.search(:filter => filter, :base => 
@group_base).collect(&:dn)
       end
 
@@ -188,6 +237,10 @@
           ldap_entry = nil
           match_count = 0
           @ldap.search(:filter => filter) {|entry| ldap_entry = entry; 
match_count+=1}
+          op_result= @ldap.get_operation_result
+          if op_result.code!=0 then
+            DeviseLdapAuthenticatable::Logger.send("LDAP Error 
#{op_result.code}: #{op_result.message}")
+          end
           DeviseLdapAuthenticatable::Logger.send("LDAP search yielded 
#{match_count} matches")
           ldap_entry
         end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/devise_ldap_authenticatable/model.rb 
new/lib/devise_ldap_authenticatable/model.rb
--- old/lib/devise_ldap_authenticatable/model.rb        2015-06-19 
18:22:40.000000000 +0200
+++ new/lib/devise_ldap_authenticatable/model.rb        2018-02-13 
19:06:27.000000000 +0100
@@ -53,7 +53,7 @@
       end
 
       def ldap_groups
-        Devise::LDAP::Adapter.get_groups(login_with)
+        @ldap_groups ||= Devise::LDAP::Adapter.get_groups(login_with)
       end
 
       def in_ldap_group?(group_name, group_attribute = 
LDAP::DEFAULT_GROUP_UNIQUE_MEMBER_LIST_KEY)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/devise_ldap_authenticatable/strategy.rb 
new/lib/devise_ldap_authenticatable/strategy.rb
--- old/lib/devise_ldap_authenticatable/strategy.rb     2015-06-19 
18:22:40.000000000 +0200
+++ new/lib/devise_ldap_authenticatable/strategy.rb     2018-02-13 
19:06:27.000000000 +0100
@@ -10,7 +10,7 @@
       # indicating whether the resource is not found in the database or the 
credentials
       # are invalid.
       def authenticate!
-        resource = 
mapping.to.find_for_ldap_authentication(authentication_hash.merge(password: 
password))
+        resource = 
mapping.to.find_for_ldap_authentication(authentication_hash.merge(:password => 
password))
 
         return fail(:invalid) unless resource
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/devise_ldap_authenticatable/version.rb 
new/lib/devise_ldap_authenticatable/version.rb
--- old/lib/devise_ldap_authenticatable/version.rb      2015-06-19 
18:22:40.000000000 +0200
+++ new/lib/devise_ldap_authenticatable/version.rb      2018-02-13 
19:06:27.000000000 +0100
@@ -1,3 +1,3 @@
 module DeviseLdapAuthenticatable
-  VERSION = "0.8.5".freeze
+  VERSION = "0.8.6".freeze
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/devise_ldap_authenticatable.rb 
new/lib/devise_ldap_authenticatable.rb
--- old/lib/devise_ldap_authenticatable.rb      2015-06-19 18:22:40.000000000 
+0200
+++ new/lib/devise_ldap_authenticatable.rb      2018-02-13 19:06:27.000000000 
+0100
@@ -1,5 +1,6 @@
 # encoding: utf-8
 require 'devise'
+require 'net/ldap'
 
 require 'devise_ldap_authenticatable/exception'
 require 'devise_ldap_authenticatable/logger'
@@ -11,31 +12,40 @@
   # Allow logging
   mattr_accessor :ldap_logger
   @@ldap_logger = true
-  
+
   # Add valid users to database
   mattr_accessor :ldap_create_user
   @@ldap_create_user = false
-  
+
   # A path to YAML config file or a Proc that returns a
   # configuration hash
   mattr_accessor :ldap_config
   # @@ldap_config = "#{Rails.root}/config/ldap.yml"
-  
+
   mattr_accessor :ldap_update_password
   @@ldap_update_password = true
-  
+
   mattr_accessor :ldap_check_group_membership
   @@ldap_check_group_membership = false
-  
+
+  mattr_accessor :ldap_check_group_membership_without_admin
+  @@ldap_check_group_membership_without_admin = false
+
   mattr_accessor :ldap_check_attributes
   @@ldap_check_role_attribute = false
-  
+
+  mattr_accessor :ldap_check_attributes_presence
+  @@ldap_check_attributes_presence = false
+
   mattr_accessor :ldap_use_admin_to_bind
   @@ldap_use_admin_to_bind = false
-  
+
   mattr_accessor :ldap_auth_username_builder
   @@ldap_auth_username_builder = Proc.new() {|attribute, login, ldap| 
"#{attribute}=#{login},#{ldap.base}" }
 
+  mattr_accessor :ldap_auth_password_builder
+  @@ldap_auth_password_builder = Proc.new() {|new_password| 
Net::LDAP::Password.generate(:sha, new_password) }
+
   mattr_accessor :ldap_ad_group_check
   @@ldap_ad_group_check = false
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/lib/generators/devise_ldap_authenticatable/install_generator.rb 
new/lib/generators/devise_ldap_authenticatable/install_generator.rb
--- old/lib/generators/devise_ldap_authenticatable/install_generator.rb 
2015-06-19 18:22:40.000000000 +0200
+++ new/lib/generators/devise_ldap_authenticatable/install_generator.rb 
2018-02-13 19:06:27.000000000 +0100
@@ -13,7 +13,7 @@
     end
 
     def create_default_devise_settings
-      inject_into_file "config/initializers/devise.rb", 
default_devise_settings, :after => "Devise.setup do |config|\n"   
+      inject_into_file "config/initializers/devise.rb", 
default_devise_settings, :after => "Devise.setup do |config|\n"
     end
 
     def update_user_model
@@ -28,7 +28,7 @@
 
     def default_devise_settings
       settings = <<-eof
-  # ==> LDAP Configuration 
+  # ==> LDAP Configuration
   # config.ldap_logger = true
   # config.ldap_create_user = false
   # config.ldap_update_password = true
@@ -36,12 +36,13 @@
   # config.ldap_check_group_membership = false
   # config.ldap_check_group_membership_without_admin = false
   # config.ldap_check_attributes = false
+  # config.ldap_check_attributes_presence = false
   # config.ldap_use_admin_to_bind = false
   # config.ldap_ad_group_check = false
 
       eof
-      if options.advanced?  
-        settings << <<-eof  
+      if options.advanced?
+        settings << <<-eof
   # ==> Advanced LDAP Configuration
   # config.ldap_auth_username_builder = Proc.new() {|attribute, login, ldap| 
"\#{attribute}=\#{login},\#{ldap.base}" }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/lib/generators/devise_ldap_authenticatable/templates/ldap.yml 
new/lib/generators/devise_ldap_authenticatable/templates/ldap.yml
--- old/lib/generators/devise_ldap_authenticatable/templates/ldap.yml   
2015-06-19 18:22:40.000000000 +0200
+++ new/lib/generators/devise_ldap_authenticatable/templates/ldap.yml   
2018-02-13 19:06:27.000000000 +0100
@@ -1,7 +1,7 @@
 ## Authorizations
 # Uncomment out the merging for each environment that you'd like to include.
 # You can also just copy and paste the tree (do not include the 
"authorizations") to each
-# environment if you need something different per enviornment.
+# environment if you need something different per environment.
 authorizations: &AUTHORIZATIONS
   allow_unauthenticated_bind: false
   group_base: ou=groups,dc=test,dc=com
@@ -18,6 +18,12 @@
   require_attribute:
     objectClass: inetOrgPerson
     authorizationRole: postsAdmin
+  ## Requires config.ldap_check_attributes_presence in devise.rb to be true
+  ## Can have multiple attributes set to true or false to check presence, all 
must match all to be authorized
+  require_attribute_presence:
+    mail: true
+    telephoneNumber: true
+    serviceAccount: false
 
 ## Environment
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2015-06-19 18:22:40.000000000 +0200
+++ new/metadata        2018-02-13 19:06:27.000000000 +0100
@@ -1,7 +1,7 @@
 --- !ruby/object:Gem::Specification
 name: devise_ldap_authenticatable
 version: !ruby/object:Gem::Version
-  version: 0.8.5
+  version: 0.8.6
 platform: ruby
 authors:
 - Curtis Schiewek
@@ -10,7 +10,7 @@
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2015-06-19 00:00:00.000000000 Z
+date: 2018-02-13 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: devise
@@ -32,20 +32,14 @@
     requirements:
     - - ">="
       - !ruby/object:Gem::Version
-        version: 0.6.0
-    - - "<="
-      - !ruby/object:Gem::Version
-        version: '0.11'
+        version: 0.16.0
   type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - ">="
       - !ruby/object:Gem::Version
-        version: 0.6.0
-    - - "<="
-      - !ruby/object:Gem::Version
-        version: '0.11'
+        version: 0.16.0
 - !ruby/object:Gem::Dependency
   name: rake
   requirement: !ruby/object:Gem::Requirement
@@ -277,6 +271,7 @@
 - spec/rails_app/script/rails
 - spec/spec_helper.rb
 - spec/support/factories.rb
+- spec/unit/adapter_spec.rb
 - spec/unit/connection_spec.rb
 - spec/unit/user_spec.rb
 homepage: https://github.com/cschiewek/devise_ldap_authenticatable
@@ -299,7 +294,7 @@
       version: '0'
 requirements: []
 rubyforge_project: 
-rubygems_version: 2.4.6
+rubygems_version: 2.6.11
 signing_key: 
 specification_version: 4
 summary: Devise extension to allow authentication via LDAP
@@ -372,5 +367,6 @@
 - spec/rails_app/script/rails
 - spec/spec_helper.rb
 - spec/support/factories.rb
+- spec/unit/adapter_spec.rb
 - spec/unit/connection_spec.rb
 - spec/unit/user_spec.rb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/rails_app/config/ldap.yml 
new/spec/rails_app/config/ldap.yml
--- old/spec/rails_app/config/ldap.yml  2015-06-19 18:22:40.000000000 +0200
+++ new/spec/rails_app/config/ldap.yml  2018-02-13 19:06:27.000000000 +0100
@@ -7,7 +7,9 @@
   require_attribute:
     objectClass: inetOrgPerson
     authorizationRole: blogAdmin
-    
+  require_attribute_presence:
+    mail: true
+
 test: &TEST
   host: localhost
   port: 3389
@@ -17,6 +19,6 @@
   admin_password: secret
   ssl: false
   <<: *AUTHORIZATIONS
-  
+
 development:
   <<: *TEST
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/rails_app/config/ldap_with_erb.yml 
new/spec/rails_app/config/ldap_with_erb.yml
--- old/spec/rails_app/config/ldap_with_erb.yml 2015-06-19 18:22:40.000000000 
+0200
+++ new/spec/rails_app/config/ldap_with_erb.yml 2018-02-13 19:06:27.000000000 
+0100
@@ -6,9 +6,11 @@
   required_groups:
     - cn=admins,<%= "ou=groups,#{@base}" %>
   require_attribute:
-    objectClass: inetOrgPerson
+    objectClass:
+      - inetOrgPerson
+      - organizationalPerson
     authorizationRole: blogAdmin
-    
+
 test: &TEST
   host: <%= "localhost" %>
   port: 3389
@@ -18,6 +20,6 @@
   admin_password: secret
   ssl: false
   <<: *AUTHORIZATIONS
-  
+
 development:
   <<: *TEST
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/spec_helper.rb new/spec/spec_helper.rb
--- old/spec/spec_helper.rb     2015-06-19 18:22:40.000000000 +0200
+++ new/spec/spec_helper.rb     2018-02-13 19:06:27.000000000 +0100
@@ -2,7 +2,6 @@
 
 require File.expand_path("rails_app/config/environment.rb",  
File.dirname(__FILE__))
 require 'rspec/rails'
-require 'rspec/autorun'
 require 'factory_girl' # not sure why this is not already required
 
 # Rails 4.1 and RSpec are a bit on different pages on who should run migrations
@@ -50,6 +49,7 @@
   ::Devise.ldap_config = "#{Rails.root}/config/#{"ssl_" if 
ENV["LDAP_SSL"]}ldap.yml"
   ::Devise.ldap_check_group_membership = false
   ::Devise.ldap_check_attributes = false
+  ::Devise.ldap_check_attributes_presence = false
   ::Devise.ldap_auth_username_builder = Proc.new() {|attribute, login, ldap| 
"#{attribute}=#{login},#{ldap.base}" }
   ::Devise.authentication_keys = [:email]
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/unit/adapter_spec.rb 
new/spec/unit/adapter_spec.rb
--- old/spec/unit/adapter_spec.rb       1970-01-01 01:00:00.000000000 +0100
+++ new/spec/unit/adapter_spec.rb       2018-02-13 19:06:27.000000000 +0100
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe Devise::LDAP::Adapter do
+  describe '#expired_valid_credentials?' do
+    before do
+      ::Devise.ldap_use_admin_to_bind = true
+      expect_any_instance_of(Devise::LDAP::Connection).to 
receive(:expired_valid_credentials?)
+    end
+
+    it 'can bind as the admin user' do
+      expect(Devise::LDAP::Connection).to receive(:new)
+        .with(hash_including(
+                  :login => 'test.u...@test.com',
+                  :password => 'pass',
+                  :ldap_auth_username_builder => kind_of(Proc),
+                  :admin => true)).and_call_original
+
+      Devise::LDAP::Adapter.expired_valid_credentials?('test.u...@test.com', 
'pass')
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/unit/connection_spec.rb 
new/spec/unit/connection_spec.rb
--- old/spec/unit/connection_spec.rb    2015-06-19 18:22:40.000000000 +0200
+++ new/spec/unit/connection_spec.rb    2018-02-13 19:06:27.000000000 +0100
@@ -11,4 +11,93 @@
     connection = Devise::LDAP::Connection.new()
     expect(connection.ldap.base).to eq('ou=testbase,dc=test,dc=com')
   end
+
+  class TestOpResult
+    attr_accessor :error_message
+  end
+
+  describe '#expired_valid_credentials?' do
+    let(:conn) { double(Net::LDAP).as_null_object }
+    let(:error) { }
+    let(:is_authed) { false }
+    before do
+      expect(Net::LDAP).to receive(:new).and_return(conn)
+      allow(conn).to 
receive(:get_operation_result).and_return(TestOpResult.new.tap{|r| 
r.error_message = error})
+      allow_any_instance_of(Devise::LDAP::Connection).to 
receive(:authenticated?).and_return(is_authed)
+      allow_any_instance_of(Devise::LDAP::Connection).to 
receive(:dn).and_return('any dn')
+      expect(DeviseLdapAuthenticatable::Logger).to 
receive(:send).with('Authorizing user any dn')
+    end
+    subject do
+      Devise::LDAP::Connection.new.expired_valid_credentials?
+    end
+
+    context do
+      let(:error) { 'THIS PART CAN BE ANYTHING AcceptSecurityContext error, 
data 773 SO CAN THIS' }
+      it 'is true when expired credential error is returned and not already 
authenticated' do
+        expect(subject).to be true
+      end
+    end
+
+    context do
+      it 'is false when expired credential error is not returned and not 
already authenticated' do
+        expect(subject).to be false
+      end
+    end
+
+    context do
+      let(:is_authed) { true }
+      it 'is false when expired credential error is not returned and already 
authenticated' do
+        expect(subject).to be false
+      end
+    end
+  end
+
+  describe '#authorized?' do
+    let(:conn) { double(Net::LDAP).as_null_object }
+    let(:error) { }
+    let(:log_message) { }
+    let(:is_authed) { false }
+    before do
+      expect(Net::LDAP).to receive(:new).and_return(conn)
+      allow(conn).to 
receive(:get_operation_result).and_return(TestOpResult.new.tap{|r| 
r.error_message = error})
+      allow_any_instance_of(Devise::LDAP::Connection).to 
receive(:authenticated?).and_return(is_authed)
+      allow_any_instance_of(Devise::LDAP::Connection).to 
receive(:dn).and_return('any dn')
+      expect(DeviseLdapAuthenticatable::Logger).to 
receive(:send).with('Authorizing user any dn')
+    end
+    subject do
+      Devise::LDAP::Connection.new.authorized?
+    end
+    context do
+      before { expect(DeviseLdapAuthenticatable::Logger).to 
receive(:send).with(log_message) }
+
+      context do
+        let(:error) { 'THIS PART CAN BE ANYTHING AcceptSecurityContext error, 
data 52e SO CAN THIS' }
+        let(:log_message) { 'Not authorized because of invalid credentials.' }
+        it 'is false when credential error is returned' do
+          expect(subject).to be false
+        end
+      end
+      context do
+        let(:error) { 'THIS PART CAN BE ANYTHING AcceptSecurityContext error, 
data 773 SO CAN THIS' }
+        let(:log_message) { 'Not authorized because of expired credentials.' }
+        it 'is false when expired error is returned' do
+          expect(subject).to be false
+        end
+      end
+      context do
+        let(:error) { 'any error' }
+        let(:log_message) { 'Not authorized because not authenticated.' }
+        it 'is false when any other error is returned' do
+          expect(subject).to be false
+        end
+      end
+    end
+
+    context do
+      let(:is_authed) { true }
+      it 'is true when already authenticated' do
+        expect(subject).to be true
+      end
+    end
+  end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/unit/user_spec.rb new/spec/unit/user_spec.rb
--- old/spec/unit/user_spec.rb  2015-06-19 18:22:40.000000000 +0200
+++ new/spec/unit/user_spec.rb  2018-02-13 19:06:27.000000000 +0100
@@ -16,7 +16,7 @@
       reset_ldap_server!
     end
 
-    describe "look up and ldap user" do
+    describe "look up an ldap user" do
       it "should return true for a user that does exist in LDAP" do
         assert_equal true, 
::Devise::LDAP::Adapter.valid_login?('example.u...@test.com')
       end
@@ -48,7 +48,7 @@
         should_be_validated @user, "secret"
         @user.password = "changed"
         @user.change_password!("secret")
-        should_be_validated @user, "changed", "password was not changed 
properly on the LDAP sevrer"
+        should_be_validated @user, "changed", "password was not changed 
properly on the LDAP server"
       end
 
       it "should not allow to change password if setting is false" do
@@ -80,7 +80,7 @@
         it "should create a user in the database" do
           @user = User.find_for_ldap_authentication(:email => 
"example.u...@test.com", :password => "secret")
           assert_equal(User.all.size, 1)
-          User.all.collect(&:email).should include("example.u...@test.com")
+          expect(User.all.collect(&:email)).to include("example.u...@test.com")
           assert(@user.persisted?)
         end
 
@@ -116,7 +116,7 @@
           ::Devise.case_insensitive_keys = [:email]
 
           @user = User.find_for_ldap_authentication(:email => 
"example.u...@test.com", :password => "secret")
-          User.all.collect(&:email).should include("example.u...@test.com")
+          expect(User.all.collect(&:email)).to include("example.u...@test.com")
         end
       end
 
@@ -135,32 +135,32 @@
       end
 
       it "should admin should have the proper groups set" do
-        @admin.ldap_groups.should include('cn=admins,ou=groups,dc=test,dc=com')
+        expect(@admin.ldap_groups).to 
include('cn=admins,ou=groups,dc=test,dc=com')
       end
 
       it "should user should not be allowed in" do
         should_not_be_validated @user, "secret"
       end
     end
-    
+
     describe "check group membership" do
       before do
         @admin = Factory.create(:admin)
         @user = Factory.create(:user)
       end
-      
+
       it "should return true for admin being in the admins group" do
         assert_equal true, 
@admin.in_ldap_group?('cn=admins,ou=groups,dc=test,dc=com')
       end
-      
+
       it "should return false for admin being in the admins group using the 
'foobar' group attribute" do
         assert_equal false, 
@admin.in_ldap_group?('cn=admins,ou=groups,dc=test,dc=com', 'foobar')
       end
-      
+
       it "should return true for user being in the users group" do
         assert_equal true, 
@user.in_ldap_group?('cn=users,ou=groups,dc=test,dc=com')
-      end   
-      
+      end
+
       it "should return false for user being in the admins group" do
         assert_equal false, 
@user.in_ldap_group?('cn=admins,ou=groups,dc=test,dc=com')
       end
@@ -217,6 +217,26 @@
       end
     end
 
+    describe "use attribute presence for authorization" do
+      before do
+        @admin = Factory.create(:admin)
+        @user = Factory.create(:user)
+        ::Devise.ldap_check_attributes_presence = true
+      end
+
+      after do
+        ::Devise.ldap_check_attributes_presence = false
+      end
+
+      it "should admin should not be allowed in" do
+        should_not_be_validated @admin, "admin_secret"
+      end
+
+      it "should user should be allowed in" do
+        should_be_validated @user, "secret"
+      end
+    end
+
     describe "use admin setting to bind" do
       before do
         @admin = Factory.create(:admin)
@@ -229,6 +249,19 @@
       end
     end
 
+    describe 'check password expiration' do
+      before { allow_any_instance_of(Devise::LDAP::Connection).to 
receive(:authenticated?).and_return(false) }
+
+      it 'should return false for a user that has a fresh password' do
+        allow_any_instance_of(Devise::LDAP::Connection).to 
receive(:last_message_expired_credentials?).and_return(false)
+        assert_equal false, 
::Devise::LDAP::Adapter.expired_valid_credentials?('example.u...@test.com','secret')
+      end
+
+      it 'should return true for a user that has an expired password' do
+        allow_any_instance_of(Devise::LDAP::Connection).to 
receive(:last_message_expired_credentials?).and_return(true)
+        assert_equal true, 
::Devise::LDAP::Adapter.expired_valid_credentials?('example.u...@test.com','secret')
+      end
+    end
   end
 
   describe "use uid for login" do
@@ -259,7 +292,7 @@
       it "should create a user in the database" do
         @user = User.find_for_ldap_authentication(:uid => "example_user", 
:password => "secret")
         assert_equal(User.all.size, 1)
-        User.all.collect(&:uid).should include("example_user")
+        expect(User.all.collect(&:uid)).to include("example_user")
       end
 
       it "should call ldap_before_save hooks" do


Reply via email to