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 - [email protected]
+
+- 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.
-
[](http://badge.fury.io/rb/devise_ldap_authenticatable)
[](https://codeclimate.com/github/cschiewek/devise_ldap_authenticatable)
[](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 => '[email protected]',
+ :password => 'pass',
+ :ldap_auth_username_builder => kind_of(Proc),
+ :admin => true)).and_call_original
+
+ Devise::LDAP::Adapter.expired_valid_credentials?('[email protected]',
'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?('[email protected]')
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 =>
"[email protected]", :password => "secret")
assert_equal(User.all.size, 1)
- User.all.collect(&:email).should include("[email protected]")
+ expect(User.all.collect(&:email)).to include("[email protected]")
assert(@user.persisted?)
end
@@ -116,7 +116,7 @@
::Devise.case_insensitive_keys = [:email]
@user = User.find_for_ldap_authentication(:email =>
"[email protected]", :password => "secret")
- User.all.collect(&:email).should include("[email protected]")
+ expect(User.all.collect(&:email)).to include("[email protected]")
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?('[email protected]','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?('[email protected]','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