diff --git a/.rubocop_gradual.lock b/.rubocop_gradual.lock index ef77441..96e544d 100644 --- a/.rubocop_gradual.lock +++ b/.rubocop_gradual.lock @@ -1,20 +1,16 @@ { - "README.md:3434634895": [ - [68, 14, 2, "Lint/Syntax: unexpected token tASSOC\n(Using Ruby 2.0 parser; configure using `TargetRubyVersion` parameter, under `AllCops`)", 5859494], - [69, 15, 2, "Lint/Syntax: unexpected token tASSOC\n(Using Ruby 2.0 parser; configure using `TargetRubyVersion` parameter, under `AllCops`)", 5859494] - ], - "lib/omniauth-ldap/adaptor.rb:3734330877": [ + "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/strategies/ldap.rb:3702989656": [ + "lib/omniauth/strategies/ldap.rb:3246704443": [ [48, 9, 53, "Lint/RescueException: Avoid rescuing the `Exception` class. Perhaps you meant to rescue `StandardError`?", 4018396070], [54, 27, 3, "Style/AndOr: Use `&&` instead of `and`.", 193409806], [71, 7, 970, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 3995669691] ], - "spec/omniauth-ldap/adaptor_spec.rb:3490841684": [ + "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], @@ -22,7 +18,7 @@ [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/strategies/ldap_spec.rb:2669791786": [ + "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], diff --git a/.yard_gfm_support.rb b/.yard_gfm_support.rb index 49dde5f..4f2f140 100644 --- a/.yard_gfm_support.rb +++ b/.yard_gfm_support.rb @@ -18,5 +18,5 @@ def initialize(source, options = {}) # - https://github.com/lsegal/yard/blob/main/lib/yard/templates/helpers/markup_helper.rb YARD::Templates::Helpers::MarkupHelper::MARKUP_PROVIDERS[:markdown].insert( 0, - {:const => "KramdownGfmDocument"}, + {const: "KramdownGfmDocument"}, ) diff --git a/Gemfile.lock b/Gemfile.lock index a357f22..1a400e6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -258,8 +258,8 @@ GEM parallel (~> 1.10) rainbow (>= 2.2.2, < 4.0) rubocop (~> 1.0) - rubocop-lts (0.1.1) - rubocop-ruby1_8 (>= 1.0.5, < 2) + rubocop-lts (4.1.1) + rubocop-ruby2_0 (>= 2.0.3, < 3) standard-rubocop-lts (>= 1.0.3, < 3) version_gem (>= 1.1.2, < 3) rubocop-md (1.2.4) @@ -282,7 +282,7 @@ GEM rubocop-rspec (3.7.0) lint_roller (~> 1.1) rubocop (~> 1.72, >= 1.72.1) - rubocop-ruby1_8 (1.0.7) + rubocop-ruby2_0 (2.0.5) rubocop-gradual (~> 0.3, >= 0.3.1) rubocop-md (~> 1.2) rubocop-rake (~> 0.6) @@ -399,11 +399,11 @@ DEPENDENCIES rdoc (~> 6.11) reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) - rubocop-lts (~> 0.1) + rubocop-lts (~> 4.0) rubocop-on-rbs (~> 1.8) rubocop-packaging (~> 0.6, >= 0.6.0) rubocop-rspec (~> 3.6) - rubocop-ruby1_8 + rubocop-ruby2_0 ruby-progressbar (~> 1.13) standard (>= 1.50) stone_checksums (~> 1.0, >= 1.0.2) diff --git a/Guardfile b/Guardfile index 875a83d..24745b9 100644 --- a/Guardfile +++ b/Guardfile @@ -1,4 +1,4 @@ -guard "rspec", :version => 2 do +guard "rspec", version: 2 do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch("spec/spec_helper.rb") { "spec" } diff --git a/README.md b/README.md index 1a9384d..e0b4154 100644 --- a/README.md +++ b/README.md @@ -51,16 +51,16 @@ Use the LDAP strategy as a middleware in your application: ```ruby -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', - :password => 'password' +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 { |name| name.gsub(/@.*$/, "") }, + bind_dn: "default_bind_dn", + password: "password" # Or, alternatively: # use OmniAuth::Strategies::LDAP, filter: '(&(uid=%{username})(memberOf=cn=myapp-users,ou=groups,dc=example,dc=com))' ``` @@ -86,11 +86,26 @@ All of the listed options are required, with the exception of `:title`, `:name_p ### Compatibility -Compatible with MRI Ruby 0+, and concordant releases of JRuby, and TruffleRuby. +Compatible with MRI Ruby 2.0+, and concordant releases of JRuby, and TruffleRuby. +| 🚚 _Amazing_ test matrix was brought to you by | πŸ”Ž appraisal2 πŸ”Ž and the color πŸ’š green πŸ’š | |------------------------------------------------|--------------------------------------------------------| | πŸ‘Ÿ 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. @@ -197,21 +212,21 @@ Below are several concrete examples to get you started. ```ruby # config.ru -require 'rack' -require 'omniauth-ldap' +require "rack" +require "omniauth-ldap" -use Rack::Session::Cookie, secret: 'change_me' +use Rack::Session::Cookie, secret: "change_me" use OmniAuth::Builder do provider :ldap, - host: 'ldap.example.com', + host: "ldap.example.com", port: 389, method: :plain, - base: 'dc=example,dc=com', - uid: 'uid', - title: 'Example LDAP' + base: "dc=example,dc=com", + uid: "uid", + title: "Example LDAP" end -run lambda { |env| [404, {'Content-Type' => 'text/plain'}, [env.key?('omniauth.auth').to_s]] } +run lambda { |env| [404, {"Content-Type" => "text/plain"}, [env.key?("omniauth.auth").to_s]] } ``` Visit `GET /auth/ldap` to initiate authentication (the middleware will render a login form unless you POST to `/auth/ldap`). @@ -219,26 +234,26 @@ Visit `GET /auth/ldap` to initiate authentication (the middleware will render a ### Sinatra example ```ruby -require 'sinatra' -require 'omniauth-ldap' +require "sinatra" +require "omniauth-ldap" -use Rack::Session::Cookie, secret: 'change_me' +use Rack::Session::Cookie, secret: "change_me" use OmniAuth::Builder do provider :ldap, - title: 'Company LDAP', - host: 'ldap.company.internal', - base: 'dc=company,dc=local', - uid: 'sAMAccountName', - name_proc: proc { |username| username.gsub(/@.*$/, '') } + title: "Company LDAP", + host: "ldap.company.internal", + base: "dc=company,dc=local", + uid: "sAMAccountName", + name_proc: proc { |username| username.gsub(/@.*$/, "") } end -get '/' do +get "/" do 'Sign in with LDAP' end -get '/auth/ldap/callback' do - auth = request.env['omniauth.auth'] - "Hello, #{auth.info['name']}" +get "/auth/ldap/callback" do + auth = request.env["omniauth.auth"] + "Hello, #{auth.info["name"]}" end ``` @@ -247,16 +262,16 @@ end Create `config/initializers/omniauth.rb`: ```ruby -Rails.application.config.middleware.use OmniAuth::Builder do +Rails.application.config.middleware.use(OmniAuth::Builder) do provider :ldap, - title: 'Acme LDAP', - host: 'ldap.acme.internal', + title: "Acme LDAP", + host: "ldap.acme.internal", port: 389, - base: 'dc=acme,dc=corp', - uid: 'uid', - bind_dn: 'cn=search,dc=acme,dc=corp', - password: ENV['LDAP_SEARCH_PASSWORD'], - name_proc: proc { |n| n.split('@').first } + base: "dc=acme,dc=corp", + uid: "uid", + bind_dn: "cn=search,dc=acme,dc=corp", + password: ENV["LDAP_SEARCH_PASSWORD"], + name_proc: proc { |n| n.split("@").first } end ``` @@ -268,11 +283,11 @@ If you need to restrict authentication to a group or use a more complex lookup, ```ruby provider :ldap, - host: 'ldap.example.com', - base: 'dc=example,dc=com', - filter: '(&(uid=%{username})(memberOf=cn=myapp-users,ou=groups,dc=example,dc=com))', - bind_dn: 'cn=search,dc=example,dc=com', - password: ENV['LDAP_SEARCH_PASSWORD'] + host: "ldap.example.com", + base: "dc=example,dc=com", + filter: "(&(uid=%{username})(memberOf=cn=myapp-users,ou=groups,dc=example,dc=com))", + bind_dn: "cn=search,dc=example,dc=com", + password: ENV["LDAP_SEARCH_PASSWORD"] ``` ### SASL (advanced) @@ -281,11 +296,11 @@ SASL enables alternative bind mechanisms. Only enable if you understand the serv ```ruby provider :ldap, - host: 'ldap.example.com', - base: 'dc=example,dc=com', + host: "ldap.example.com", + base: "dc=example,dc=com", try_sasl: true, - sasl_mechanisms: ['DIGEST-MD5'], - uid: 'uid' + sasl_mechanisms: ["DIGEST-MD5"], + uid: "uid" ``` Supported mechanisms include `"DIGEST-MD5"` and `"GSS-SPNEGO"` depending on your environment and gems. @@ -296,10 +311,10 @@ If users log in with an email but LDAP expects a short username, use `:name_proc ```ruby provider :ldap, - host: 'ldap.example.com', - base: 'dc=example,dc=com', - uid: 'sAMAccountName', - name_proc: proc { |name| name.gsub(/@.*$/, '') } + host: "ldap.example.com", + base: "dc=example,dc=com", + uid: "sAMAccountName", + name_proc: proc { |name| name.gsub(/@.*$/, "") } ``` This trims `alice@example.com` to `alice` before searching. diff --git a/gemfiles/audit.gemfile b/gemfiles/audit.gemfile index 6d5d06b..8880702 100644 --- a/gemfiles/audit.gemfile +++ b/gemfiles/audit.gemfile @@ -2,6 +2,6 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/x_std_libs.gemfile") diff --git a/gemfiles/coverage.gemfile b/gemfiles/coverage.gemfile index a2ed98b..7b2ce5a 100644 --- a/gemfiles/coverage.gemfile +++ b/gemfiles/coverage.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r3/v2.1.gemfile") diff --git a/gemfiles/current.gemfile b/gemfiles/current.gemfile index b95b341..969a99f 100644 --- a/gemfiles/current.gemfile +++ b/gemfiles/current.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r3/v2.1.gemfile") diff --git a/gemfiles/dep_heads.gemfile b/gemfiles/dep_heads.gemfile index 6c555e0..90dec92 100644 --- a/gemfiles/dep_heads.gemfile +++ b/gemfiles/dep_heads.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/vHEAD.gemfile") diff --git a/gemfiles/head.gemfile b/gemfiles/head.gemfile index 68c5773..7c11290 100644 --- a/gemfiles/head.gemfile +++ b/gemfiles/head.gemfile @@ -4,7 +4,7 @@ source "https://gem.coop" gem "benchmark", "~> 0.4", ">= 0.4.1" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/vHEAD.gemfile") diff --git a/gemfiles/modular/coverage.gemfile b/gemfiles/modular/coverage.gemfile index f46bb51..ee32b0a 100644 --- a/gemfiles/modular/coverage.gemfile +++ b/gemfiles/modular/coverage.gemfile @@ -3,4 +3,4 @@ # We run code coverage on the latest version of Ruby only. # Coverage -gem "kettle-soup-cover", "~> 1.0", ">= 1.0.10", :require => false +gem "kettle-soup-cover", "~> 1.0", ">= 1.0.10", require: false diff --git a/gemfiles/modular/documentation.gemfile b/gemfiles/modular/documentation.gemfile index 7c5c2e9..7853390 100644 --- a/gemfiles/modular/documentation.gemfile +++ b/gemfiles/modular/documentation.gemfile @@ -3,8 +3,8 @@ # Documentation gem "kramdown", "~> 2.5", ">= 2.5.1" # Ruby >= 2.5 gem "kramdown-parser-gfm", "~> 1.1" # Ruby >= 2.3 -gem "yard", "~> 0.9", ">= 0.9.37", :require => false -gem "yard-junk", "~> 0.0", ">= 0.0.10", :github => "pboling/yard-junk", :branch => "next", :require => false +gem "yard", "~> 0.9", ">= 0.9.37", require: false +gem "yard-junk", "~> 0.0", ">= 0.0.10", github: "pboling/yard-junk", branch: "next", require: false gem "yard-relative_markdown_links", "~> 0.5.0" # Std Lib extractions diff --git a/gemfiles/modular/erb/vHEAD.gemfile b/gemfiles/modular/erb/vHEAD.gemfile index f61337d..65f8433 100644 --- a/gemfiles/modular/erb/vHEAD.gemfile +++ b/gemfiles/modular/erb/vHEAD.gemfile @@ -1,2 +1,2 @@ # Ruby >= 3.2 (dependency of kettle-dev) -gem "erb", :github => "ruby/erb", :branch => "master" +gem "erb", github: "ruby/erb", branch: "master" diff --git a/gemfiles/modular/logger/vHEAD.gemfile b/gemfiles/modular/logger/vHEAD.gemfile index 0de4c02..81a6bb8 100644 --- a/gemfiles/modular/logger/vHEAD.gemfile +++ b/gemfiles/modular/logger/vHEAD.gemfile @@ -1,2 +1,2 @@ # Ruby >= 2.5 (dependency of omniauth) -gem "logger", :github => "ruby/logger", :branch => "master" +gem "logger", github: "ruby/logger", branch: "master" diff --git a/gemfiles/modular/mutex_m/vHEAD.gemfile b/gemfiles/modular/mutex_m/vHEAD.gemfile index 3137d03..8af3b6f 100644 --- a/gemfiles/modular/mutex_m/vHEAD.gemfile +++ b/gemfiles/modular/mutex_m/vHEAD.gemfile @@ -1,2 +1,2 @@ # Ruby >= 2.5 (dependency of omniauth) -gem "mutex_m", :github => "ruby/mutex_m", :branch => "master" +gem "mutex_m", github: "ruby/mutex_m", branch: "master" diff --git a/gemfiles/modular/omniauth/vHEAD.gemfile b/gemfiles/modular/omniauth/vHEAD.gemfile index 1f0fa38..a11e691 100644 --- a/gemfiles/modular/omniauth/vHEAD.gemfile +++ b/gemfiles/modular/omniauth/vHEAD.gemfile @@ -1,4 +1,4 @@ # frozen_string_literal: true # Ruby >= 2.2 -gem "omniauth", :github => "omniauth/omniauth", :branch => "master" +gem "omniauth", github: "omniauth/omniauth", branch: "master" diff --git a/gemfiles/modular/optional.gemfile b/gemfiles/modular/optional.gemfile index 05e5ab1..b0232fe 100644 --- a/gemfiles/modular/optional.gemfile +++ b/gemfiles/modular/optional.gemfile @@ -5,7 +5,7 @@ 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 removed from stdlib in Ruby 3.4. +# 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/gemfiles/modular/rack/vHEAD.gemfile b/gemfiles/modular/rack/vHEAD.gemfile index ae66484..1725933 100644 --- a/gemfiles/modular/rack/vHEAD.gemfile +++ b/gemfiles/modular/rack/vHEAD.gemfile @@ -1 +1 @@ -gem "rack", :github => "rack/rack", :branch => "main" +gem "rack", github: "rack/rack", branch: "main" diff --git a/gemfiles/modular/runtime_heads.gemfile b/gemfiles/modular/runtime_heads.gemfile index a51e134..df49acf 100644 --- a/gemfiles/modular/runtime_heads.gemfile +++ b/gemfiles/modular/runtime_heads.gemfile @@ -3,7 +3,7 @@ # Test against HEAD of runtime dependencies so we can proactively file bugs # Ruby >= 2.2 -gem "version_gem", :github => "ruby-oauth/version_gem", :branch => "main" +gem "version_gem", github: "ruby-oauth/version_gem", branch: "main" eval_gemfile("rack/vHEAD.gemfile") diff --git a/gemfiles/modular/stringio/vHEAD.gemfile b/gemfiles/modular/stringio/vHEAD.gemfile index 22794f3..5f2a741 100644 --- a/gemfiles/modular/stringio/vHEAD.gemfile +++ b/gemfiles/modular/stringio/vHEAD.gemfile @@ -1,2 +1,2 @@ # Ruby >= 2.5 (dependency of omniauth) -gem "stringio", :github => "ruby/stringio", :branch => "master" +gem "stringio", github: "ruby/stringio", branch: "master" diff --git a/gemfiles/modular/style.gemfile b/gemfiles/modular/style.gemfile index 3be1c01..35c587e 100644 --- a/gemfiles/modular/style.gemfile +++ b/gemfiles/modular/style.gemfile @@ -14,12 +14,12 @@ gem "benchmark", "~> 0.4", ">= 0.4.1" # Removed from Std Lib in Ruby 3.5 if ENV.fetch("RUBOCOP_LTS_LOCAL", "false").casecmp("true").zero? home = ENV["HOME"] - gem "rubocop-lts", :path => "#{home}/src/rubocop-lts/rubocop-lts" - gem "rubocop-lts-rspec", :path => "#{home}/src/rubocop-lts/rubocop-lts-rspec" - gem "rubocop-ruby1_8", :path => "#{home}/src/rubocop-lts/rubocop-ruby1_8" - gem "standard-rubocop-lts", :path => "#{home}/src/rubocop-lts/standard-rubocop-lts" + gem "rubocop-lts", path: "#{home}/src/rubocop-lts/rubocop-lts" + gem "rubocop-lts-rspec", path: "#{home}/src/rubocop-lts/rubocop-lts-rspec" + gem "rubocop-ruby2_0", path: "#{home}/src/rubocop-lts/rubocop-ruby2_0" + gem "standard-rubocop-lts", path: "#{home}/src/rubocop-lts/standard-rubocop-lts" else - gem "rubocop-lts", "~> 0.1" - gem "rubocop-ruby1_8" + gem "rubocop-lts", "~> 4.0" + gem "rubocop-ruby2_0" gem "rubocop-rspec", "~> 3.6" end diff --git a/gemfiles/ruby_2_3.gemfile b/gemfiles/ruby_2_3.gemfile index 93dfbbf..5bbab38 100644 --- a/gemfiles/ruby_2_3.gemfile +++ b/gemfiles/ruby_2_3.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r2/v1.1.gemfile") diff --git a/gemfiles/ruby_2_4.gemfile b/gemfiles/ruby_2_4.gemfile index fc574a4..b4bc15f 100644 --- a/gemfiles/ruby_2_4.gemfile +++ b/gemfiles/ruby_2_4.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r2/v1.5.gemfile") diff --git a/gemfiles/ruby_2_5.gemfile b/gemfiles/ruby_2_5.gemfile index 5436566..020f2c0 100644 --- a/gemfiles/ruby_2_5.gemfile +++ b/gemfiles/ruby_2_5.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r2/v1.9.gemfile") diff --git a/gemfiles/ruby_2_6.gemfile b/gemfiles/ruby_2_6.gemfile index c565538..ff5a59c 100644 --- a/gemfiles/ruby_2_6.gemfile +++ b/gemfiles/ruby_2_6.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r2/v2.0.gemfile") diff --git a/gemfiles/ruby_2_7.gemfile b/gemfiles/ruby_2_7.gemfile index 9d497a9..9668cd6 100644 --- a/gemfiles/ruby_2_7.gemfile +++ b/gemfiles/ruby_2_7.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r2/v2.1.gemfile") diff --git a/gemfiles/ruby_3_0.gemfile b/gemfiles/ruby_3_0.gemfile index b0c229d..074cbfa 100644 --- a/gemfiles/ruby_3_0.gemfile +++ b/gemfiles/ruby_3_0.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r3/v2.1.gemfile") diff --git a/gemfiles/ruby_3_1.gemfile b/gemfiles/ruby_3_1.gemfile index b0c229d..074cbfa 100644 --- a/gemfiles/ruby_3_1.gemfile +++ b/gemfiles/ruby_3_1.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r3/v2.1.gemfile") diff --git a/gemfiles/ruby_3_2.gemfile b/gemfiles/ruby_3_2.gemfile index 690fdd5..b06e171 100644 --- a/gemfiles/ruby_3_2.gemfile +++ b/gemfiles/ruby_3_2.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r3/v2.1.gemfile") diff --git a/gemfiles/ruby_3_3.gemfile b/gemfiles/ruby_3_3.gemfile index 690fdd5..b06e171 100644 --- a/gemfiles/ruby_3_3.gemfile +++ b/gemfiles/ruby_3_3.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/omniauth/r3/v2.1.gemfile") diff --git a/gemfiles/style.gemfile b/gemfiles/style.gemfile index e4e8ff7..f1d77e5 100644 --- a/gemfiles/style.gemfile +++ b/gemfiles/style.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/style.gemfile") diff --git a/gemfiles/unlocked_deps.gemfile b/gemfiles/unlocked_deps.gemfile index a3d951e..a87cd22 100644 --- a/gemfiles/unlocked_deps.gemfile +++ b/gemfiles/unlocked_deps.gemfile @@ -2,7 +2,7 @@ source "https://gem.coop" -gemspec :path => "../" +gemspec path: "../" eval_gemfile("modular/coverage.gemfile") diff --git a/lib/omniauth-ldap/adaptor.rb b/lib/omniauth-ldap/adaptor.rb index ed295f1..ed41b23 100644 --- a/lib/omniauth-ldap/adaptor.rb +++ b/lib/omniauth-ldap/adaptor.rb @@ -1,7 +1,7 @@ # this code borrowed pieces from activeldap and net-ldap # nkf/kconv has been part of Ruby since long ago. -# Eventually it became a standard gem, but was removed from stdlib in Ruby 3.4. +# 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" @@ -26,9 +26,9 @@ class ConnectionError < StandardError; end MUST_HAVE_KEYS = [:host, :port, :method, [:uid, :filter], :base] METHOD = { - :ssl => :simple_tls, - :tls => :start_tls, - :plain => nil, + ssl: :simple_tls, + tls: :start_tls, + plain: nil, } attr_accessor :bind_dn, :password @@ -55,9 +55,9 @@ def initialize(configuration = {}) end method = ensure_method(@method) config = { - :host => @host, - :port => @port, - :base => @base, + host: @host, + port: @port, + base: @base, } @bind_method = if @try_sasl :sasl @@ -65,11 +65,11 @@ def initialize(configuration = {}) ((@allow_anonymous || !@bind_dn || !@password) ? :anonymous : :simple) end - @auth = sasl_auths({:username => @bind_dn, :password => @password}).first if @bind_method == :sasl + @auth = sasl_auths({username: @bind_dn, password: @password}).first if @bind_method == :sasl @auth ||= { - :method => @bind_method, - :username => @bind_dn, - :password => @password, + method: @bind_method, + username: @bind_dn, + password: @password, } config[:auth] = @auth config[:encryption] = method @@ -88,11 +88,11 @@ def bind_as(args = {}) method = args[:method] || @method password = password.call if password.respond_to?(:call) if method == "sasl" - result = rs.first if me.bind(sasl_auths({:username => dn, :password => password}).first) + result = rs.first if me.bind(sasl_auths({username: dn, password: password}).first) elsif me.bind( - :method => :simple, - :username => dn, - :password => password, + method: :simple, + username: dn, + password: password, ) result = rs.first end @@ -122,10 +122,10 @@ def sasl_auths(options = {}) next unless respond_to?(sasl_bind_setup, true) initial_credential, challenge_response = send(sasl_bind_setup, options) auths << { - :method => :sasl, - :initial_credential => initial_credential, - :mechanism => mechanism, - :challenge_response => challenge_response, + method: :sasl, + initial_credential: initial_credential, + mechanism: mechanism, + challenge_response: challenge_response, } end auths @@ -135,7 +135,7 @@ def sasl_bind_setup_digest_md5(options) bind_dn = options[:username] initial_credential = "" challenge_response = proc do |cred| - pref = SASL::Preferences.new(:digest_uri => "ldap/#{@host}", :username => bind_dn, :has_password? => true, :password => options[:password]) + pref = SASL::Preferences.new(digest_uri: "ldap/#{@host}", username: bind_dn, has_password?: true, password: options[:password]) sasl = SASL.new("DIGEST-MD5", pref) response = sasl.receive("challenge", cred) response[1] @@ -152,7 +152,7 @@ def sasl_bind_setup_gss_spnego(options) t2_msg = Net::NTLM::Message.parse(challenge) bind_dn, domain = bind_dn.split("\\").reverse t2_msg.target_name = Net::NTLM.encode_utf16le(domain) if domain - t3_msg = t2_msg.response({:user => bind_dn, :password => psw}, {:ntlmv2 => true}) + t3_msg = t2_msg.response({user: bind_dn, password: psw}, {ntlmv2: true}) t3_msg.serialize } [Net::NTLM::Message::Type1.new.serialize, nego] diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index bdcd63b..16b219a 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -28,7 +28,7 @@ class LDAP def request_phase OmniAuth::LDAP::Adaptor.validate(@options) - f = OmniAuth::Form.new(:title => options[:title] || "LDAP Authentication", :url => callback_path) + f = OmniAuth::Form.new(title: options[:title] || "LDAP Authentication", url: callback_path) f.text_field("Login", "username") f.password_field("Password", "password") f.button("Sign In") @@ -40,7 +40,7 @@ def callback_phase return fail!(:missing_credentials) if missing_credentials? begin - @ldap_user_info = @adaptor.bind_as(:filter => filter(@adaptor), :size => 1, :password => request.params["password"]) + @ldap_user_info = @adaptor.bind_as(filter: filter(@adaptor), size: 1, password: request.params["password"]) return fail!(:invalid_credentials) if !@ldap_user_info @user_info = self.class.map_user(@@config, @ldap_user_info) @@ -52,7 +52,7 @@ 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.params["username"])}) + Net::LDAP::Filter.construct(adaptor.filter % {username: @options[:name_proc].call(request.params["username"])}) else Net::LDAP::Filter.eq(adaptor.uid, @options[:name_proc].call(request.params["username"])) end @@ -65,7 +65,7 @@ def filter adaptor @user_info } extra { - {:raw_info => @ldap_user_info} + {raw_info: @ldap_user_info} } def self.map_user(mapper, object) diff --git a/omniauth-ldap.gemspec b/omniauth-ldap.gemspec index e95e03e..9d8bd6d 100644 --- a/omniauth-ldap.gemspec +++ b/omniauth-ldap.gemspec @@ -27,7 +27,7 @@ Gem::Specification.new do |spec| spec.description = "πŸ“ LDAP strategy for OmniAuth." spec.homepage = "https://github.com/omniauth/omniauth-ldap" spec.licenses = ["MIT"] - spec.required_ruby_version = ">= 0" + spec.required_ruby_version = ">= 2.0" # Linux distros often package gems and securely certify them independent # of the official RubyGem certification process. Allowed via ENV["SKIP_GEM_SIGNING"] @@ -99,7 +99,7 @@ Gem::Specification.new do |spec| spec.add_dependency("net-ldap", "~> 0.16") # ruby >= 2.0 # nkf/kconv has been part of Ruby since long ago. - # Eventually it became a standard gem, but was removed from stdlib in Ruby 3.4. + # 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 diff --git a/spec/omniauth-ldap/adaptor_spec.rb b/spec/omniauth-ldap/adaptor_spec.rb index aa1300d..50f70d6 100644 --- a/spec/omniauth-ldap/adaptor_spec.rb +++ b/spec/omniauth-ldap/adaptor_spec.rb @@ -5,36 +5,36 @@ 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"}) + OmniAuth::LDAP::Adaptor.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"}) + 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) end it "setups 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", 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 expect(adaptor.connection.base).to eq "dc=intridea, dc=com" - expect(adaptor.connection.instance_variable_get(:@auth)).to eq({:method => :anonymous, :username => nil, :password => nil}) + expect(adaptor.connection.instance_variable_get(:@auth)).to eq({method: :anonymous, username: nil, password: nil}) end it "setups 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", 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 expect(adaptor.connection.base).to eq "dc=intridea, dc=com" - expect(adaptor.connection.instance_variable_get(:@auth)).to eq({:method => :simple, :username => "bind_dn", :password => "password"}) + expect(adaptor.connection.instance_variable_get(:@auth)).to eq({method: :simple, username: "bind_dn", password: "password"}) end it "setups 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", 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 @@ -46,7 +46,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 = 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"}) expect(adaptor.connection).not_to be_nil expect(adaptor.connection.host).to eq "192.168.1.145" expect(adaptor.connection.port).to eq 389 @@ -58,25 +58,25 @@ end it "sets 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"}) - expect(adaptor.connection.instance_variable_get(:@encryption)).to include :method => :start_tls + 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 end end describe "bind_as" do - let(:args) { {:filter => Net::LDAP::Filter.eq("sAMAccountName", "username"), :password => "password", :size => 1} } + let(:args) { {filter: Net::LDAP::Filter.eq("sAMAccountName", "username"), password: "password", size: 1} } let(:rs) { Struct.new(:dn).new("new dn") } it "binds 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", method: "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) + expect(adaptor.connection).to receive(:bind).with({username: "new dn", password: args[:password], method: :simple}).and_return(true) expect(adaptor.bind_as(args)).to eq rs end it "binds 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", 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).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/strategies/ldap_spec.rb b/spec/omniauth/strategies/ldap_spec.rb index 2ae5584..3e235c7 100644 --- a/spec/omniauth/strategies/ldap_spec.rb +++ b/spec/omniauth/strategies/ldap_spec.rb @@ -15,7 +15,7 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end let(:app) do 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 { |name| name.gsub(/@.*$/, "") } + use MyLdapProvider, name: "ldap", title: "MyLdap Form", host: "192.168.1.145", base: "dc=score, dc=local", name_proc: proc { |name| name.gsub(/@.*$/, "") } run lambda { |env| [404, {"Content-Type" => "text/plain"}, [env.key?("omniauth.auth").to_s]] } }.to_app end @@ -67,7 +67,7 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end describe "post /auth/ldap/callback" do before do - @adaptor = double(OmniAuth::LDAP::Adaptor, {:uid => "ping"}) + @adaptor = double(OmniAuth::LDAP::Adaptor, {uid: "ping"}) allow(@adaptor).to receive(:filter) allow(OmniAuth::LDAP::Adaptor).to receive(:new) { @adaptor } @@ -90,7 +90,7 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end context "when username is empty" do it "redirects to error page" do - post("/auth/ldap/callback", {:username => ""}) + post("/auth/ldap/callback", {username: ""}) expect(last_response).to be_redirect expect(last_response.headers["Location"]).to match %r{missing_credentials} @@ -100,7 +100,7 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end context "when username is present" do context "and password is not preset" do it "redirects to error page" do - post("/auth/ldap/callback", {:username => "ping"}) + post("/auth/ldap/callback", {username: "ping"}) expect(last_response).to be_redirect expect(last_response.headers["Location"]).to match %r{missing_credentials} @@ -109,7 +109,7 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end context "and password is empty" do it "redirects to error page" do - post("/auth/ldap/callback", {:username => "ping", :password => ""}) + post("/auth/ldap/callback", {username: "ping", password: ""}) expect(last_response).to be_redirect expect(last_response.headers["Location"]).to match %r{missing_credentials} @@ -120,7 +120,7 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end context "when username and password are present" do context "and bind on LDAP server failed" do it "redirects to error page" do - post("/auth/ldap/callback", {:username => "ping", :password => "password"}) + post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(last_response).to be_redirect expect(last_response.headers["Location"]).to match %r{invalid_credentials} @@ -130,7 +130,7 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end it "binds with filter" do allow(@adaptor).to receive(:filter).and_return("uid=%{username}") expect(Net::LDAP::Filter).to receive(:construct).with("uid=ping") - post("/auth/ldap/callback", {:username => "ping", :password => "password"}) + post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(last_response).to be_redirect expect(last_response.headers["Location"]).to match %r{invalid_credentials} @@ -144,7 +144,7 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end end it "redirects to error page" do - post("/auth/ldap/callback", {:username => "ping", :password => "password"}) + post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(last_response).to be_redirect expect(last_response.headers["Location"]).to match %r{ldap_error} @@ -182,7 +182,7 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end end it "does not redirect to error page" do - post("/auth/ldap/callback", {:username => "ping", :password => "password"}) + post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(last_response).not_to be_redirect end @@ -190,14 +190,14 @@ class MyLdapProvider < OmniAuth::Strategies::LDAP; end it "binds with filter" do allow(@adaptor).to receive(:filter).and_return("uid=%{username}") expect(Net::LDAP::Filter).to receive(:construct).with("uid=ping") - post("/auth/ldap/callback", {:username => "ping", :password => "password"}) + post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(last_response).not_to be_redirect end end it "maps user info to Auth Hash" do - post("/auth/ldap/callback", {:username => "ping", :password => "password"}) + post("/auth/ldap/callback", {username: "ping", password: "password"}) expect(auth_hash.uid).to eq "cn=ping, dc=intridea, dc=com" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9d93e05..dbc2cdd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -27,7 +27,7 @@ RSpec.configure do |config| config.include Rack::Test::Methods - config.extend OmniAuth::Test::StrategyMacros, :type => :strategy + config.extend OmniAuth::Test::StrategyMacros, type: :strategy end # The last thing before loading this gem is to set up code coverage