activeldap 6.0.2 → 6.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e102a4e1e1913dcbc4ba91e6efdcf1c810273ab0df7843dda96e7a25448115e
4
- data.tar.gz: 641ed3e13f779e61a8ca2bb7b7451a2a262e6118cf3ebae09e05bca731ed3531
3
+ metadata.gz: 671ebd65e9137cf2ec38a775a132613c5449488b3b4a3aa9e41a75cf139409ed
4
+ data.tar.gz: 7f85f67f45bb076a68708ba5254f1594762f5d064218354e9e28e8a23e0e36b8
5
5
  SHA512:
6
- metadata.gz: 8cdb1be2238d42a244c1e4bfd1d02741b3944f16bbfdd4b787fa07d7b16fb9c054f91316b540eec1e27660a16fe84a6fed30cdbb103d04bab565f4f1ed366026
7
- data.tar.gz: bd5abb24368bc0e966398d8352b323f665ee6c9ff7ccb3d7cbaea556b87c0c9885458dcaba804176ba8992ad513e812a4e3a357c380fa14801e2b7838cbbc790
6
+ metadata.gz: 5896d1b97e081ec36d8ca8839391dea136ecf5a6cf49c71cf712095919364e6a6928405e4b63ed8bd96b36a9e2720604447713ccb610471b229b191d70a4f32a
7
+ data.tar.gz: 1d0c88a095252b8adec8df38aa4192ece39ef39ddbf741e38927685a4dd603b62f0d30a0d4c30137bc7a8f66c3b296cfb8214b7343a839949a0c51b04abd3247
@@ -1,5 +1,24 @@
1
1
  # News
2
2
 
3
+ ## 6.0.3: 2020-08-17 {#release-6-0-3}
4
+
5
+ ### Improvements
6
+
7
+ * Added support for `save(validate: false)`.
8
+ [GitHub#180][Reported by Kevin McCormack]
9
+
10
+ * jndi: Added support for follow referrals.
11
+ [GitHub#182][Patch by Kevin McCormack]
12
+
13
+ ### Fixes
14
+
15
+ * Fixed a bug that sub base is ignored in DN specified by `new`.
16
+ [GitHub#185][Reported by Kevin McCormack]
17
+
18
+ ### Thanks
19
+
20
+ * Kevin McCormack
21
+
3
22
  ## 6.0.2: 2020-05-19 {#release-6-0-2}
4
23
 
5
24
  ### Improvements
@@ -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
@@ -203,9 +204,10 @@ module ActiveLdap
203
204
  Context::PROVIDER_URL => ldap_uri,
204
205
  'com.sun.jndi.ldap.connect.timeout' => (@timeout * 1000).to_i.to_s,
205
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',
206
209
  }
207
- environment = HashTable.new(environment)
208
- context = InitialLdapContext.new(environment, nil)
210
+ context = InitialLdapContext.new(HashTable.new(environment), nil)
209
211
  if @method == :start_tls
210
212
  @tls = context.extended_operation(StartTlsRequest.new)
211
213
  @tls.negotiate
@@ -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
@@ -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.2"
2
+ VERSION = "6.0.3"
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,6 +502,11 @@ 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
511
  return if current_configuration[:adapter] == "ldap"
472
512
  omit(message || "This test is not for ruby-ldap")
@@ -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
@@ -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,7 +427,7 @@ class TestBase < Test::Unit::TestCase
383
427
  end
384
428
  end
385
429
 
386
- def test_set_dn_with_unnormalized_dn_attribute_with_forward_slash
430
+ def test_set_dn_with_unnormalized_dn_attribute_with_forward_slash
387
431
  make_temporary_user do |user,|
388
432
  new_dn = "uid=temp/user1,#{user.class.base}"
389
433
  assert_not_equal(user.dn.to_s, new_dn)
@@ -394,7 +438,7 @@ class TestBase < Test::Unit::TestCase
394
438
  assert_true(user.save!)
395
439
  assert_true(user.class.find(user.uid).update_attributes!(gidNumber: 100069))
396
440
  end
397
- end
441
+ end
398
442
 
399
443
  def test_destroy_with_empty_base_and_prefix_of_class
400
444
  make_temporary_user do |user,|
@@ -958,7 +1002,8 @@ class TestBase < Test::Unit::TestCase
958
1002
  ou_class.ldap_mapping(:dn_attribute => :ou,
959
1003
  :prefix => "",
960
1004
  :classes => ["top", "organizationalUnit"])
961
- assert_equal(["ou=Groups,#{current_configuration['base']}",
1005
+ assert_equal(["ou=GroupOfURLsSet,#{current_configuration['base']}",
1006
+ "ou=Groups,#{current_configuration['base']}",
962
1007
  "ou=Users,#{current_configuration['base']}"],
963
1008
  ou_class.find(:all).collect(&:dn).collect(&:to_s).sort)
964
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.2
4
+ version: 6.0.3
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-05-18 00:00:00.000000000 Z
12
+ date: 2020-08-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -279,6 +279,7 @@ files:
279
279
  - test/al-test-utils.rb
280
280
  - test/command.rb
281
281
  - test/config.yaml.sample
282
+ - test/enable-dynamic-groups.ldif
282
283
  - test/enable-start-tls.ldif
283
284
  - test/fixtures/lower_case_object_class_schema.rb
284
285
  - test/run-test.rb
@@ -344,7 +345,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
344
345
  - !ruby/object:Gem::Version
345
346
  version: '0'
346
347
  requirements: []
347
- rubygems_version: 3.2.0.pre1
348
+ rubygems_version: 3.2.0.rc.1
348
349
  signing_key:
349
350
  specification_version: 4
350
351
  summary: ActiveLdap is a object-oriented API to LDAP
@@ -353,6 +354,7 @@ test_files:
353
354
  - test/al-test-utils.rb
354
355
  - test/command.rb
355
356
  - test/config.yaml.sample
357
+ - test/enable-dynamic-groups.ldif
356
358
  - test/enable-start-tls.ldif
357
359
  - test/fixtures/lower_case_object_class_schema.rb
358
360
  - test/run-test.rb