activeldap 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +61 -0
- data/README +8 -1
- data/Rakefile +4 -1
- data/benchmark/bench-al.rb +12 -2
- data/examples/al-admin/app/controllers/account_controller.rb +4 -3
- data/examples/al-admin/app/controllers/application.rb +5 -2
- data/examples/al-admin/app/controllers/directory_controller.rb +3 -1
- data/examples/al-admin/app/controllers/users_controller.rb +19 -4
- data/examples/al-admin/app/controllers/welcome_controller.rb +4 -2
- data/examples/al-admin/app/helpers/application_helper.rb +7 -1
- data/examples/al-admin/app/helpers/url_helper.rb +4 -0
- data/examples/al-admin/app/models/ldap_user.rb +4 -0
- data/examples/al-admin/app/views/_entry/{_attributes_information.rhtml → _attributes_information.html.erb} +0 -0
- data/examples/al-admin/app/views/_entry/{_entry.rhtml → _entry.html.erb} +0 -0
- data/examples/al-admin/app/views/_schema/{_aliases.rhtml → _aliases.html.erb} +0 -0
- data/examples/al-admin/app/views/_switcher/{_after.rhtml → _after.html.erb} +0 -0
- data/examples/al-admin/app/views/_switcher/{_before.rhtml → _before.html.erb} +0 -0
- data/examples/al-admin/app/views/account/{login.rhtml → login.html.erb} +0 -0
- data/examples/al-admin/app/views/account/{sign_up.rhtml → sign_up.html.erb} +0 -0
- data/examples/al-admin/app/views/attributes/{_attributes.rhtml → _attributes.html.erb} +0 -0
- data/examples/al-admin/app/views/attributes/{_detail.rhtml → _detail.html.erb} +0 -0
- data/examples/al-admin/app/views/attributes/{index.rhtml → index.html.erb} +0 -0
- data/examples/al-admin/app/views/attributes/{show.rhtml → show.html.erb} +0 -0
- data/examples/al-admin/app/views/directory/{_tree.rhtml → _tree.html.erb} +0 -0
- data/examples/al-admin/app/views/directory/{_tree_view_js.rhtml → _tree_view_js.html.erb} +4 -5
- data/examples/al-admin/app/views/directory/{index.rhtml → index.html.erb} +0 -0
- data/examples/al-admin/app/views/directory/{populate.rhtml → populate.html.erb} +0 -0
- data/examples/al-admin/app/views/layouts/{_footer.rhtml → _footer.html.erb} +0 -0
- data/examples/al-admin/app/views/layouts/{_header_menu.rhtml → _header_menu.html.erb} +0 -0
- data/examples/al-admin/app/views/layouts/{_main_menu.rhtml → _main_menu.html.erb} +0 -0
- data/examples/al-admin/app/views/layouts/{application.rhtml → application.html.erb} +3 -2
- data/examples/al-admin/app/views/object_classes/{_attributes.rhtml → _attributes.html.erb} +0 -0
- data/examples/al-admin/app/views/object_classes/{_object_classes.rhtml → _object_classes.html.erb} +0 -0
- data/examples/al-admin/app/views/object_classes/{index.rhtml → index.html.erb} +0 -0
- data/examples/al-admin/app/views/object_classes/{show.rhtml → show.html.erb} +0 -0
- data/examples/al-admin/app/views/syntaxes/{_detail.rhtml → _detail.html.erb} +0 -0
- data/examples/al-admin/app/views/syntaxes/{_syntaxes.rhtml → _syntaxes.html.erb} +0 -0
- data/examples/al-admin/app/views/syntaxes/{index.rhtml → index.html.erb} +0 -0
- data/examples/al-admin/app/views/syntaxes/{show.rhtml → show.html.erb} +0 -0
- data/examples/al-admin/app/views/users/{_attributes_update_form.rhtml → _attributes_update_form.html.erb} +0 -0
- data/examples/al-admin/app/views/users/{_form.rhtml → _form.html.erb} +0 -0
- data/examples/al-admin/app/views/users/{_object_classes_update_form.rhtml → _object_classes_update_form.html.erb} +7 -1
- data/examples/al-admin/app/views/users/{_password_change_form.rhtml → _password_change_form.html.erb} +0 -0
- data/examples/al-admin/app/views/users/{edit.rhtml → edit.html.erb} +0 -0
- data/examples/al-admin/app/views/users/{index.rhtml → index.html.erb} +0 -0
- data/examples/al-admin/app/views/users/{show.rhtml → show.html.erb} +0 -0
- data/examples/al-admin/app/views/welcome/{index.rhtml → index.html.erb} +0 -0
- data/examples/al-admin/config/boot.rb +96 -32
- data/examples/al-admin/config/environment.rb +30 -36
- data/examples/al-admin/config/environments/development.rb +2 -5
- data/examples/al-admin/config/environments/production.rb +1 -0
- data/examples/al-admin/config/environments/test.rb +4 -1
- data/examples/al-admin/config/initializers/exception_notifier.rb +2 -0
- data/examples/al-admin/config/initializers/gettext.rb +1 -0
- data/examples/al-admin/config/initializers/inflections.rb +10 -0
- data/examples/al-admin/config/initializers/mime_types.rb +5 -0
- data/examples/al-admin/config/initializers/ralative_url_support.rb +1 -0
- data/examples/al-admin/config/routes.rb +24 -12
- data/examples/al-admin/lib/authenticated_system.rb +1 -1
- data/examples/al-admin/lib/tasks/gettext.rake +1 -1
- data/examples/al-admin/po/en/al-admin.po +102 -100
- data/examples/al-admin/po/ja/al-admin.po +112 -110
- data/examples/al-admin/po/nl/al-admin.po +117 -110
- data/examples/al-admin/public/javascripts/controls.js +484 -354
- data/examples/al-admin/public/javascripts/dragdrop.js +88 -58
- data/examples/al-admin/public/javascripts/effects.js +396 -364
- data/examples/al-admin/public/javascripts/prototype.js +2817 -1107
- data/examples/al-admin/public/stylesheets/base.css +5 -0
- data/examples/al-admin/script/performance/request +3 -0
- data/lib/active_ldap.rb +13 -10
- data/lib/active_ldap/adapter/base.rb +159 -43
- data/lib/active_ldap/adapter/jndi.rb +175 -0
- data/lib/active_ldap/adapter/jndi_connection.rb +180 -0
- data/lib/active_ldap/adapter/ldap.rb +91 -46
- data/lib/active_ldap/adapter/ldap_ext.rb +19 -5
- data/lib/active_ldap/adapter/net_ldap.rb +52 -44
- data/lib/active_ldap/association/has_many_wrap.rb +1 -1
- data/lib/active_ldap/attributes.rb +20 -95
- data/lib/active_ldap/base.rb +195 -186
- data/lib/active_ldap/callbacks.rb +33 -0
- data/lib/active_ldap/command.rb +3 -3
- data/lib/active_ldap/connection.rb +21 -3
- data/lib/active_ldap/distinguished_name.rb +18 -11
- data/lib/active_ldap/entry_attribute.rb +78 -0
- data/lib/active_ldap/human_readable.rb +20 -0
- data/lib/active_ldap/ldif.rb +860 -10
- data/lib/active_ldap/object_class.rb +6 -4
- data/lib/active_ldap/operations.rb +129 -22
- data/lib/active_ldap/schema.rb +118 -9
- data/lib/active_ldap/schema/syntaxes.rb +33 -16
- data/lib/active_ldap/validations.rb +74 -65
- data/po/en/active-ldap.po +378 -768
- data/po/ja/active-ldap.po +935 -868
- data/rails/plugin/active_ldap/init.rb +40 -2
- data/test/al-test-utils.rb +78 -58
- data/test/command.rb +51 -1
- data/test/test-unit-ext/priority.rb +29 -6
- data/test/test_adapter.rb +21 -2
- data/test/test_attributes.rb +13 -0
- data/test/test_base.rb +51 -1
- data/test/test_connection.rb +2 -1
- data/test/test_connection_per_class.rb +55 -1
- data/test/test_connection_per_dn.rb +29 -1
- data/test/test_find.rb +73 -0
- data/test/test_ldif.rb +1829 -15
- data/test/test_load.rb +126 -0
- data/test/test_object_class.rb +23 -5
- data/test/test_schema.rb +28 -0
- data/test/test_syntax.rb +22 -11
- data/test/test_user.rb +16 -25
- data/test/test_useradd-binary.rb +1 -1
- data/test/test_usermod-binary-add-time.rb +1 -1
- data/test/test_usermod-binary-add.rb +1 -1
- data/test/test_validation.rb +100 -22
- metadata +77 -71
- data/data/locale/en/LC_MESSAGES/active-ldap.mo +0 -0
- data/data/locale/ja/LC_MESSAGES/active-ldap.mo +0 -0
- data/examples/al-admin/app/views/layouts/_flash_box.rhtml +0 -4
- data/examples/al-admin/public/stylesheets/common.css +0 -2
- data/examples/al-admin/script/breakpointer +0 -3
@@ -13,7 +13,7 @@ module ActiveLdap
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def add_class(*target_classes)
|
16
|
-
replace_class(
|
16
|
+
replace_class(classes + target_classes)
|
17
17
|
end
|
18
18
|
|
19
19
|
def ensure_recommended_classes
|
@@ -21,16 +21,18 @@ module ActiveLdap
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def remove_class(*target_classes)
|
24
|
-
replace_class(
|
24
|
+
replace_class(classes - target_classes)
|
25
25
|
end
|
26
26
|
|
27
27
|
def replace_class(*target_classes)
|
28
|
-
new_classes = target_classes.flatten.uniq
|
28
|
+
new_classes = target_classes.flatten.compact.uniq
|
29
29
|
assert_object_classes(new_classes)
|
30
30
|
if new_classes.sort != classes.sort
|
31
31
|
set_attribute('objectClass', new_classes)
|
32
|
+
clear_object_class_based_cache
|
32
33
|
end
|
33
34
|
end
|
35
|
+
alias_method(:classes=, :replace_class)
|
34
36
|
|
35
37
|
def classes
|
36
38
|
(get_attribute('objectClass', true) || []).dup
|
@@ -50,7 +52,7 @@ module ActiveLdap
|
|
50
52
|
unless invalid_classes.empty?
|
51
53
|
format = _("Value in objectClass array is not a String: %s")
|
52
54
|
invalid_classes_info = invalid_classes.collect do |invalid_class|
|
53
|
-
"#{invalid_class.class}
|
55
|
+
"#{invalid_class.class}: #{invalid_class.inspect}"
|
54
56
|
end.join(", ")
|
55
57
|
raise TypeError, format % invalid_classes_info
|
56
58
|
end
|
@@ -33,18 +33,14 @@ module ActiveLdap
|
|
33
33
|
classes = options[:classes]
|
34
34
|
|
35
35
|
value = value.first if value.is_a?(Array) and value.first.size == 1
|
36
|
-
if filter.nil? and !value.is_a?(String)
|
37
|
-
message = _("Search value must be a String: %s") % value.inspect
|
38
|
-
raise ArgumentError, message
|
39
|
-
end
|
40
36
|
|
41
37
|
_attr, value, _prefix = split_search_value(value)
|
42
38
|
attr ||= _attr || ensure_search_attribute
|
43
39
|
prefix ||= _prefix
|
44
40
|
filter ||= [attr, value]
|
45
41
|
filter = [:and, filter, *object_class_filters(classes)]
|
46
|
-
_base = options[:base]
|
47
|
-
_base
|
42
|
+
_base = options[:base] ? [options[:base]] : [prefix, base]
|
43
|
+
_base = prepare_search_base(_base)
|
48
44
|
if options.has_key?(:ldap_scope)
|
49
45
|
logger.warning do
|
50
46
|
_(":ldap_scope search option is deprecated. Use :scope instead.")
|
@@ -136,14 +132,37 @@ module ActiveLdap
|
|
136
132
|
end
|
137
133
|
end
|
138
134
|
|
135
|
+
def prepare_search_base(components)
|
136
|
+
components.compact.collect do |component|
|
137
|
+
if component.is_a?(String)
|
138
|
+
component
|
139
|
+
else
|
140
|
+
DN.new(*component).to_s
|
141
|
+
end
|
142
|
+
end.reject{|x| x.empty?}.join(",")
|
143
|
+
end
|
144
|
+
|
139
145
|
def object_class_filters(classes=nil)
|
140
|
-
(classes || required_classes).collect do |name|
|
141
|
-
|
146
|
+
expected_classes = (classes || required_classes).collect do |name|
|
147
|
+
Escape.ldap_filter_escape(name)
|
148
|
+
end
|
149
|
+
unexpected_classes = excluded_classes.collect do |name|
|
150
|
+
Escape.ldap_filter_escape(name)
|
142
151
|
end
|
152
|
+
filters = []
|
153
|
+
unless expected_classes.empty?
|
154
|
+
filters << ["objectClass", "=", *expected_classes]
|
155
|
+
end
|
156
|
+
unless unexpected_classes.empty?
|
157
|
+
filters << [:not, [:or, ["objectClass", "=", *unexpected_classes]]]
|
158
|
+
end
|
159
|
+
filters
|
143
160
|
end
|
144
161
|
|
145
162
|
def split_search_value(value)
|
146
163
|
attr = prefix = nil
|
164
|
+
return [attr, value, prefix] unless value.is_a?(String)
|
165
|
+
|
147
166
|
begin
|
148
167
|
dn = DN.parse(value)
|
149
168
|
attr, value = dn.rdns.first.to_a.first
|
@@ -204,9 +223,10 @@ module ActiveLdap
|
|
204
223
|
|
205
224
|
def find_every(options)
|
206
225
|
options = options.dup
|
207
|
-
sort_by = options.delete(:sort_by) || sort_by
|
208
|
-
order = options.delete(:order) || order
|
226
|
+
sort_by = options.delete(:sort_by) || self.sort_by
|
227
|
+
order = options.delete(:order) || self.order
|
209
228
|
limit = options.delete(:limit) if sort_by or order
|
229
|
+
options[:attributes] |= ["objectClass"] if options[:attributes]
|
210
230
|
|
211
231
|
results = search(options).collect do |dn, attrs|
|
212
232
|
instantiate([dn, attrs, {:connection => options[:connection]}])
|
@@ -302,24 +322,101 @@ module ActiveLdap
|
|
302
322
|
|
303
323
|
module LDIF
|
304
324
|
def dump(options={})
|
305
|
-
|
325
|
+
ldif = Ldif.new
|
306
326
|
options = {:base => base, :scope => scope}.merge(options)
|
307
327
|
options[:connection] ||= connection
|
308
328
|
options[:connection].search(options) do |dn, attributes|
|
309
|
-
|
329
|
+
ldif << Ldif::Record.new(dn, attributes)
|
310
330
|
end
|
311
|
-
|
331
|
+
return "" if ldif.records.empty?
|
332
|
+
ldif.to_s
|
312
333
|
end
|
313
334
|
|
314
|
-
def to_ldif(dn, attributes
|
315
|
-
|
316
|
-
|
335
|
+
def to_ldif(dn, attributes)
|
336
|
+
record = Ldif::Record.new(dn, attributes)
|
337
|
+
Ldif.new([record]).to_s
|
317
338
|
end
|
318
339
|
|
319
|
-
def load(
|
320
|
-
|
321
|
-
|
340
|
+
def load(ldif, options={})
|
341
|
+
return if ldif.blank?
|
342
|
+
Ldif.parse(ldif).each do |record|
|
343
|
+
record.load(self, options)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
module ContentRecordLoadable
|
348
|
+
def load(operator, options)
|
349
|
+
operator.add_entry(dn, attributes, options)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
Ldif::ContentRecord.send(:include, ContentRecordLoadable)
|
353
|
+
|
354
|
+
module AddRecordLoadable
|
355
|
+
def load(operator, options)
|
356
|
+
entries = attributes.collect do |key, value|
|
357
|
+
[:add, key, value]
|
358
|
+
end
|
359
|
+
options = {:controls => controls}.merge(options)
|
360
|
+
operator.modify_entry(dn, entries, options)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
Ldif::AddRecord.send(:include, AddRecordLoadable)
|
364
|
+
|
365
|
+
module DeleteRecordLoadable
|
366
|
+
def load(operator, options)
|
367
|
+
operator.delete_entry(dn, {:controls => controls}.merge(options))
|
368
|
+
end
|
322
369
|
end
|
370
|
+
Ldif::DeleteRecord.send(:include, DeleteRecordLoadable)
|
371
|
+
|
372
|
+
module ModifyNameRecordLoadable
|
373
|
+
def load(operator, options)
|
374
|
+
operator.modify_rdn_entry(dn, new_rdn, delete_old_rdn?, new_superior,
|
375
|
+
{:controls => controls}.merge(options))
|
376
|
+
end
|
377
|
+
end
|
378
|
+
Ldif::ModifyNameRecord.send(:include, ModifyNameRecordLoadable)
|
379
|
+
|
380
|
+
module ModifyRecordLoadable
|
381
|
+
def load(operator, options)
|
382
|
+
each do |operation|
|
383
|
+
operator.modify_entry(dn, operation.to_modify_entries,
|
384
|
+
{:controls => controls}.merge(options))
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
module AddOperationModifiable
|
389
|
+
def to_modify_entries
|
390
|
+
attributes.collect do |key, value|
|
391
|
+
[:add, key, value]
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
Ldif::ModifyRecord::AddOperation.send(:include, AddOperationModifiable)
|
396
|
+
|
397
|
+
module DeleteOperationModifiable
|
398
|
+
def to_modify_entries
|
399
|
+
return [[:delete, full_attribute_name, []]] if attributes.empty?
|
400
|
+
attributes.collect do |key, value|
|
401
|
+
[:delete, key, value]
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
Ldif::ModifyRecord::DeleteOperation.send(:include,
|
406
|
+
DeleteOperationModifiable)
|
407
|
+
|
408
|
+
module ReplaceOperationModifiable
|
409
|
+
def to_modify_entries
|
410
|
+
return [[:replace, full_attribute_name, []]] if attributes.empty?
|
411
|
+
attributes.collect do |key, value|
|
412
|
+
[:replace, key, value]
|
413
|
+
end
|
414
|
+
end
|
415
|
+
end
|
416
|
+
Ldif::ModifyRecord::ReplaceOperation.send(:include,
|
417
|
+
ReplaceOperationModifiable)
|
418
|
+
end
|
419
|
+
Ldif::ModifyRecord.send(:include, ModifyRecordLoadable)
|
323
420
|
end
|
324
421
|
|
325
422
|
module Delete
|
@@ -349,8 +446,12 @@ module ActiveLdap
|
|
349
446
|
targets = targets.collect do |target|
|
350
447
|
ensure_dn_attribute(ensure_base(target))
|
351
448
|
end
|
449
|
+
delete_entry(targets, options)
|
450
|
+
end
|
451
|
+
|
452
|
+
def delete_entry(dn, options={})
|
352
453
|
options[:connection] ||= connection
|
353
|
-
options[:connection].delete(
|
454
|
+
options[:connection].delete(dn, options)
|
354
455
|
end
|
355
456
|
|
356
457
|
def delete_all(filter=nil, options={})
|
@@ -370,8 +471,8 @@ module ActiveLdap
|
|
370
471
|
|
371
472
|
module Update
|
372
473
|
def add_entry(dn, attributes, options={})
|
373
|
-
unnormalized_attributes = attributes.collect do |
|
374
|
-
[
|
474
|
+
unnormalized_attributes = attributes.collect do |key, value|
|
475
|
+
[:add, key, unnormalize_attribute(key, value)]
|
375
476
|
end
|
376
477
|
options[:connection] ||= connection
|
377
478
|
options[:connection].add(dn, unnormalized_attributes, options)
|
@@ -385,6 +486,12 @@ module ActiveLdap
|
|
385
486
|
options[:connection].modify(dn, unnormalized_attributes, options)
|
386
487
|
end
|
387
488
|
|
489
|
+
def modify_rdn_entry(dn, new_rdn, delete_old_rdn, new_superior, options={})
|
490
|
+
options[:connection] ||= connection
|
491
|
+
options[:connection].modify_rdn(dn, new_rdn, delete_old_rdn,
|
492
|
+
new_superior, options)
|
493
|
+
end
|
494
|
+
|
388
495
|
def update(dn, attributes, options={})
|
389
496
|
if dn.is_a?(Array)
|
390
497
|
i = -1
|
data/lib/active_ldap/schema.rb
CHANGED
@@ -349,6 +349,9 @@ module ActiveLdap
|
|
349
349
|
end
|
350
350
|
|
351
351
|
class Attribute < Entry
|
352
|
+
include GetTextSupport
|
353
|
+
include HumanReadable
|
354
|
+
|
352
355
|
attr_reader :super_attribute
|
353
356
|
def initialize(name, schema)
|
354
357
|
super(name, schema, "attributeTypes")
|
@@ -387,7 +390,7 @@ module ActiveLdap
|
|
387
390
|
end
|
388
391
|
|
389
392
|
def syntax
|
390
|
-
|
393
|
+
@derived_syntax
|
391
394
|
end
|
392
395
|
|
393
396
|
def valid?(value)
|
@@ -395,7 +398,14 @@ module ActiveLdap
|
|
395
398
|
end
|
396
399
|
|
397
400
|
def validate(value)
|
398
|
-
|
401
|
+
error_info = validate_each_value(value)
|
402
|
+
return error_info if error_info
|
403
|
+
begin
|
404
|
+
normalize_value(value)
|
405
|
+
nil
|
406
|
+
rescue AttributeValueInvalid
|
407
|
+
[$!.message]
|
408
|
+
end
|
399
409
|
end
|
400
410
|
|
401
411
|
def type_cast(value)
|
@@ -403,13 +413,21 @@ module ActiveLdap
|
|
403
413
|
end
|
404
414
|
|
405
415
|
def normalize_value(value)
|
406
|
-
|
416
|
+
normalize_value_internal(value, false)
|
407
417
|
end
|
408
418
|
|
409
419
|
def syntax_description
|
410
420
|
send_to_syntax(nil, :description)
|
411
421
|
end
|
412
422
|
|
423
|
+
def human_attribute_name
|
424
|
+
self.class.human_attribute_name(self)
|
425
|
+
end
|
426
|
+
|
427
|
+
def human_attribute_description
|
428
|
+
self.class.human_attribute_description(self)
|
429
|
+
end
|
430
|
+
|
413
431
|
private
|
414
432
|
def attribute(attribute_name, name=@name)
|
415
433
|
@schema.attribute_type(name, attribute_name)
|
@@ -429,18 +447,15 @@ module ActiveLdap
|
|
429
447
|
if @syntax
|
430
448
|
@binary_required = @syntax.binary_transfer_required?
|
431
449
|
@binary = (@binary_required or !@syntax.human_readable?)
|
450
|
+
@derived_syntax = @syntax
|
432
451
|
else
|
433
452
|
@binary_required = false
|
434
453
|
@binary = false
|
454
|
+
@derived_syntax = nil
|
455
|
+
@derived_syntax = @super_attribute.syntax if @super_attribute
|
435
456
|
end
|
436
457
|
end
|
437
458
|
|
438
|
-
def derived_syntax
|
439
|
-
return @syntax if @syntax
|
440
|
-
return @super_attribute.syntax if @super_attribute
|
441
|
-
nil
|
442
|
-
end
|
443
|
-
|
444
459
|
def send_to_syntax(default_value, method_name, *args)
|
445
460
|
_syntax = syntax
|
446
461
|
if _syntax
|
@@ -449,6 +464,100 @@ module ActiveLdap
|
|
449
464
|
default_value
|
450
465
|
end
|
451
466
|
end
|
467
|
+
|
468
|
+
def validate_each_value(value, option=nil)
|
469
|
+
failed_reason = nil
|
470
|
+
case value
|
471
|
+
when Hash
|
472
|
+
original_option = option
|
473
|
+
value.each do |sub_option, val|
|
474
|
+
opt = [original_option, sub_option].compact.join(";")
|
475
|
+
failed_reason, option = validate_each_value(val, opt)
|
476
|
+
break if failed_reason
|
477
|
+
end
|
478
|
+
when Array
|
479
|
+
original_option = option
|
480
|
+
value.each do |val|
|
481
|
+
failed_reason, option = validate_each_value(val, original_option)
|
482
|
+
break if failed_reason
|
483
|
+
end
|
484
|
+
else
|
485
|
+
failed_reason = send_to_syntax(nil, :validate, value)
|
486
|
+
end
|
487
|
+
return nil if failed_reason.nil?
|
488
|
+
[failed_reason, option]
|
489
|
+
end
|
490
|
+
|
491
|
+
def normalize_value_internal(value, have_binary_mark)
|
492
|
+
case value
|
493
|
+
when Array
|
494
|
+
normalize_array_value(value, have_binary_mark)
|
495
|
+
when Hash
|
496
|
+
normalize_hash_value(value, have_binary_mark)
|
497
|
+
else
|
498
|
+
if value.blank?
|
499
|
+
value = []
|
500
|
+
else
|
501
|
+
value = send_to_syntax(value, :normalize_value, value)
|
502
|
+
end
|
503
|
+
if !have_binary_mark and binary_required?
|
504
|
+
[{'binary' => value}]
|
505
|
+
else
|
506
|
+
value.is_a?(Array) ? value : [value]
|
507
|
+
end
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
def normalize_array_value(value, have_binary_mark)
|
512
|
+
if single_value? and value.reject {|v| v.is_a?(Hash)}.size > 1
|
513
|
+
format = _("Attribute %s can only have a single value: %s")
|
514
|
+
message = format % [human_attribute_name, value.inspect]
|
515
|
+
raise AttributeValueInvalid.new(self, value, message)
|
516
|
+
end
|
517
|
+
if value.empty?
|
518
|
+
if !have_binary_mark and binary_required?
|
519
|
+
[{'binary' => value}]
|
520
|
+
else
|
521
|
+
value
|
522
|
+
end
|
523
|
+
else
|
524
|
+
value.collect do |entry|
|
525
|
+
normalize_value_internal(entry, have_binary_mark)[0]
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
def normalize_hash_value(value, have_binary_mark)
|
531
|
+
if value.size > 1
|
532
|
+
format = _("Attribute %s: Hash must have one key-value pair only: %s")
|
533
|
+
message = format % [human_attribute_name, value.inspect]
|
534
|
+
raise AttributeValueInvalid.new(self, value, message)
|
535
|
+
end
|
536
|
+
|
537
|
+
if !have_binary_mark and binary_required? and !have_binary_key?(value)
|
538
|
+
[append_binary_key(value)]
|
539
|
+
else
|
540
|
+
key = value.keys[0]
|
541
|
+
have_binary_mark ||= key == "binary"
|
542
|
+
[{key => normalize_value_internal(value.values[0], have_binary_mark)}]
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
def have_binary_key?(hash)
|
547
|
+
key, value = hash.to_a[0]
|
548
|
+
return true if key == "binary"
|
549
|
+
return have_binary_key?(value) if value.is_a?(Hash)
|
550
|
+
false
|
551
|
+
end
|
552
|
+
|
553
|
+
def append_binary_key(hash)
|
554
|
+
key, value = hash.to_a[0]
|
555
|
+
if value.is_a?(Hash)
|
556
|
+
append_binary_key(value)
|
557
|
+
else
|
558
|
+
hash.merge(key => {"binary" => value})
|
559
|
+
end
|
560
|
+
end
|
452
561
|
end
|
453
562
|
|
454
563
|
class ObjectClass < Entry
|
@@ -165,12 +165,32 @@ module ActiveLdap
|
|
165
165
|
|
166
166
|
class GeneralizedTime < Base
|
167
167
|
SYNTAXES["1.3.6.1.4.1.1466.115.121.1.24"] = self
|
168
|
+
FORMAT = /\A
|
169
|
+
(\d{4,4})?
|
170
|
+
(\d{2,2})?
|
171
|
+
(\d{2,2})?
|
172
|
+
(\d{2,2})?
|
173
|
+
(\d{2,2})?
|
174
|
+
(\d{2,2})?
|
175
|
+
([,.]\d+)?
|
176
|
+
([+-]\d{4,4}|Z)?
|
177
|
+
\z/x
|
168
178
|
|
169
179
|
def type_cast(value)
|
170
180
|
return value if value.nil? or value.is_a?(Time)
|
171
|
-
|
172
|
-
|
173
|
-
|
181
|
+
match_data = FORMAT.match(value)
|
182
|
+
if match_data
|
183
|
+
required_components = match_data.to_a[1, 6]
|
184
|
+
return value if required_components.any?(&:nil?)
|
185
|
+
year, month, day, hour, minute, second =
|
186
|
+
required_components.collect(&:to_i)
|
187
|
+
fraction = match_data[-2]
|
188
|
+
fraction = fraction.to_f if fraction
|
189
|
+
time_zone = match_data[-1]
|
190
|
+
Time.send(:make_time,
|
191
|
+
year, month, day, hour, minute, second, fraction,
|
192
|
+
time_zone, Time.now)
|
193
|
+
else
|
174
194
|
value
|
175
195
|
end
|
176
196
|
end
|
@@ -190,20 +210,12 @@ module ActiveLdap
|
|
190
210
|
|
191
211
|
private
|
192
212
|
def validate_normalized_value(value, original_value)
|
193
|
-
match_data =
|
194
|
-
(\d{4,4})?
|
195
|
-
(\d{2,2})?
|
196
|
-
(\d{2,2})?
|
197
|
-
(\d{2,2})?
|
198
|
-
(\d{2,2})?
|
199
|
-
(\d{2,2}(?:[,.]\d+)?)?
|
200
|
-
([+-]\d{4,4}|Z)?
|
201
|
-
\z/x.match(value)
|
213
|
+
match_data = FORMAT.match(value)
|
202
214
|
if match_data
|
203
|
-
year, month, day, hour, minute, second, time_zone =
|
215
|
+
year, month, day, hour, minute, second, fraction, time_zone =
|
204
216
|
match_data.to_a[1..-1]
|
205
217
|
missing_components = []
|
206
|
-
%w(year month day hour minute).each do |component|
|
218
|
+
%w(year month day hour minute second).each do |component|
|
207
219
|
missing_components << component unless eval(component)
|
208
220
|
end
|
209
221
|
if missing_components.empty?
|
@@ -231,7 +243,7 @@ module ActiveLdap
|
|
231
243
|
end
|
232
244
|
|
233
245
|
def normalize_value(value)
|
234
|
-
if value.is_a?(Integer)
|
246
|
+
if value.is_a?(::Integer)
|
235
247
|
value.to_s
|
236
248
|
else
|
237
249
|
value
|
@@ -309,7 +321,12 @@ module ActiveLdap
|
|
309
321
|
DN.parse("#{value}=dummy")
|
310
322
|
nil
|
311
323
|
rescue DistinguishedNameInvalid
|
312
|
-
|
324
|
+
reason = $!.reason
|
325
|
+
if reason
|
326
|
+
_("%s is invalid OID format: %s") % [original_value.inspect, reason]
|
327
|
+
else
|
328
|
+
_("%s is invalid OID format") % original_value.inspect
|
329
|
+
end
|
313
330
|
end
|
314
331
|
end
|
315
332
|
|