From 7edf27d0281e09561838122982c16b7e62181f44 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 26 Jun 2012 10:51:15 +0300 Subject: [PATCH 01/62] Fix ldap blank password --- lib/omniauth/strategies/ldap.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index 45fb1d1..e0edce9 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -38,7 +38,12 @@ def request_phase def callback_phase @adaptor = OmniAuth::LDAP::Adaptor.new @options - raise MissingCredentialsError.new("Missing login credentials") if request['username'].nil? || request['password'].nil? + # GITLAB security patch + # Dont allow blank password for ldap auth + if request['username'].nil? || request['username'].empty? || request['password'].nil? || request['password'].empty? + raise MissingCredentialsError.new("Missing login credentials") + end + begin @ldap_user_info = @adaptor.bind_as(:filter => Net::LDAP::Filter.eq(@adaptor.uid, @options[:name_proc].call(request['username'])),:size => 1, :password => request['password']) return fail!(:invalid_credentials) if !@ldap_user_info From 536c321236702dd9b759831f8ce5f2bc250d43b0 Mon Sep 17 00:00:00 2001 From: Pat Thoyts Date: Fri, 20 Jul 2012 23:25:26 +0100 Subject: [PATCH 02/62] Report missing credentials to the Rails application. If no username or password is provided a MissingCredentialsError is raised which causes a Rack caught exception and a 500 Error in gitlab. Omniauth provides a way to raise such errors to the application by using the 'fail!' method to pass the exception to the registered failure handler. For gitlab this is the omniauth_controller code. This is required to resolve gitlab issue #1077. Signed-off-by: Pat Thoyts --- lib/omniauth/strategies/ldap.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index e0edce9..c28628d 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -38,13 +38,13 @@ def request_phase def callback_phase @adaptor = OmniAuth::LDAP::Adaptor.new @options - # GITLAB security patch - # Dont allow blank password for ldap auth - if request['username'].nil? || request['username'].empty? || request['password'].nil? || request['password'].empty? - raise MissingCredentialsError.new("Missing login credentials") - end - begin + # GITLAB security patch + # Dont allow blank password for ldap auth + if request['username'].nil? || request['username'].empty? || request['password'].nil? || request['password'].empty? + raise MissingCredentialsError.new("Missing login credentials") + end + @ldap_user_info = @adaptor.bind_as(:filter => Net::LDAP::Filter.eq(@adaptor.uid, @options[:name_proc].call(request['username'])),:size => 1, :password => request['password']) return fail!(:invalid_credentials) if !@ldap_user_info From d92ef39dcd9a392fe458ca868e9ba2a501b11881 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sun, 30 Dec 2012 15:06:58 +0200 Subject: [PATCH 03/62] Fixed test and travis --- .travis.yml | 6 +++ Gemfile | 9 ++-- Gemfile.lock | 78 +++++++++------------------ lib/omniauth-ldap/adaptor.rb | 10 ++-- omniauth-ldap.gemspec | 13 ++--- spec/omniauth/strategies/ldap_spec.rb | 40 ++++++++------ spec/spec_helper.rb | 2 - 7 files changed, 67 insertions(+), 91 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..baef6da --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +branches: + only: + - 'master' +rvm: + - 1.9.2 +script: "bundle exec rspec spec" diff --git a/Gemfile b/Gemfile index 339f969..2bc1e2f 100644 --- a/Gemfile +++ b/Gemfile @@ -3,9 +3,8 @@ source 'http://rubygems.org' gemspec group :development, :test do - gem 'guard' - gem 'guard-rspec' - gem 'guard-bundler' - gem 'growl' - gem 'rb-fsevent' + gem 'rspec' + gem 'pry' + gem 'rake' + gem 'rack-test' end diff --git a/Gemfile.lock b/Gemfile.lock index 6b0d47f..057ddb3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - omniauth-ldap (1.0.2) + gitlab_omniauth-ldap (1.0.2) net-ldap (~> 0.2.2) omniauth (~> 1.0) pyu-ruby-sasl (~> 0.0.3.1) @@ -10,70 +10,40 @@ PATH GEM remote: http://rubygems.org/ specs: - archive-tar-minitar (0.5.2) - columnize (0.3.4) + coderay (1.0.8) diff-lcs (1.1.3) - ffi (1.0.9) - growl (1.0.3) - guard (0.8.8) - thor (~> 0.14.6) - guard-bundler (0.1.3) - bundler (>= 1.0.0) - guard (>= 0.2.2) - guard-rspec (0.5.0) - guard (>= 0.8.4) hashie (1.2.0) - libnotify (0.5.7) - ffi (= 1.0.9) - linecache19 (0.5.12) - ruby_core_source (>= 0.1.4) - multi_json (1.0.3) + method_source (0.8.1) net-ldap (0.2.2) - omniauth (1.0.1) + omniauth (1.1.1) hashie (~> 1.2) rack + pry (0.9.10) + coderay (~> 1.0.5) + method_source (~> 0.8) + slop (~> 3.3.1) pyu-ruby-sasl (0.0.3.3) - rack (1.3.5) - rack-test (0.6.1) + rack (1.4.1) + rack-test (0.6.2) rack (>= 1.0) - rb-fsevent (0.4.3.1) - rspec (2.7.0) - rspec-core (~> 2.7.0) - rspec-expectations (~> 2.7.0) - rspec-mocks (~> 2.7.0) - rspec-core (2.7.1) - rspec-expectations (2.7.0) - diff-lcs (~> 1.1.2) - rspec-mocks (2.7.0) - ruby-debug-base19 (0.11.25) - columnize (>= 0.3.1) - linecache19 (>= 0.5.11) - ruby_core_source (>= 0.1.4) - ruby-debug19 (0.11.6) - columnize (>= 0.3.1) - linecache19 (>= 0.5.11) - ruby-debug-base19 (>= 0.11.19) - ruby_core_source (0.1.5) - archive-tar-minitar (>= 0.5.2) + rake (10.0.3) + rspec (2.12.0) + rspec-core (~> 2.12.0) + rspec-expectations (~> 2.12.0) + rspec-mocks (~> 2.12.0) + rspec-core (2.12.2) + rspec-expectations (2.12.1) + diff-lcs (~> 1.1.3) + rspec-mocks (2.12.1) rubyntlm (0.1.1) - simplecov (0.5.4) - multi_json (~> 1.0.3) - simplecov-html (~> 0.5.3) - simplecov-html (0.5.3) - thor (0.14.6) + slop (3.3.3) PLATFORMS ruby DEPENDENCIES - growl - guard - guard-bundler - guard-rspec - libnotify - omniauth-ldap! + gitlab_omniauth-ldap! + pry rack-test - rb-fsevent - rspec (~> 2.7) - ruby-debug19 - simplecov + rake + rspec diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index 5c769b2..66459ad 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -49,10 +49,10 @@ def initialize(configuration={}) :base => @base } @uri = construct_uri(@host, @port, @method != :plain) - + @bind_method = @try_sasl ? :sasl : (@allow_anonymous||!@bind_dn||!@password ? :anonymous : :simple) - - + + @auth = sasl_auths({:username => @bind_dn, :password => @password}).first if @bind_method == :sasl @auth ||= { :method => @bind_method, :username => @bind_dn, @@ -61,11 +61,11 @@ def initialize(configuration={}) config[:auth] = @auth @connection = Net::LDAP.new(config) end - + #:base => "dc=yourcompany, dc=com", # :filter => "(mail=#{user})", # :password => psw - def bind_as(args = {}) + def bind_as(args = {}) result = false @connection.open do |me| rs = me.search args diff --git a/omniauth-ldap.gemspec b/omniauth-ldap.gemspec index 71e44d5..74f5291 100644 --- a/omniauth-ldap.gemspec +++ b/omniauth-ldap.gemspec @@ -6,22 +6,17 @@ Gem::Specification.new do |gem| gem.email = ["ping@intridea.com"] gem.description = %q{A LDAP strategy for OmniAuth.} gem.summary = %q{A LDAP strategy for OmniAuth.} - gem.homepage = "https://github.com/intridea/omniauth-ldap" + gem.homepage = "https://github.com/gitlabhq/omniauth-ldap" gem.add_runtime_dependency 'omniauth', '~> 1.0' gem.add_runtime_dependency 'net-ldap', '~> 0.2.2' gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.1' - gem.add_runtime_dependency 'rubyntlm', '~> 0.1.1' - gem.add_development_dependency 'rspec', '~> 2.7' - gem.add_development_dependency 'simplecov' - gem.add_development_dependency 'rack-test' - gem.add_development_dependency 'libnotify' - gem.add_development_dependency 'ruby-debug19' - + gem.add_runtime_dependency 'rubyntlm', '~> 0.1.1' + gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } gem.files = `git ls-files`.split("\n") gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - gem.name = "omniauth-ldap" + gem.name = "gitlab_omniauth-ldap" gem.require_paths = ["lib"] gem.version = OmniAuth::LDAP::VERSION end diff --git a/spec/omniauth/strategies/ldap_spec.rb b/spec/omniauth/strategies/ldap_spec.rb index 2a39f79..01a48bb 100644 --- a/spec/omniauth/strategies/ldap_spec.rb +++ b/spec/omniauth/strategies/ldap_spec.rb @@ -1,6 +1,7 @@ require 'spec_helper' + describe "OmniAuth::Strategies::LDAP" do - # :title => "My LDAP", + # :title => "My LDAP", # :host => '10.101.10.1', # :port => 389, # :method => :plain, @@ -8,12 +9,13 @@ # :uid => 'sAMAccountName', # :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')} # :bind_dn => 'default_bind_dn' - # :password => 'password' - class MyLdapProvider < OmniAuth::Strategies::LDAP; end + # :password => 'password' + class MyLdapProvider < OmniAuth::Strategies::LDAP; end + def app Rack::Builder.new { use OmniAuth::Test::PhonySession - use MyLdapProvider, :name => 'ldap', :title => 'MyLdap Form', :host => '192.168.1.145', :base => 'dc=score, dc=local', :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')} + use MyLdapProvider, :name => 'ldap', :title => 'MyLdap Form', :host => '192.168.1.145', :base => 'dc=score, dc=local', :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')} run lambda { |env| [404, {'Content-Type' => 'text/plain'}, [env.key?('omniauth.auth').to_s]] } }.to_app end @@ -52,36 +54,42 @@ def session @adaptor = mock(OmniAuth::LDAP::Adaptor, {:uid => 'ping'}) OmniAuth::LDAP::Adaptor.stub(:new).and_return(@adaptor) end + context 'failure' do - before(:each) do - @adaptor.stub(:bind_as).and_return(false) - end + before(:each) do + @adaptor.stub(:bind_as).and_return(false) + end + it 'should raise MissingCredentialsError' do - lambda{post('/auth/ldap/callback', {})}.should raise_error OmniAuth::Strategies::LDAP::MissingCredentialsError + post('/auth/ldap/callback', {}) + last_response.should be_redirect + last_response.headers['Location'].should =~ %r{ldap_error} end - it 'should redirect to error page' do + + it 'should redirect to error page' do post('/auth/ldap/callback', {:username => 'ping', :password => 'password'}) last_response.should be_redirect last_response.headers['Location'].should =~ %r{invalid_credentials} end - it 'should redirect to error page when there is exception' do + + it 'should redirect to error page when there is exception' do @adaptor.stub(:bind_as).and_throw(Exception.new('connection_error')) post('/auth/ldap/callback', {:username => 'ping', :password => 'password'}) last_response.should be_redirect last_response.headers['Location'].should =~ %r{ldap_error} end end - + context 'success' do let(:auth_hash){ last_request.env['omniauth.auth'] } before(:each) do - @adaptor.stub(:bind_as).and_return({:dn => ['cn=ping, dc=intridea, dc=com'], :mail => ['ping@intridea.com'], :givenname => ['Ping'], :sn => ['Yu'], - :telephonenumber => ['555-555-5555'], :mobile => ['444-444-4444'], :uid => ['ping'], :title => ['dev'], :address =>[ 'k street'], - :l => ['Washington'], :st => ['DC'], :co => ["U.S.A"], :postofficebox => ['20001'], :wwwhomepage => ['www.intridea.com'], - :jpegphoto => ['http://www.intridea.com/ping.jpg'], :description => ['omniauth-ldap']}) + @adaptor.stub(:bind_as).and_return({:dn => ['cn=ping, dc=intridea, dc=com'], :mail => ['ping@intridea.com'], :givenname => ['Ping'], :sn => ['Yu'], + :telephonenumber => ['555-555-5555'], :mobile => ['444-444-4444'], :uid => ['ping'], :title => ['dev'], :address =>[ 'k street'], + :l => ['Washington'], :st => ['DC'], :co => ["U.S.A"], :postofficebox => ['20001'], :wwwhomepage => ['www.intridea.com'], + :jpegphoto => ['http://www.intridea.com/ping.jpg'], :description => ['omniauth-ldap']}) post('/auth/ldap/callback', {:username => 'ping', :password => 'password'}) end - + it 'should raise MissingCredentialsError' do should_not raise_error OmniAuth::Strategies::LDAP::MissingCredentialsError end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c0facec..5506076 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,7 +1,5 @@ $:.unshift File.expand_path('..', __FILE__) $:.unshift File.expand_path('../../lib', __FILE__) -require 'simplecov' -SimpleCov.start require 'rspec' require 'rack/test' require 'omniauth' From 2d45b8d50c8e566ce15e81fc8afc98f3822be1c7 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sun, 30 Dec 2012 15:10:08 +0200 Subject: [PATCH 04/62] badge addded --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 60d7e77..cfd2270 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# OmniAuth LDAP +# GitLab fork | OmniAuth LDAP [![build status](https://secure.travis-ci.org/gitlabhq/omniauth-ldap.png)](https://travis-ci.org/gitlabhq/omniauth-ldap) -== LDAP +### LDAP Use the LDAP strategy as a middleware in your application: From 8e4ceb51144ac6ac8ec6d8eca77c98ac508fe58b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sun, 30 Dec 2012 15:13:04 +0200 Subject: [PATCH 05/62] rename gemspec --- omniauth-ldap.gemspec => gitlab_omniauth-ldap.gemspec | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename omniauth-ldap.gemspec => gitlab_omniauth-ldap.gemspec (100%) diff --git a/omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec similarity index 100% rename from omniauth-ldap.gemspec rename to gitlab_omniauth-ldap.gemspec From ed838fc58795f1f3e2fcb6f4bc150c802af96d30 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 26 Apr 2013 20:40:26 +0300 Subject: [PATCH 06/62] Update net-ldap dependency --- gitlab_omniauth-ldap.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index 74f5291..589bb8a 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |gem| gem.homepage = "https://github.com/gitlabhq/omniauth-ldap" gem.add_runtime_dependency 'omniauth', '~> 1.0' - gem.add_runtime_dependency 'net-ldap', '~> 0.2.2' + gem.add_runtime_dependency 'net-ldap', '~> 0.3.1' gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.1' gem.add_runtime_dependency 'rubyntlm', '~> 0.1.1' From 8c50f199f8e2d8a4dc901ddbbe3e37a2630843ac Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Wed, 12 Jun 2013 22:13:07 -0700 Subject: [PATCH 07/62] Gemfile.lock: update net-ldap to fix LDAP authentication issues Newer LDAP servers fail with older versions of net-ldap. Update to the fixed version. Signed-off-by: David Aguilar --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 057ddb3..3641e51 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,7 +2,7 @@ PATH remote: . specs: gitlab_omniauth-ldap (1.0.2) - net-ldap (~> 0.2.2) + net-ldap (~> 0.3.1) omniauth (~> 1.0) pyu-ruby-sasl (~> 0.0.3.1) rubyntlm (~> 0.1.1) @@ -14,7 +14,7 @@ GEM diff-lcs (1.1.3) hashie (1.2.0) method_source (0.8.1) - net-ldap (0.2.2) + net-ldap (0.3.1) omniauth (1.1.1) hashie (~> 1.2) rack From daa9b62763c98a83141e1f2484976096df88c702 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Jun 2013 10:04:29 +0300 Subject: [PATCH 08/62] version up to 1.0.3 --- lib/omniauth-ldap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 628e132..1531127 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "1.0.2" + VERSION = "1.0.3" end end From 80f438f4fa72d322b920347b31d08382d4ed8ff2 Mon Sep 17 00:00:00 2001 From: Jan Bessai Date: Wed, 27 Aug 2014 15:36:28 +0000 Subject: [PATCH 09/62] Push version of net-ldap dependency to get rid of utf-8 bug: https://github.com/ruby-ldap/ruby-net-ldap/issues/80 --- gitlab_omniauth-ldap.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index b928ee3..606c8bd 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |gem| gem.license = "MIT" gem.add_runtime_dependency 'omniauth', '~> 1.0' - gem.add_runtime_dependency 'net-ldap', '~> 0.3.1' + gem.add_runtime_dependency 'net-ldap', '~> 0.7.0' gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.1' gem.add_runtime_dependency 'rubyntlm', '~> 0.1.1' From 54a602177221aced24a67156ce5965a27ac71413 Mon Sep 17 00:00:00 2001 From: Jan Bessai Date: Tue, 2 Sep 2014 16:28:46 +0200 Subject: [PATCH 10/62] push versions in Gemfile.lock --- Gemfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9bff2bd..60064d2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,7 +2,7 @@ PATH remote: . specs: gitlab_omniauth-ldap (1.0.4) - net-ldap (~> 0.3.1) + net-ldap (~> 0.7.0) omniauth (~> 1.0) pyu-ruby-sasl (~> 0.0.3.1) rubyntlm (~> 0.1.1) @@ -12,12 +12,12 @@ GEM specs: coderay (1.0.8) diff-lcs (1.1.3) - hashie (1.2.0) + hashie (3.3.1) method_source (0.8.1) - net-ldap (0.3.1) - omniauth (1.1.1) - hashie (~> 1.2) - rack + net-ldap (0.7.0) + omniauth (1.2.2) + hashie (>= 1.2, < 4) + rack (~> 1.0) pry (0.9.10) coderay (~> 1.0.5) method_source (~> 0.8) From aaac56274cff8ad9d996c13720f2bbf470b559ad Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 8 Sep 2014 17:19:33 +0200 Subject: [PATCH 11/62] Bump VERSION to 1.1.0 Considering we are bumping net-ldap from 0.3.1 to 0.7.0 I thought a minor version bump might be called for. --- lib/omniauth-ldap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index d5adc48..f7f9b4b 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "1.0.4" + VERSION = "1.1.0" end end From 14f97bdac8e587ab05adf5483f6ce3424cdcac4c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 29 Oct 2014 17:06:58 +0200 Subject: [PATCH 12/62] Bump dependencies Signed-off-by: Dmitriy Zaporozhets --- Gemfile.lock | 10 +++++----- gitlab_omniauth-ldap.gemspec | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 60064d2..5dd6d08 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,11 @@ PATH remote: . specs: - gitlab_omniauth-ldap (1.0.4) - net-ldap (~> 0.7.0) + gitlab_omniauth-ldap (1.1.0) + net-ldap (~> 0.9) omniauth (~> 1.0) pyu-ruby-sasl (~> 0.0.3.1) - rubyntlm (~> 0.1.1) + rubyntlm (~> 0.3) GEM remote: http://rubygems.org/ @@ -14,7 +14,7 @@ GEM diff-lcs (1.1.3) hashie (3.3.1) method_source (0.8.1) - net-ldap (0.7.0) + net-ldap (0.9.0) omniauth (1.2.2) hashie (>= 1.2, < 4) rack (~> 1.0) @@ -35,7 +35,7 @@ GEM rspec-expectations (2.12.1) diff-lcs (~> 1.1.3) rspec-mocks (2.12.1) - rubyntlm (0.1.1) + rubyntlm (0.4.0) slop (3.3.3) PLATFORMS diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index 606c8bd..940512d 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -10,9 +10,9 @@ Gem::Specification.new do |gem| gem.license = "MIT" gem.add_runtime_dependency 'omniauth', '~> 1.0' - gem.add_runtime_dependency 'net-ldap', '~> 0.7.0' + gem.add_runtime_dependency 'net-ldap', '~> 0.9' gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.1' - gem.add_runtime_dependency 'rubyntlm', '~> 0.1.1' + gem.add_runtime_dependency 'rubyntlm', '~> 0.3' gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } gem.files = `git ls-files`.split("\n") From cfbb9040c0247b1d6636b228cc21c1bc451d196e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 29 Oct 2014 17:12:01 +0200 Subject: [PATCH 13/62] Bump version Signed-off-by: Dmitriy Zaporozhets --- Gemfile.lock | 2 +- lib/omniauth-ldap/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5dd6d08..530ade2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - gitlab_omniauth-ldap (1.1.0) + gitlab_omniauth-ldap (1.2.0) net-ldap (~> 0.9) omniauth (~> 1.0) pyu-ruby-sasl (~> 0.0.3.1) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index f7f9b4b..1d8c32e 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "1.1.0" + VERSION = "1.2.0" end end From f2acd1f9b8719cda9bbaf78651ebdb78d013993e Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 6 Mar 2015 13:25:59 +0100 Subject: [PATCH 14/62] Escape wildcards in username. --- lib/omniauth/strategies/ldap.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index 4b075e4..b26f607 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -52,9 +52,10 @@ def callback_phase def filter adaptor if adaptor.filter and !adaptor.filter.empty? - Net::LDAP::Filter.construct(adaptor.filter % {username: @options[:name_proc].call(request['username'])}) + username = Net::LDAP::Filter.escape(@options[:name_proc].call(request['username'])) + Net::LDAP::Filter.construct(adaptor.filter % { username: username }) else - Net::LDAP::Filter.eq(adaptor.uid, @options[:name_proc].call(request['username'])) + Net::LDAP::Filter.equals(adaptor.uid, @options[:name_proc].call(request['username'])) end end From 1bfda92229763eaad8141fd5675df7dcfe3acb3e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 6 Mar 2015 18:01:14 -0800 Subject: [PATCH 15/62] Add ruby 2.1.5 to travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index e8fd1f0..91f7083 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,5 @@ branches: - 'master' rvm: - 2.0.0 + - 2.1.5 script: "bundle exec rspec spec" From 2dd5b77abe7174ceb647cc9260987868ddb3c5a2 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 17 Mar 2015 17:10:03 +0100 Subject: [PATCH 16/62] Bump version to 1.2.1. --- lib/omniauth-ldap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 1d8c32e..4e21bee 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "1.2.0" + VERSION = "1.2.1" end end From 81d2e680712698447f8e134bef695dc0d6030be1 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 17 Mar 2015 17:11:06 +0100 Subject: [PATCH 17/62] Update gems. --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 530ade2..ab3d3d9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - gitlab_omniauth-ldap (1.2.0) + gitlab_omniauth-ldap (1.2.1) net-ldap (~> 0.9) omniauth (~> 1.0) pyu-ruby-sasl (~> 0.0.3.1) @@ -12,9 +12,9 @@ GEM specs: coderay (1.0.8) diff-lcs (1.1.3) - hashie (3.3.1) + hashie (3.4.0) method_source (0.8.1) - net-ldap (0.9.0) + net-ldap (0.11) omniauth (1.2.2) hashie (>= 1.2, < 4) rack (~> 1.0) @@ -35,7 +35,7 @@ GEM rspec-expectations (2.12.1) diff-lcs (~> 1.1.3) rspec-mocks (2.12.1) - rubyntlm (0.4.0) + rubyntlm (0.5.0) slop (3.3.3) PLATFORMS From bc9199d2e12aa0735351ddeb18ff88895e3d68d9 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Tue, 27 Sep 2016 23:47:53 -0500 Subject: [PATCH 18/62] Add support for LDAP failover --- .gitlab-ci.yml | 12 +++++++++ Gemfile.lock | 15 ++++++----- gitlab_omniauth-ldap.gemspec | 2 +- lib/omniauth-ldap/adaptor.rb | 23 +++++++++++------ lib/omniauth-ldap/version.rb | 2 +- spec/omniauth-ldap/adaptor_spec.rb | 40 +++++++++++++++++++++++++++++- 6 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..37a97d7 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,12 @@ +image: "ruby:2.3.1" + +before_script: + - bundle install + +stages: + - test + +rspec: + stage: test + script: + - bundle exec rake spec diff --git a/Gemfile.lock b/Gemfile.lock index ab3d3d9..13b7bdf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,7 +2,7 @@ PATH remote: . specs: gitlab_omniauth-ldap (1.2.1) - net-ldap (~> 0.9) + net-ldap (~> 0.12) omniauth (~> 1.0) pyu-ruby-sasl (~> 0.0.3.1) rubyntlm (~> 0.3) @@ -12,12 +12,12 @@ GEM specs: coderay (1.0.8) diff-lcs (1.1.3) - hashie (3.4.0) + hashie (3.4.4) method_source (0.8.1) - net-ldap (0.11) - omniauth (1.2.2) + net-ldap (0.15.0) + omniauth (1.3.1) hashie (>= 1.2, < 4) - rack (~> 1.0) + rack (>= 1.0, < 3) pry (0.9.10) coderay (~> 1.0.5) method_source (~> 0.8) @@ -35,7 +35,7 @@ GEM rspec-expectations (2.12.1) diff-lcs (~> 1.1.3) rspec-mocks (2.12.1) - rubyntlm (0.5.0) + rubyntlm (0.5.2) slop (3.3.3) PLATFORMS @@ -47,3 +47,6 @@ DEPENDENCIES rack-test rake rspec + +BUNDLED WITH + 1.12.5 diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index 940512d..c9606db 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |gem| gem.license = "MIT" gem.add_runtime_dependency 'omniauth', '~> 1.0' - gem.add_runtime_dependency 'net-ldap', '~> 0.9' + gem.add_runtime_dependency 'net-ldap', '~> 0.12' gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.1' gem.add_runtime_dependency 'rubyntlm', '~> 0.3' diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index 68b4e14..eb5603e 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -13,10 +13,19 @@ class ConfigurationError < StandardError; end class AuthenticationError < StandardError; end class ConnectionError < StandardError; end - VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :bind_dn, :password, :try_sasl, :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter] + VALID_ADAPTER_CONFIGURATION_KEYS = [ + :hosts, :host, :port, :method, :bind_dn, :password, :try_sasl, + :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter + ] # A list of needed keys. Possible alternatives are specified using sub-lists. - MUST_HAVE_KEYS = [:host, :port, :method, [:uid, :filter], :base] + MUST_HAVE_KEYS = [ + :base, + :method, + [:hosts, :host], + [:hosts, :port], + [:uid, :filter] + ] METHOD = { :ssl => :simple_tls, @@ -47,12 +56,12 @@ def initialize(configuration={}) end method = ensure_method(@method) config = { - :host => @host, - :port => @port, - :encryption => method, - :base => @base + base: @base, + hosts: @hosts, + host: @host, + port: @port, + method: @method } - @bind_method = @try_sasl ? :sasl : (@allow_anonymous||!@bind_dn||!@password ? :anonymous : :simple) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 4e21bee..951e9fa 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "1.2.1" + VERSION = "1.3.1" end end diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index e6a304f..8b6a474 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -1,5 +1,5 @@ require 'spec_helper' -describe "OmniAuth::LDAP::Adaptor" do +describe OmniAuth::LDAP::Adaptor do describe 'initialize' do it 'should throw exception when must have field is not set' do @@ -7,6 +7,17 @@ lambda { OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain'})}.should raise_error(ArgumentError) end + it 'should not throw an error if hosts is set but host and port are not' do + expect( + described_class.new( + hosts: [['192.168.1.145', 389], ['192.168.1.146', 389]], + method: 'plain', + base: 'dc=example,dc=com', + uid: 'uid' + ) + ).not_to raise_error(ArgumentError) + end + it 'should throw exception when method is not supported' do lambda { OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'myplain', uid: 'uid', port: 389, base: 'dc=com'})}.should raise_error(OmniAuth::LDAP::Adaptor::ConfigurationError) end @@ -52,6 +63,33 @@ adaptor.connection.instance_variable_get('@auth')[:initial_credential].should =~ /^NTLMSSP/ adaptor.connection.instance_variable_get('@auth')[:challenge_response].should_not be_nil end + + it 'sets up a connection with the proper host and port' do + adapter = described_class.new( + host: '192.168.1.145', + method: 'plain', + base: 'dc=example,dc=com', + port: 3890, + uid: 'uid' + ) + + expect(adapter.connection.host).to eq('192.168.1.145') + expect(adapter.connection.port).to eq(3890) + expect(adapter.connection.hosts).to be_nil + end + + it 'sets up a connection with a enumerable pairs of hosts' do + adapter = described_class.new( + hosts: [['192.168.1.145', 636], ['192.168.1.146', 636]], + method: 'plain', + base: 'dc=example,dc=com', + uid: 'uid' + ) + + expect(adapter.connection.host).to eq('127.0.0.1') + expect(adapter.connection.port).to eq(389) + expect(adapter.connection.hosts).to match_array([['192.168.1.145', 636], ['192.168.1.146', 636]]) + end end describe 'bind_as' do From 226c1d8867018d4a04907788df1a432d1d3e94ca Mon Sep 17 00:00:00 2001 From: Mike Tierney Date: Mon, 8 Feb 2016 10:41:22 -0800 Subject: [PATCH 19/62] Merge pull request #65 from JulianKniephoff/net-ldap-compatibility Net::LDAP compatibility --- lib/omniauth-ldap/adaptor.rb | 2 +- spec/omniauth-ldap/adaptor_spec.rb | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index eb5603e..90859c6 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -60,7 +60,6 @@ def initialize(configuration={}) hosts: @hosts, host: @host, port: @port, - method: @method } @bind_method = @try_sasl ? :sasl : (@allow_anonymous||!@bind_dn||!@password ? :anonymous : :simple) @@ -72,6 +71,7 @@ def initialize(configuration={}) } config[:auth] = @auth @connection = Net::LDAP.new(config) + @connection.encryption(method) end #:base => "dc=yourcompany, dc=com", diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index 8b6a474..0e1064c 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -90,6 +90,11 @@ expect(adapter.connection.port).to eq(389) expect(adapter.connection.hosts).to match_array([['192.168.1.145', 636], ['192.168.1.146', 636]]) end + + it 'should set the encryption method correctly' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include method: :start_tls + end end describe 'bind_as' do From 83ef8bda170f8d9ea3be8cdf4bf86478489c666e Mon Sep 17 00:00:00 2001 From: kirolous Date: Tue, 14 Jul 2015 08:49:44 -0400 Subject: [PATCH 20/62] Update omniauth-ldap.gemspec --- gitlab_omniauth-ldap.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index c9606db..074b3ea 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |gem| gem.add_runtime_dependency 'omniauth', '~> 1.0' gem.add_runtime_dependency 'net-ldap', '~> 0.12' - gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.1' + gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.2'#0.0.3.1 has been yanked gem.add_runtime_dependency 'rubyntlm', '~> 0.3' gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } From 7080cd19aff874db4c4227e2970d52003adfc044 Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Tue, 6 Jun 2017 09:12:43 -0700 Subject: [PATCH 21/62] Fix dependencies http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/ --- .gitignore | 2 ++ Gemfile.lock | 52 ------------------------------ gitlab_omniauth-ldap.gemspec | 12 ++++--- spec/omniauth-ldap/adaptor_spec.rb | 4 +-- 4 files changed, 12 insertions(+), 58 deletions(-) delete mode 100644 Gemfile.lock diff --git a/.gitignore b/.gitignore index bf84190..7c911bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .project +.tags coverage +Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 13b7bdf..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,52 +0,0 @@ -PATH - remote: . - specs: - gitlab_omniauth-ldap (1.2.1) - net-ldap (~> 0.12) - omniauth (~> 1.0) - pyu-ruby-sasl (~> 0.0.3.1) - rubyntlm (~> 0.3) - -GEM - remote: http://rubygems.org/ - specs: - coderay (1.0.8) - diff-lcs (1.1.3) - hashie (3.4.4) - method_source (0.8.1) - net-ldap (0.15.0) - omniauth (1.3.1) - hashie (>= 1.2, < 4) - rack (>= 1.0, < 3) - pry (0.9.10) - coderay (~> 1.0.5) - method_source (~> 0.8) - slop (~> 3.3.1) - pyu-ruby-sasl (0.0.3.3) - rack (1.4.1) - rack-test (0.6.2) - rack (>= 1.0) - rake (10.0.3) - rspec (2.12.0) - rspec-core (~> 2.12.0) - rspec-expectations (~> 2.12.0) - rspec-mocks (~> 2.12.0) - rspec-core (2.12.2) - rspec-expectations (2.12.1) - diff-lcs (~> 1.1.3) - rspec-mocks (2.12.1) - rubyntlm (0.5.2) - slop (3.3.3) - -PLATFORMS - ruby - -DEPENDENCIES - gitlab_omniauth-ldap! - pry - rack-test - rake - rspec - -BUNDLED WITH - 1.12.5 diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index 074b3ea..c00bf55 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -9,10 +9,14 @@ Gem::Specification.new do |gem| gem.homepage = "https://github.com/gitlabhq/omniauth-ldap" gem.license = "MIT" - gem.add_runtime_dependency 'omniauth', '~> 1.0' - gem.add_runtime_dependency 'net-ldap', '~> 0.12' - gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.2'#0.0.3.1 has been yanked - gem.add_runtime_dependency 'rubyntlm', '~> 0.3' + gem.add_runtime_dependency 'omniauth', '~> 1.3.1' + gem.add_runtime_dependency 'net-ldap', '~> 0.15' + gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.3' + gem.add_runtime_dependency 'rubyntlm', '~> 0.5.2' + gem.add_development_dependency 'rspec', '~> 3.6.0' + gem.add_development_dependency 'pry', '~> 0.10.4' + gem.add_development_dependency 'rake', '~> 12.0.0' + gem.add_development_dependency 'rack-test', '~> 0.6.3' gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } gem.files = `git ls-files`.split("\n") diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index 0e1064c..6c1a53e 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -8,14 +8,14 @@ end it 'should not throw an error if hosts is set but host and port are not' do - expect( + expect { described_class.new( hosts: [['192.168.1.145', 389], ['192.168.1.146', 389]], method: 'plain', base: 'dc=example,dc=com', uid: 'uid' ) - ).not_to raise_error(ArgumentError) + }.not_to raise_error(ArgumentError) end it 'should throw exception when method is not supported' do From 2c3511fc0b8fe0580a6c2800e1363cae60b43555 Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Tue, 6 Jun 2017 09:15:56 -0700 Subject: [PATCH 22/62] Require latest net-ldap This version verifies SSL certificate hostnames. --- gitlab_omniauth-ldap.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index c00bf55..4ba3e4c 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |gem| gem.license = "MIT" gem.add_runtime_dependency 'omniauth', '~> 1.3.1' - gem.add_runtime_dependency 'net-ldap', '~> 0.15' + gem.add_runtime_dependency 'net-ldap', '~> 0.16' gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.3' gem.add_runtime_dependency 'rubyntlm', '~> 0.5.2' gem.add_development_dependency 'rspec', '~> 3.6.0' From d12d7380229bf3bcd8ba1603a7ef5a66af495c52 Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Tue, 6 Jun 2017 10:37:24 -0700 Subject: [PATCH 23/62] Verify certificates by default, and add disable option --- lib/omniauth-ldap/adaptor.rb | 40 +++++++++++++--- lib/omniauth/strategies/ldap.rb | 1 + spec/omniauth-ldap/adaptor_spec.rb | 69 +++++++++++++++++++++++++-- spec/omniauth/strategies/ldap_spec.rb | 3 +- 4 files changed, 102 insertions(+), 11 deletions(-) diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index 90859c6..59e6adc 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -14,7 +14,7 @@ class AuthenticationError < StandardError; end class ConnectionError < StandardError; end VALID_ADAPTER_CONFIGURATION_KEYS = [ - :hosts, :host, :port, :method, :bind_dn, :password, :try_sasl, + :hosts, :host, :port, :method, :disable_verify_certificates, :bind_dn, :password, :try_sasl, :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter ] @@ -35,6 +35,7 @@ class ConnectionError < StandardError; end attr_accessor :bind_dn, :password attr_reader :connection, :uid, :base, :auth, :filter + def self.validate(configuration={}) message = [] MUST_HAVE_KEYS.each do |names| @@ -46,6 +47,7 @@ def self.validate(configuration={}) end raise ArgumentError.new(message.join(",") +" MUST be provided") unless message.empty? end + def initialize(configuration={}) Adaptor.validate(configuration) @configuration = configuration.dup @@ -54,7 +56,6 @@ def initialize(configuration={}) VALID_ADAPTER_CONFIGURATION_KEYS.each do |name| instance_variable_set("@#{name}", @configuration[name]) end - method = ensure_method(@method) config = { base: @base, hosts: @hosts, @@ -71,7 +72,7 @@ def initialize(configuration={}) } config[:auth] = @auth @connection = Net::LDAP.new(config) - @connection.encryption(method) + @connection.encryption(encryption_options(@method, @disable_verify_certificates)) end #:base => "dc=yourcompany, dc=com", @@ -97,14 +98,39 @@ def bind_as(args = {}) end private - def ensure_method(method) - method ||= "plain" - normalized_method = method.to_s.downcase.to_sym - return METHOD[normalized_method] if METHOD.has_key?(normalized_method) + def encryption_options(method, disable_verify_certificates) + method = translate_method(method) + + { + method: method, + tls_options: tls_options(method, disable_verify_certificates) + } + end + + def translate_method(method) + method ||= "plain" + normalized_method = method.to_s.downcase.to_sym + + unless METHOD.has_key?(normalized_method) available_methods = METHOD.keys.collect {|m| m.inspect}.join(", ") format = "%s is not one of the available connect methods: %s" raise ConfigurationError, format % [method.inspect, available_methods] + end + + METHOD[normalized_method] + end + + def tls_options(method, disable_verify_certificates) + return {} if method == nil # (plain) + + # It is important to explicitly set verify_mode for two reasons: + # 1. The behavior of OpenSSL is undefined when verify_mode is not set. + # 2. The net-ldap gem implementation verifies the certificate hostname + # unless verify_mode is set to VERIFY_NONE. + return { verify_mode: OpenSSL::SSL::VERIFY_NONE } if disable_verify_certificates + + OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end def sasl_auths(options={}) diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index b26f607..5a95817 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -22,6 +22,7 @@ class LDAP option :title, "LDAP Authentication" #default title for authentication form option :port, 389 option :method, :plain + option :disable_verify_certificates, false option :uid, 'sAMAccountName' option :name_proc, lambda {|n| n} diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index 6c1a53e..c2ff9b5 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -91,9 +91,72 @@ expect(adapter.connection.hosts).to match_array([['192.168.1.145', 636], ['192.168.1.146', 636]]) end - it 'should set the encryption method correctly' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - adaptor.connection.instance_variable_get('@encryption').should include method: :start_tls + context 'when method is plain' do + it 'should set the encryption method to nil' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include method: nil + end + + it 'should set the encryption tls_options to empty' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: {} + end + end + + context 'when method is ssl' do + it 'should set the encryption method to simple_tls' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include method: :simple_tls + end + + context 'when disable_verify_certificates is not specified' do + it 'should set the encryption tls_options to OpenSSL default params' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + end + end + + context 'when disable_verify_certificates is true' do + it 'should set the encryption tls_options verify_mode explicitly to verify none' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', disable_verify_certificates: true, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE } + end + end + + context 'when disable_verify_certificates is false' do + it 'should set the encryption tls_options to OpenSSL default params' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', disable_verify_certificates: false, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + end + end + end + + context 'when method is tls' do + it 'should set the encryption method to start_tls' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include method: :start_tls + end + + context 'when disable_verify_certificates is not specified' do + it 'should set the encryption tls_options to OpenSSL default params' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + end + end + + context 'when disable_verify_certificates is true' do + it 'should set the encryption tls_options verify_mode explicitly to verify none' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', disable_verify_certificates: true, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE } + end + end + + context 'when disable_verify_certificates is false' do + it 'should set the encryption tls_options to OpenSSL default params' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', disable_verify_certificates: false, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + end + end end end diff --git a/spec/omniauth/strategies/ldap_spec.rb b/spec/omniauth/strategies/ldap_spec.rb index 1c13329..cda9448 100644 --- a/spec/omniauth/strategies/ldap_spec.rb +++ b/spec/omniauth/strategies/ldap_spec.rb @@ -5,6 +5,7 @@ # :host => '10.101.10.1', # :port => 389, # :method => :plain, + # :verify_certificates => true, # :base => 'dc=intridea, dc=com', # :uid => 'sAMAccountName', # :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')} @@ -210,7 +211,7 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end auth_hash.info.description.should == 'omniauth-ldap' end end - + context 'alternate fields' do let(:auth_hash){ last_request.env['omniauth.auth'] } From 3cd7d699b93d23c565bcb7929d89f6a868e2fd6a Mon Sep 17 00:00:00 2001 From: Sasha Kotlyar Date: Fri, 27 May 2016 13:57:36 -0400 Subject: [PATCH 24/62] Add ability to specify ca_file and ssl_version --- lib/omniauth-ldap/adaptor.rb | 41 +++++++++++++++++------------- lib/omniauth/strategies/ldap.rb | 2 ++ spec/omniauth-ldap/adaptor_spec.rb | 15 +++++++++++ 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index 59e6adc..d2adab8 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -15,7 +15,7 @@ class ConnectionError < StandardError; end VALID_ADAPTER_CONFIGURATION_KEYS = [ :hosts, :host, :port, :method, :disable_verify_certificates, :bind_dn, :password, :try_sasl, - :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter + :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter, :ca_file, :ssl_version ] # A list of needed keys. Possible alternatives are specified using sub-lists. @@ -72,7 +72,7 @@ def initialize(configuration={}) } config[:auth] = @auth @connection = Net::LDAP.new(config) - @connection.encryption(encryption_options(@method, @disable_verify_certificates)) + @connection.encryption(encryption_options) end #:base => "dc=yourcompany, dc=com", @@ -99,16 +99,17 @@ def bind_as(args = {}) private - def encryption_options(method, disable_verify_certificates) - method = translate_method(method) + def encryption_options + translated_method = translate_method { - method: method, - tls_options: tls_options(method, disable_verify_certificates) + method: translated_method, + tls_options: tls_options(translated_method) } end - def translate_method(method) + def translate_method + method = @method method ||= "plain" normalized_method = method.to_s.downcase.to_sym @@ -121,16 +122,22 @@ def translate_method(method) METHOD[normalized_method] end - def tls_options(method, disable_verify_certificates) - return {} if method == nil # (plain) - - # It is important to explicitly set verify_mode for two reasons: - # 1. The behavior of OpenSSL is undefined when verify_mode is not set. - # 2. The net-ldap gem implementation verifies the certificate hostname - # unless verify_mode is set to VERIFY_NONE. - return { verify_mode: OpenSSL::SSL::VERIFY_NONE } if disable_verify_certificates - - OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + def tls_options(translated_method) + return {} if translated_method == nil # (plain) + + tls_options = if @disable_verify_certificates + # It is important to explicitly set verify_mode for two reasons: + # 1. The behavior of OpenSSL is undefined when verify_mode is not set. + # 2. The net-ldap gem implementation verifies the certificate hostname + # unless verify_mode is set to VERIFY_NONE. + { verify_mode: OpenSSL::SSL::VERIFY_NONE } + else + OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + end + + tls_options[:ca_file] = @ca_file if @ca_file + tls_options[:ssl_version] = @ssl_version if @ssl_version + tls_options end def sasl_auths(options={}) diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index 5a95817..959487f 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -23,6 +23,8 @@ class LDAP option :port, 389 option :method, :plain option :disable_verify_certificates, false + option :ca_file, nil + option :ssl_version, nil # use OpenSSL default if nil option :uid, 'sAMAccountName' option :name_proc, lambda {|n| n} diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index c2ff9b5..f51a75c 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -38,6 +38,7 @@ adaptor.connection.port.should == 389 adaptor.connection.base.should == 'dc=intridea, dc=com' adaptor.connection.instance_variable_get('@auth').should == {:method => :simple, :username => 'bind_dn', :password => 'password'} + adaptor.connection.instance_variable_get('@encryption').should == {:method => nil, :tls_options => {}} end it 'should setup ldap connection with sasl-md5' do @@ -129,6 +130,20 @@ adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end end + + context 'when ca_file is specified' do + it 'should set the encryption tls_options ca_file' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', ca_file: '/etc/ca.pem'}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ca_file: '/etc/ca.pem') + end + end + + context 'when ssl_version is specified' do + it 'should overwrite the encryption tls_options ssl_version' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', ssl_version: 'TLSv1_2'}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ssl_version: 'TLSv1_2') + end + end end context 'when method is tls' do From 065ff02b48ab424d8b5269765afcf429c5949973 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Tue, 28 Feb 2017 14:57:12 -0600 Subject: [PATCH 25/62] Allow encryption method to accept simple_tls/start_tls The current mapping of `ssl` to `simple_tls` and `tls` to `start_tls` were confusing. Pass through the standard terms used in `Net::LDAP`. Also, update use of `method` to `encryption_method` for clarity. --- README.md | 45 +++++++++++---------- lib/omniauth-ldap/adaptor.rb | 26 +++++++----- spec/omniauth-ldap/adaptor_spec.rb | 63 +++++++++++++++++------------- 3 files changed, 76 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 420a960..0f5e876 100644 --- a/README.md +++ b/README.md @@ -5,43 +5,46 @@ Use the LDAP strategy as a middleware in your application: use OmniAuth::Strategies::LDAP, - :title => "My LDAP", - :host => '10.101.10.1', - :port => 389, - :method => :plain, - :base => 'dc=intridea, dc=com', - :uid => 'sAMAccountName', - :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')}, - :bind_dn => 'default_bind_dn', + :title => "My LDAP", + :host => '10.101.10.1', + :port => 389, + :encryption => :plain, + :base => 'dc=intridea, dc=com', + :uid => 'sAMAccountName', + :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')}, + :bind_dn => 'default_bind_dn', # Or, alternatively: - #:filter => '(&(uid=%{username})(memberOf=cn=myapp-users,ou=groups,dc=example,dc=com))' - :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')} - :bind_dn => 'default_bind_dn' - :password => 'password' + #:filter => '(&(uid=%{username})(memberOf=cn=myapp-users,ou=groups,dc=example,dc=com))' + :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')} + :bind_dn => 'default_bind_dn' + :password => 'password' All of the listed options are required, with the exception of :title, :name_proc, :bind_dn, and :password. -Allowed values of :method are: :plain, :ssl, :tls. -:bind_dn and :password is the default credentials to perform user lookup. +- `encryption` is the type of encryption to use between this library and the + LDAP server. `:plain` means no encryption. `:simple_tls` represents SSL/TLS + (usually on port 636) while `:start_tls` represents StartTLS (usually port 389). + +- `:bind_dn` and `:password` are the default credentials to perform user lookup. most LDAP servers require that you supply a complete DN as a binding-credential, along with an authenticator such as a password. But for many applications, you often don’t have a full DN to identify the user. You usually get a simple identifier like a username or an email address, along with a password. Since many LDAP servers don't allow anonymous access, search function will require a bound connection, - :bind_dn and :password will be required for searching on the username or email to retrieve the DN attribute + `:bind_dn` and `:password` will be required for searching on the username or email to retrieve the DN attribute for the user. If the LDAP server allows anonymous access, you don't need to provide these two parameters. -:uid is the LDAP attribute name for the user name in the login form. +- `:uid` is the LDAP attribute name for the user name in the login form. typically AD would be 'sAMAccountName' or 'UserPrincipalName', while OpenLDAP is 'uid'. -:filter is the LDAP filter used to search the user entry. It can be used in place of :uid for more flexibility. - `%{username}` will be replaced by the user name processed by :name_proc. +- `:filter` is the LDAP filter used to search the user entry. It can be used in place of :uid for more flexibility. + `%{username}` will be replaced by the user name processed by `:name_proc`. -:name_proc allows you to match the user name entered with the format of the :uid attributes. +- `:name_proc` allows you to match the user name entered with the format of the :uid attributes. For example, value of 'sAMAccountName' in AD contains only the windows user name. If your user prefers using email to login, a name_proc as above will trim the email string down to just the windows login name. - In summary, use :name_proc to fill the gap between the submitted username and LDAP uid attribute value. + In summary, use `:name_proc` to fill the gap between the submitted username and LDAP uid attribute value. -:try_sasl and :sasl_mechanisms are optional. :try_sasl [true | false], :sasl_mechanisms ['DIGEST-MD5' | 'GSS-SPNEGO'] +- `:try_sasl` and `:sasl_mechanisms` are optional. `:try_sasl` [`true` | `false`], `:sasl_mechanisms` [`'DIGEST-MD5'` | `'GSS-SPNEGO'`] Use them to initialize a SASL connection to server. If you are not familiar with these authentication methods, please just avoid them. diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index d2adab8..24655bb 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -14,23 +14,31 @@ class AuthenticationError < StandardError; end class ConnectionError < StandardError; end VALID_ADAPTER_CONFIGURATION_KEYS = [ - :hosts, :host, :port, :method, :disable_verify_certificates, :bind_dn, :password, :try_sasl, - :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter, :ca_file, :ssl_version + :hosts, :host, :port, :encryption, :disable_verify_certificates, :bind_dn, :password, :try_sasl, + :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter, :ca_file, :ssl_version, + + # Deprecated + :method ] # A list of needed keys. Possible alternatives are specified using sub-lists. MUST_HAVE_KEYS = [ :base, - :method, + [:encryption, :method], # :method is deprecated [:hosts, :host], [:hosts, :port], [:uid, :filter] ] - METHOD = { + ENCRYPTION_METHOD = { + :simple_tls => :simple_tls, + :start_tls => :start_tls, + :plain => nil, + + # Deprecated. This mapping aimed to be user-friendly, but only caused + # confusion. Better to pass-through the actual `Net::LDAP` encryption type. :ssl => :simple_tls, :tls => :start_tls, - :plain => nil, } attr_accessor :bind_dn, :password @@ -109,17 +117,17 @@ def encryption_options end def translate_method - method = @method + method = @encryption || @method method ||= "plain" normalized_method = method.to_s.downcase.to_sym - unless METHOD.has_key?(normalized_method) - available_methods = METHOD.keys.collect {|m| m.inspect}.join(", ") + unless ENCRYPTION_METHOD.has_key?(normalized_method) + available_methods = ENCRYPTION_METHOD.keys.collect {|m| m.inspect}.join(", ") format = "%s is not one of the available connect methods: %s" raise ConfigurationError, format % [method.inspect, available_methods] end - METHOD[normalized_method] + ENCRYPTION_METHOD[normalized_method] end def tls_options(translated_method) diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index f51a75c..46f0b48 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -3,27 +3,27 @@ describe 'initialize' do it 'should throw exception when must have field is not set' do - #[:host, :port, :method, :bind_dn] - lambda { OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain'})}.should raise_error(ArgumentError) + #[:host, :port, :encryption, :bind_dn] + lambda { OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain'})}.should raise_error(ArgumentError) end it 'should not throw an error if hosts is set but host and port are not' do expect { described_class.new( hosts: [['192.168.1.145', 389], ['192.168.1.146', 389]], - method: 'plain', + encryption: 'plain', base: 'dc=example,dc=com', uid: 'uid' ) }.not_to raise_error(ArgumentError) end - it 'should throw exception when method is not supported' do - lambda { OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'myplain', uid: 'uid', port: 389, base: 'dc=com'})}.should raise_error(OmniAuth::LDAP::Adaptor::ConfigurationError) + it 'should throw exception when encryption method is not supported' do + lambda { OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'myplain', uid: 'uid', port: 389, base: 'dc=com'})}.should raise_error(OmniAuth::LDAP::Adaptor::ConfigurationError) end it 'should setup ldap connection with anonymous' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.should_not == nil adaptor.connection.host.should == '192.168.1.145' adaptor.connection.port.should == 389 @@ -32,7 +32,7 @@ end it 'should setup ldap connection with simple' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password'}) adaptor.connection.should_not == nil adaptor.connection.host.should == '192.168.1.145' adaptor.connection.port.should == 389 @@ -42,7 +42,7 @@ end it 'should setup ldap connection with sasl-md5' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', try_sasl: true, sasl_mechanisms: ["DIGEST-MD5"], bind_dn: 'bind_dn', password: 'password'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', try_sasl: true, sasl_mechanisms: ["DIGEST-MD5"], bind_dn: 'bind_dn', password: 'password'}) adaptor.connection.should_not == nil adaptor.connection.host.should == '192.168.1.145' adaptor.connection.port.should == 389 @@ -54,7 +54,7 @@ end it 'should setup ldap connection with sasl-gss' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', try_sasl: true, sasl_mechanisms: ["GSS-SPNEGO"], bind_dn: 'bind_dn', password: 'password'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', try_sasl: true, sasl_mechanisms: ["GSS-SPNEGO"], bind_dn: 'bind_dn', password: 'password'}) adaptor.connection.should_not == nil adaptor.connection.host.should == '192.168.1.145' adaptor.connection.port.should == 389 @@ -68,7 +68,7 @@ it 'sets up a connection with the proper host and port' do adapter = described_class.new( host: '192.168.1.145', - method: 'plain', + encryption: 'plain', base: 'dc=example,dc=com', port: 3890, uid: 'uid' @@ -82,7 +82,7 @@ it 'sets up a connection with a enumerable pairs of hosts' do adapter = described_class.new( hosts: [['192.168.1.145', 636], ['192.168.1.146', 636]], - method: 'plain', + encryption: 'plain', base: 'dc=example,dc=com', uid: 'uid' ) @@ -92,87 +92,94 @@ expect(adapter.connection.hosts).to match_array([['192.168.1.145', 636], ['192.168.1.146', 636]]) end - context 'when method is plain' do + context 'when encryption is plain' do it 'should set the encryption method to nil' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.instance_variable_get('@encryption').should include method: nil end it 'should set the encryption tls_options to empty' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.instance_variable_get('@encryption').should include tls_options: {} end end - context 'when method is ssl' do + context 'when encryption is ssl' do it 'should set the encryption method to simple_tls' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.instance_variable_get('@encryption').should include method: :simple_tls end context 'when disable_verify_certificates is not specified' do it 'should set the encryption tls_options to OpenSSL default params' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end end context 'when disable_verify_certificates is true' do it 'should set the encryption tls_options verify_mode explicitly to verify none' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', disable_verify_certificates: true, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', disable_verify_certificates: true, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.instance_variable_get('@encryption').should include tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE } end end context 'when disable_verify_certificates is false' do it 'should set the encryption tls_options to OpenSSL default params' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', disable_verify_certificates: false, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', disable_verify_certificates: false, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end end context 'when ca_file is specified' do it 'should set the encryption tls_options ca_file' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', ca_file: '/etc/ca.pem'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', ca_file: '/etc/ca.pem'}) adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ca_file: '/etc/ca.pem') end end context 'when ssl_version is specified' do it 'should overwrite the encryption tls_options ssl_version' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', ssl_version: 'TLSv1_2'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', ssl_version: 'TLSv1_2'}) adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ssl_version: 'TLSv1_2') end end end - context 'when method is tls' do + context 'when encryption is tls' do it 'should set the encryption method to start_tls' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.instance_variable_get('@encryption').should include method: :start_tls end context 'when disable_verify_certificates is not specified' do it 'should set the encryption tls_options to OpenSSL default params' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end end context 'when disable_verify_certificates is true' do it 'should set the encryption tls_options verify_mode explicitly to verify none' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', disable_verify_certificates: true, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'tls', disable_verify_certificates: true, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.instance_variable_get('@encryption').should include tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE } end end context 'when disable_verify_certificates is false' do it 'should set the encryption tls_options to OpenSSL default params' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', disable_verify_certificates: false, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'tls', disable_verify_certificates: false, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end end end + + context 'when method is set instead of encryption' do + it 'should set the encryption method for backwards-compatibility' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) + adaptor.connection.instance_variable_get('@encryption').should include method: :start_tls + end + end end describe 'bind_as' do @@ -180,7 +187,7 @@ let(:rs) { Struct.new(:dn).new('new dn') } it 'should bind simple' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.126", method: 'plain', base: 'dc=score, dc=local', port: 389, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.126", encryption: 'plain', base: 'dc=score, dc=local', port: 389, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password'}) adaptor.connection.should_receive(:open).and_yield(adaptor.connection) adaptor.connection.should_receive(:search).with(args).and_return([rs]) adaptor.connection.should_receive(:bind).with({:username => 'new dn', :password => args[:password], :method => :simple}).and_return(true) @@ -188,7 +195,7 @@ end it 'should bind sasl' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', try_sasl: true, sasl_mechanisms: ["GSS-SPNEGO"], bind_dn: 'bind_dn', password: 'password'}) + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', try_sasl: true, sasl_mechanisms: ["GSS-SPNEGO"], bind_dn: 'bind_dn', password: 'password'}) adaptor.connection.should_receive(:open).and_yield(adaptor.connection) adaptor.connection.should_receive(:search).with(args).and_return([rs]) adaptor.connection.should_receive(:bind).and_return(true) From 2f38f36faa0bcf1148b38a4d6792ad2d3e750ad6 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 7 Jun 2017 08:35:54 -0500 Subject: [PATCH 26/62] Bump version to 2.0.0 --- lib/omniauth-ldap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 951e9fa..507a2af 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "1.3.1" + VERSION = "2.0.0" end end From b9b5d9decf42b61d4ea38f8d5dab013ea7b5cb8d Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Thu, 8 Jun 2017 14:46:08 -0700 Subject: [PATCH 27/62] Remove unnecessary Gemfile code Because the development dependencies are now defined in the gemspec as well. --- Gemfile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Gemfile b/Gemfile index 2bc1e2f..d65e2a6 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,3 @@ source 'http://rubygems.org' gemspec - -group :development, :test do - gem 'rspec' - gem 'pry' - gem 'rake' - gem 'rack-test' -end From 684ac1760cbca69933ed1553beaba6b21fab524d Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Thu, 8 Jun 2017 14:47:25 -0700 Subject: [PATCH 28/62] Relax dependency version specifiers So application authors can have more flexibility in satisfying the dependencies. --- gitlab_omniauth-ldap.gemspec | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index 4ba3e4c..57bf7b2 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -9,14 +9,14 @@ Gem::Specification.new do |gem| gem.homepage = "https://github.com/gitlabhq/omniauth-ldap" gem.license = "MIT" - gem.add_runtime_dependency 'omniauth', '~> 1.3.1' + gem.add_runtime_dependency 'omniauth', '~> 1.3' gem.add_runtime_dependency 'net-ldap', '~> 0.16' - gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.3' - gem.add_runtime_dependency 'rubyntlm', '~> 0.5.2' - gem.add_development_dependency 'rspec', '~> 3.6.0' - gem.add_development_dependency 'pry', '~> 0.10.4' - gem.add_development_dependency 'rake', '~> 12.0.0' - gem.add_development_dependency 'rack-test', '~> 0.6.3' + gem.add_runtime_dependency 'pyu-ruby-sasl', '>= 0.0.3.3', '< 0.1' + gem.add_runtime_dependency 'rubyntlm', '~> 0.5' + gem.add_development_dependency 'rspec', '>= 2.12' + gem.add_development_dependency 'pry', '>= 0.9' + gem.add_development_dependency 'rake', '>= 10.0' + gem.add_development_dependency 'rack-test', '>= 0.6' gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } gem.files = `git ls-files`.split("\n") From 9496a905004ccb77dd72fedc68649902aee9b858 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 9 Jun 2017 09:50:19 -0500 Subject: [PATCH 29/62] Bump version to 2.0.1 --- lib/omniauth-ldap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 507a2af..45a7127 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "2.0.0" + VERSION = "2.0.1" end end From 2610fa7f2989c5a505d28469f4bd7bb00a84a4a1 Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Mon, 12 Jun 2017 14:50:04 -0700 Subject: [PATCH 30/62] Fix no encryption `Net::LDAP` config --- lib/omniauth-ldap/adaptor.rb | 1 + spec/omniauth-ldap/adaptor_spec.rb | 11 +++-------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index 24655bb..f1b485d 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -109,6 +109,7 @@ def bind_as(args = {}) def encryption_options translated_method = translate_method + return nil unless translated_method { method: translated_method, diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index 46f0b48..b2397f9 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -38,7 +38,7 @@ adaptor.connection.port.should == 389 adaptor.connection.base.should == 'dc=intridea, dc=com' adaptor.connection.instance_variable_get('@auth').should == {:method => :simple, :username => 'bind_dn', :password => 'password'} - adaptor.connection.instance_variable_get('@encryption').should == {:method => nil, :tls_options => {}} + adaptor.connection.instance_variable_get('@encryption').should == nil end it 'should setup ldap connection with sasl-md5' do @@ -93,14 +93,9 @@ end context 'when encryption is plain' do - it 'should set the encryption method to nil' do + it 'should set encryption to nil' do adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - adaptor.connection.instance_variable_get('@encryption').should include method: nil - end - - it 'should set the encryption tls_options to empty' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - adaptor.connection.instance_variable_get('@encryption').should include tls_options: {} + adaptor.connection.instance_variable_get('@encryption').should eq(nil) end end From 804397889b169aae802584a1af0538d21b862dfd Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Mon, 12 Jun 2017 14:51:38 -0700 Subject: [PATCH 31/62] Set encryption as recommended in net-ldap > 0.13 --- lib/omniauth-ldap/adaptor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index f1b485d..03ed887 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -69,6 +69,7 @@ def initialize(configuration={}) hosts: @hosts, host: @host, port: @port, + encryption: encryption_options } @bind_method = @try_sasl ? :sasl : (@allow_anonymous||!@bind_dn||!@password ? :anonymous : :simple) @@ -80,7 +81,6 @@ def initialize(configuration={}) } config[:auth] = @auth @connection = Net::LDAP.new(config) - @connection.encryption(encryption_options) end #:base => "dc=yourcompany, dc=com", From 5cc4a55507c786d30a6ef62cb2a616903de66cb6 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 13 Jun 2017 16:12:57 -0500 Subject: [PATCH 32/62] Bump version to 2.0.2 --- lib/omniauth-ldap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 45a7127..8f952ee 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "2.0.1" + VERSION = "2.0.2" end end From 709aa39665ab8d629c567a5ac88197fdad5d50fb Mon Sep 17 00:00:00 2001 From: Tiago Botelho Date: Sat, 15 Jul 2017 13:32:24 +0100 Subject: [PATCH 33/62] Protects against wrong request method call to callback --- lib/omniauth/strategies/ldap.rb | 5 +++++ spec/omniauth/strategies/ldap_spec.rb | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index 959487f..08df2c6 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -40,6 +40,7 @@ def request_phase def callback_phase @adaptor = OmniAuth::LDAP::Adaptor.new @options + return fail!(:invalid_request_method) unless valid_request_method? return fail!(:missing_credentials) if missing_credentials? begin @ldap_user_info = @adaptor.bind_as(:filter => filter(@adaptor), :size => 1, :password => request['password']) @@ -96,6 +97,10 @@ def self.map_user(mapper, object) protected + def valid_request_method? + request.env['REQUEST_METHOD'] == 'POST' + end + def missing_credentials? request['username'].nil? or request['username'].empty? or request['password'].nil? or request['password'].empty? end # missing_credentials? diff --git a/spec/omniauth/strategies/ldap_spec.rb b/spec/omniauth/strategies/ldap_spec.rb index cda9448..6ba794b 100644 --- a/spec/omniauth/strategies/ldap_spec.rb +++ b/spec/omniauth/strategies/ldap_spec.rb @@ -80,6 +80,15 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end last_response.headers['Location'].should =~ %r{ldap_error} end + context 'wrong request method' do + it 'redirects to error page' do + get('/auth/ldap/callback', { username: 'ping', password: 'password' }) + + expect(last_response).to be_redirect + expect(last_response.headers['Location']).to match('invalid_request_method') + end + end + context "when username is not preset" do it 'should redirect to error page' do post('/auth/ldap/callback', {}) From 80f28f0419943e1fc8bc9522913f964bb61fcfb1 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 20 Jul 2017 19:20:37 +0300 Subject: [PATCH 34/62] Add changelog file Signed-off-by: Dmitriy Zaporozhets --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 CHANGELOG diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..952b285 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,2 @@ +## 2.0.3 + - Protects against wrong request method call to callback From 8e1e0cb78ee10e42802709b50a01ce018c8c33ca Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 20 Jul 2017 19:20:52 +0300 Subject: [PATCH 35/62] Bump version to 2.0.3 Signed-off-by: Dmitriy Zaporozhets --- lib/omniauth-ldap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 8f952ee..de4be40 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "2.0.2" + VERSION = "2.0.3" end end From 17cfc1c42b2f9387d657b6aa1dfae0dbe612bc40 Mon Sep 17 00:00:00 2001 From: Tiago Botelho Date: Wed, 9 Aug 2017 10:07:25 +0100 Subject: [PATCH 36/62] Improves log message when invalid credentials are used --- CHANGELOG | 3 +++ lib/omniauth-ldap/version.rb | 2 +- lib/omniauth/strategies/ldap.rb | 9 +++++++-- spec/omniauth/strategies/ldap_spec.rb | 16 ++++++++++------ 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 952b285..5d7ed6a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,2 +1,5 @@ +## 2.0.4 + - Improve log message when invalid credentials are used + ## 2.0.3 - Protects against wrong request method call to callback diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index de4be40..9af06d5 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "2.0.3" + VERSION = "2.0.4" end end diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index 08df2c6..d8a1fe0 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -4,6 +4,9 @@ module OmniAuth module Strategies class LDAP include OmniAuth::Strategy + + InvalidCredentialsError = Class.new(StandardError) + @@config = { 'name' => 'cn', 'first_name' => 'givenName', @@ -45,7 +48,9 @@ def callback_phase begin @ldap_user_info = @adaptor.bind_as(:filter => filter(@adaptor), :size => 1, :password => request['password']) - return fail!(:invalid_credentials) if !@ldap_user_info + unless @ldap_user_info + return fail!(:invalid_credentials, InvalidCredentialsError.new("Invalid credentials for #{request['username']}")) + end @user_info = self.class.map_user(@@config, @ldap_user_info) super @@ -54,7 +59,7 @@ def callback_phase end end - def filter adaptor + def filter(adaptor) if adaptor.filter and !adaptor.filter.empty? username = Net::LDAP::Filter.escape(@options[:name_proc].call(request['username'])) Net::LDAP::Filter.construct(adaptor.filter % { username: username }) diff --git a/spec/omniauth/strategies/ldap_spec.rb b/spec/omniauth/strategies/ldap_spec.rb index 6ba794b..203af57 100644 --- a/spec/omniauth/strategies/ldap_spec.rb +++ b/spec/omniauth/strategies/ldap_spec.rb @@ -69,8 +69,10 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end it 'should redirect to error page' do post('/auth/ldap/callback', {:username => 'ping', :password => 'password'}) - last_response.should be_redirect - last_response.headers['Location'].should =~ %r{invalid_credentials} + + expect(last_response).to be_redirect + expect(last_response.headers['Location']).to match('invalid_credentials') + expect(last_request.env['omniauth.error'].message).to eq('Invalid credentials for ping') end it 'should redirect to error page when there is exception' do @@ -132,8 +134,9 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end it 'should redirect to error page' do post('/auth/ldap/callback', {:username => 'ping', :password => 'password'}) - last_response.should be_redirect - last_response.headers['Location'].should =~ %r{invalid_credentials} + expect(last_response).to be_redirect + expect(last_response.headers['Location']).to match('invalid_credentials') + expect(last_request.env['omniauth.error'].message).to eq('Invalid credentials for ping') end context 'and filter is set' do it 'should bind with filter' do @@ -141,8 +144,9 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end Net::LDAP::Filter.should_receive(:construct).with('uid=ping') post('/auth/ldap/callback', {:username => 'ping', :password => 'password'}) - last_response.should be_redirect - last_response.headers['Location'].should =~ %r{invalid_credentials} + expect(last_response).to be_redirect + expect(last_response.headers['Location']).to match('invalid_credentials') + expect(last_request.env['omniauth.error'].message).to eq('Invalid credentials for ping') end end From d518e9d38fd3e2fdf3fc65650cf0c68532d94d5c Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 21 Aug 2017 08:33:10 +0000 Subject: [PATCH 37/62] Update gem homepage --- gitlab_omniauth-ldap.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index 57bf7b2..eef2dac 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |gem| gem.email = ["ping@intridea.com"] gem.description = %q{A LDAP strategy for OmniAuth.} gem.summary = %q{A LDAP strategy for OmniAuth.} - gem.homepage = "https://github.com/gitlabhq/omniauth-ldap" + gem.homepage = "https://gitlab.com/gitlab-org/omniauth-ldap" gem.license = "MIT" gem.add_runtime_dependency 'omniauth', '~> 1.3' From 78c05092d2cff41351117829052fa2c1684eb475 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Tue, 29 May 2018 13:48:18 -0500 Subject: [PATCH 38/62] Allow raw tls_options to be passed as a configuration We've previously exposed ca_file and ssl_version but there are many possible options that can be used inside tls_options. Instead of exposing individual ones, simply expose the entire hash so it can be passed in and we won't have to add things in the future. --- CHANGELOG | 3 ++ README.md | 8 ++++ lib/omniauth-ldap/adaptor.rb | 60 ++++++++++++++++++++++-------- spec/omniauth-ldap/adaptor_spec.rb | 14 +++++++ 4 files changed, 70 insertions(+), 15 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5d7ed6a..2437f25 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +## Next release + - Expose `:tls_options` SSL configuration option. Deprecate :ca_file, :ssl_version + ## 2.0.4 - Improve log message when invalid credentials are used diff --git a/README.md b/README.md index 0f5e876..70c73b1 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,10 @@ Use the LDAP strategy as a middleware in your application: :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')} :bind_dn => 'default_bind_dn' :password => 'password' + :tls_options => { + :ssl_version => 'TLSv1_2', + :ciphers => ["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", "AES-128-CBC-HMAC-SHA256"] + } All of the listed options are required, with the exception of :title, :name_proc, :bind_dn, and :password. @@ -48,6 +52,10 @@ All of the listed options are required, with the exception of :title, :name_proc Use them to initialize a SASL connection to server. If you are not familiar with these authentication methods, please just avoid them. +- `:tls_options` allows you to pass in OpenSSL options like `:ssl_version`, + `:ciphers` and more. See http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html + for all available options and values. + Direct users to '/auth/ldap' to have them authenticated via your company's LDAP server. diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index 03ed887..c922a07 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -15,10 +15,12 @@ class ConnectionError < StandardError; end VALID_ADAPTER_CONFIGURATION_KEYS = [ :hosts, :host, :port, :encryption, :disable_verify_certificates, :bind_dn, :password, :try_sasl, - :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter, :ca_file, :ssl_version, + :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter, :tls_options, # Deprecated - :method + :method, + :ca_file, + :ssl_version ] # A list of needed keys. Possible alternatives are specified using sub-lists. @@ -134,19 +136,21 @@ def translate_method def tls_options(translated_method) return {} if translated_method == nil # (plain) - tls_options = if @disable_verify_certificates - # It is important to explicitly set verify_mode for two reasons: - # 1. The behavior of OpenSSL is undefined when verify_mode is not set. - # 2. The net-ldap gem implementation verifies the certificate hostname - # unless verify_mode is set to VERIFY_NONE. - { verify_mode: OpenSSL::SSL::VERIFY_NONE } - else - OpenSSL::SSL::SSLContext::DEFAULT_PARAMS - end - - tls_options[:ca_file] = @ca_file if @ca_file - tls_options[:ssl_version] = @ssl_version if @ssl_version - tls_options + options = default_options + + if @tls_options + # Prevent blank config values from overwriting SSL defaults + configured_options = sanitize_hash_values(@tls_options) + configured_options = symbolize_hash_keys(configured_options) + + options.merge!(configured_options) + end + + # Retain backward compatibility until deprecated configs are removed. + options[:ca_file] = @ca_file if @ca_file + options[:ssl_version] = @ssl_version if @ssl_version + + options end def sasl_auths(options={}) @@ -194,6 +198,32 @@ def sasl_bind_setup_gss_spnego(options) [Net::NTLM::Message::Type1.new.serialize, nego] end + private + + def default_options + if @disable_verify_certificates + # It is important to explicitly set verify_mode for two reasons: + # 1. The behavior of OpenSSL is undefined when verify_mode is not set. + # 2. The net-ldap gem implementation verifies the certificate hostname + # unless verify_mode is set to VERIFY_NONE. + { verify_mode: OpenSSL::SSL::VERIFY_NONE } + else + OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.dup + end + end + + # Removes keys that have blank values + def sanitize_hash_values(hash) + hash.delete_if { |_, value| value.nil? || value !~ /\S/ } + end + + def symbolize_hash_keys(hash) + hash.keys.each do |key| + hash[key.to_sym] = hash[key] + end + + hash + end end end end diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index b2397f9..306ac0f 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -126,6 +126,19 @@ end end + context 'when tls_options are specified' do + it 'should pass the values along with defaults' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', tls_options: { ca_file: '/etc/ca.pem', ssl_version: 'TLSv1_2' }}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ca_file: '/etc/ca.pem', ssl_version: 'TLSv1_2') + end + + it 'does not pass nil or blank values' do + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', tls_options: { ca_file: nil, ssl_version: ' ' }}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + end + end + + # DEPRECATED context 'when ca_file is specified' do it 'should set the encryption tls_options ca_file' do adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', ca_file: '/etc/ca.pem'}) @@ -133,6 +146,7 @@ end end + # DEPRECATED context 'when ssl_version is specified' do it 'should overwrite the encryption tls_options ssl_version' do adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', ssl_version: 'TLSv1_2'}) From 66bd2e634b9743517abca57ec5fe50910599cf55 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Mon, 18 Jun 2018 11:29:46 -0500 Subject: [PATCH 39/62] Release 2.1.0 --- CHANGELOG | 2 +- lib/omniauth-ldap/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 2437f25..d401bbe 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -## Next release +## 2.1.0 - Expose `:tls_options` SSL configuration option. Deprecate :ca_file, :ssl_version ## 2.0.4 diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 9af06d5..1594142 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "2.0.4" + VERSION = "2.1.0" end end From d0b1e4f13b33f2b18f5c1a617e0b2d940ad9b3e6 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Thu, 21 Feb 2019 09:48:36 -0600 Subject: [PATCH 40/62] Add a String check to tls_options sanitization to allow other objects Only a String should be checked against the regex `/\S/`. Other objects like OpenSSL::X509::Certificate are valid but don't pass that regex. --- lib/omniauth-ldap/adaptor.rb | 8 +++++++- spec/omniauth-ldap/adaptor_spec.rb | 7 +++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index c922a07..ca3fe17 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -213,8 +213,14 @@ def default_options end # Removes keys that have blank values + # + # This gem may not always be in the context of Rails so we + # do this rather than `.blank?`. def sanitize_hash_values(hash) - hash.delete_if { |_, value| value.nil? || value !~ /\S/ } + hash.delete_if do |_, value| + value.nil? || + (value.is_a?(String) && value !~ /\S/) + end end def symbolize_hash_keys(hash) diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index 306ac0f..5dd38f5 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -128,8 +128,11 @@ context 'when tls_options are specified' do it 'should pass the values along with defaults' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', tls_options: { ca_file: '/etc/ca.pem', ssl_version: 'TLSv1_2' }}) - adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ca_file: '/etc/ca.pem', ssl_version: 'TLSv1_2') + cert = OpenSSL::X509::Certificate.new + key = OpenSSL::PKey::RSA.new + + adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', tls_options: { ca_file: '/etc/ca.pem', ssl_version: 'TLSv1_2', cert: cert, key: key }}) + adaptor.connection.instance_variable_get('@encryption').should include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ca_file: '/etc/ca.pem', ssl_version: 'TLSv1_2', cert: cert, key: key) end it 'does not pass nil or blank values' do From d32bd81b162f4a9bc9e42380f299832f71560d7c Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Fri, 22 Feb 2019 12:52:15 -0600 Subject: [PATCH 41/62] Release 2.1.1 --- CHANGELOG | 3 +++ lib/omniauth-ldap/version.rb | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index d401bbe..405ce01 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +## 2.1.1 + - Add a String check to `tls_options` sanitization to allow other objects + ## 2.1.0 - Expose `:tls_options` SSL configuration option. Deprecate :ca_file, :ssl_version diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 1594142..2a8916d 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "2.1.0" + VERSION = "2.1.1" end end From 52f19000c58be4d3298e5d61778fba83efce5060 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 18 Jun 2022 23:15:23 -0700 Subject: [PATCH 42/62] Loosen dependency of Omniauth to allow v2 By default, OmniAuth v2 only allows POST requests and adds CSRF protection by default. The tests were failing because the POST requests were not generating CSRF tokens. --- gitlab_omniauth-ldap.gemspec | 2 +- spec/omniauth/strategies/ldap_spec.rb | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index eef2dac..0e86d22 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |gem| gem.homepage = "https://gitlab.com/gitlab-org/omniauth-ldap" gem.license = "MIT" - gem.add_runtime_dependency 'omniauth', '~> 1.3' + gem.add_runtime_dependency 'omniauth', '>= 1.3', '< 3' gem.add_runtime_dependency 'net-ldap', '~> 0.16' gem.add_runtime_dependency 'pyu-ruby-sasl', '>= 0.0.3.3', '< 0.1' gem.add_runtime_dependency 'rubyntlm', '~> 0.5' diff --git a/spec/omniauth/strategies/ldap_spec.rb b/spec/omniauth/strategies/ldap_spec.rb index 203af57..b10f419 100644 --- a/spec/omniauth/strategies/ldap_spec.rb +++ b/spec/omniauth/strategies/ldap_spec.rb @@ -30,7 +30,20 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end end describe '/auth/ldap' do - before(:each){ get '/auth/ldap' } + let!(:csrf_token) { SecureRandom.base64(32) } + let(:post_env) { make_env('/auth/ldap', 'rack.session' => { csrf: csrf_token }, 'rack.input' => StringIO.new("authenticity_token=#{escaped_token}")) } + let(:escaped_token) { URI.encode_www_form_component(csrf_token, Encoding::UTF_8) } + + before(:each) { post '/auth/ldap', nil, post_env } + + def make_env(path = '/auth/ldap', props = {}) + { + 'REQUEST_METHOD' => 'POST', + 'PATH_INFO' => path, + 'rack.session' => {}, + 'rack.input' => StringIO.new('test=true') + }.merge(props) + end it 'should display a form' do last_response.status.should == 200 From ec27937c2cdb209eedc5ef4f82cd6f3adeca4c3c Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 18 Jun 2022 23:17:02 -0700 Subject: [PATCH 43/62] Update .gitlab-ci.yml to test Ruby 2.7 and 3.0 --- .gitlab-ci.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 37a97d7..33288a0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,12 +1,17 @@ -image: "ruby:2.3.1" - -before_script: - - bundle install +default: + image: "ruby:${RUBY_VERSION}" stages: - test -rspec: - stage: test +.test-template: &test + before_script: + - bundle install script: - bundle exec rake spec + +rspec: + parallel: + matrix: + - RUBY_VERSION: [ "2.7", "3.0" ] + <<: *test From 7831fc4aca94817be2c226ffcbcf3063c2366f40 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Fri, 24 Jun 2022 10:38:39 -0500 Subject: [PATCH 44/62] Release v2.2.0 --- lib/omniauth-ldap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 2a8916d..0b8747b 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "2.1.1" + VERSION = "2.2.0" end end From 64c59f64cd8a7405f00da10058bc267c32b54a16 Mon Sep 17 00:00:00 2001 From: Thong Kuah Date: Tue, 8 Nov 2022 22:38:13 +0000 Subject: [PATCH 45/62] Test with Ruby 3.1 as well We will eventually need to upgrade to Ruby 3.1. --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 33288a0..9d95f3c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,5 +13,5 @@ stages: rspec: parallel: matrix: - - RUBY_VERSION: [ "2.7", "3.0" ] + - RUBY_VERSION: [ "2.7", "3.0", "3.1" ] <<: *test From bc5f505f159426730c48a4278de846ee9cdaa448 Mon Sep 17 00:00:00 2001 From: Aboobacker MK Date: Mon, 22 Jan 2024 16:50:06 +0000 Subject: [PATCH 46/62] Add ruby 3.2 and 3.3 to the CI --- .gitlab-ci.yml | 2 +- .travis.yml | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 .travis.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9d95f3c..939d5aa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,5 +13,5 @@ stages: rspec: parallel: matrix: - - RUBY_VERSION: [ "2.7", "3.0", "3.1" ] + - RUBY_VERSION: [ "2.7", "3.0", "3.1", "3.2", "3.3"] <<: *test diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 91f7083..0000000 --- a/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -branches: - only: - - 'master' -rvm: - - 2.0.0 - - 2.1.5 -script: "bundle exec rspec spec" From 4dcee9752edc082f44af8300b479f1a8e1a35a2e Mon Sep 17 00:00:00 2001 From: Hakeem Abdul-Razak Date: Wed, 14 May 2025 13:06:17 -0400 Subject: [PATCH 47/62] Add ruby 3.4 to the CI --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 939d5aa..7c1f59e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,5 +13,5 @@ stages: rspec: parallel: matrix: - - RUBY_VERSION: [ "2.7", "3.0", "3.1", "3.2", "3.3"] + - RUBY_VERSION: [ "2.7", "3.0", "3.1", "3.2", "3.3", "3.4"] <<: *test From 86ec71df39652c6b5fe02b0edd0092db2dbcb16f Mon Sep 17 00:00:00 2001 From: Hakeem Abdul-Razak Date: Wed, 14 May 2025 13:51:00 -0400 Subject: [PATCH 48/62] Replace deprecated rack method --- lib/omniauth/strategies/ldap.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index d8a1fe0..124de36 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -46,10 +46,10 @@ def callback_phase return fail!(:invalid_request_method) unless valid_request_method? return fail!(:missing_credentials) if missing_credentials? begin - @ldap_user_info = @adaptor.bind_as(:filter => filter(@adaptor), :size => 1, :password => request['password']) + @ldap_user_info = @adaptor.bind_as(:filter => filter(@adaptor), :size => 1, :password => request.params['password']) unless @ldap_user_info - return fail!(:invalid_credentials, InvalidCredentialsError.new("Invalid credentials for #{request['username']}")) + return fail!(:invalid_credentials, InvalidCredentialsError.new("Invalid credentials for #{request.params['username']}")) end @user_info = self.class.map_user(@@config, @ldap_user_info) @@ -61,10 +61,10 @@ def callback_phase def filter(adaptor) if adaptor.filter and !adaptor.filter.empty? - username = Net::LDAP::Filter.escape(@options[:name_proc].call(request['username'])) + username = Net::LDAP::Filter.escape(@options[:name_proc].call(request.params['username'])) Net::LDAP::Filter.construct(adaptor.filter % { username: username }) else - Net::LDAP::Filter.equals(adaptor.uid, @options[:name_proc].call(request['username'])) + Net::LDAP::Filter.equals(adaptor.uid, @options[:name_proc].call(request.params['username'])) end end @@ -107,7 +107,7 @@ def valid_request_method? end def missing_credentials? - request['username'].nil? or request['username'].empty? or request['password'].nil? or request['password'].empty? + request.params['username'].nil? or request.params['username'].empty? or request.params['password'].nil? or request.params['password'].empty? end # missing_credentials? end end From 5f006f2bfd1ab097c39381726a7334aa1fb9e00f Mon Sep 17 00:00:00 2001 From: Hakeem Abdul-Razak Date: Sat, 17 May 2025 01:26:38 -0400 Subject: [PATCH 49/62] Remove kconv library --- lib/omniauth-ldap/adaptor.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index ca3fe17..82cb2e8 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -4,7 +4,6 @@ require 'net/ldap' require 'net/ntlm' require 'sasl' -require 'kconv' module OmniAuth module LDAP class Adaptor From bf6f94e29e5e8b906e60d69b268ee5a6f8fdd4fc Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Wed, 20 Aug 2025 08:59:37 -0500 Subject: [PATCH 50/62] Add gem release component to CI --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7c1f59e..c98594f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,3 +15,6 @@ rspec: matrix: - RUBY_VERSION: [ "2.7", "3.0", "3.1", "3.2", "3.3", "3.4"] <<: *test + +include: + - component: $CI_SERVER_FQDN/gitlab-org/components/gem-release/gem-release@~latest \ No newline at end of file From a9f60cf3d95f3dc93cab0d524b17a27d0026e686 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Wed, 20 Aug 2025 09:00:42 -0500 Subject: [PATCH 51/62] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c98594f..7c1f59e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,6 +15,3 @@ rspec: matrix: - RUBY_VERSION: [ "2.7", "3.0", "3.1", "3.2", "3.3", "3.4"] <<: *test - -include: - - component: $CI_SERVER_FQDN/gitlab-org/components/gem-release/gem-release@~latest \ No newline at end of file From cc681e06aea5ac4ada995aa4701084bb6e5bad31 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Wed, 20 Aug 2025 09:03:00 -0500 Subject: [PATCH 52/62] Include gem release component --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7c1f59e..753828c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,3 +15,6 @@ rspec: matrix: - RUBY_VERSION: [ "2.7", "3.0", "3.1", "3.2", "3.3", "3.4"] <<: *test + +include: + - component: gitlab.com/gitlab-org/components/gem-release/gem-release@main From 4f0ae8a0f2523f031ae405ae157ec4e21a2f9f25 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Wed, 20 Aug 2025 09:47:33 -0500 Subject: [PATCH 53/62] Include gem release component --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 753828c..d9b3836 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,7 @@ default: stages: - test + - deploy .test-template: &test before_script: From 93206df44d35c35811f1070113d9ca708f3acae9 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Wed, 20 Aug 2025 09:51:27 -0500 Subject: [PATCH 54/62] Edit .gitlab-ci.yml --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d9b3836..dc4d2f9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,3 +19,5 @@ rspec: include: - component: gitlab.com/gitlab-org/components/gem-release/gem-release@main + inputs: + - gem_name: gitlab_omniauth-ldap \ No newline at end of file From ff2d70b9a8a0101fd504be43067c731e6f0aea63 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Wed, 20 Aug 2025 10:01:47 -0500 Subject: [PATCH 55/62] Release 2.3.0 --- lib/omniauth-ldap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth-ldap/version.rb b/lib/omniauth-ldap/version.rb index 0b8747b..59f87ad 100644 --- a/lib/omniauth-ldap/version.rb +++ b/lib/omniauth-ldap/version.rb @@ -1,5 +1,5 @@ module OmniAuth module LDAP - VERSION = "2.2.0" + VERSION = "2.3.0" end end From 24968b16b0f179aba92cb1241f0696070136a849 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Wed, 20 Aug 2025 10:02:31 -0500 Subject: [PATCH 56/62] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dc4d2f9..caee18c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,4 +20,4 @@ rspec: include: - component: gitlab.com/gitlab-org/components/gem-release/gem-release@main inputs: - - gem_name: gitlab_omniauth-ldap \ No newline at end of file + gem_name: gitlab_omniauth-ldap \ No newline at end of file From 37ae001d648f7969399069cfd8fd20c2abe3a396 Mon Sep 17 00:00:00 2001 From: "Peter H. Boling" Date: Tue, 4 Nov 2025 22:04:52 -0700 Subject: [PATCH 57/62] =?UTF-8?q?=E2=9E=96=20nkf=20not=20needed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .rubocop_gradual.lock | 53 ++++---- Gemfile.lock | 2 - README.md | 18 +-- gemfiles/modular/optional.gemfile | 6 - gitlab_omniauth-ldap.gemspec | 5 - lib/omniauth-ldap/adaptor.rb | 45 ++++--- lib/omniauth/strategies/ldap.rb | 8 +- spec/omniauth-ldap/adaptor_spec.rb | 166 +++++++++++++------------- spec/omniauth/adaptor_spec.rb | 6 +- spec/omniauth/strategies/ldap_spec.rb | 70 +++++------ 10 files changed, 182 insertions(+), 197 deletions(-) diff --git a/.rubocop_gradual.lock b/.rubocop_gradual.lock index 489de8c..0430551 100644 --- a/.rubocop_gradual.lock +++ b/.rubocop_gradual.lock @@ -1,9 +1,9 @@ { - "lib/omniauth-ldap/adaptor.rb:2352927785": [ - [36, 7, 413, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 105664470], - [86, 17, 3, "Style/AndOr: Use `&&` instead of `and`.", 193409806], - [86, 30, 3, "Style/AndOr: Use `&&` instead of `and`.", 193409806], - [86, 37, 1, "Lint/AssignmentInCondition: Wrap assignment in parentheses if intentional", 177560] + "lib/omniauth-ldap/adaptor.rb:3906050285": [ + [64, 7, 413, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 105664470], + [114, 17, 3, "Style/AndOr: Use `&&` instead of `and`.", 193409806], + [114, 30, 3, "Style/AndOr: Use `&&` instead of `and`.", 193409806], + [114, 37, 1, "Lint/AssignmentInCondition: Wrap assignment in parentheses if intentional", 177560] ], "spec/integration/middleware_spec.rb:4062046892": [ [3, 16, 39, "RSpec/DescribeClass: The first argument to describe should be the class or module being tested.", 638096201], @@ -15,29 +15,30 @@ [4, 3, 12, "RSpec/BeforeAfterAll: Beware of using `before(:all)` as it may cause state to leak between tests. If you are using `rspec-rails`, and `use_transactional_fixtures` is enabled, then records created in `before(:all)` are not automatically rolled back.", 86334566], [70, 16, 5, "RSpec/ExpectActual: Provide the actual value you are testing to `expect(...)`.", 237881235] ], - "spec/omniauth-ldap/adaptor_spec.rb:3624298807": [ - [72, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310], - [73, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310], - [74, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310], - [80, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310], - [81, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310], - [82, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310] + "spec/omniauth-ldap/adaptor_spec.rb:2715031579": [ + [3, 1, 38, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/ldap/adaptor*_spec.rb`.", 1973618936], + [206, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310], + [207, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310], + [208, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310], + [214, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310], + [215, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310], + [216, 7, 26, "RSpec/StubbedMock: Prefer `allow` over `expect` when configuring a response.", 1924417310] ], - "spec/omniauth/adaptor_spec.rb:3492754784": [ + "spec/omniauth/adaptor_spec.rb:1168013709": [ [3, 1, 38, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/ldap/adaptor*_spec.rb`.", 1973618936], - [42, 7, 38, "RSpec/AnyInstance: Avoid stubbing using `allow_any_instance_of`.", 3627954156], - [43, 7, 38, "RSpec/AnyInstance: Avoid stubbing using `allow_any_instance_of`.", 3627954156], - [80, 7, 48, "RSpec/AnyInstance: Avoid stubbing using `allow_any_instance_of`.", 2759780562] + [46, 7, 38, "RSpec/AnyInstance: Avoid stubbing using `allow_any_instance_of`.", 3627954156], + [47, 7, 38, "RSpec/AnyInstance: Avoid stubbing using `allow_any_instance_of`.", 3627954156], + [84, 7, 48, "RSpec/AnyInstance: Avoid stubbing using `allow_any_instance_of`.", 2759780562] ], - "spec/omniauth/strategies/ldap_spec.rb:3760791626": [ - [13, 3, 54, "RSpec/LeakyConstantDeclaration: Stub class constant instead of declaring explicitly.", 2419068710], - [76, 13, 9, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 1130140517], - [101, 17, 28, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 3444838747], - [110, 17, 23, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 1584148894], - [121, 17, 32, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 1515076977], - [129, 19, 19, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 2526348694], - [141, 17, 56, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 2413495789], - [156, 13, 9, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 3182939526], - [189, 15, 19, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 2526348694] + "spec/omniauth/strategies/ldap_spec.rb:86189447": [ + [14, 3, 54, "RSpec/LeakyConstantDeclaration: Stub class constant instead of declaring explicitly.", 2419068710], + [90, 13, 9, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 1130140517], + [145, 17, 28, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 3444838747], + [154, 17, 23, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 1584148894], + [165, 17, 32, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 1515076977], + [174, 19, 19, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 2526348694], + [187, 17, 56, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 2413495789], + [202, 13, 9, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 3182939526], + [235, 15, 19, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 2526348694] ] } diff --git a/Gemfile.lock b/Gemfile.lock index a453cad..56ee66d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -157,7 +157,6 @@ GEM net-ldap (0.20.0) base64 ostruct - nkf (0.2.0) nokogiri (1.18.10-x86_64-linux-gnu) racc (~> 1.4) notiffany (0.1.3) @@ -393,7 +392,6 @@ DEPENDENCIES kramdown-parser-gfm (~> 1.1) logger (~> 1.7) mutex_m (~> 0.2) - nkf omniauth-ldap! rack-test (~> 2.2) rake (~> 13.0) diff --git a/README.md b/README.md index b4d4114..4c8f9f6 100644 --- a/README.md +++ b/README.md @@ -64,8 +64,8 @@ use OmniAuth::Strategies::LDAP, bind_dn: "default_bind_dn", password: "password", tls_options: { - ssl_version: 'TLSv1_2', - ciphers: ["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", "AES-128-CBC-HMAC-SHA256"] + ssl_version: "TLSv1_2", + ciphers: ["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", "AES-128-CBC-HMAC-SHA256"], } # Or, alternatively: # use OmniAuth::Strategies::LDAP, filter: '(&(uid=%{username})(memberOf=cn=myapp-users,ou=groups,dc=example,dc=com))' @@ -97,20 +97,6 @@ Compatible with MRI Ruby 2.0+, and concordant releases of JRuby, and TruffleRuby |------------------------------------------------|--------------------------------------------------------| | 👟 Check it out! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ | -#### Ruby 3.4 - -nkf/kconv has been part of Ruby since long ago. -Eventually it became a standard gem, but was changed to a bundled gem in Ruby 3.4. -In general, kconv and iconv have been superseded since Ruby 1.9 by the built-in -encoding support provided by String#encode, String#force_encoding, and similar methods. -But this gem has not yet been updated to remove its dependency on nkf/kconv. - -As a result of all this you should add `nkf` to your Gemfile if you are using Ruby 3.4 or later. - -```ruby -gem "nkf", "~> 0.1" -``` - ### Enterprise Support [![Tidelift](https://tidelift.com/badges/package/rubygems/omniauth-ldap)](https://tidelift.com/subscription/pkg/rubygems-omniauth-ldap?utm_source=rubygems-omniauth-ldap&utm_medium=referral&utm_campaign=readme) Available as part of the Tidelift Subscription. diff --git a/gemfiles/modular/optional.gemfile b/gemfiles/modular/optional.gemfile index b0232fe..8526e8f 100644 --- a/gemfiles/modular/optional.gemfile +++ b/gemfiles/modular/optional.gemfile @@ -3,9 +3,3 @@ # Required for kettle-pre-release # URL parsing with Unicode support (falls back to URI if not available) gem "addressable", ">= 2.8", "< 3" # ruby >= 2.2 - -# nkf/kconv has been part of Ruby since long ago. -# Eventually it became a standard gem, but was changed to a bundled gem in Ruby 3.4. -# In general, kconv and iconv have been superseded since Ruby 1.9 by the built-in -# encoding support provided by String#encode, String#force_encoding, and similar methods. -gem "nkf" # ruby >= 2.3 diff --git a/gitlab_omniauth-ldap.gemspec b/gitlab_omniauth-ldap.gemspec index 6423e7e..aff328f 100644 --- a/gitlab_omniauth-ldap.gemspec +++ b/gitlab_omniauth-ldap.gemspec @@ -98,11 +98,6 @@ Gem::Specification.new do |spec| spec.executables = [] spec.add_dependency("net-ldap", "~> 0.16", "< 1") # ruby >= 2.0 - # nkf/kconv has been part of Ruby since long ago. - # Eventually it became a standard gem, but was changed to a bundled gem in Ruby 3.4. - # In general, kconv and iconv have been superseded since Ruby 1.9 by the built-in - # encoding support provided by String#encode, String#force_encoding, and similar methods. - # spec.add_dependency("nkf") # ruby >= 2.3 spec.add_dependency("omniauth", ">= 1", "< 3") # ruby >= 0.0 spec.add_dependency("pyu-ruby-sasl", ">= 0.0.3.3", "< 0.1") # ruby >= 0.0 spec.add_dependency("rack", ">= 1", "< 4") # ruby >= 0.0 diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index 59d334e..ad22bcf 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -1,10 +1,6 @@ -# this code borrowed pieces from activeldap and net-ldap +# frozen_string_literal: true -# nkf/kconv has been part of Ruby since long ago. -# Eventually it became a standard gem, but was changed to a bundled gem in Ruby 3.4. -# In general, kconv and iconv have been superseded since Ruby 1.9 by the built-in -# encoding support provided by String#encode, String#force_encoding, and similar methods. -require "nkf" +# this code borrowed pieces from activeldap and net-ldap # External Gems require "net/ldap" @@ -21,8 +17,20 @@ class AuthenticationError < StandardError; end class ConnectionError < StandardError; end VALID_ADAPTER_CONFIGURATION_KEYS = [ - :hosts, :host, :port, :encryption, :disable_verify_certificates, :bind_dn, :password, :try_sasl, - :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter, :tls_options, + :hosts, + :host, + :port, + :encryption, + :disable_verify_certificates, + :bind_dn, + :password, + :try_sasl, + :sasl_mechanisms, + :uid, + :base, + :allow_anonymous, + :filter, + :tls_options, # Deprecated :method, @@ -78,9 +86,13 @@ def initialize(configuration = {}) hosts: @hosts, host: @host, port: @port, - encryption: encryption_options + encryption: encryption_options, } - @bind_method = @try_sasl ? :sasl : (@allow_anonymous||!@bind_dn||!@password ? :anonymous : :simple) + @bind_method = if @try_sasl + :sasl + else + ((@allow_anonymous || !@bind_dn || !@password) ? :anonymous : :simple) + end @auth = sasl_auths({username: @bind_dn, password: @password}).first if @bind_method == :sasl @auth ||= { @@ -121,11 +133,11 @@ def bind_as(args = {}) def encryption_options translated_method = translate_method - return nil unless translated_method + return unless translated_method { method: translated_method, - tls_options: tls_options(translated_method) + tls_options: tls_options(translated_method), } end @@ -135,7 +147,7 @@ def translate_method normalized_method = method.to_s.downcase.to_sym unless ENCRYPTION_METHOD.has_key?(normalized_method) - available_methods = ENCRYPTION_METHOD.keys.collect {|m| m.inspect}.join(", ") + available_methods = ENCRYPTION_METHOD.keys.collect { |m| m.inspect }.join(", ") format = "%s is not one of the available connect methods: %s" raise ConfigurationError, format % [method.inspect, available_methods] end @@ -143,9 +155,8 @@ def translate_method ENCRYPTION_METHOD[normalized_method] end - def tls_options(translated_method) - return {} if translated_method == nil # (plain) + return {} if translated_method.nil? # (plain) options = default_options @@ -217,7 +228,7 @@ def default_options # 1. The behavior of OpenSSL is undefined when verify_mode is not set. # 2. The net-ldap gem implementation verifies the certificate hostname # unless verify_mode is set to VERIFY_NONE. - { verify_mode: OpenSSL::SSL::VERIFY_NONE } + {verify_mode: OpenSSL::SSL::VERIFY_NONE} else OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.dup end @@ -230,7 +241,7 @@ def default_options def sanitize_hash_values(hash) hash.delete_if do |_, value| value.nil? || - (value.is_a?(String) && value !~ /\S/) + (value.is_a?(String) && value !~ /\S/) end end diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index 6d70629..ddadbd6 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -71,7 +71,7 @@ def callback_phase @ldap_user_info = @adaptor.bind_as(filter: filter(@adaptor), size: 1, password: request.params["password"]) unless @ldap_user_info - return fail!(:invalid_credentials, InvalidCredentialsError.new("Invalid credentials for #{request.params['username']}")) + return fail!(:invalid_credentials, InvalidCredentialsError.new("Invalid credentials for #{request.params["username"]}")) end @user_info = self.class.map_user(CONFIG, @ldap_user_info) @@ -83,8 +83,8 @@ def callback_phase def filter(adaptor) if adaptor.filter && !adaptor.filter.empty? - username = Net::LDAP::Filter.escape(@options[:name_proc].call(request.params['username'])) - Net::LDAP::Filter.construct(adaptor.filter % { username: username }) + username = Net::LDAP::Filter.escape(@options[:name_proc].call(request.params["username"])) + Net::LDAP::Filter.construct(adaptor.filter % {username: username}) else Net::LDAP::Filter.equals(adaptor.uid, @options[:name_proc].call(request.params["username"])) end @@ -140,7 +140,7 @@ def map_user(mapper, object) protected def valid_request_method? - request.env['REQUEST_METHOD'] == 'POST' + request.env["REQUEST_METHOD"] == "POST" end def missing_credentials? diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index 1adf0fd..57feb7d 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -5,29 +5,29 @@ it "throws exception when must have field is not set" do #[:host, :port, :method, :bind_dn] expect { - OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: "plain"}) + described_class.new({host: "192.168.1.145", method: "plain"}) }.to raise_error(ArgumentError) end it "throws exception when method is not supported" do expect { - OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: "myplain", uid: "uid", port: 389, base: "dc=com"}) - }.to raise_error(OmniAuth::LDAP::Adaptor::ConfigurationError) + described_class.new({host: "192.168.1.145", method: "myplain", uid: "uid", port: 389, base: "dc=com"}) + }.to raise_error(described_class::ConfigurationError) end - it 'should not throw an error if hosts is set but host and port are not' do + it "does not throw an error if hosts is set but host and port are not" do expect { described_class.new( - hosts: [['192.168.1.145', 389], ['192.168.1.146', 389]], - encryption: 'plain', - base: 'dc=example,dc=com', - uid: 'uid' + hosts: [["192.168.1.145", 389], ["192.168.1.146", 389]], + encryption: "plain", + base: "dc=example,dc=com", + uid: "uid", ) }.not_to raise_error end it "sets up ldap connection with anonymous" do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + adaptor = described_class.new({host: "192.168.1.145", method: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) expect(adaptor.connection).not_to be_nil expect(adaptor.connection.host).to eq "192.168.1.145" expect(adaptor.connection.port).to eq 389 @@ -36,7 +36,7 @@ end it "sets up ldap connection with simple" do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName", bind_dn: "bind_dn", password: "password"}) + adaptor = described_class.new({host: "192.168.1.145", method: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName", bind_dn: "bind_dn", password: "password"}) expect(adaptor.connection).not_to be_nil expect(adaptor.connection.host).to eq "192.168.1.145" expect(adaptor.connection.port).to eq 389 @@ -45,7 +45,7 @@ end it "sets up ldap connection with sasl-md5" do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName", try_sasl: true, sasl_mechanisms: ["DIGEST-MD5"], bind_dn: "bind_dn", password: "password"}) + adaptor = described_class.new({host: "192.168.1.145", method: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName", try_sasl: true, sasl_mechanisms: ["DIGEST-MD5"], bind_dn: "bind_dn", password: "password"}) expect(adaptor.connection).not_to be_nil expect(adaptor.connection.host).to eq "192.168.1.145" expect(adaptor.connection.port).to eq 389 @@ -57,7 +57,7 @@ end it "setups ldap connection with sasl-gss" do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName", try_sasl: true, sasl_mechanisms: ["GSS-SPNEGO"], bind_dn: "bind_dn", password: "password"}) + adaptor = described_class.new({host: "192.168.1.145", method: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName", try_sasl: true, sasl_mechanisms: ["GSS-SPNEGO"], bind_dn: "bind_dn", password: "password"}) expect(adaptor.connection).not_to be_nil expect(adaptor.connection.host).to eq "192.168.1.145" expect(adaptor.connection.port).to eq 389 @@ -68,131 +68,131 @@ expect(adaptor.connection.instance_variable_get(:@auth)[:challenge_response]).not_to be_nil end - it 'sets up a connection with the proper host and port' do + it "sets up a connection with the proper host and port" do adapter = described_class.new( - host: '192.168.1.145', - encryption: 'plain', - base: 'dc=example,dc=com', + host: "192.168.1.145", + encryption: "plain", + base: "dc=example,dc=com", port: 3890, - uid: 'uid' + uid: "uid", ) - expect(adapter.connection.host).to eq('192.168.1.145') + expect(adapter.connection.host).to eq("192.168.1.145") expect(adapter.connection.port).to eq(3890) expect(adapter.connection.hosts).to be_nil end - it 'sets up a connection with a enumerable pairs of hosts' do + it "sets up a connection with a enumerable pairs of hosts" do adapter = described_class.new( - hosts: [['192.168.1.145', 636], ['192.168.1.146', 636]], - encryption: 'plain', - base: 'dc=example,dc=com', - uid: 'uid' + hosts: [["192.168.1.145", 636], ["192.168.1.146", 636]], + encryption: "plain", + base: "dc=example,dc=com", + uid: "uid", ) - expect(adapter.connection.host).to eq('127.0.0.1') + expect(adapter.connection.host).to eq("127.0.0.1") expect(adapter.connection.port).to eq(389) - expect(adapter.connection.hosts).to match_array([['192.168.1.145', 636], ['192.168.1.146', 636]]) + expect(adapter.connection.hosts).to contain_exactly(["192.168.1.145", 636], ["192.168.1.146", 636]) end - context 'when encryption is plain' do - it 'should set encryption to nil' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to eq(nil) + context "when encryption is plain" do + it "sets encryption to nil" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to be_nil end end - context 'when encryption is ssl' do - it 'should set the encryption method to simple_tls' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include method: :simple_tls + context "when encryption is ssl" do + it "sets the encryption method to simple_tls" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "ssl", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include method: :simple_tls end - context 'when disable_verify_certificates is not specified' do - it 'should set the encryption tls_options to OpenSSL default params' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + context "when disable_verify_certificates is not specified" do + it "sets the encryption tls_options to OpenSSL default params" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "ssl", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end end - context 'when disable_verify_certificates is true' do - it 'should set the encryption tls_options verify_mode explicitly to verify none' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', disable_verify_certificates: true, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE } + context "when disable_verify_certificates is true" do + it "sets the encryption tls_options verify_mode explicitly to verify none" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "ssl", disable_verify_certificates: true, base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include tls_options: {verify_mode: OpenSSL::SSL::VERIFY_NONE} end end - context 'when disable_verify_certificates is false' do - it 'should set the encryption tls_options to OpenSSL default params' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', disable_verify_certificates: false, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + context "when disable_verify_certificates is false" do + it "sets the encryption tls_options to OpenSSL default params" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "ssl", disable_verify_certificates: false, base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end end - context 'when tls_options are specified' do - it 'should pass the values along with defaults' do + context "when tls_options are specified" do + it "passes the values along with defaults" do cert = OpenSSL::X509::Certificate.new - key = OpenSSL::PKey::RSA.new + key = OpenSSL::PKey::RSA.new - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', tls_options: { ca_file: '/etc/ca.pem', ssl_version: 'TLSv1_2', cert: cert, key: key }}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ca_file: '/etc/ca.pem', ssl_version: 'TLSv1_2', cert: cert, key: key) + adaptor = described_class.new({host: "192.168.1.145", encryption: "ssl", base: "dc=intridea, dc=com", port: 636, uid: "sAMAccountName", bind_dn: "bind_dn", password: "password", tls_options: {ca_file: "/etc/ca.pem", ssl_version: "TLSv1_2", cert: cert, key: key}}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ca_file: "/etc/ca.pem", ssl_version: "TLSv1_2", cert: cert, key: key) end - it 'does not pass nil or blank values' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', tls_options: { ca_file: nil, ssl_version: ' ' }}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + it "does not pass nil or blank values" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "ssl", base: "dc=intridea, dc=com", port: 636, uid: "sAMAccountName", bind_dn: "bind_dn", password: "password", tls_options: {ca_file: nil, ssl_version: " "}}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end end # DEPRECATED - context 'when ca_file is specified' do - it 'should set the encryption tls_options ca_file' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', ca_file: '/etc/ca.pem'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ca_file: '/etc/ca.pem') + context "when ca_file is specified" do + it "sets the encryption tls_options ca_file" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "ssl", base: "dc=intridea, dc=com", port: 636, uid: "sAMAccountName", bind_dn: "bind_dn", password: "password", ca_file: "/etc/ca.pem"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ca_file: "/etc/ca.pem") end end # DEPRECATED - context 'when ssl_version is specified' do - it 'should overwrite the encryption tls_options ssl_version' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'ssl', base: 'dc=intridea, dc=com', port: 636, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password', ssl_version: 'TLSv1_2'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ssl_version: 'TLSv1_2') + context "when ssl_version is specified" do + it "overwrites the encryption tls_options ssl_version" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "ssl", base: "dc=intridea, dc=com", port: 636, uid: "sAMAccountName", bind_dn: "bind_dn", password: "password", ssl_version: "TLSv1_2"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(ssl_version: "TLSv1_2") end end end - context 'when encryption is tls' do - it 'should set the encryption method to start_tls' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include method: :start_tls + context "when encryption is tls" do + it "sets the encryption method to start_tls" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "tls", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include method: :start_tls end - context 'when disable_verify_certificates is not specified' do - it 'should set the encryption tls_options to OpenSSL default params' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + context "when disable_verify_certificates is not specified" do + it "sets the encryption tls_options to OpenSSL default params" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "tls", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end end - context 'when disable_verify_certificates is true' do - it 'should set the encryption tls_options verify_mode explicitly to verify none' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'tls', disable_verify_certificates: true, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE } + context "when disable_verify_certificates is true" do + it "sets the encryption tls_options verify_mode explicitly to verify none" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "tls", disable_verify_certificates: true, base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include tls_options: {verify_mode: OpenSSL::SSL::VERIFY_NONE} end end - context 'when disable_verify_certificates is false' do - it 'should set the encryption tls_options to OpenSSL default params' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: 'tls', disable_verify_certificates: false, base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS + context "when disable_verify_certificates is false" do + it "sets the encryption tls_options to OpenSSL default params" do + adaptor = described_class.new({host: "192.168.1.145", encryption: "tls", disable_verify_certificates: false, base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS end end end - context 'when method is set instead of encryption' do - it 'should set the encryption method for backwards-compatibility' do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName'}) - expect(adaptor.connection.instance_variable_get('@encryption')).to include method: :start_tls + context "when method is set instead of encryption" do + it "sets the encryption method for backwards-compatibility" do + adaptor = described_class.new({host: "192.168.1.145", method: "tls", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName"}) + expect(adaptor.connection.instance_variable_get(:@encryption)).to include method: :start_tls end end end @@ -202,7 +202,7 @@ let(:rs) { Struct.new(:dn).new("new dn") } it "binds simple" do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.126", encryption: "plain", base: "dc=score, dc=local", port: 389, uid: "sAMAccountName", bind_dn: "bind_dn", password: "password"}) + adaptor = described_class.new({host: "192.168.1.126", encryption: "plain", base: "dc=score, dc=local", port: 389, uid: "sAMAccountName", bind_dn: "bind_dn", password: "password"}) expect(adaptor.connection).to receive(:open).and_yield(adaptor.connection) expect(adaptor.connection).to receive(:search).with(args).and_return([rs]) expect(adaptor.connection).to receive(:bind).with({username: "new dn", password: args[:password], method: :simple}).and_return(true) @@ -210,7 +210,7 @@ end it "binds sasl" do - adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", encryption: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName", try_sasl: true, sasl_mechanisms: ["GSS-SPNEGO"], bind_dn: "bind_dn", password: "password"}) + adaptor = described_class.new({host: "192.168.1.145", encryption: "plain", base: "dc=intridea, dc=com", port: 389, uid: "sAMAccountName", try_sasl: true, sasl_mechanisms: ["GSS-SPNEGO"], bind_dn: "bind_dn", password: "password"}) expect(adaptor.connection).to receive(:open).and_yield(adaptor.connection) expect(adaptor.connection).to receive(:search).with(args).and_return([rs]) expect(adaptor.connection).to receive(:bind).and_return(true) diff --git a/spec/omniauth/adaptor_spec.rb b/spec/omniauth/adaptor_spec.rb index 4eb3686..c2b3b71 100644 --- a/spec/omniauth/adaptor_spec.rb +++ b/spec/omniauth/adaptor_spec.rb @@ -21,9 +21,9 @@ end it "maps ssl/tls to Net::LDAP encryption symbols" do - ssl_adaptor = described_class.new(valid_config.merge(method: 'ssl')) - tls_adaptor = described_class.new(valid_config.merge(method: 'tls')) - plain_adaptor = described_class.new(valid_config.merge(method: 'plain')) + ssl_adaptor = described_class.new(valid_config.merge(method: "ssl")) + tls_adaptor = described_class.new(valid_config.merge(method: "tls")) + plain_adaptor = described_class.new(valid_config.merge(method: "plain")) expect(ssl_adaptor.send(:translate_method)).to eq(OmniAuth::LDAP::Adaptor::ENCRYPTION_METHOD[:ssl]) expect(tls_adaptor.send(:translate_method)).to eq(OmniAuth::LDAP::Adaptor::ENCRYPTION_METHOD[:tls]) diff --git a/spec/omniauth/strategies/ldap_spec.rb b/spec/omniauth/strategies/ldap_spec.rb index 74e37d8..22e7ed4 100644 --- a/spec/omniauth/strategies/ldap_spec.rb +++ b/spec/omniauth/strategies/ldap_spec.rb @@ -45,19 +45,19 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end end end - describe '/auth/ldap' do + describe "/auth/ldap" do let!(:csrf_token) { SecureRandom.base64(32) } - let(:post_env) { make_env('/auth/ldap', 'rack.session' => { csrf: csrf_token }, 'rack.input' => StringIO.new("authenticity_token=#{escaped_token}")) } + let(:post_env) { make_env("/auth/ldap", "rack.session" => {csrf: csrf_token}, "rack.input" => StringIO.new("authenticity_token=#{escaped_token}")) } let(:escaped_token) { URI.encode_www_form_component(csrf_token, Encoding::UTF_8) } - before(:each) { post '/auth/ldap', nil, post_env } + before { post "/auth/ldap", nil, post_env } - def make_env(path = '/auth/ldap', props = {}) + def make_env(path = "/auth/ldap", props = {}) { - 'REQUEST_METHOD' => 'POST', - 'PATH_INFO' => path, - 'rack.session' => {}, - 'rack.input' => StringIO.new('test=true') + "REQUEST_METHOD" => "POST", + "PATH_INFO" => path, + "rack.session" => {}, + "rack.input" => StringIO.new("test=true"), }.merge(props) end @@ -92,33 +92,33 @@ def make_env(path = '/auth/ldap', props = {}) allow(@adaptor).to receive(:bind_as).and_return(false) end - it 'should fail with missing_credentials' do - post('/auth/ldap/callback', {}) + it "fails with missing_credentials" do + post("/auth/ldap/callback", {}) expect(last_response).to be_redirect - expect(last_response.headers['Location']).to match(%r{missing_credentials}) + expect(last_response.headers["Location"]).to match(%r{missing_credentials}) end - it 'should redirect to error page' do - post('/auth/ldap/callback', {:username => 'ping', :password => 'password'}) + it "redirects to error page" do + post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(last_response).to be_redirect - expect(last_response.headers['Location']).to match('invalid_credentials') - expect(last_request.env['omniauth.error'].message).to eq('Invalid credentials for ping') + expect(last_response.headers["Location"]).to match("invalid_credentials") + expect(last_request.env["omniauth.error"].message).to eq("Invalid credentials for ping") end - it 'should redirect to error page when there is exception' do - allow(@adaptor).to receive(:bind_as).and_raise(StandardError.new('connection_error')) - post('/auth/ldap/callback', {:username => 'ping', :password => 'password'}) + it "redirects to error page when there is exception" do + allow(@adaptor).to receive(:bind_as).and_raise(StandardError.new("connection_error")) + post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(last_response).to be_redirect - expect(last_response.headers['Location']).to match(%r{ldap_error}) + expect(last_response.headers["Location"]).to match(%r{ldap_error}) end - context 'wrong request method' do - it 'redirects to error page' do - get('/auth/ldap/callback', { username: 'ping', password: 'password' }) + context "when wrong request method" do + it "redirects to error page" do + get("/auth/ldap/callback", {username: "ping", password: "password"}) expect(last_response).to be_redirect - expect(last_response.headers['Location']).to match('invalid_request_method') + expect(last_response.headers["Location"]).to match("invalid_request_method") end end @@ -167,8 +167,8 @@ def make_env(path = '/auth/ldap', props = {}) post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(last_response).to be_redirect - expect(last_response.headers['Location']).to match('invalid_credentials') - expect(last_request.env['omniauth.error'].message).to eq('Invalid credentials for ping') + expect(last_response.headers["Location"]).to match("invalid_credentials") + expect(last_request.env["omniauth.error"].message).to eq("Invalid credentials for ping") end context "and filter is set" do @@ -178,8 +178,8 @@ def make_env(path = '/auth/ldap', props = {}) post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(last_response).to be_redirect - expect(last_response.headers['Location']).to match('invalid_credentials') - expect(last_request.env['omniauth.error'].message).to eq('Invalid credentials for ping') + expect(last_response.headers["Location"]).to match("invalid_credentials") + expect(last_request.env["omniauth.error"].message).to eq("Invalid credentials for ping") end end end @@ -242,7 +242,7 @@ def make_env(path = '/auth/ldap', props = {}) end end - it 'maps user info to Auth Hash' do + it "maps user info to Auth Hash" do post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(auth_hash.uid).to eq "cn=ping, dc=intridea, dc=com" @@ -262,13 +262,13 @@ def make_env(path = '/auth/ldap', props = {}) end end - context 'alternate fields' do - let(:auth_hash){ last_request.env['omniauth.auth'] } + context "when alternate fields" do + let(:auth_hash) { last_request.env["omniauth.auth"] } - before(:each) do + before do allow(@adaptor).to receive(:filter) allow(@adaptor).to receive(:bind_as).and_return(Net::LDAP::Entry.from_single_ldif_string( -%Q{dn: cn=ping, dc=intridea, dc=com + %{dn: cn=ping, dc=intridea, dc=com userprincipalname: ping@intridea.com givenname: Ping sn: Yu @@ -284,11 +284,11 @@ def make_env(path = '/auth/ldap', props = {}) wwwhomepage: www.intridea.com jpegphoto: http://www.intridea.com/ping.jpg description: omniauth-ldap -} - )) +}, + )) end - it 'maps user info to Auth Hash' do + it "maps user info to Auth Hash" do post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(auth_hash.uid).to eq "cn=ping, dc=intridea, dc=com" From a96d907d2f025c3e27e3b8ab75d425a382d2c456 Mon Sep 17 00:00:00 2001 From: "Peter H. Boling" Date: Tue, 4 Nov 2025 22:15:10 -0700 Subject: [PATCH 58/62] =?UTF-8?q?=E2=9C=85=20Update=20coverage=20minimums?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .envrc | 4 ++-- .github/workflows/coverage.yml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.envrc b/.envrc index d84c0f8..1164e64 100644 --- a/.envrc +++ b/.envrc @@ -21,8 +21,8 @@ export K_SOUP_COV_DO=true # Means you want code coverage export K_SOUP_COV_COMMAND_NAME="Test Coverage" # Available formats are html, xml, rcov, lcov, json, tty export K_SOUP_COV_FORMATTERS="html,xml,rcov,lcov,json,tty" -export K_SOUP_COV_MIN_BRANCH=70 # Means you want to enforce X% branch coverage -export K_SOUP_COV_MIN_LINE=93 # Means you want to enforce X% line coverage +export K_SOUP_COV_MIN_BRANCH=78 # Means you want to enforce X% branch coverage +export K_SOUP_COV_MIN_LINE=98 # Means you want to enforce X% line coverage export K_SOUP_COV_MIN_HARD=true # Means you want the build to fail if the coverage thresholds are not met export K_SOUP_COV_MULTI_FORMATTERS=true export K_SOUP_COV_OPEN_BIN= # Means don't try to open coverage results in browser diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 5a9b42e..1d7963a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -6,8 +6,8 @@ permissions: id-token: write env: - K_SOUP_COV_MIN_BRANCH: 70 - K_SOUP_COV_MIN_LINE: 93 + K_SOUP_COV_MIN_BRANCH: 78 + K_SOUP_COV_MIN_LINE: 98 K_SOUP_COV_MIN_HARD: true K_SOUP_COV_FORMATTERS: "xml,rcov,lcov,tty" K_SOUP_COV_DO: true @@ -115,7 +115,7 @@ jobs: hide_complexity: true indicators: true output: both - thresholds: '93 70' + thresholds: '98 78' continue-on-error: ${{ matrix.experimental != 'false' }} - name: Add Coverage PR Comment From 5b9654811c4a3c24320877c652d1a5df28f6eaae Mon Sep 17 00:00:00 2001 From: "Peter H. Boling" Date: Tue, 4 Nov 2025 22:22:54 -0700 Subject: [PATCH 59/62] =?UTF-8?q?=F0=9F=9A=9A=20back=20to=20omniauth-ldap.?= =?UTF-8?q?gemspec?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gitlab_omniauth-ldap.gemspec => omniauth-ldap.gemspec | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename gitlab_omniauth-ldap.gemspec => omniauth-ldap.gemspec (100%) diff --git a/gitlab_omniauth-ldap.gemspec b/omniauth-ldap.gemspec similarity index 100% rename from gitlab_omniauth-ldap.gemspec rename to omniauth-ldap.gemspec From 3d61662a00d4f33a9972dc5cdc283b9fde8dd30b Mon Sep 17 00:00:00 2001 From: "Peter H. Boling" Date: Wed, 5 Nov 2025 01:39:13 -0700 Subject: [PATCH 60/62] =?UTF-8?q?=F0=9F=9A=9A=20sync=20CHANGELOG.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG | 11 ---- CHANGELOG.md | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 148 insertions(+), 13 deletions(-) delete mode 100644 CHANGELOG diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index 405ce01..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,11 +0,0 @@ -## 2.1.1 - - Add a String check to `tls_options` sanitization to allow other objects - -## 2.1.0 - - Expose `:tls_options` SSL configuration option. Deprecate :ca_file, :ssl_version - -## 2.0.4 - - Improve log message when invalid credentials are used - -## 2.0.3 - - Protects against wrong request method call to callback diff --git a/CHANGELOG.md b/CHANGELOG.md index a35f990..cb05069 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,9 @@ [![SemVer 2.0.0][📌semver-img]][📌semver] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] -All notable changes to this project will be documented in this file. +Since version v2.3.1, all notable changes to this project will be documented in this file. + +This changelog lists the releases of the original omniauth-ldap, and the GitLab forked versions, up until v2.3.0. The format is based on [Keep a Changelog][📗keep-changelog], and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), @@ -20,12 +22,156 @@ Please file a bug if you notice a violation of semantic versioning. ### Added +- Added RBS types +- Upgraded RSpec tests to v3 syntax +- Improved code coverage to 98% lines and 78% branches +- Added integration tests with a complete Roda-based demo app for specs +- Well tested support for all versions of OmniAuth >= v1 and Rack >= v1 via appraisals + ### Changed +- Make support for Ruby v2.0 explicit +- Make support for OmniAuth v1+ explicit +- Make support for Rack v1+ explicit +- Modernize codebase to use more recent Ruby syntax (upgrade from Ruby v1 to v2 syntax) and conventions + ### Deprecated ### Removed ### Fixed -### Security \ No newline at end of file +### Security + +## [2.3.0-gl] (gitlab fork) - 2025-08-20 + +- TAG: [v2.3.0][2.3.0t-gl] (gitlab) + +## [2.2.0-gl] (gitlab fork) - 2022-06-24 + +- TAG: [v2.2.0][2.2.0t-gl] (gitlab) + +## [2.1.1-gl] (gitlab fork) - 2019-02-22 + +- TAG: [v2.1.1][2.1.1t-gl] (gitlab) + +### Added + +- Add a String check to `tls_options` sanitization to allow other objects + +## [2.1.0-gl] (gitlab fork) - 2018-06-18 + +- TAG: [v2.1.0][2.1.0t-gl] (gitlab) + +### Added + +- Expose `:tls_options` SSL configuration option. + +### Deprecated + +- Deprecate :ca_file, :ssl_version + +## [2.0.4-gl] (gitlab fork) - 2017-08-10 + +- TAG: [v2.0.4][2.0.4t-gl] (gitlab) + +- Improve log message when invalid credentials are used + +## 2.0.3 (gitlab fork) - 2017-07-20 + +- Protects against wrong request method call to callback + +## [2.0.2-gl] (gitlab fork) - 2017-06-13 + +- TAG: [v2.0.2][2.0.2t-gl] (gitlab) + +## [2.0.1-gl] (gitlab fork) - 2017-06-09 + +- TAG: [v2.0.1][2.0.1t-gl] (gitlab) + +## [2.0.0-gl] (gitlab fork) - 2017-06-07 + +- TAG: [v2.0.0][2.0.0t-gl] (gitlab) + +## [2.0.0] (intridea) - 2018-01-09 + +- TAG: [v2.0.0][2.0.0t] (github) + +## [1.2.1-gl] (gitlab fork) - 2015-03-17 + +- TAG: [v1.2.1][1.2.1t-gl] (gitlab) + +## [1.2.0-gl] (gitlab fork) - 2014-10-29 + +- TAG: [v1.2.0][1.2.0t-gl] (gitlab) + +## [1.1.0-gl] (gitlab fork) - 2014-09-08 + +- TAG: [v1.1.0][1.1.0t-gl] (gitlab) + +## [1.0.5-gl] - 2016-02-17 + +- TAG: [v1.0.5][1.0.5t-gl] (gitlab fork, gem not released) +- TAG: [v1.0.5][1.0.5t] (github) + +## 1.0.4 + +- released 2014-02-03 (intridea) +- released 2013-11-13 (gitlab fork) + +## 1.0.3 + +- released 2013-01-23 (intridea) +- released 2013-06-13 (gitlab fork) + +## [1.0.2-gl] + +- TAG: [v1.0.2][1.0.2t-gl] (gitlab) - released 2012-12-30 +- TAG: [v1.0.2][1.0.2t] (github) - released 2011-12-17 + +## 1.0.1 - 2011-11-02 + +## [1.0.0-gl] - 2011-11-02 + +- TAG: [v1.0.0][1.0.0t-gl] (gitlab) +- TAG: [v1.0.0][1.0.0t] (github) + +[2.3.0-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v2.2.0...v2.3.0 +[2.3.0t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/2.3.0 +[2.2.0-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v2.1.1...v2.2.0 +[2.2.0t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/2.2.0 +[2.1.1-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v2.1.0...v2.1.1 +[2.1.1t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/2.1.1 +[2.1.0-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v2.0.4...v2.1.0 +[2.1.0t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/2.1.0 +[2.0.4-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v2.0.2...v2.0.4 +[2.0.4t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/2.0.4 +[//]: # ( There is no tag for v2.0.3 on GitLab) +[2.0.2-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v2.0.1...v2.0.2 +[2.0.2t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/2.0.2 +[2.0.1-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v2.0.0...v2.0.1 +[2.0.1t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/2.0.1 +[2.0.0-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v1.2.1...v2.0.0 +[2.0.0t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/2.0.0 +[2.0.0]: https://github.com/omniauth/omniauth-ldap/compare/v1.0.5...v2.0.0 +[2.0.0t]: https://github.com/omniauth/omniauth-ldap/releases/tag/v2.0.0 +[1.2.1-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v1.2.0...v1.2.1 +[1.2.1t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/1.2.1 +[1.2.0-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v1.1.0...v1.2.0 +[1.2.0t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/1.2.0 +[1.1.0-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v1.0.2...v1.1.0 +[1.1.0t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/1.1.0 +[1.0.5-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v1.0.2...v1.0.5 +[1.0.5t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/1.0.5 +[1.0.5]: https://github.com/omniauth/omniauth-ldap/compare/v1.0.2...v1.0.5 +[1.0.5t]: https://github.com/omniauth/omniauth-ldap/releases/tag/v1.0.5 +[//]: # ( There are no tags for v1.0.3, v1.0.4 on GitHub, or GitLab) +[1.0.2-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/v1.0.1...v1.0.2 +[1.0.2t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/1.0.2 +[1.0.2]: https://github.com/omniauth/omniauth-ldap/compare/v1.0.1...v1.0.2 +[1.0.2t]: https://github.com/omniauth/omniauth-ldap/releases/tag/v1.0.2 +[//]: # ( There are no tags for v1.0.1 on GitHub, or GitLab) +[1.0.0-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/compare/5656da80d4193e0d0584f44bac493a87695e580f...v1.0.0 +[1.0.0t-gl]: https://gitlab.com/gitlab-org/ruby/gems/omniauth-ldap/-/tags/1.0.0 +[1.0.0]: https://github.com/omniauth/omniauth-ldap/compare/5656da80d4193e0d0584f44bac493a87695e580f...v1.0.0 +[1.0.0t]: https://github.com/omniauth/omniauth-ldap/releases/tag/v1.0.0 From 58df0fc3d3804ea0488542081f7a76d8cbfa10fd Mon Sep 17 00:00:00 2001 From: "Peter H. Boling" Date: Wed, 5 Nov 2025 01:39:33 -0700 Subject: [PATCH 61/62] =?UTF-8?q?=F0=9F=90=9B=20Prevent=20key=20duplicatio?= =?UTF-8?q?n=20in=20symbolize=5Fhash=5Fkeys?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 ++ lib/omniauth-ldap/adaptor.rb | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb05069..069ba29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ Please file a bug if you notice a violation of semantic versioning. ### Fixed +- Prevent key duplication in symbolize_hash_keys + ### Security ## [2.3.0-gl] (gitlab fork) - 2025-08-20 diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index ad22bcf..23cb13a 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -246,11 +246,9 @@ def sanitize_hash_values(hash) end def symbolize_hash_keys(hash) - hash.keys.each do |key| - hash[key.to_sym] = hash[key] + hash.each_with_object({}) do |(key, value), result| + result[key.to_sym] = value end - - hash end end end From f281bdd0beab7b47f113c80c52599daa3b87e040 Mon Sep 17 00:00:00 2001 From: "Peter H. Boling" Date: Wed, 5 Nov 2025 01:41:39 -0700 Subject: [PATCH 62/62] =?UTF-8?q?=F0=9F=9A=A8=20Update=20lint=20lock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .rubocop_gradual.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rubocop_gradual.lock b/.rubocop_gradual.lock index 0430551..b4ed25a 100644 --- a/.rubocop_gradual.lock +++ b/.rubocop_gradual.lock @@ -1,5 +1,5 @@ { - "lib/omniauth-ldap/adaptor.rb:3906050285": [ + "lib/omniauth-ldap/adaptor.rb:715274645": [ [64, 7, 413, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 105664470], [114, 17, 3, "Style/AndOr: Use `&&` instead of `and`.", 193409806], [114, 30, 3, "Style/AndOr: Use `&&` instead of `and`.", 193409806],