activeldap 6.0.0 → 6.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddf65edda308e8db6ca8c35e3ef87c3299f048c0088b2f0836bab3f194709d11
4
- data.tar.gz: fb21442b49251ff549b0f8c9189443b29830230eb77b71fd9cd44da14a04afd0
3
+ metadata.gz: fd73013b75dc4f7aa629d12ba1b144ea34458f64f69245f1e78a399f5a5a7072
4
+ data.tar.gz: 8ee47f89c8e5e9316bdbe7f9fdc620657a336dceb968751cf15ad8aae0d39e6f
5
5
  SHA512:
6
- metadata.gz: ee133139964a025b4b55e294c3601ee7b686016718cf347a70f8beb1832a1b8a8f7867171dca577366bdf09a3e2777e4d61daf371570e7718eb0ef89c1423c9a
7
- data.tar.gz: 6fa4404370ecfcbb9509db4628165f9a41a0dc58ef420bc6809ba2ddb7d57c03761d6330bffbb1fc05d9a3ab5dbc2f336f1f7449d6d0df9fcea042792a840a15
6
+ metadata.gz: caaa12bfb35a8cf5838de135583e0165c7ef7a08e825b553f75dee95a26074430365f112cfb78cc11b42460ce039857af144c3e2d87da15426f97ade72c17eec
7
+ data.tar.gz: a148359f6c91dafb62b3883cd3bd38e95ab0650f68243cc5a0d69229a591111b8625d816cf8db75ee4d128ad69b6352e054a1d5170542e38031272ca3434d623
@@ -1,5 +1,73 @@
1
1
  # News
2
2
 
3
+ ## 6.1.0: 2020-12-24 {#release-6-1-0}
4
+
5
+ ### Improvements
6
+
7
+ * Changed to use `:use_paged_results` option value by default.
8
+ [GitHub#189][Reported by Kevin McCormack]
9
+
10
+ ### Thanks
11
+
12
+ * Kevin McCormack
13
+
14
+ ## 6.0.4: 2020-12-06 {#release-6-0-4}
15
+
16
+ ### Improvements
17
+
18
+ * Enabled concurrency by default.
19
+ [GitHub#188][Reported by Kevin McCormack]
20
+
21
+ ### Thanks
22
+
23
+ * Kevin McCormack
24
+
25
+ ## 6.0.3: 2020-08-17 {#release-6-0-3}
26
+
27
+ ### Improvements
28
+
29
+ * Added support for `save(validate: false)`.
30
+ [GitHub#180][Reported by Kevin McCormack]
31
+
32
+ * jndi: Added support for follow referrals.
33
+ [GitHub#182][Patch by Kevin McCormack]
34
+
35
+ ### Fixes
36
+
37
+ * Fixed a bug that sub base is ignored in DN specified by `new`.
38
+ [GitHub#185][Reported by Kevin McCormack]
39
+
40
+ ### Thanks
41
+
42
+ * Kevin McCormack
43
+
44
+ ## 6.0.2: 2020-05-19 {#release-6-0-2}
45
+
46
+ ### Improvements
47
+
48
+ * Added `options` to {ActiveLdap::Persistance#reload}.
49
+ [GitHub#176][Reported by Kevin McCormack]
50
+
51
+ * jndi: Improved DN escaping.
52
+ [GitHub#178][Patch by Kevin McCormack]
53
+
54
+ ### Thanks
55
+
56
+ * Kevin McCormack
57
+
58
+ ## 6.0.1: 2020-04-21 {#release-6-0-1}
59
+
60
+ ### Improvements
61
+
62
+ * Dropped support for Ruby 2.4.
63
+
64
+ * Stopped using paged results when we need only one entry.
65
+ [GitHub#173][Patch by Kevin McCormack]
66
+
67
+ ### Thanks
68
+
69
+ * Kevin McCormack
70
+
3
71
  ## 6.0.0: 2020-04-16 {#release-6-0-0}
4
72
 
5
73
  ### Improvements
@@ -60,6 +60,15 @@ to skip `active_ldap prefix` in `config/application.rb`:
60
60
  config.app_generators.orm :active_ldap
61
61
  ```
62
62
 
63
+ Concurrency is now enabled by default to ensure thread safe searches and modifications. This can
64
+ still be disabled if desired.
65
+
66
+ ```ruby
67
+ # config/initializers/active_ldap.rb
68
+
69
+ ActiveLdap::Base.allow_concurrency = false
70
+ ```
71
+
63
72
  ## Model
64
73
 
65
74
  You can generate a User model that represents entries under
@@ -641,7 +641,6 @@ base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
641
641
  $LOAD_PATH << File.join(base, "lib")
642
642
  $LOAD_PATH << File.join(base, "examples")
643
643
 
644
- require 'rubygems'
645
644
  require 'active_ldap'
646
645
  require 'objects/user'
647
646
  require 'objects/group'
@@ -694,7 +693,6 @@ base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
694
693
  $LOAD_PATH << File.join(base, "lib")
695
694
  $LOAD_PATH << File.join(base, "examples")
696
695
 
697
- require 'rubygems'
698
696
  require 'active_ldap'
699
697
  require 'objects/user'
700
698
  require 'objects/group'
@@ -744,7 +742,6 @@ base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
744
742
  $LOAD_PATH << File.join(base, "lib")
745
743
  $LOAD_PATH << File.join(base, "examples")
746
744
 
747
- require 'rubygems'
748
745
  require 'active_ldap'
749
746
  require 'objects/user'
750
747
  require 'objects/group'
@@ -1,4 +1,3 @@
1
- require "rubygems"
2
1
  require "active_model"
3
2
  require "active_support/core_ext"
4
3
 
@@ -180,8 +180,9 @@ module ActiveLdap
180
180
  limit = options[:limit] || 0
181
181
  limit = nil if limit <= 0
182
182
  use_paged_results = options[:use_paged_results]
183
- if use_paged_results or use_paged_results.nil?
184
- use_paged_results = supported_control.paged_results?
183
+ use_paged_results = @use_paged_results if use_paged_results.nil?
184
+ if use_paged_results
185
+ use_paged_results = limit != 1 && supported_control.paged_results?
185
186
  end
186
187
  search_options = {
187
188
  base: base,
@@ -682,8 +683,7 @@ module ActiveLdap
682
683
  :scope => :base,
683
684
  :attributes => attrs,
684
685
  :limit => 1,
685
- :try_reconnect => try_reconnect,
686
- :use_paged_results => false) do |dn, attributes|
686
+ :try_reconnect => try_reconnect) do |dn, attributes|
687
687
  found_attributes = attributes
688
688
  end
689
689
  found_attributes
@@ -22,9 +22,23 @@ module ActiveLdap
22
22
  super do |host, port, method|
23
23
  uri = construct_uri(host, port, method == :ssl)
24
24
  with_start_tls = method == :start_tls
25
- info = {:uri => uri, :with_start_tls => with_start_tls}
26
- [log("connect", info) {JndiConnection.new(host, port, method, @timeout)},
27
- uri, with_start_tls]
25
+ follow_referrals = follow_referrals?(options)
26
+ info = {
27
+ :uri => uri,
28
+ :with_start_tls => with_start_tls,
29
+ :follow_referrals => follow_referrals,
30
+ }
31
+ [
32
+ log("connect", info) {
33
+ JndiConnection.new(host,
34
+ port,
35
+ method,
36
+ @timeout,
37
+ follow_referrals)
38
+ },
39
+ uri,
40
+ with_start_tls,
41
+ ]
28
42
  end
29
43
  end
30
44
 
@@ -75,13 +75,14 @@ module ActiveLdap
75
75
  end
76
76
  end
77
77
 
78
- def initialize(host, port, method, timeout)
78
+ def initialize(host, port, method, timeout, follow_referrals)
79
79
  @host = host
80
80
  @port = port
81
81
  @method = method
82
82
  @timeout = timeout
83
83
  @context = nil
84
84
  @tls = nil
85
+ @follow_referrals = follow_referrals
85
86
  end
86
87
 
87
88
  def unbind
@@ -136,6 +137,7 @@ module ActiveLdap
136
137
  end
137
138
 
138
139
  escaped_base = escape_dn(base)
140
+
139
141
  loop do
140
142
  @context.search(escaped_base, filter, controls).each do |search_result|
141
143
  yield(build_raw_search_result(search_result))
@@ -166,26 +168,23 @@ module ActiveLdap
166
168
  records.each do |record|
167
169
  attributes.put(record.to_java_attribute)
168
170
  end
169
- escaped_dn = escape_dn(dn)
170
171
  @context.set_request_controls([])
171
- @context.create_subcontext(escaped_dn, attributes)
172
+ @context.create_subcontext(escape_dn(dn), attributes)
172
173
  end
173
174
 
174
175
  def modify(dn, records)
175
- escaped_dn = escape_dn(dn)
176
176
  items = records.collect(&:to_java_modification_item)
177
177
  @context.set_request_controls([])
178
- @context.modify_attributes(escaped_dn, items.to_java(ModificationItem))
178
+ @context.modify_attributes(escape_dn(dn), items.to_java(ModificationItem))
179
179
  end
180
180
 
181
181
  def modify_rdn(dn, new_rdn, delete_old_rdn)
182
- escaped_dn = escape_dn(dn)
183
182
  # should use mutex
184
183
  delete_rdn_key = "java.naming.ldap.deleteRDN"
185
184
  @context.set_request_controls([])
186
185
  begin
187
186
  @context.add_to_environment(delete_rdn_key, delete_old_rdn.to_s)
188
- @context.rename(escaped_dn, new_rdn)
187
+ @context.rename(escape_dn(dn), escape_dn(new_rdn))
189
188
  ensure
190
189
  @context.remove_from_environment(delete_rdn_key)
191
190
  end
@@ -205,9 +204,10 @@ module ActiveLdap
205
204
  Context::PROVIDER_URL => ldap_uri,
206
205
  'com.sun.jndi.ldap.connect.timeout' => (@timeout * 1000).to_i.to_s,
207
206
  'com.sun.jndi.ldap.read.timeout' => (@timeout * 1000).to_i.to_s,
207
+ 'java.naming.ldap.derefAliases' => 'never',
208
+ 'java.naming.referral' => @follow_referrals ? 'follow' : 'ignore',
208
209
  }
209
- environment = HashTable.new(environment)
210
- context = InitialLdapContext.new(environment, nil)
210
+ context = InitialLdapContext.new(HashTable.new(environment), nil)
211
211
  if @method == :start_tls
212
212
  @tls = context.extended_operation(StartTlsRequest.new)
213
213
  @tls.negotiate
@@ -230,34 +230,9 @@ module ActiveLdap
230
230
  end
231
231
 
232
232
  def escape_dn(dn)
233
- parsed_dn = nil
234
- begin
235
- parsed_dn = DN.parse(dn)
236
- rescue DistinguishedNameInvalid
237
- return dn
238
- end
239
-
240
- escaped_rdns = parsed_dn.rdns.collect do |rdn|
241
- escaped_rdn_strings = rdn.collect do |key, value|
242
- escaped_value = DN.escape_value(value)
243
- # We may need to escape the followings too:
244
- # * ,
245
- # * =
246
- # * +
247
- # * <
248
- # * >
249
- # * #
250
- # * ;
251
- #
252
- # See javax.naming.ldap.Rdn.unescapeValue()
253
- escaped_value = escaped_value.gsub(/\\\\/) do
254
- "\\5C"
255
- end
256
- "#{key}=#{escaped_value}"
257
- end
258
- escaped_rdn_strings.join("+")
259
- end
260
- escaped_rdns.join(",")
233
+ javax.naming.ldap.LdapName.new(dn)
234
+ rescue Java::JavaLang::IllegalArgumentException, Java::JavaxNaming::InvalidNameException
235
+ dn
261
236
  end
262
237
 
263
238
  def build_paged_results_control(page_size, page_cookie=nil)
@@ -209,15 +209,17 @@ module ActiveLdap
209
209
  def prepare_connection(options={})
210
210
  operation(options) do
211
211
  @connection.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
212
- unless follow_referrals?(options)
213
- @connection.set_option(LDAP::LDAP_OPT_REFERRALS, 0)
214
- end
212
+ @ldap_follow_referrals = follow_referrals?(options) ? 1 : 0
213
+ @connection.set_option(LDAP::LDAP_OPT_REFERRALS,
214
+ @ldap_follow_referrals)
215
215
  end
216
216
  end
217
217
 
218
218
  def execute(method, info=nil, *args, &block)
219
219
  begin
220
220
  name = (info || {}).delete(:name) || method
221
+ @connection.set_option(LDAP::LDAP_OPT_REFERRALS,
222
+ @ldap_follow_referrals)
221
223
  log(name, info) {@connection.send(method, *args, &block)}
222
224
  rescue LDAP::ResultError
223
225
  @connection.assert_error_code
@@ -851,6 +851,8 @@ module ActiveLdap
851
851
 
852
852
  _schema = _local_entry_attribute = nil
853
853
  targets = sanitize_for_mass_assignment(new_attributes)
854
+ have_dn = false
855
+ dn_value = nil
854
856
  targets.each do |key, value|
855
857
  setter = "#{key}="
856
858
  unless respond_to?(setter)
@@ -860,8 +862,15 @@ module ActiveLdap
860
862
  _local_entry_attribute ||= local_entry_attribute
861
863
  _local_entry_attribute.register(attribute)
862
864
  end
863
- send(setter, value)
865
+ case setter
866
+ when "dn=", "id="
867
+ have_dn = true
868
+ dn_value = value
869
+ else
870
+ send(setter, value)
871
+ end
864
872
  end
873
+ self.dn = dn_value if have_dn
865
874
  end
866
875
 
867
876
  def to_ldif_record
@@ -1281,6 +1290,7 @@ module ActiveLdap
1281
1290
  end
1282
1291
 
1283
1292
  def compute_base
1293
+ ensure_update_dn
1284
1294
  base_of_class = self.class.base
1285
1295
  if @base_value.nil?
1286
1296
  base_of_class
@@ -6,7 +6,7 @@ module ActiveLdap
6
6
 
7
7
  module ClassMethods
8
8
  @@active_connections = {}
9
- @@allow_concurrency = false
9
+ @@allow_concurrency = true
10
10
 
11
11
  def thread_safe_active_connections
12
12
  @@active_connections[Thread.current.object_id] ||= {}
@@ -81,9 +81,10 @@ module ActiveLdap
81
81
  end
82
82
  end
83
83
 
84
- def reload
84
+ def reload(options={})
85
85
  clear_association_cache
86
- _, attributes = search(:value => id).find do |_dn, _attributes|
86
+ search_options = options.merge(value: id)
87
+ _, attributes = search(search_options).find do |_dn, _attributes|
87
88
  dn == _dn
88
89
  end
89
90
  if attributes.nil?
@@ -53,15 +53,23 @@ module ActiveLdap
53
53
  errors.empty? && output
54
54
  end
55
55
 
56
- def save(*)
57
- valid? ? super : false
56
+ def save(**options)
57
+ perform_validations(options) ? super : false
58
58
  end
59
59
 
60
- def save!(*)
61
- valid? ? super : raise(EntryInvalid.new(self))
60
+ def save!(**options)
61
+ perform_validations(options) ? super : raise(EntryInvalid.new(self))
62
62
  end
63
63
 
64
64
  private
65
+ def perform_validations(options)
66
+ if options[:validate] == false
67
+ true
68
+ else
69
+ valid?(options[:context])
70
+ end
71
+ end
72
+
65
73
  def format_validation_message(format, parameters)
66
74
  format % parameters
67
75
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveLdap
2
- VERSION = "6.0.0"
2
+ VERSION = "6.1.0"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  # Your LDAP server needs to accept 'phonetic' attribute option for test.
2
2
  # This is a LDIF file for OpenLDAP to do the configuration.
3
- # You can use this file by the following command linne on Debian GNU/Linux
3
+ # You can use this file by the following command line on Debian GNU/Linux
4
4
  # or Ubuntu:
5
5
  # % sudo -H ldapmodify -Y EXTERNAL -H ldapi:/// -f test/add-phonetic-attribute-options-to-slapd.ldif
6
6
  version: 1
@@ -182,6 +182,7 @@ module AlTestUtils
182
182
  populate_ou
183
183
  populate_user_class
184
184
  populate_group_class
185
+ populate_group_of_urls_class
185
186
  populate_associations
186
187
  end
187
188
 
@@ -215,7 +216,7 @@ module AlTestUtils
215
216
  end
216
217
 
217
218
  def populate_ou
218
- %w(Users Groups).each do |name|
219
+ %w(Users Groups GroupOfURLsSet).each do |name|
219
220
  make_ou(name)
220
221
  end
221
222
  end
@@ -246,6 +247,14 @@ module AlTestUtils
246
247
  assign_class_name(@group_class, "Group")
247
248
  end
248
249
 
250
+ def populate_group_of_urls_class
251
+ @group_of_urls_class = Class.new(ActiveLdap::Base)
252
+ @group_of_urls_class.ldap_mapping :prefix => "ou=GroupOfURLsSet",
253
+ :scope => :sub,
254
+ :classes => ["groupOfURLs"]
255
+ assign_class_name(@group_of_urls_class, "GroupOfURLs")
256
+ end
257
+
249
258
  def populate_associations
250
259
  @user_class.belongs_to :groups, :many => "memberUid"
251
260
  @user_class.belongs_to :primary_group,
@@ -280,6 +289,7 @@ module AlTestUtils
280
289
  super
281
290
  @user_index = 0
282
291
  @group_index = 0
292
+ @group_of_urls_index = 0
283
293
  @temporary_uids = []
284
294
  end
285
295
 
@@ -366,6 +376,25 @@ module AlTestUtils
366
376
  end
367
377
  end
368
378
 
379
+ def make_temporary_group_of_urls(config={})
380
+ @group_of_urls_index += 1
381
+ cn = config[:cn] || "temp-group-of-urls-#{@group_of_urls_index}"
382
+ ensure_delete_group_of_urls(cn) do
383
+ _wrap_assertion do
384
+ assert(!@group_of_urls_class.exists?(cn))
385
+ assert_raise(ActiveLdap::EntryNotFound) do
386
+ @group_of_urls_class.find(cn)
387
+ end
388
+ group_of_urls = @group_of_urls_class.new(cn)
389
+ assert(group_of_urls.new_entry?)
390
+ group_of_urls.member_url = config[:member_url]
391
+ assert(group_of_urls.save!)
392
+ assert(!group_of_urls.new_entry?)
393
+ yield(@group_of_urls_class.find(group_of_urls.cn))
394
+ end
395
+ end
396
+ end
397
+
369
398
  def ensure_delete_user(uid)
370
399
  yield(uid)
371
400
  ensure
@@ -379,6 +408,12 @@ module AlTestUtils
379
408
  @group_class.delete(cn) if @group_class.exists?(cn)
380
409
  end
381
410
 
411
+ def ensure_delete_group_of_urls(cn)
412
+ yield(cn)
413
+ ensure
414
+ @group_of_urls_class.delete(cn) if @group_of_urls_class.exists?(cn)
415
+ end
416
+
382
417
  def default_uid
383
418
  "10000#{@user_index}"
384
419
  end
@@ -467,8 +502,13 @@ module AlTestUtils
467
502
  omit(message || "This test is not for JRuby")
468
503
  end
469
504
 
505
+ def omit_unless_jruby(message=nil)
506
+ return if RUBY_PLATFORM == "java"
507
+ omit(message || "This test is only for JRuby")
508
+ end
509
+
470
510
  def omit_if_ldap(message=nil)
471
- return unless current_configuration[:adapter] == "ldap"
511
+ return if current_configuration[:adapter] == "ldap"
472
512
  omit(message || "This test is not for ruby-ldap")
473
513
  end
474
514
  end
@@ -0,0 +1,22 @@
1
+ # Your LDAP server needs to support dynamic list for test.
2
+ # This is a LDIF file for OpenLDAP to do the configuration.
3
+ # You can use this file by the following command line on Debian GNU/Linux
4
+ # or Ubuntu:
5
+ #
6
+ # % sudo -H ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/dyngroup.ldif
7
+ # % sudo -H ldapmodify -Y EXTERNAL -H ldapi:/// -f test/enable-dynamic-groups.ldif
8
+ version: 1
9
+
10
+ # Enable dynlist module
11
+ dn: cn=module{0},cn=config
12
+ changetype: modify
13
+ add: olcModuleLoad
14
+ olcModuleLoad: dynlist
15
+
16
+ # Set up dynlist overlay
17
+ dn: olcOverlay=dynlist,olcDatabase={1}mdb,cn=config
18
+ changetype: add
19
+ objectClass: olcOverlayConfig
20
+ objectClass: olcDynamicList
21
+ olcOverlay: dynlist
22
+ olcDlAttrSet: groupOfURLs memberURL member
@@ -1,6 +1,6 @@
1
1
  # Your LDAP server needs to support StartTLS when you test StartTLS related
2
2
  # feature. This is a LDIF file for OpenLDAP to do the configuration.
3
- # You can use this file by the following command linne on Debian GNU/Linux
3
+ # You can use this file by the following command line on Debian GNU/Linux
4
4
  # or Ubuntu:
5
5
  #
6
6
  # % sudo usermod -a -G ssl-cert openldap
@@ -2,8 +2,6 @@
2
2
 
3
3
  $VERBOSE = true
4
4
 
5
- $KCODE = 'u' if RUBY_VERSION < "1.9"
6
-
7
5
  base_dir = File.expand_path(File.dirname(__FILE__))
8
6
  top_dir = File.expand_path(File.join(base_dir, ".."))
9
7
  lib_dir = File.join(top_dir, "lib")
@@ -11,11 +9,9 @@ test_dir = File.join(top_dir, "test")
11
9
  $LOAD_PATH.unshift(lib_dir)
12
10
  $LOAD_PATH.unshift(test_dir)
13
11
 
14
- require "rubygems"
15
12
  require "bundler/setup"
16
13
 
17
14
  require "test/unit"
18
- require "test/unit/notify"
19
15
  Test::Unit::Priority.enable
20
16
 
21
17
  Dir.glob(File.join(test_dir, "**", "test_*.rb")) do |test_file|
@@ -5,7 +5,52 @@ require 'al-test-utils'
5
5
  class TestBase < Test::Unit::TestCase
6
6
  include AlTestUtils
7
7
 
8
+ sub_test_case("follow_referrals") do
9
+ def test_default
10
+ make_temporary_user do |user1,|
11
+ make_temporary_user do |user2,|
12
+ member_url = ["ldap:///#{user1.base.to_s}??one?(objectClass=person)"]
13
+ make_temporary_group_of_urls(member_url: member_url) do |group_of_urls|
14
+ assert_equal([user1.dn, user2.dn],
15
+ group_of_urls.attributes["member"])
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ def test_connection_false
22
+ omit_unless_jruby
23
+ @group_of_urls_class.setup_connection(
24
+ current_configuration.merge(follow_referrals: false)
25
+ )
26
+ make_temporary_user do |user1,|
27
+ make_temporary_user do |user2,|
28
+ member_url = ["ldap:///#{user1.base.to_s}??one?(objectClass=person)"]
29
+ make_temporary_group_of_urls(member_url: member_url) do |group_of_urls|
30
+ assert_nil(group_of_urls.attributes["member"])
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def test_connect_false
37
+ omit_unless_jruby
38
+ connection = @group_of_urls_class.connection
39
+ connection.disconnect!
40
+ connection.connect(follow_referrals: false)
41
+ make_temporary_user do |user1,|
42
+ make_temporary_user do |user2,|
43
+ member_url = ["ldap:///#{user1.base.to_s}??one?(objectClass=person)"]
44
+ make_temporary_group_of_urls(member_url: member_url) do |group_of_urls|
45
+ assert_nil(group_of_urls.attributes["member"])
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+
8
52
  priority :must
53
+ priority :normal
9
54
  def test_search_colon_value
10
55
  make_temporary_group(:cn => "temp:group") do |group|
11
56
  assert_equal("temp:group", group.cn)
@@ -13,7 +58,6 @@ class TestBase < Test::Unit::TestCase
13
58
  end
14
59
  end
15
60
 
16
- priority :normal
17
61
  def test_lower_case_object_class
18
62
  fixture_file = fixture("lower_case_object_class_schema.rb")
19
63
  schema_entries = eval(File.read(fixture_file))
@@ -122,9 +166,9 @@ class TestBase < Test::Unit::TestCase
122
166
 
123
167
  def test_operational_attributes
124
168
  make_temporary_group do |group|
125
- dn, attributes = @group_class.search(:attributes => ["*"])[0]
169
+ _dn, attributes = @group_class.search(:attributes => ["*"])[0]
126
170
  normal_attributes = attributes.keys
127
- dn, attributes = @group_class.search(:attributes => ["*", "+"])[0]
171
+ _dn, attributes = @group_class.search(:attributes => ["*", "+"])[0]
128
172
  operational_attributes = attributes.keys - normal_attributes
129
173
  operational_attribute = operational_attributes[0]
130
174
 
@@ -383,6 +427,19 @@ class TestBase < Test::Unit::TestCase
383
427
  end
384
428
  end
385
429
 
430
+ def test_set_dn_with_unnormalized_dn_attribute_with_forward_slash
431
+ make_temporary_user do |user,|
432
+ new_dn = "uid=temp/user1,#{user.class.base}"
433
+ assert_not_equal(user.dn.to_s, new_dn)
434
+
435
+ user.uid = 'temp/user1'
436
+ assert_equal(user.dn.to_s, new_dn)
437
+
438
+ assert_true(user.save!)
439
+ assert_true(user.class.find(user.uid).update_attributes!(gidNumber: 100069))
440
+ end
441
+ end
442
+
386
443
  def test_destroy_with_empty_base_and_prefix_of_class
387
444
  make_temporary_user do |user,|
388
445
  base = user.class.base
@@ -945,7 +1002,8 @@ class TestBase < Test::Unit::TestCase
945
1002
  ou_class.ldap_mapping(:dn_attribute => :ou,
946
1003
  :prefix => "",
947
1004
  :classes => ["top", "organizationalUnit"])
948
- assert_equal(["ou=Groups,#{current_configuration['base']}",
1005
+ assert_equal(["ou=GroupOfURLsSet,#{current_configuration['base']}",
1006
+ "ou=Groups,#{current_configuration['base']}",
949
1007
  "ou=Users,#{current_configuration['base']}"],
950
1008
  ou_class.find(:all).collect(&:dn).collect(&:to_s).sort)
951
1009
  end
@@ -9,13 +9,45 @@ class TestBasePerInstance < Test::Unit::TestCase
9
9
  end
10
10
 
11
11
  priority :must
12
+ def test_dn_with_sub_base_first
13
+ sub_user = @user_class.new(dn: "uid=user1,ou=Sub,#{@user_class.base}",
14
+ uid: "user1")
15
+ # Order is important. #base should be called before #dn.
16
+ base = sub_user.base.to_s
17
+ dn = sub_user.dn.to_s
18
+ assert_equal([
19
+ "ou=Sub,#{@user_class.base}",
20
+ "uid=user1,ou=Sub,#{@user_class.base}",
21
+ ],
22
+ [
23
+ base,
24
+ dn,
25
+ ])
26
+ end
27
+
28
+ def test_dn_with_sub_base_last
29
+ sub_user = @user_class.new(uid: "user1",
30
+ dn: "uid=user1,ou=Sub,#{@user_class.base}")
31
+ # Order is important. #base should be called before #dn.
32
+ base = sub_user.base.to_s
33
+ dn = sub_user.dn.to_s
34
+ assert_equal([
35
+ "ou=Sub,#{@user_class.base}",
36
+ "uid=user1,ou=Sub,#{@user_class.base}",
37
+ ],
38
+ [
39
+ base,
40
+ dn,
41
+ ])
42
+ end
43
+
44
+ priority :normal
12
45
  def test_set_base
13
46
  guest = @user_class.new("guest")
14
47
  guest.base = "ou=Sub"
15
48
  assert_equal("uid=guest,ou=Sub,#{@user_class.base}", guest.dn)
16
49
  end
17
50
 
18
- priority :normal
19
51
  def test_dn_is_base
20
52
  entry_class = Class.new(ActiveLdap::Base)
21
53
  entry_class.ldap_mapping :prefix => "",
@@ -11,6 +11,7 @@ class TestEntry < Test::Unit::TestCase
11
11
  all_entries = [ActiveLdap::Base.base]
12
12
  all_entries += [user.dn, user.base]
13
13
  all_entries += [group.dn, group.base]
14
+ all_entries += [@group_of_urls_class.base]
14
15
  assert_equal(all_entries.sort,
15
16
  ActiveLdap::Entry.all.collect(&:dn).sort)
16
17
  end
@@ -37,6 +37,15 @@ class TestValidation < Test::Unit::TestCase
37
37
  priority :must
38
38
 
39
39
  priority :normal
40
+ def test_validate_false
41
+ make_temporary_user(:simple => true) do |user,|
42
+ user.sn = nil
43
+ assert_raise(ActiveLdap::RequiredAttributeMissed) do
44
+ user.save(validate: false)
45
+ end
46
+ end
47
+ end
48
+
40
49
  def test_octet_string
41
50
  make_temporary_user(:simple => true) do |user,|
42
51
  utf8_encoded_binary_value = "\xff".force_encoding("UTF-8")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeldap
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0
4
+ version: 6.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Will Drewry
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-04-15 00:00:00.000000000 Z
12
+ date: 2020-12-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '4.2'
20
+ version: '5.2'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: '4.2'
27
+ version: '5.2'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: locale
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -151,20 +151,6 @@ dependencies:
151
151
  - - ">="
152
152
  - !ruby/object:Gem::Version
153
153
  version: '0'
154
- - !ruby/object:Gem::Dependency
155
- name: test-unit-notify
156
- requirement: !ruby/object:Gem::Requirement
157
- requirements:
158
- - - ">="
159
- - !ruby/object:Gem::Version
160
- version: '0'
161
- type: :development
162
- prerelease: false
163
- version_requirements: !ruby/object:Gem::Requirement
164
- requirements:
165
- - - ">="
166
- - !ruby/object:Gem::Version
167
- version: '0'
168
154
  - !ruby/object:Gem::Dependency
169
155
  name: yard
170
156
  requirement: !ruby/object:Gem::Requirement
@@ -293,6 +279,7 @@ files:
293
279
  - test/al-test-utils.rb
294
280
  - test/command.rb
295
281
  - test/config.yaml.sample
282
+ - test/enable-dynamic-groups.ldif
296
283
  - test/enable-start-tls.ldif
297
284
  - test/fixtures/lower_case_object_class_schema.rb
298
285
  - test/run-test.rb
@@ -358,7 +345,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
358
345
  - !ruby/object:Gem::Version
359
346
  version: '0'
360
347
  requirements: []
361
- rubygems_version: 3.2.0.pre1
348
+ rubygems_version: 3.2.0.rc.2
362
349
  signing_key:
363
350
  specification_version: 4
364
351
  summary: ActiveLdap is a object-oriented API to LDAP
@@ -367,6 +354,7 @@ test_files:
367
354
  - test/al-test-utils.rb
368
355
  - test/command.rb
369
356
  - test/config.yaml.sample
357
+ - test/enable-dynamic-groups.ldif
370
358
  - test/enable-start-tls.ldif
371
359
  - test/fixtures/lower_case_object_class_schema.rb
372
360
  - test/run-test.rb