omniauth-ldap 2.3.1 → 2.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,12 +10,36 @@ require "sasl"
10
10
 
11
11
  module OmniAuth
12
12
  module LDAP
13
+ # Adaptor encapsulates the behavior required to connect to an LDAP server
14
+ # and perform searches and binds. It maps user-provided configuration into
15
+ # a Net::LDAP connection and provides compatibility helpers for different
16
+ # net-ldap and SASL versions. The adaptor is intentionally defensive and
17
+ # provides a small, stable API used by the OmniAuth strategy.
18
+ #
19
+ # @example Initialize with minimal config
20
+ # adaptor = OmniAuth::LDAP::Adaptor.new(base: 'dc=example,dc=com', host: 'ldap.example.com')
21
+ #
22
+ # @note Public API: {validate}, {initialize}, {bind_as}, and attr readers such as {connection}, {uid}
13
23
  class Adaptor
24
+ # Generic adaptor error super-class
25
+ # @see Error classes that inherit from this class
14
26
  class LdapError < StandardError; end
27
+
28
+ # Raised when configuration is invalid
29
+ # @example
30
+ # raise ConfigurationError, 'missing base'
15
31
  class ConfigurationError < StandardError; end
32
+
33
+ # Raised when authentication fails
16
34
  class AuthenticationError < StandardError; end
35
+
36
+ # Raised on connection-related failures
17
37
  class ConnectionError < StandardError; end
18
38
 
39
+ # Valid configuration keys accepted by the adaptor. These correspond to
40
+ # the options supported by the gem and are used during initialization.
41
+ #
42
+ # @return [Array<Symbol>]
19
43
  VALID_ADAPTER_CONFIGURATION_KEYS = [
20
44
  :hosts,
21
45
  :host,
@@ -31,6 +55,10 @@ module OmniAuth
31
55
  :allow_anonymous,
32
56
  :filter,
33
57
  :tls_options,
58
+ :password_policy,
59
+ # Timeouts
60
+ :connect_timeout,
61
+ :read_timeout,
34
62
 
35
63
  # Deprecated
36
64
  :method,
@@ -38,7 +66,9 @@ module OmniAuth
38
66
  :ssl_version,
39
67
  ]
40
68
 
41
- # A list of needed keys. Possible alternatives are specified using sub-lists.
69
+ # Required configuration keys. This may include alternatives as sub-lists
70
+ # (e.g., [:hosts, :host] means either key is acceptable).
71
+ # @return [Array]
42
72
  MUST_HAVE_KEYS = [
43
73
  :base,
44
74
  [:encryption, :method], # :method is deprecated
@@ -47,6 +77,8 @@ module OmniAuth
47
77
  [:uid, :filter],
48
78
  ]
49
79
 
80
+ # Supported encryption method mapping for configuration readability.
81
+ # @return [Hash<Symbol,Symbol,nil>]
50
82
  ENCRYPTION_METHOD = {
51
83
  simple_tls: :simple_tls,
52
84
  start_tls: :start_tls,
@@ -58,9 +90,47 @@ module OmniAuth
58
90
  tls: :start_tls,
59
91
  }
60
92
 
93
+ # @!attribute [rw] bind_dn
94
+ # The distinguished name used for binding when provided in configuration.
95
+ # @return [String, nil]
96
+ # @!attribute [rw] password
97
+ # The bind password (may be nil for anonymous binds)
98
+ # @return [String, nil]
61
99
  attr_accessor :bind_dn, :password
62
- attr_reader :connection, :uid, :base, :auth, :filter
63
100
 
101
+ # Read-only attributes exposing connection and configuration state.
102
+ # @!attribute [r] connection
103
+ # The underlying Net::LDAP connection object.
104
+ # @return [Net::LDAP]
105
+ # @!attribute [r] uid
106
+ # The user id attribute used for lookups (e.g., 'sAMAccountName')
107
+ # @return [String]
108
+ # @!attribute [r] base
109
+ # The base DN for searches.
110
+ # @return [String]
111
+ # @!attribute [r] auth
112
+ # The final auth structure used by net-ldap.
113
+ # @return [Hash]
114
+ # @!attribute [r] filter
115
+ # Custom filter pattern when provided in configuration.
116
+ # @return [String, nil]
117
+ # @!attribute [r] password_policy
118
+ # Whether to request LDAP Password Policy controls.
119
+ # @return [Boolean]
120
+ # @!attribute [r] last_operation_result
121
+ # Last operation result object returned by the ldap library (if any)
122
+ # @return [Object, nil]
123
+ # @!attribute [r] last_password_policy_response
124
+ # Last extracted password policy response control (if any)
125
+ # @return [Object, nil]
126
+ attr_reader :connection, :uid, :base, :auth, :filter, :password_policy, :last_operation_result, :last_password_policy_response
127
+
128
+ # Validate that a minimal configuration is present. Raises ArgumentError when required
129
+ # keys are missing. This is a convenience to provide early feedback to callers.
130
+ #
131
+ # @param configuration [Hash] configuration hash passed to the adaptor
132
+ # @raise [ArgumentError] when required keys are missing
133
+ # @return [void]
64
134
  def self.validate(configuration = {})
65
135
  message = []
66
136
  MUST_HAVE_KEYS.each do |names|
@@ -73,6 +143,15 @@ module OmniAuth
73
143
  raise ArgumentError.new(message.join(",") + " MUST be provided") unless message.empty?
74
144
  end
75
145
 
146
+ # Create a new adaptor instance backed by a Net::LDAP connection.
147
+ #
148
+ # The constructor does not immediately open a network connection but
149
+ # prepares the Net::LDAP instance according to the provided configuration.
150
+ # It also applies timeout settings where supported by the installed net-ldap version.
151
+ #
152
+ # @param configuration [Hash] user-provided configuration options
153
+ # @raise [ArgumentError, ConfigurationError] on invalid configuration
154
+ # @return [OmniAuth::LDAP::Adaptor]
76
155
  def initialize(configuration = {})
77
156
  Adaptor.validate(configuration)
78
157
  @configuration = configuration.dup
@@ -88,6 +167,8 @@ module OmniAuth
88
167
  port: @port,
89
168
  encryption: encryption_options,
90
169
  }
170
+ # Remove passing timeouts here to avoid issues on older net-ldap versions.
171
+ # We'll set them after initialization if the connection responds to writers.
91
172
  @bind_method = if @try_sasl
92
173
  :sasl
93
174
  else
@@ -102,27 +183,79 @@ module OmniAuth
102
183
  }
103
184
  config[:auth] = @auth
104
185
  @connection = Net::LDAP.new(config)
186
+ # Apply optional timeout settings if supported by the installed net-ldap version
187
+ if !@connect_timeout.nil?
188
+ if @connection.respond_to?(:connect_timeout=)
189
+ @connection.connect_timeout = @connect_timeout
190
+ else
191
+ @connection.instance_variable_set(:@connect_timeout, @connect_timeout)
192
+ end
193
+ end
194
+ if !@read_timeout.nil?
195
+ if @connection.respond_to?(:read_timeout=)
196
+ @connection.read_timeout = @read_timeout
197
+ else
198
+ @connection.instance_variable_set(:@read_timeout, @read_timeout)
199
+ end
200
+ end
105
201
  end
106
202
 
107
203
  #:base => "dc=yourcompany, dc=com",
108
204
  # :filter => "(mail=#{user})",
109
205
  # :password => psw
206
+ #
207
+ # Attempt to locate a user entry and bind as that entry using the supplied
208
+ # password. Returns the entry on success, or false/nil on failure.
209
+ #
210
+ # @param args [Hash] search and bind options forwarded to net-ldap's search
211
+ # @option args [Net::LDAP::Filter,String] :filter LDAP filter to use
212
+ # @option args [Integer] :size maximum number of results to fetch
213
+ # @option args [String,Proc] :password a password string or callable returning a password
214
+ # @return [Net::LDAP::Entry, false, nil] the found entry on successful bind, otherwise false/nil
215
+ # @raise [ConnectionError] if the underlying LDAP search fails
110
216
  def bind_as(args = {})
111
217
  result = false
218
+ @last_operation_result = nil
219
+ @last_password_policy_response = nil
112
220
  @connection.open do |me|
113
221
  rs = me.search(args)
114
- if rs and rs.first and dn = rs.first.dn
115
- password = args[:password]
116
- method = args[:method] || @method
117
- password = password.call if password.respond_to?(:call)
118
- if method == "sasl"
119
- result = rs.first if me.bind(sasl_auths({username: dn, password: password}).first)
120
- elsif me.bind(
121
- method: :simple,
122
- username: dn,
123
- password: password,
124
- )
125
- result = rs.first
222
+ raise ConnectionError.new("LDAP search operation failed") unless rs
223
+
224
+ if rs && rs.first
225
+ dn = rs.first.dn
226
+ if dn
227
+ password = args[:password]
228
+ password = password.call if password.respond_to?(:call)
229
+
230
+ bind_args = if @bind_method == :sasl
231
+ sasl_auths({username: dn, password: password}).first
232
+ else
233
+ {
234
+ method: :simple,
235
+ username: dn,
236
+ password: password,
237
+ }
238
+ end
239
+
240
+ # Optionally request LDAP Password Policy control (RFC Draft - de facto standard)
241
+ if @password_policy
242
+ # Always request by OID using a simple hash; avoids depending on gem-specific control classes
243
+ control = {oid: "1.3.6.1.4.1.42.2.27.8.5.1", criticality: true, value: nil}
244
+ if bind_args.is_a?(Hash)
245
+ bind_args = bind_args.merge({controls: [control]})
246
+ else
247
+ # Some Net::LDAP versions allow passing a block for SASL only; ensure we still can add controls if hash
248
+ # When not a Hash, we can't merge; rely on server default behavior.
249
+ end
250
+ end
251
+
252
+ begin
253
+ success = bind_args ? me.bind(bind_args) : me.bind
254
+ ensure
255
+ capture_password_policy(me)
256
+ end
257
+
258
+ result = rs.first if success
126
259
  end
127
260
  end
128
261
  end
@@ -131,6 +264,9 @@ module OmniAuth
131
264
 
132
265
  private
133
266
 
267
+ # Build encryption options for Net::LDAP given the configured method
268
+ #
269
+ # @return [Hash, nil] encryption options or nil for plain (no encryption)
134
270
  def encryption_options
135
271
  translated_method = translate_method
136
272
  return unless translated_method
@@ -141,6 +277,10 @@ module OmniAuth
141
277
  }
142
278
  end
143
279
 
280
+ # Normalize the user-provided encryption/method option and map to known values.
281
+ #
282
+ # @raise [ConfigurationError] when an unknown method is provided
283
+ # @return [Symbol, nil]
144
284
  def translate_method
145
285
  method = @encryption || @method
146
286
  method ||= "plain"
@@ -155,6 +295,10 @@ module OmniAuth
155
295
  ENCRYPTION_METHOD[normalized_method]
156
296
  end
157
297
 
298
+ # Build TLS options including backward-compatibility for deprecated keys.
299
+ #
300
+ # @param translated_method [Symbol] the normalized encryption method
301
+ # @return [Hash] a hash suitable for passing as :tls_options
158
302
  def tls_options(translated_method)
159
303
  return {} if translated_method.nil? # (plain)
160
304
 
@@ -175,6 +319,10 @@ module OmniAuth
175
319
  options
176
320
  end
177
321
 
322
+ # Build a list of SASL auth structures for each requested mechanism.
323
+ #
324
+ # @param options [Hash] options such as :username and :password
325
+ # @return [Array<Hash>] list of auth structures
178
326
  def sasl_auths(options = {})
179
327
  auths = []
180
328
  sasl_mechanisms = options[:sasl_mechanisms] || @sasl_mechanisms
@@ -193,6 +341,9 @@ module OmniAuth
193
341
  auths
194
342
  end
195
343
 
344
+ # Prepare SASL DIGEST-MD5 bind details
345
+ # @param options [Hash]
346
+ # @return [Array] initial_credential and a challenge response proc
196
347
  def sasl_bind_setup_digest_md5(options)
197
348
  bind_dn = options[:username]
198
349
  initial_credential = ""
@@ -205,6 +356,9 @@ module OmniAuth
205
356
  [initial_credential, challenge_response]
206
357
  end
207
358
 
359
+ # Prepare SASL GSS-SPNEGO bind details
360
+ # @param options [Hash]
361
+ # @return [Array] initial Type1 message and a nego proc
208
362
  def sasl_bind_setup_gss_spnego(options)
209
363
  bind_dn = options[:username]
210
364
  psw = options[:password]
@@ -220,8 +374,9 @@ module OmniAuth
220
374
  [Net::NTLM::Message::Type1.new.serialize, nego]
221
375
  end
222
376
 
223
- private
224
-
377
+ # Default TLS/OpenSSL options used when not explicitly configured.
378
+ #
379
+ # @return [Hash]
225
380
  def default_options
226
381
  if @disable_verify_certificates
227
382
  # It is important to explicitly set verify_mode for two reasons:
@@ -238,6 +393,9 @@ module OmniAuth
238
393
  #
239
394
  # This gem may not always be in the context of Rails so we
240
395
  # do this rather than `.blank?`.
396
+ #
397
+ # @param hash [Hash]
398
+ # @return [Hash] sanitized hash with blank values removed
241
399
  def sanitize_hash_values(hash)
242
400
  hash.delete_if do |_, value|
243
401
  value.nil? ||
@@ -245,11 +403,47 @@ module OmniAuth
245
403
  end
246
404
  end
247
405
 
406
+ # Convert string keys to symbol keys for options hashes.
407
+ #
408
+ # @param hash [Hash]
409
+ # @return [Hash<Symbol, Object>]
248
410
  def symbolize_hash_keys(hash)
249
411
  hash.each_with_object({}) do |(key, value), result|
250
412
  result[key.to_sym] = value
251
413
  end
252
414
  end
415
+
416
+ # Capture the operation result and extract any Password Policy response control if present.
417
+ #
418
+ # This method is defensive: if the server or the installed net-ldap gem doesn't
419
+ # support controls, the method will swallow errors and leave policy fields nil.
420
+ #
421
+ # @param conn [Net::LDAP]
422
+ # @return [void]
423
+ def capture_password_policy(conn)
424
+ return unless @password_policy
425
+ return unless conn.respond_to?(:get_operation_result)
426
+
427
+ begin
428
+ @last_operation_result = conn.get_operation_result
429
+ controls = if @last_operation_result && @last_operation_result.respond_to?(:controls)
430
+ @last_operation_result.controls || []
431
+ else
432
+ []
433
+ end
434
+ if controls.any?
435
+ # Find Password Policy response control by OID
436
+ ppolicy_oid = "1.3.6.1.4.1.42.2.27.8.5.1"
437
+ ctrl = controls.find do |c|
438
+ (c.respond_to?(:oid) && c.oid == ppolicy_oid) || (c.is_a?(Hash) && c[:oid] == ppolicy_oid)
439
+ end
440
+ @last_password_policy_response = ctrl if ctrl
441
+ end
442
+ rescue StandardError
443
+ # Swallow errors to keep authentication flow unaffected when server or gem doesn't support controls
444
+ @last_password_policy_response = nil
445
+ end
446
+ end
253
447
  end
254
448
  end
255
449
  end
@@ -1,8 +1,17 @@
1
1
  module OmniAuth
2
2
  module LDAP
3
+ # Version namespace for the omniauth-ldap gem
4
+ #
5
+ # This module contains the version constant used by rubygems and in code
6
+ # consumers. It intentionally exposes VERSION both inside the Version
7
+ # namespace and as OmniAuth::LDAP::VERSION for compatibility.
3
8
  module Version
4
- VERSION = "2.3.1"
9
+ # Public semantic version for the gem
10
+ # @return [String]
11
+ VERSION = "2.3.3"
5
12
  end
13
+ # Convenience constant for consumers that expect OmniAuth::LDAP::VERSION
14
+ # @return [String]
6
15
  VERSION = Version::VERSION # Make VERSION available in traditional way
7
16
  end
8
17
  end
data/lib/omniauth-ldap.rb CHANGED
@@ -1,3 +1,11 @@
1
+ # Integrate the VersionGem helper into the OmniAuth::LDAP::Version module
2
+ # to expose common version-related helper methods. This file is the public
3
+ # entry point required by consumers of the gem.
4
+ #
5
+ # @example
6
+ # require 'omniauth-ldap'
7
+ # OmniAuth::LDAP::VERSION # => "2.3.2"
8
+
1
9
  require "version_gem"
2
10
 
3
11
  require "omniauth-ldap/version"
@@ -15,7 +15,7 @@ module OmniAuth
15
15
 
16
16
  VALID_ADAPTER_CONFIGURATION_KEYS: Array[Symbol]
17
17
  MUST_HAVE_KEYS: Array[untyped]
18
- METHOD: Hash[Symbol, Symbol?]
18
+ ENCRYPTION_METHOD: Hash[Symbol, Symbol?]
19
19
 
20
20
  attr_accessor bind_dn: String?
21
21
  attr_accessor password: String?
@@ -28,6 +28,10 @@ module OmniAuth
28
28
  attr_reader auth: Hash[Symbol, untyped]
29
29
  # filter is an LDAP filter string when configured
30
30
  attr_reader filter: String?
31
+ # optional: request password policy control and capture response
32
+ attr_reader password_policy: bool?
33
+ attr_reader last_operation_result: untyped
34
+ attr_reader last_password_policy_response: untyped
31
35
 
32
36
  # Validate that required keys exist in the configuration
33
37
  def self.validate: (?Hash[Symbol, untyped]) -> void
@@ -38,17 +42,31 @@ module OmniAuth
38
42
 
39
43
  private
40
44
 
41
- # Returns a Net::LDAP encryption symbol (e.g. :simple_tls, :start_tls) or nil
42
- def ensure_method: (untyped) -> Symbol?
45
+ # Returns encryption settings hash or nil
46
+ def encryption_options: () -> Hash[Symbol, untyped]?
47
+ # Translate configured method/encryption into Net::LDAP symbol
48
+ def translate_method: () -> Symbol?
49
+ # Returns a Net::LDAP encryption default options hash
50
+ def default_options: () -> Hash[Symbol, untyped]
51
+ # Sanitize provided TLS options
52
+ def sanitize_hash_values: (Hash[untyped, untyped]) -> Hash[untyped, untyped]
53
+ # Symbolize option keys
54
+ def symbolize_hash_keys: (Hash[untyped, untyped]) -> Hash[Symbol, untyped]
55
+ # Capture password policy control from last operation
56
+ def capture_password_policy: (Net::LDAP) -> void
43
57
 
44
58
  # Returns an array of SASL auth hashes
45
59
  def sasl_auths: (?Hash[Symbol, untyped]) -> Array[Hash[Symbol, untyped]]
46
60
 
47
- # Returns initial credential (string) and a proc that accepts a challenge and returns the response
48
- # Use Array[untyped] here to avoid tuple syntax issues in some linters; the runtime value
49
- # is commonly a two-element array [initial_credential, proc].
61
+ # Returns initial credential and a proc that accepts a challenge and returns the response
50
62
  def sasl_bind_setup_digest_md5: (?Hash[Symbol, untyped]) -> Array[untyped]
51
63
  def sasl_bind_setup_gss_spnego: (?Hash[Symbol, untyped]) -> Array[untyped]
64
+
65
+ @try_sasl: bool?
66
+ @allow_anonymous: bool?
67
+ @tls_options: Hash[untyped, untyped]?
68
+ @sasl_mechanisms: Array[String]?
69
+ @disable_verify_certificates: bool?
52
70
  end
53
71
  end
54
72
  end
@@ -3,9 +3,6 @@ module OmniAuth
3
3
  class LDAP
4
4
  OMNIAUTH_GTE_V2: bool
5
5
 
6
- # CONFIG is a read-only mapping of string keys to mapping definitions
7
- CONFIG: Hash[String, untyped]
8
-
9
6
  # The request_phase either returns a Rack-compatible response or the form response.
10
7
  def request_phase: () -> (Rack::Response | Array[untyped] | String)
11
8
 
@@ -27,6 +24,12 @@ module OmniAuth
27
24
 
28
25
  # Perform a directory lookup for a given username; returns an Entry or nil
29
26
  def directory_lookup: (OmniAuth::LDAP::Adaptor, String) -> untyped
27
+
28
+ def uid: () { () -> String } -> void
29
+
30
+ def info: () { () -> Hash[untyped, untyped] } -> void
31
+
32
+ def extra: () { () -> Hash[Symbol, untyped] } -> void
30
33
  end
31
34
  end
32
35
  end
@@ -3,3 +3,8 @@
3
3
  # - sig/omniauth/ldap/adaptor.rbs
4
4
  # - sig/omniauth/strategies/ldap.rbs
5
5
  # This file is intentionally minimal to avoid duplicating declarations.
6
+
7
+ module OmniAuth
8
+ module LDAP
9
+ end
10
+ end
data/sig/rbs/net-ldap.rbs CHANGED
@@ -5,6 +5,7 @@ module Net
5
5
  def open: () { (self) -> untyped } -> untyped
6
6
  def search: (?Hash[Symbol, untyped]) -> Array[Net::LDAP::Entry]
7
7
  def bind: (?Hash[Symbol, untyped]) -> bool
8
+ def get_operation_result: () -> Net::LDAP::PDU
8
9
  end
9
10
 
10
11
  class LDAP::Entry
@@ -15,5 +16,20 @@ module Net
15
16
  def self.construct: (String) -> Net::LDAP::Filter
16
17
  def self.eq: (String, String) -> Net::LDAP::Filter
17
18
  end
18
- end
19
19
 
20
+ class LDAP::Control
21
+ def initialize: (String, bool, untyped) -> void
22
+ def oid: () -> String
23
+ end
24
+
25
+ module LDAP::Controls
26
+ class PasswordPolicy
27
+ def initialize: () -> void
28
+ def oid: () -> String
29
+ end
30
+ end
31
+
32
+ class LDAP::PDU
33
+ def controls: () -> Array[untyped]
34
+ end
35
+ end
data/sig/rbs/net-ntlm.rbs CHANGED
@@ -4,6 +4,8 @@ module Net
4
4
  class Message
5
5
  def self.parse: (untyped) -> Net::NTLM::Message
6
6
  def response: (?Hash[Symbol, untyped], ?Hash[Symbol, untyped]) -> Net::NTLM::Message
7
+ # writer used by adaptor to set target name when a domain is present
8
+ def target_name=: (String) -> String
7
9
  end
8
10
 
9
11
  class Message::Type1
@@ -13,4 +15,3 @@ module Net
13
15
  def self.encode_utf16le: (String) -> String
14
16
  end
15
17
  end
16
-
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-ldap
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
@@ -65,7 +65,7 @@ dependencies:
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '1'
68
+ version: '1.2'
69
69
  - - "<"
70
70
  - !ruby/object:Gem::Version
71
71
  version: '3'
@@ -75,7 +75,7 @@ dependencies:
75
75
  requirements:
76
76
  - - ">="
77
77
  - !ruby/object:Gem::Version
78
- version: '1'
78
+ version: '1.2'
79
79
  - - "<"
80
80
  - !ruby/object:Gem::Version
81
81
  version: '3'
@@ -337,34 +337,6 @@ dependencies:
337
337
  - - ">="
338
338
  - !ruby/object:Gem::Version
339
339
  version: 1.0.3
340
- - !ruby/object:Gem::Dependency
341
- name: vcr
342
- requirement: !ruby/object:Gem::Requirement
343
- requirements:
344
- - - ">="
345
- - !ruby/object:Gem::Version
346
- version: '4'
347
- type: :development
348
- prerelease: false
349
- version_requirements: !ruby/object:Gem::Requirement
350
- requirements:
351
- - - ">="
352
- - !ruby/object:Gem::Version
353
- version: '4'
354
- - !ruby/object:Gem::Dependency
355
- name: webmock
356
- requirement: !ruby/object:Gem::Requirement
357
- requirements:
358
- - - ">="
359
- - !ruby/object:Gem::Version
360
- version: '3'
361
- type: :development
362
- prerelease: false
363
- version_requirements: !ruby/object:Gem::Requirement
364
- requirements:
365
- - - ">="
366
- - !ruby/object:Gem::Version
367
- version: '3'
368
340
  description: "\U0001F4C1 LDAP strategy for OmniAuth."
369
341
  email:
370
342
  - floss@galtzo.com
@@ -408,10 +380,10 @@ licenses:
408
380
  - MIT
409
381
  metadata:
410
382
  homepage_uri: https://omniauth-ldap.galtzo.com/
411
- source_code_uri: https://github.com/omniauth/omniauth-ldap/tree/v2.3.1
412
- changelog_uri: https://github.com/omniauth/omniauth-ldap/blob/v2.3.1/CHANGELOG.md
383
+ source_code_uri: https://github.com/omniauth/omniauth-ldap/tree/v2.3.3
384
+ changelog_uri: https://github.com/omniauth/omniauth-ldap/blob/v2.3.3/CHANGELOG.md
413
385
  bug_tracker_uri: https://github.com/omniauth/omniauth-ldap/issues
414
- documentation_uri: https://www.rubydoc.info/gems/omniauth-ldap/2.3.1
386
+ documentation_uri: https://www.rubydoc.info/gems/omniauth-ldap/2.3.3
415
387
  funding_uri: https://github.com/sponsors/pboling
416
388
  wiki_uri: https://github.com/omniauth/omniauth-ldap/wiki
417
389
  news_uri: https://www.railsbling.com/tags/omniauth-ldap
metadata.gz.sig CHANGED
Binary file