activeldap 5.2.3 → 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.
@@ -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
@@ -48,6 +48,15 @@ module ActiveLdap
48
48
  DEFAULT_CONFIG[:retry_on_timeout] = true
49
49
  DEFAULT_CONFIG[:follow_referrals] = true
50
50
 
51
+ # 500 is the default size limit value of OpenLDAP 2.4:
52
+ # https://openldap.org/doc/admin24/limits.html#Global%20Limits
53
+ #
54
+ # We may change this when we find LDAP server that its the default
55
+ # size limit is smaller than 500.
56
+ DEFAULT_CONFIG[:page_size] = 500
57
+ # Whether using paged results if available.
58
+ DEFAULT_CONFIG[:use_paged_results] = true
59
+
51
60
  DEFAULT_CONFIG[:logger] = nil
52
61
 
53
62
  module ClassMethods
@@ -103,8 +112,22 @@ module ActiveLdap
103
112
  end
104
113
  end
105
114
 
115
+ def parent_configuration(target)
116
+ if target.is_a?(Base)
117
+ target = target.class
118
+ else
119
+ target = target.superclass
120
+ end
121
+ while target <= Base
122
+ config = defined_configurations[target.active_connection_key]
123
+ return config if config
124
+ target = target.superclass
125
+ end
126
+ default_configuration
127
+ end
128
+
106
129
  def merge_configuration(user_configuration, target=self)
107
- configuration = default_configuration
130
+ configuration = parent_configuration(target).dup
108
131
  prepare_configuration(user_configuration).each do |key, value|
109
132
  case key
110
133
  when :base
@@ -165,11 +165,11 @@ module ActiveLdap
165
165
  connection.schema
166
166
  end
167
167
 
168
- private
169
168
  def active_connection_key(k=self)
170
169
  k.name.blank? ? k.object_id : k.name
171
170
  end
172
171
 
172
+ private
173
173
  def determine_active_connection_name
174
174
  key = active_connection_key
175
175
  if active_connections[key] or configuration(key)
@@ -17,11 +17,12 @@ module ActiveLdap
17
17
  if attribute_or_name.is_a?(Schema::Attribute)
18
18
  name = attribute_or_name.name
19
19
  else
20
- attribute = schema.attribute(attribute_or_name.to_s)
20
+ attribute_name = attribute_or_name.to_s
21
+ attribute = schema.attribute(attribute_name)
21
22
  return nil if attribute.id.nil?
22
- if attribute.name == attribute_or_name or
23
- attribute.aliases.include?(attribute_or_name.to_s)
24
- name = attribute_or_name
23
+ if attribute.name == attribute_name or
24
+ attribute.aliases.include?(attribute_name)
25
+ name = attribute_name
25
26
  else
26
27
  return nil
27
28
  end
@@ -22,9 +22,23 @@ module ActiveLdap
22
22
  end
23
23
 
24
24
  module Common
25
- VALID_SEARCH_OPTIONS = [:attribute, :value, :filter, :prefix,
26
- :classes, :scope, :limit, :attributes,
27
- :sort_by, :order, :connection, :base, :offset]
25
+ VALID_SEARCH_OPTIONS = [
26
+ :attribute,
27
+ :value,
28
+ :filter,
29
+ :prefix,
30
+ :classes,
31
+ :scope,
32
+ :limit,
33
+ :attributes,
34
+ :sort_by,
35
+ :order,
36
+ :connection,
37
+ :base,
38
+ :offset,
39
+ :use_paged_results,
40
+ :page_size,
41
+ ]
28
42
 
29
43
  def search(options={}, &block)
30
44
  validate_search_options(options)
@@ -62,6 +76,8 @@ module ActiveLdap
62
76
  :attributes => requested_attributes,
63
77
  :sort_by => options[:sort_by] || sort_by,
64
78
  :order => options[:order] || order,
79
+ :use_paged_results => options[:use_paged_results],
80
+ :page_size => options[:page_size],
65
81
  }
66
82
  options[:connection] ||= connection
67
83
  values = []
@@ -96,10 +112,11 @@ module ActiveLdap
96
112
  }
97
113
 
98
114
  attribute = attr || ensure_search_attribute
115
+ escaped_value = DN.escape_value(value)
99
116
  options_for_non_leaf = {
100
117
  :attribute => attr,
101
118
  :value => value,
102
- :prefix => ["#{attribute}=#{value}", prefix].compact.join(","),
119
+ :prefix => ["#{attribute}=#{escaped_value}", prefix].compact.join(","),
103
120
  :limit => 1,
104
121
  :scope => :base,
105
122
  }
@@ -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 = "5.2.3"
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
@@ -23,6 +23,7 @@ module AlTestUtils
23
23
  include TemporaryEntry
24
24
  include CommandSupport
25
25
  include MockLogger
26
+ include Omittable
26
27
  end
27
28
  end
28
29
 
@@ -39,7 +40,13 @@ module AlTestUtils
39
40
  @top_dir = File.expand_path(File.join(@base_dir, ".."))
40
41
  @example_dir = File.join(@top_dir, "examples")
41
42
  @fixtures_dir = File.join(@base_dir, "fixtures")
42
- @config_file = File.join(@base_dir, "config.yaml")
43
+ current_config_file = File.expand_path("config.yaml")
44
+ test_config_file = File.join(@base_dir, "config.yaml")
45
+ if File.exist?(current_config_file)
46
+ @config_file = current_config_file
47
+ else
48
+ @config_file = test_config_file
49
+ end
43
50
  ActiveLdap::Base.configurations = read_config
44
51
  end
45
52
 
@@ -175,6 +182,7 @@ module AlTestUtils
175
182
  populate_ou
176
183
  populate_user_class
177
184
  populate_group_class
185
+ populate_group_of_urls_class
178
186
  populate_associations
179
187
  end
180
188
 
@@ -208,7 +216,7 @@ module AlTestUtils
208
216
  end
209
217
 
210
218
  def populate_ou
211
- %w(Users Groups).each do |name|
219
+ %w(Users Groups GroupOfURLsSet).each do |name|
212
220
  make_ou(name)
213
221
  end
214
222
  end
@@ -239,6 +247,14 @@ module AlTestUtils
239
247
  assign_class_name(@group_class, "Group")
240
248
  end
241
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
+
242
258
  def populate_associations
243
259
  @user_class.belongs_to :groups, :many => "memberUid"
244
260
  @user_class.belongs_to :primary_group,
@@ -273,41 +289,70 @@ module AlTestUtils
273
289
  super
274
290
  @user_index = 0
275
291
  @group_index = 0
292
+ @group_of_urls_index = 0
293
+ @temporary_uids = []
294
+ end
295
+
296
+ def teardown
297
+ @temporary_uids.each do |uid|
298
+ delete_temporary_user(uid)
299
+ end
300
+ super
301
+ end
302
+
303
+ def delete_temporary_user(uid)
304
+ return unless @user_class.exists?(uid)
305
+ @user_class.search(:value => uid) do |dn, attribute|
306
+ @user_class.remove_connection(dn)
307
+ @user_class.delete(dn)
308
+ end
309
+ end
310
+
311
+ def build_temporary_user(config={})
312
+ uid = config[:uid] || "temp-user#{@user_index}"
313
+ password = config[:password] || "password#{@user_index}"
314
+ uid_number = config[:uid_number] || default_uid
315
+ gid_number = config[:gid_number] || default_gid
316
+ home_directory = config[:home_directory] || "/nonexistent"
317
+ see_also = config[:see_also]
318
+ user = nil
319
+ _wrap_assertion do
320
+ assert(!@user_class.exists?(uid))
321
+ assert_raise(ActiveLdap::EntryNotFound) do
322
+ @user_class.find(uid).dn
323
+ end
324
+ user = @user_class.new(uid)
325
+ assert(user.new_entry?)
326
+ user.cn = user.uid
327
+ user.sn = user.uid
328
+ user.uid_number = uid_number
329
+ user.gid_number = gid_number
330
+ user.home_directory = home_directory
331
+ user.user_password = ActiveLdap::UserPassword.ssha(password)
332
+ user.see_also = see_also
333
+ unless config[:simple]
334
+ user.add_class('shadowAccount', 'inetOrgPerson',
335
+ 'organizationalPerson')
336
+ user.user_certificate = certificate
337
+ user.jpeg_photo = jpeg_photo
338
+ end
339
+ user.save
340
+ assert(!user.new_entry?)
341
+ end
342
+ [@user_class.find(user.uid), password]
276
343
  end
277
344
 
278
345
  def make_temporary_user(config={})
279
346
  @user_index += 1
280
- uid = config[:uid] || "temp-user#{@user_index}"
281
- ensure_delete_user(uid) do
282
- password = config[:password] || "password#{@user_index}"
283
- uid_number = config[:uid_number] || default_uid
284
- gid_number = config[:gid_number] || default_gid
285
- home_directory = config[:home_directory] || "/nonexistent"
286
- see_also = config[:see_also]
287
- _wrap_assertion do
288
- assert(!@user_class.exists?(uid))
289
- assert_raise(ActiveLdap::EntryNotFound) do
290
- @user_class.find(uid).dn
291
- end
292
- user = @user_class.new(uid)
293
- assert(user.new_entry?)
294
- user.cn = user.uid
295
- user.sn = user.uid
296
- user.uid_number = uid_number
297
- user.gid_number = gid_number
298
- user.home_directory = home_directory
299
- user.user_password = ActiveLdap::UserPassword.ssha(password)
300
- user.see_also = see_also
301
- unless config[:simple]
302
- user.add_class('shadowAccount', 'inetOrgPerson',
303
- 'organizationalPerson')
304
- user.user_certificate = certificate
305
- user.jpeg_photo = jpeg_photo
306
- end
307
- user.save
308
- assert(!user.new_entry?)
309
- yield(@user_class.find(user.uid), password)
347
+ config = config.merge(uid: config[:uid] || "temp-user#{@user_index}")
348
+ uid = config[:uid]
349
+ @temporary_uids << uid
350
+ if block_given?
351
+ ensure_delete_user(uid) do
352
+ yield(*build_temporary_user(config))
310
353
  end
354
+ else
355
+ build_temporary_user(config)
311
356
  end
312
357
  end
313
358
 
@@ -331,15 +376,30 @@ module AlTestUtils
331
376
  end
332
377
  end
333
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
+
334
398
  def ensure_delete_user(uid)
335
399
  yield(uid)
336
400
  ensure
337
- if @user_class.exists?(uid)
338
- @user_class.search(:value => uid) do |dn, attribute|
339
- @user_class.remove_connection(dn)
340
- @user_class.delete(dn)
341
- end
342
- end
401
+ delete_temporary_user(uid)
402
+ @temporary_uids.delete(uid)
343
403
  end
344
404
 
345
405
  def ensure_delete_group(cn)
@@ -348,6 +408,12 @@ module AlTestUtils
348
408
  @group_class.delete(cn) if @group_class.exists?(cn)
349
409
  end
350
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
+
351
417
  def default_uid
352
418
  "10000#{@user_index}"
353
419
  end
@@ -373,6 +439,10 @@ module AlTestUtils
373
439
  end
374
440
 
375
441
  def run_command(*args, &block)
442
+ if RUBY_VERSION >= "2.7"
443
+ omit("Need to fix an optional arguments warning in net-ldap: " +
444
+ "ruby-ldap/ruby-net-ldap/pull/342")
445
+ end
376
446
  file = Tempfile.new("al-command-support")
377
447
  file.open
378
448
  file.puts(ActiveLdap::Base.configurations["test"].to_yaml)
@@ -425,4 +495,21 @@ module AlTestUtils
425
495
  ActiveLdap::Base.logger = original_logger
426
496
  end
427
497
  end
498
+
499
+ module Omittable
500
+ def omit_if_jruby(message=nil)
501
+ return unless RUBY_PLATFORM == "java"
502
+ omit(message || "This test is not for JRuby")
503
+ end
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
+
510
+ def omit_if_ldap(message=nil)
511
+ return if current_configuration[:adapter] == "ldap"
512
+ omit(message || "This test is not for ruby-ldap")
513
+ end
514
+ end
428
515
  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