activeldap 4.0.5 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +3 -1
  3. data/doc/text/development.md +26 -0
  4. data/doc/text/{news.textile → news.md} +451 -241
  5. data/doc/text/{rails.textile → rails.md} +44 -33
  6. data/doc/text/{tutorial.textile → tutorial.md} +177 -185
  7. data/lib/active_ldap/adapter/base.rb +40 -17
  8. data/lib/active_ldap/adapter/jndi.rb +21 -9
  9. data/lib/active_ldap/adapter/jndi_connection.rb +83 -20
  10. data/lib/active_ldap/adapter/ldap.rb +50 -28
  11. data/lib/active_ldap/adapter/ldap_ext.rb +32 -13
  12. data/lib/active_ldap/adapter/net_ldap.rb +26 -24
  13. data/lib/active_ldap/associations.rb +5 -5
  14. data/lib/active_ldap/attribute_methods/before_type_cast.rb +1 -1
  15. data/lib/active_ldap/attribute_methods/dirty.rb +4 -7
  16. data/lib/active_ldap/attribute_methods/query.rb +1 -1
  17. data/lib/active_ldap/attribute_methods/read.rb +5 -1
  18. data/lib/active_ldap/attribute_methods/write.rb +1 -1
  19. data/lib/active_ldap/attribute_methods.rb +1 -2
  20. data/lib/active_ldap/base.rb +61 -14
  21. data/lib/active_ldap/callbacks.rb +7 -8
  22. data/lib/active_ldap/configuration.rb +27 -3
  23. data/lib/active_ldap/connection.rb +4 -22
  24. data/lib/active_ldap/distinguished_name.rb +1 -1
  25. data/lib/active_ldap/human_readable.rb +5 -4
  26. data/lib/active_ldap/operations.rb +24 -4
  27. data/lib/active_ldap/persistence.rb +3 -2
  28. data/lib/active_ldap/populate.rb +5 -3
  29. data/lib/active_ldap/railties/controller_runtime.rb +1 -2
  30. data/lib/active_ldap/schema/syntaxes.rb +8 -4
  31. data/lib/active_ldap/validations.rb +12 -4
  32. data/lib/active_ldap/version.rb +1 -1
  33. data/lib/active_ldap.rb +0 -7
  34. data/po/en/active-ldap.po +2 -2
  35. data/po/ja/active-ldap.po +3 -3
  36. data/test/add-phonetic-attribute-options-to-slapd.ldif +3 -3
  37. data/test/al-test-utils.rb +125 -38
  38. data/test/command.rb +13 -16
  39. data/test/enable-dynamic-groups.ldif +22 -0
  40. data/test/enable-start-tls.ldif +27 -0
  41. data/test/run-test.rb +0 -4
  42. data/test/test_base.rb +223 -22
  43. data/test/test_base_per_instance.rb +33 -1
  44. data/test/test_callback.rb +10 -8
  45. data/test/test_connection.rb +4 -0
  46. data/test/test_connection_per_class.rb +34 -0
  47. data/test/test_dn.rb +7 -0
  48. data/test/test_entry.rb +1 -0
  49. data/test/test_find.rb +14 -3
  50. data/test/test_supported_control.rb +1 -1
  51. data/test/test_syntax.rb +5 -0
  52. data/test/test_validation.rb +28 -15
  53. metadata +23 -24
  54. data/README.textile +0 -141
  55. data/doc/text/development.textile +0 -54
  56. data/lib/active_ldap/timeout.rb +0 -75
  57. data/lib/active_ldap/timeout_stub.rb +0 -17
@@ -9,8 +9,7 @@ module ActiveLdap
9
9
  def save(*) #:nodoc:
10
10
  succeeded = super
11
11
  if succeeded
12
- @previously_changed = changes
13
- @changed_attributes.clear
12
+ changes_applied
14
13
  end
15
14
  succeeded
16
15
  end
@@ -18,20 +17,18 @@ module ActiveLdap
18
17
  # Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
19
18
  def save!(*) #:nodoc:
20
19
  super.tap do
21
- @previously_changed = changes
22
- @changed_attributes.clear
20
+ changes_applied
23
21
  end
24
22
  end
25
23
 
26
24
  # <tt>reload</tt> the record and clears changed attributes.
27
25
  def reload(*) #:nodoc:
28
26
  super.tap do
29
- @previously_changed.clear
30
- @changed_attributes.clear
27
+ clear_changes_information
31
28
  end
32
29
  end
33
30
 
34
- protected
31
+ private
35
32
  def set_attribute(name, value)
36
33
  if name and name != "objectClass"
37
34
  attribute_will_change!(name) unless value == get_attribute(name)
@@ -8,7 +8,7 @@ module ActiveLdap
8
8
  attribute_method_suffix '?'
9
9
  end
10
10
 
11
- protected
11
+ private
12
12
  def get_attribute_as_query(name, force_array=false)
13
13
  name, value = get_attribute_before_type_cast(name, force_array)
14
14
  if force_array
@@ -3,11 +3,15 @@ module ActiveLdap
3
3
  module Read
4
4
  extend ActiveSupport::Concern
5
5
 
6
- protected
6
+ private
7
7
  def attribute(attr, *args)
8
8
  return get_attribute(attr, args.first)
9
9
  end
10
10
 
11
+ def _read_attribute(name)
12
+ get_attribute(name)
13
+ end
14
+
11
15
  # get_attribute
12
16
  #
13
17
  # Return the value of the attribute called by method_missing?
@@ -7,7 +7,7 @@ module ActiveLdap
7
7
  attribute_method_suffix '='
8
8
  end
9
9
 
10
- protected
10
+ private
11
11
  def attribute=(attr, *args)
12
12
  return set_attribute(attr, args.first)
13
13
  end
@@ -13,8 +13,7 @@ module ActiveLdap
13
13
  end.flatten
14
14
  end
15
15
 
16
- protected
17
-
16
+ private
18
17
  # overiding ActiveModel::AttributeMethods
19
18
  def attribute_method?(method_name)
20
19
  have_attribute?(method_name, ['objectClass'])
@@ -32,6 +32,7 @@
32
32
  require 'English'
33
33
  require 'thread'
34
34
  require 'erb'
35
+ require 'set'
35
36
 
36
37
  module ActiveLdap
37
38
  # OO-interface to LDAP assuming pam/nss_ldap-style organization with
@@ -330,6 +331,7 @@ module ActiveLdap
330
331
  class_local_attr_accessor true, :dn_attribute, :scope, :sort_by, :order
331
332
  class_local_attr_accessor true, :required_classes, :recommended_classes
332
333
  class_local_attr_accessor true, :excluded_classes
334
+ class_local_attr_accessor false, :sub_classes
333
335
 
334
336
  class << self
335
337
  # Hide new in Base
@@ -340,6 +342,7 @@ module ActiveLdap
340
342
  sub_class.module_eval do
341
343
  include GetTextSupport
342
344
  end
345
+ (self.sub_classes ||= []) << sub_class
343
346
  end
344
347
 
345
348
  # Set LDAP connection configuration up. It doesn't connect
@@ -548,6 +551,20 @@ module ActiveLdap
548
551
  defaults.first || name || to_s
549
552
  end
550
553
 
554
+ protected
555
+ def find_real_class(object_classes)
556
+ (sub_classes || []).each do |sub_class|
557
+ real_class = sub_class.find_real_class(object_classes)
558
+ return real_class if real_class
559
+ end
560
+
561
+ if object_classes.superset?(Set.new(classes))
562
+ self
563
+ else
564
+ nil
565
+ end
566
+ end
567
+
551
568
  private
552
569
  def inspect_attributes(attributes)
553
570
  inspected_attribute_names = {}
@@ -594,12 +611,19 @@ module ActiveLdap
594
611
  def instantiate(args)
595
612
  dn, attributes, options = args
596
613
  options ||= {}
597
- if self.class == Class
598
- klass = self.ancestors[0].to_s.split(':').last
599
- real_klass = self.ancestors[0]
614
+
615
+ object_classes_raw =
616
+ attributes["objectClass"] ||
617
+ attributes["objectclass"] ||
618
+ []
619
+ if sub_classes.nil? or object_classes_raw.empty?
620
+ real_klass = self
600
621
  else
601
- klass = self.class.to_s.split(':').last
602
- real_klass = self.class
622
+ object_classes = Set.new
623
+ object_classes_raw.each do |object_class_raw|
624
+ object_classes << schema.object_class(object_class_raw)
625
+ end
626
+ real_klass = find_real_class(object_classes) || self
603
627
  end
604
628
 
605
629
  obj = real_klass.allocate
@@ -827,6 +851,8 @@ module ActiveLdap
827
851
 
828
852
  _schema = _local_entry_attribute = nil
829
853
  targets = sanitize_for_mass_assignment(new_attributes)
854
+ have_dn = false
855
+ dn_value = nil
830
856
  targets.each do |key, value|
831
857
  setter = "#{key}="
832
858
  unless respond_to?(setter)
@@ -836,8 +862,15 @@ module ActiveLdap
836
862
  _local_entry_attribute ||= local_entry_attribute
837
863
  _local_entry_attribute.register(attribute)
838
864
  end
839
- 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
840
872
  end
873
+ self.dn = dn_value if have_dn
841
874
  end
842
875
 
843
876
  def to_ldif_record
@@ -922,9 +955,7 @@ module ActiveLdap
922
955
  def clear_object_class_based_cache
923
956
  @entry_attribute = nil
924
957
  @real_names = {}
925
- @changed_attributes.reject! do |key, _|
926
- not attribute_method?(key)
927
- end
958
+ clear_changes_information
928
959
  end
929
960
 
930
961
  def clear_removed_attributes_data(removed_attributes)
@@ -1093,7 +1124,7 @@ module ActiveLdap
1093
1124
  end
1094
1125
  set_attribute(key, value)
1095
1126
  end
1096
- @changed_attributes.clear
1127
+ clear_changes_information
1097
1128
  end
1098
1129
  private :initialize_attributes
1099
1130
 
@@ -1143,8 +1174,6 @@ module ActiveLdap
1143
1174
  @dn_split_value = nil
1144
1175
  @connection ||= nil
1145
1176
  @_hashing = false
1146
- @previously_changed = []
1147
- @changed_attributes = {}
1148
1177
  clear_connection_based_cache
1149
1178
  end
1150
1179
 
@@ -1261,6 +1290,7 @@ module ActiveLdap
1261
1290
  end
1262
1291
 
1263
1292
  def compute_base
1293
+ ensure_update_dn
1264
1294
  base_of_class = self.class.base
1265
1295
  if @base_value.nil?
1266
1296
  base_of_class
@@ -1352,7 +1382,14 @@ module ActiveLdap
1352
1382
  if k == _dn_attribute
1353
1383
  new_dn_value = value[0]
1354
1384
  else
1355
- attributes.push([:replace, k, value])
1385
+ if (v.size == 1 and value.size == 1) or force_replace?(k)
1386
+ attributes.push([:replace, k, value])
1387
+ else
1388
+ removed_values = v - value
1389
+ added_values = value - v
1390
+ attributes.push([:delete, k, removed_values]) unless removed_values.empty?
1391
+ attributes.push([:add, k, added_values]) unless added_values.empty?
1392
+ end
1356
1393
  end
1357
1394
  end
1358
1395
 
@@ -1366,12 +1403,22 @@ module ActiveLdap
1366
1403
  # Detect subtypes and account for them
1367
1404
  # REPLACE will function like ADD, but doesn't hit EQUALITY problems
1368
1405
  # TODO: Added equality(attr) to Schema
1369
- attributes.push([:replace, k, value])
1406
+ if force_replace?(k)
1407
+ attributes.push([:replace, k, value])
1408
+ else
1409
+ attributes.push([:add, k, value])
1410
+ end
1370
1411
  end
1371
1412
 
1372
1413
  [new_dn_value, attributes]
1373
1414
  end
1374
1415
 
1416
+ def force_replace?(k)
1417
+ attribute = schema.attribute(k)
1418
+ attribute.single_value? or
1419
+ attribute.binary? # TODO: this should probably explicitly check for fields with no equality matching rule instead
1420
+ end
1421
+
1375
1422
  def collect_all_attributes(data)
1376
1423
  dn_attr = dn_attribute
1377
1424
  dn_value = data[dn_attr]
@@ -14,13 +14,12 @@ module ActiveLdap
14
14
  included do
15
15
  extend ActiveModel::Callbacks
16
16
  include ActiveModel::Validations::Callbacks
17
-
17
+ singleton_class.class_eval do
18
+ prepend CallbackedInstantiatable
19
+ end
20
+
18
21
  define_model_callbacks :initialize, :find, :touch, :only => :after
19
22
  define_model_callbacks :save, :create, :update, :destroy
20
-
21
- class << self
22
- alias_method_chain :instantiate, :callbacks
23
- end
24
23
  end
25
24
 
26
25
  module ClassMethods
@@ -33,9 +32,9 @@ module ActiveLdap
33
32
  end
34
33
  end
35
34
 
36
- module ClassMethods
37
- def instantiate_with_callbacks(record)
38
- object = instantiate_without_callbacks(record)
35
+ module CallbackedInstantiatable
36
+ def instantiate(record)
37
+ object = super(record)
39
38
  object.run_callbacks(:find)
40
39
  object.run_callbacks(:initialize)
41
40
  object
@@ -27,6 +27,7 @@ module ActiveLdap
27
27
  DEFAULT_CONFIG[:host] = '127.0.0.1'
28
28
  DEFAULT_CONFIG[:port] = nil
29
29
  DEFAULT_CONFIG[:method] = :plain # :ssl, :tls, :plain allowed
30
+ DEFAULT_CONFIG[:tls_options] = nil
30
31
 
31
32
  DEFAULT_CONFIG[:bind_dn] = nil
32
33
  DEFAULT_CONFIG[:password_block] = nil
@@ -47,6 +48,15 @@ module ActiveLdap
47
48
  DEFAULT_CONFIG[:retry_on_timeout] = true
48
49
  DEFAULT_CONFIG[:follow_referrals] = true
49
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
+
50
60
  DEFAULT_CONFIG[:logger] = nil
51
61
 
52
62
  module ClassMethods
@@ -91,8 +101,8 @@ module ActiveLdap
91
101
  @@defined_configurations
92
102
  end
93
103
 
94
- def remove_configuration_by_configuration(config)
95
- @@defined_configurations.delete_if {|key, value| value == config}
104
+ def remove_configuration_by_key(key)
105
+ @@defined_configurations.delete(key)
96
106
  end
97
107
 
98
108
  CONNECTION_CONFIGURATION_KEYS = [:uri, :base, :adapter]
@@ -102,8 +112,22 @@ module ActiveLdap
102
112
  end
103
113
  end
104
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
+
105
129
  def merge_configuration(user_configuration, target=self)
106
- configuration = default_configuration
130
+ configuration = parent_configuration(target).dup
107
131
  prepare_configuration(user_configuration).each do |key, value|
108
132
  case key
109
133
  when :base
@@ -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] ||= {}
@@ -135,7 +135,7 @@ module ActiveLdap
135
135
  end
136
136
  config = configuration(key)
137
137
  conn = active_connections[key]
138
- remove_configuration_by_configuration(config)
138
+ remove_configuration_by_key(key)
139
139
  active_connections.delete_if {|_key, value| value == conn}
140
140
  conn.disconnect! if conn
141
141
  config
@@ -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)
@@ -197,27 +197,9 @@ module ActiveLdap
197
197
  if Object.respond_to?(:java)
198
198
  "jndi"
199
199
  else
200
- ruby_ldap_available = false
201
- $LOAD_PATH.each do |path|
202
- if File.exist?(File.join(path, "ldap", "ldif.rb"))
203
- ruby_ldap_available = true
204
- break
205
- end
206
- end
207
- if !ruby_ldap_available and Object.const_defined?(:Gem)
208
- ruby_ldap_available = gem_available?("ruby-ldap")
209
- end
210
- if ruby_ldap_available
211
- "ldap"
212
- else
213
- "net-ldap"
214
- end
200
+ "net-ldap"
215
201
  end
216
202
  end
217
-
218
- def gem_available?(name)
219
- not Gem::Specification.find_all_by_name(name).empty?
220
- end
221
203
  end
222
204
 
223
205
  def setup_connection(config=nil)
@@ -62,7 +62,7 @@ module ActiveLdap
62
62
 
63
63
  HEX_PAIR = "(?:[\\da-fA-F]{2})"
64
64
  STRING_CHARS_RE = /[^,=\+<>\#;\\\"]*/ #
65
- PAIR_RE = /\\([,=\+<>\#;]|\\|\"|(#{HEX_PAIR}))/ #
65
+ PAIR_RE = /\\([,=\+<>\#;]|\\|\"| |(#{HEX_PAIR}))/ #
66
66
  HEX_STRING_RE = /\#(#{HEX_PAIR}+)/ #
67
67
  def scan_attribute_value(scanner)
68
68
  if scanner.scan(HEX_STRING_RE)
@@ -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
  }
@@ -291,6 +308,9 @@ module ActiveLdap
291
308
  offset = options.delete(:offset) || offset
292
309
  options[:attributes] = options.delete(:attributes) || ['*']
293
310
  options[:attributes] |= ['objectClass']
311
+ if options.delete(:include_operational_attributes)
312
+ options[:attributes] |= ["+"]
313
+ end
294
314
  results = search(options).collect do |dn, attrs|
295
315
  instantiate([dn, attrs, {:connection => options[:connection]}])
296
316
  end
@@ -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?
@@ -1,9 +1,11 @@
1
1
  module ActiveLdap
2
2
  module Populate
3
3
  module_function
4
- def ensure_base(base_class=nil)
4
+ def ensure_base(base_class=nil, options={})
5
5
  base_class ||= Base
6
6
  return unless base_class.search(:scope => :base).empty?
7
+ dc_base_class = options[:dc_base_class] || base_class
8
+ ou_base_class = options[:ou_base_class] || base_class
7
9
 
8
10
  base_dn = DN.parse(base_class.base)
9
11
  suffixes = []
@@ -15,11 +17,11 @@ module ActiveLdap
15
17
  begin
16
18
  case name.downcase
17
19
  when "dc"
18
- ensure_dc(value, prefix, base_class)
20
+ ensure_dc(value, prefix, dc_base_class)
19
21
  when "ou"
20
22
  ensure_ou(value,
21
23
  :base => prefix,
22
- :base_class => base_class)
24
+ :base_class => ou_base_class)
23
25
  end
24
26
  rescue ActiveLdap::OperationNotPermitted
25
27
  end
@@ -6,8 +6,7 @@ module ActiveLdap
6
6
  module ControllerRuntime #:nodoc:
7
7
  extend ActiveSupport::Concern
8
8
 
9
- protected
10
-
9
+ private
11
10
  attr_internal :ldap_runtime
12
11
 
13
12
  def process_action(action, *args)
@@ -192,11 +192,11 @@ module ActiveLdap
192
192
  fraction = fraction.to_f if fraction
193
193
  time_zone = match_data[-1]
194
194
  arguments = [
195
- year, month, day, hour, minute, second, fraction, time_zone,
195
+ value, year, month, day, hour, minute, second, fraction, time_zone,
196
196
  Time.now,
197
197
  ]
198
- if Time.method(:make_time).arity == 10
199
- arguments.unshift(value)
198
+ if Time.method(:make_time).arity == 11
199
+ arguments[2, 0] = nil
200
200
  end
201
201
  begin
202
202
  Time.send(:make_time, *arguments)
@@ -222,7 +222,11 @@ module ActiveLdap
222
222
  if value.gmt?
223
223
  normalized_value + "Z"
224
224
  else
225
- normalized_value + ("%+03d%02d" % value.gmtoff.divmod(3600))
225
+ # for timezones with non-zero minutes, such as IST which is +0530,
226
+ # divmod(3600) will give wrong value of 1800
227
+
228
+ offset = value.gmtoff / 60 # in minutes
229
+ normalized_value + ("%+03d%02d" % offset.divmod(60))
226
230
  end
227
231
  else
228
232
  value
@@ -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 = "4.0.5"
2
+ VERSION = "6.1.0"
3
3
  end
data/lib/active_ldap.rb CHANGED
@@ -1,4 +1,3 @@
1
- require "rubygems"
2
1
  require "active_model"
3
2
  require "active_support/core_ext"
4
3
 
@@ -8,12 +7,6 @@ module ActiveLdap
8
7
  autoload :Command, "active_ldap/command"
9
8
  end
10
9
 
11
- if RUBY_PLATFORM.match('linux')
12
- require 'active_ldap/timeout'
13
- else
14
- require 'active_ldap/timeout_stub'
15
- end
16
-
17
10
  require 'active_ldap/get_text'
18
11
 
19
12
  require 'active_ldap/compatible'
data/po/en/active-ldap.po CHANGED
@@ -7,7 +7,7 @@ msgid ""
7
7
  msgstr ""
8
8
  "Project-Id-Version: Ruby/ActiveLdap 1.1.1\n"
9
9
  "POT-Creation-Date: 2009-08-04 23:26+0900\n"
10
- "PO-Revision-Date: 2009-02-25 08:40+0900\n"
10
+ "PO-Revision-Date: 2016-05-13 21:52+0900\n"
11
11
  "Last-Translator: Kouhei Sutou <kou@cozmixng.org>\n"
12
12
  "Language-Team: English\n"
13
13
  "MIME-Version: 1.0\n"
@@ -3524,7 +3524,7 @@ msgstr ""
3524
3524
 
3525
3525
  #: lib/active_ldap/adapter/base.rb:579
3526
3526
  msgid ""
3527
- "Reconnect to server failed: %s\n"
3527
+ "Reconnect to server failed: %s: %s\n"
3528
3528
  "Reconnect to server failed backtrace:\n"
3529
3529
  "%s"
3530
3530
  msgstr ""
data/po/ja/active-ldap.po CHANGED
@@ -7,7 +7,7 @@ msgid ""
7
7
  msgstr ""
8
8
  "Project-Id-Version: Ruby/ActiveLdap 1.1.1\n"
9
9
  "POT-Creation-Date: 2009-08-04 23:26+0900\n"
10
- "PO-Revision-Date: 2009-08-04 23:28+0900\n"
10
+ "PO-Revision-Date: 2016-05-13 21:53+0900\n"
11
11
  "Last-Translator: Kouhei Sutou <kou@cozmixng.org>\n"
12
12
  "Language-Team: Japanese\n"
13
13
  "MIME-Version: 1.0\n"
@@ -3533,11 +3533,11 @@ msgstr "再接続を試みています"
3533
3533
 
3534
3534
  #: lib/active_ldap/adapter/base.rb:579
3535
3535
  msgid ""
3536
- "Reconnect to server failed: %s\n"
3536
+ "Reconnect to server failed: %s: %s\n"
3537
3537
  "Reconnect to server failed backtrace:\n"
3538
3538
  "%s"
3539
3539
  msgstr ""
3540
- "サーバへの再接続が失敗しました: %s\n"
3540
+ "サーバへの再接続が失敗しました: %s: %s\n"
3541
3541
  "サーバへの再接続失敗時のバックトレース:\n"
3542
3542
  "%s"
3543
3543
 
@@ -1,6 +1,6 @@
1
- # Your LDAP server need to accept 'phonetic' attribute option for test.
2
- # This is a LDIF file for OpenLDAP to do the confiugration.
3
- # You can use this file by the following command linne on Debian GNU/Linux
1
+ # Your LDAP server needs to accept 'phonetic' attribute option 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
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