activeldap 3.2.3 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -9,4 +9,7 @@ group :test do
9
9
  platforms :mri_18, :mri_19 do
10
10
  gem "ruby-ldap"
11
11
  end
12
+ platforms :jruby do
13
+ gem "jruby-openssl"
14
+ end
12
15
  end
data/README.textile CHANGED
@@ -3,13 +3,13 @@ h1. ActiveLdap
3
3
  A ruby library for object-oriented LDAP interface.
4
4
 
5
5
  * Copyright (C) 2004-2006 Will Drewry _<will@alum.bu.edu>_
6
- * Copyright (C) 2006-2011 Kouhei Sutou _<kou@clear-code.com>_
6
+ * Copyright (C) 2006-2013 Kouhei Sutou _<kou@clear-code.com>_
7
7
 
8
8
  h2. Description
9
9
 
10
10
  'ActiveLdap' is a ruby library which provides a clean
11
11
  objected oriented interface to LDAP library. It was
12
- inspired by ActivRecord. This is not nearly as clean or as
12
+ inspired by ActiveRecord. This is not nearly as clean or as
13
13
  flexible as ActiveRecord, but it is still trivial to define
14
14
  new objects and manipulate them with minimal difficulty.
15
15
 
@@ -20,7 +20,7 @@ h2. Prerequisites
20
20
 
21
21
  - Ruby intepreter :=
22
22
  One of them:
23
- * "Ruby":http://www.ruby-lang.org (1.8.x or 1.9.x)
23
+ * "Ruby":http://www.ruby-lang.org (1.9.3 or 2.0.x)
24
24
  * "JRuby":http://www.jruby.org/
25
25
 
26
26
  See the above links for installation.
@@ -45,7 +45,7 @@ h2. Notes
45
45
 
46
46
  h2. Rails
47
47
 
48
- See "Rails":file.rails.html page for Rails integration.
48
+ See "Rails":doc/text/rails.textile page for Rails integration.
49
49
 
50
50
  h2. Licence
51
51
 
@@ -1,5 +1,55 @@
1
1
  h1. News
2
2
 
3
+ h2(#4-0-0). 4.0.0: 2013-07-13
4
+
5
+ h3. Improvements
6
+
7
+ * [activeldap-discuss] Added {ActiveLdap::Entry} for convenient.
8
+ [Suggested by Craig White]
9
+ * [GitHub:#45] Ensured that {ActiveLdap::Persistence#save!} returns
10
+ true on success. But you should use {ActiveLdap::Persistence#save}
11
+ to determine success or failure by return value.
12
+ [Reported by Suggested by Erik M Jacobs]
13
+ * [GitHub:#52] Improved binary data handling on Ruby 1.9.3.
14
+ [Patch by Carl P. Corliss]
15
+ * [GitHub:#53] Supported lower case hashed password.
16
+ [Patch by jpiotro3]
17
+ * [GitHub:#51] Supported implicit railtie load by
18
+ @require "active_ldap"@.
19
+ [Patch by mperrando]
20
+ * [GitHub:#62] Improved JNDI communication error handling.
21
+ [Patch by Ryosuke Yamazaki]
22
+ * [GitHub:#61] Supported Rails 4. Dropped Rails 3 support.
23
+ [Patch by superscott]
24
+ * [GitHub:#63] Handled Errno::ECONNRESET as connection in
25
+ net-ldap adapter [Patch by mpoornima]
26
+ h3. Fixes
27
+
28
+ * [GitHub:#44] Fixed a typo in document.
29
+ [Patch by Vaucher Philippe]
30
+ * [GitHub:#50] Fixed a stack overflow during SASL bind to a
31
+ unresponsive LDAP server.
32
+ [Patch by pwillred]
33
+ * [GitHub:#54] Fixed a link in document.
34
+ [Patch by marco]
35
+ * [GitHub:#57] Fixed a wrong blank value detection for "false".
36
+ [Reported by Robin Doer]
37
+
38
+ h3. Thanks
39
+
40
+ * Craig White
41
+ * Vaucher Philippe
42
+ * Erik M Jacobs
43
+ * pwillred
44
+ * Carl P. Corliss
45
+ * jpiotro3
46
+ * marco
47
+ * mperrando
48
+ * Robin Doer
49
+ * Ryosuke Yamazaki
50
+ * superscott
51
+ * mpoornima
52
+
3
53
  h2(#3-2-2). 3.2.2: 2012-09-01
4
54
 
5
55
  * Supported entry creation by direct ActiveLdap::Base use.
data/lib/active_ldap.rb CHANGED
@@ -55,7 +55,7 @@ ActiveLdap::Base.class_eval do
55
55
  include ActiveLdap::Persistence
56
56
 
57
57
  include ActiveLdap::Associations
58
- include ActiveModel::MassAssignmentSecurity
58
+ include ActiveModel::ForbiddenAttributesProtection
59
59
  include ActiveLdap::Attributes
60
60
  include ActiveLdap::AttributeMethods
61
61
  include ActiveLdap::AttributeMethods::BeforeTypeCast
@@ -83,3 +83,5 @@ ACTIVE_LDAP_CONNECTION_ADAPTERS.each do |adapter|
83
83
  require "active_ldap/adapter/#{adapter}"
84
84
  end
85
85
 
86
+ require "active_ldap/entry"
87
+ require "active_ldap/railtie" if defined?(Rails)
@@ -336,7 +336,7 @@ module ActiveLdap
336
336
  def sasl_bind(bind_dn, options={})
337
337
  # Get all SASL mechanisms
338
338
  mechanisms = operation(options) do
339
- root_dse_values("supportedSASLMechanisms")
339
+ root_dse_values("supportedSASLMechanisms", options)
340
340
  end
341
341
 
342
342
  if options.has_key?(:sasl_quiet)
@@ -579,9 +579,10 @@ module ActiveLdap
579
579
  options[:reconnect_attempts] = 0 if force
580
580
  options[:reconnect_attempts] += 1 if retry_limit >= 0
581
581
  begin
582
+ options[:try_reconnect] = false
582
583
  connect(options)
583
584
  break
584
- rescue AuthenticationError
585
+ rescue AuthenticationError, Timeout::Error
585
586
  raise
586
587
  rescue => detail
587
588
  @logger.error do
@@ -633,10 +634,17 @@ module ActiveLdap
633
634
 
634
635
  def root_dse(attrs, options={})
635
636
  found_attributes = nil
637
+ if options.has_key?(:try_reconnect)
638
+ try_reconnect = options[:try_reconnect]
639
+ else
640
+ try_reconnect = true
641
+ end
642
+
636
643
  search(:base => "",
637
644
  :scope => :base,
638
645
  :attributes => attrs,
639
- :limit => 1) do |dn, attributes|
646
+ :limit => 1,
647
+ :try_reconnect => try_reconnect) do |dn, attributes|
640
648
  found_attributes = attributes
641
649
  end
642
650
  found_attributes
@@ -28,6 +28,10 @@ module ActiveLdap
28
28
  end
29
29
  end
30
30
 
31
+ def connecting?
32
+ super and @connection.bound?
33
+ end
34
+
31
35
  def unbind(options={})
32
36
  super do
33
37
  execute(:unbind)
@@ -89,6 +93,8 @@ module ActiveLdap
89
93
  def execute(method, info=nil, *args, &block)
90
94
  name = (info || {}).delete(:name) || method
91
95
  log(name, info) {@connection.send(method, *args, &block)}
96
+ rescue JndiConnection::CommunicationException => e
97
+ raise ActiveLdap::ConnectionError.new(e.getMessage())
92
98
  rescue JndiConnection::NamingException
93
99
  if /\[LDAP: error code (\d+) - ([^\]]+)\]/ =~ $!.to_s
94
100
  message = $2
@@ -26,6 +26,7 @@ module ActiveLdap
26
26
  StartTlsRequest = ldap.StartTlsRequest
27
27
  Control = ldap.Control
28
28
 
29
+ CommunicationException = naming.CommunicationException
29
30
  NamingException = naming.NamingException
30
31
  NameNotFoundException = naming.NameNotFoundException
31
32
 
@@ -183,10 +183,6 @@ module ActiveLdap
183
183
  end
184
184
  end
185
185
 
186
- def do_in_timeout(timeout, &block)
187
- Timeout.timeout(timeout, &block)
188
- end
189
-
190
186
  def ensure_method(method)
191
187
  normalized_method = method.to_s.downcase
192
188
  Method.constants.each do |name|
@@ -142,7 +142,7 @@ module ActiveLdap
142
142
  result = log(name, info) do
143
143
  begin
144
144
  @connection.send(method, *args, &block)
145
- rescue Errno::EPIPE
145
+ rescue Errno::EPIPE, Errno::ECONNRESET
146
146
  raise ConnectionError, "#{$!.class}: #{$!.message}"
147
147
  end
148
148
  end
@@ -16,7 +16,9 @@ module ActiveLdap
16
16
  when Array
17
17
  value.all? {|val| blank_value?(val)}
18
18
  when String
19
- /\A\s*\z/ =~ value
19
+ /\A\s*\z/ === value
20
+ when true, false
21
+ false
20
22
  when nil
21
23
  true
22
24
  else
@@ -138,37 +140,6 @@ module ActiveLdap
138
140
  end
139
141
 
140
142
  private
141
- def sanitize_for_mass_assignment(attributes, role=nil)
142
- role ||= :default
143
- authorizer = mass_assignment_authorizer(role)
144
- black_list_p =
145
- authorizer.is_a?(ActiveModel::MassAssignmentSecurity::BlackList)
146
-
147
- always_needless_attributes = {}
148
- needless_attributes = {}
149
-
150
- _dn_attribute = nil
151
- begin
152
- _dn_attribute = dn_attribute_with_fallback
153
- rescue DistinguishedNameInvalid
154
- end
155
- [_dn_attribute, 'objectClass'].compact.each do |name|
156
- always_needless_attributes[to_real_attribute_name(name)] = true
157
- end
158
- authorizer.each do |name|
159
- needless_attributes[to_real_attribute_name(name)] = black_list_p
160
- end
161
-
162
- sanitized_attributes = attributes.collect do |key, value|
163
- key = _dn_attribute if ["id", "dn"].include?(key.to_s)
164
- [to_real_attribute_name(key) || key, value]
165
- end
166
- sanitized_attributes = sanitized_attributes.reject do |key, value|
167
- always_needless_attributes[key] or needless_attributes[key]
168
- end
169
- sanitized_attributes
170
- end
171
-
172
143
  def normalize_attribute_name(name)
173
144
  self.class.normalize_attribute_name(name)
174
145
  end
@@ -224,11 +224,11 @@ module ActiveLdap
224
224
  end
225
225
 
226
226
  class EntryInvalid < Error
227
- attr_reader :entry
228
- def initialize(entry)
229
- @entry = entry
230
- errors = @entry.errors.full_messages.join(", ")
231
- super(errors)
227
+ attr_reader :entry
228
+ def initialize(entry)
229
+ @entry = entry
230
+ errors = @entry.errors.full_messages.join(", ")
231
+ super(errors)
232
232
  end
233
233
  end
234
234
 
@@ -679,15 +679,10 @@ module ActiveLdap
679
679
  self.classes = initial_classes
680
680
  self.dn = attributes
681
681
  when Hash
682
- classes, attributes = extract_object_class(attributes)
682
+ attributes = attributes.clone
683
+ classes = extract_object_class!(attributes)
683
684
  self.classes = classes | initial_classes
684
- normalized_attributes = {}
685
- attributes.each do |key, value|
686
- real_key = to_real_attribute_name(key) || key
687
- normalized_attributes[real_key] = value
688
- end
689
- self.dn = normalized_attributes.delete(dn_attribute)
690
- self.attributes = normalized_attributes
685
+ self.attributes = attributes
691
686
  else
692
687
  format = _("'%s' must be either nil, DN value as ActiveLdap::DN, " \
693
688
  "String or Array or attributes as Hash")
@@ -831,15 +826,11 @@ module ActiveLdap
831
826
  assign_attributes(new_attributes)
832
827
  end
833
828
 
834
- def assign_attributes(new_attributes, options={})
829
+ def assign_attributes(new_attributes)
835
830
  return if new_attributes.blank?
836
831
 
837
832
  _schema = _local_entry_attribute = nil
838
- if options[:without_protection]
839
- targets = new_attributes
840
- else
841
- targets = sanitize_for_mass_assignment(new_attributes, options[:role])
842
- end
833
+ targets = sanitize_for_mass_assignment(new_attributes)
843
834
  targets.each do |key, value|
844
835
  setter = "#{key}="
845
836
  unless respond_to?(setter)
@@ -1032,18 +1023,31 @@ module ActiveLdap
1032
1023
  @local_entry_attribute ||= connection.entry_attribute([])
1033
1024
  end
1034
1025
 
1035
- def extract_object_class(attributes)
1026
+ def extract_object_class!(attributes)
1036
1027
  classes = []
1037
- attrs = {}
1038
- attributes.each do |key, value|
1039
- key = key.to_s
1040
- if /\Aobject_?class\z/i =~ key
1041
- classes.concat(value.to_a)
1028
+ attributes.keys.each do |key|
1029
+ string_key = key.to_s
1030
+ if /\Aobject_?class\z/i =~ string_key
1031
+ classes.concat(attributes[key].to_a)
1032
+ attributes.delete(key)
1033
+ end
1034
+ end
1035
+ classes
1036
+ end
1037
+
1038
+ def remove_dn_attribute!(attributes)
1039
+ _dn_attribute = dn_attribute
1040
+ attributes.keys.each do |key|
1041
+ case key
1042
+ when "id", :id, "dn", :dn
1043
+ attributes.delete(key)
1042
1044
  else
1043
- attrs[key] = value
1045
+ normalized_key = to_real_attribute_name(key) || key
1046
+ if normalized_key == _dn_attribute
1047
+ attributes.delete(key)
1048
+ end
1044
1049
  end
1045
1050
  end
1046
- [classes, attributes]
1047
1051
  end
1048
1052
 
1049
1053
  def init_base
@@ -1061,9 +1065,11 @@ module ActiveLdap
1061
1065
  @new_entry = false
1062
1066
  @dn_is_base = false
1063
1067
  @ldap_data = attributes
1064
- classes, attributes = extract_object_class(attributes)
1068
+ attributes = attributes.clone
1069
+ classes = extract_object_class!(attributes)
1065
1070
  self.classes = classes
1066
1071
  self.dn = dn
1072
+ remove_dn_attribute!(attributes)
1067
1073
  initialize_attributes(attributes)
1068
1074
  yield self if block_given?
1069
1075
  end
@@ -1181,8 +1187,9 @@ module ActiveLdap
1181
1187
 
1182
1188
  def split_dn_value(value)
1183
1189
  dn_value = relative_dn_value = nil
1190
+ value = value.first if value.is_a?(Array) and value.size == 1
1191
+ dn_value = value if value.is_a?(DN)
1184
1192
  begin
1185
- dn_value = value if value.is_a?(DN)
1186
1193
  dn_value ||= DN.parse(value)
1187
1194
  rescue DistinguishedNameInvalid
1188
1195
  begin
@@ -36,8 +36,8 @@ module ActiveLdap
36
36
  module ClassMethods
37
37
  def instantiate_with_callbacks(record)
38
38
  object = instantiate_without_callbacks(record)
39
- object.send(:_run_find_callbacks)
40
- object.send(:_run_initialize_callbacks)
39
+ object.run_callbacks(:find)
40
+ object.run_callbacks(:initialize)
41
41
  object
42
42
  end
43
43
  end
@@ -0,0 +1,8 @@
1
+ module ActiveLdap
2
+ class Entry < ActiveLdap::Base
3
+ ldap_mapping :prefix => "",
4
+ :classes => ["top"],
5
+ :scope => :sub
6
+ self.dn_attribute = nil
7
+ end
8
+ end
@@ -44,6 +44,7 @@ module ActiveLdap
44
44
  unless create_or_update
45
45
  raise EntryNotSaved, _("entry %s can't be saved") % dn
46
46
  end
47
+ true
47
48
  end
48
49
 
49
50
  def create_or_update
@@ -90,7 +91,7 @@ module ActiveLdap
90
91
  end
91
92
 
92
93
  @ldap_data.update(attributes)
93
- classes, attributes = extract_object_class(attributes)
94
+ classes = extract_object_class!(attributes)
94
95
  self.classes = classes
95
96
  self.attributes = attributes
96
97
  @new_entry = false
@@ -88,6 +88,7 @@ module ActiveLdap
88
88
  end
89
89
 
90
90
  def attribute(name)
91
+ name = name.to_s if name.is_a?(Symbol)
91
92
  cache([:attribute, name]) do
92
93
  Attribute.new(name, self)
93
94
  end
@@ -552,7 +553,7 @@ module ActiveLdap
552
553
  when Hash
553
554
  normalize_hash_value(value, have_binary_mark)
554
555
  else
555
- if value.blank?
556
+ if value.nil?
556
557
  value = []
557
558
  else
558
559
  value = send_to_syntax(value, :normalize_value, value)
@@ -187,15 +187,10 @@ module ActiveLdap
187
187
  fraction = match_data[-2]
188
188
  fraction = fraction.to_f if fraction
189
189
  time_zone = match_data[-1]
190
- arguments = [
191
- year, month, day, hour, minute, second, fraction, time_zone,
192
- Time.now
193
- ]
194
- if Time.method(:make_time).arity == 10
195
- arguments.unshift(value)
196
- end
197
190
  begin
198
- Time.send(:make_time, *arguments)
191
+ Time.send(:make_time,
192
+ year, month, day, hour, minute, second, fraction,
193
+ time_zone, Time.now)
199
194
  rescue ArgumentError
200
195
  raise if year >= 1700
201
196
  out_of_range_messages = ["argument out of range",
@@ -7,7 +7,7 @@ module ActiveLdap
7
7
  module UserPassword
8
8
  module_function
9
9
  def valid?(password, hashed_password)
10
- unless /^\{([A-Z][A-Z\d]+)\}/ =~ hashed_password
10
+ unless /^\{([A-Za-z][A-Za-z\d]+)\}/ =~ hashed_password
11
11
  # Plain text password
12
12
  return hashed_password == password
13
13
  end
@@ -147,7 +147,7 @@ module ActiveLdap
147
147
  next if required_attribute.read_only?
148
148
  next if _validation_skip_attributes.include?(real_name)
149
149
 
150
- value = @data[real_name] || []
150
+ value = @data[real_name]
151
151
  next unless self.class.blank_value?(value)
152
152
 
153
153
  _schema ||= schema
@@ -171,6 +171,10 @@ module ActiveLdap
171
171
  def validate_ldap_values
172
172
  entry_attribute.schemata.each do |name, attribute|
173
173
  value = self[name]
174
+ # Is it really proper location for setting encoding?
175
+ if attribute.binary? and value.respond_to?(:force_encoding)
176
+ value.force_encoding("ASCII-8BIT")
177
+ end
174
178
  next if self.class.blank_value?(value)
175
179
  validate_ldap_value(attribute, name, value)
176
180
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveLdap
2
- VERSION = "3.2.3"
2
+ VERSION = "4.0.0"
3
3
  end
@@ -33,10 +33,10 @@ module ActiveLdap
33
33
 
34
34
  def ldap_mapping(indent=' ')
35
35
  mapping = "ldap_mapping "
36
- mapping_options = [key_value(:dn_attribute, options[:dn_attribute].dump)]
37
- mapping_options << key_value(:prefix, prefix.dump)
36
+ mapping_options = ["dn_attribute: #{options[:dn_attribute].dump}"]
37
+ mapping_options << "prefix: #{prefix.dump}"
38
38
  if options[:classes]
39
- mapping_options << key_value(:classes, options[:classes].inspect)
39
+ mapping_options << "classes: #{options[:classes].inspect}"
40
40
  end
41
41
  mapping_options = mapping_options.join(",\n#{indent}#{' ' * mapping.size}")
42
42
  "#{indent}#{mapping}#{mapping_options}"
data/test/command.rb CHANGED
@@ -32,6 +32,7 @@ module Command
32
32
  if args.any? {|x| x.nil?}
33
33
  raise ArgumentError, "args has nil: #{args.inspect}"
34
34
  end
35
+ args = args.collect {|arg| arg.to_s}
35
36
  return java_run(cmd, *args, &block) if Object.respond_to?(:java)
36
37
  in_r, in_w = IO.pipe
37
38
  out_r, out_w = IO.pipe
@@ -48,7 +49,7 @@ module Command
48
49
  STDOUT.reopen(out_w)
49
50
  STDERR.reopen(out_w)
50
51
  out_w.close
51
- exec(cmd, *args.collect {|arg| arg.to_s})
52
+ exec(cmd, *args)
52
53
  exit!(-1)
53
54
  end
54
55
  $VERBOSE = verbose
@@ -17,22 +17,6 @@ class TestAttributes < Test::Unit::TestCase
17
17
  assert_nil(user.__send__(:to_real_attribute_name, "objectclass", false))
18
18
  end
19
19
 
20
- def test_protect_object_class_from_mass_assignment
21
- classes = @user_class.required_classes + ["inetOrgPerson"]
22
- user = @user_class.new(:uid => "XXX", :object_class => classes)
23
- assert_equal(["inetOrgPerson"],
24
- user.classes - @user_class.required_classes)
25
-
26
- user = @user_class.new(:uid => "XXX", :object_class => ['inetOrgPerson'])
27
- assert_equal(["inetOrgPerson"],
28
- user.classes - @user_class.required_classes)
29
-
30
- user = @user_class.new("XXX")
31
- assert_equal([], user.classes - @user_class.required_classes)
32
- user.attributes = {:object_class => classes}
33
- assert_equal([], user.classes - @user_class.required_classes)
34
- end
35
-
36
20
  def test_normalize_attribute
37
21
  assert_normalize_attribute(["usercertificate", [{"binary" => []}]],
38
22
  "userCertificate",
@@ -71,41 +55,6 @@ class TestAttributes < Test::Unit::TestCase
71
55
  {"phonetic" => ["やまだ"]}]}])
72
56
  end
73
57
 
74
- def test_attr_protected
75
- user = @user_class.new(:uid => "XXX")
76
- assert_equal("XXX", user.uid)
77
- user.attributes = {:uid => "ZZZ"}
78
- assert_equal("XXX", user.uid)
79
-
80
- user = @user_class.new(:sn => "ZZZ")
81
- assert_equal("ZZZ", user.sn)
82
-
83
- user = @user_class.new(:uid => "XXX", :sn => "ZZZ")
84
- assert_equal("XXX", user.uid)
85
- assert_equal("ZZZ", user.sn)
86
-
87
- @user_class.attr_protected :sn
88
- user = @user_class.new(:sn => "ZZZ")
89
- assert_nil(user.sn)
90
-
91
- sub_user_class = Class.new(@user_class)
92
- sub_user_class.ldap_mapping :dn_attribute => "uid"
93
- user = sub_user_class.new(:uid => "XXX", :sn => "ZZZ")
94
- assert_equal("XXX", user.uid)
95
- assert_nil(user.sn)
96
-
97
- sub_user_class.attr_protected :cn
98
- user = sub_user_class.new(:uid => "XXX", :sn => "ZZZ", :cn => "Common Name")
99
- assert_equal("XXX", user.uid)
100
- assert_nil(user.sn)
101
- assert_nil(user.cn)
102
-
103
- user = @user_class.new(:uid => "XXX", :sn => "ZZZ", :cn => "Common Name")
104
- assert_equal("XXX", user.uid)
105
- assert_nil(user.sn)
106
- assert_equal("Common Name", user.cn)
107
- end
108
-
109
58
  private
110
59
  def assert_normalize_attribute(expected, name, value)
111
60
  assert_equal(expected, ActiveLdap::Base.normalize_attribute(name, value))
@@ -114,4 +63,121 @@ class TestAttributes < Test::Unit::TestCase
114
63
  def assert_unnormalize_attribute(expected, name, value)
115
64
  assert_equal(expected, ActiveLdap::Base.unnormalize_attribute(name, value))
116
65
  end
66
+
67
+ class TestBlankValue < self
68
+ private
69
+ def assert_blank_value(value)
70
+ assert_true(ActiveLdap::Base.blank_value?(value),
71
+ "value: <#{value.inspect}>")
72
+ end
73
+
74
+ def assert_not_blank_value(value)
75
+ assert_false(ActiveLdap::Base.blank_value?(value),
76
+ "value: <#{value.inspect}>")
77
+ end
78
+
79
+ class TestHash < self
80
+ def test_empty
81
+ assert_blank_value({})
82
+ end
83
+
84
+ def test_have_elements
85
+ assert_not_blank_value({"name" => "Taro", "age" => 29})
86
+ end
87
+
88
+ def test_have_blank_element
89
+ assert_not_blank_value({"name" => nil, "age" => 29})
90
+ end
91
+
92
+ def test_all_blank_elements
93
+ assert_blank_value({"name" => nil, "age" => nil})
94
+ end
95
+ end
96
+
97
+ class TestArray < self
98
+ def test_empty
99
+ assert_blank_value([])
100
+ end
101
+
102
+ def test_have_elements
103
+ assert_not_blank_value(["Taro", "Jiro"])
104
+ end
105
+
106
+ def test_have_blank_element
107
+ assert_not_blank_value(["Taro", nil])
108
+ end
109
+
110
+ def test_all_blank_elements
111
+ assert_blank_value([nil, nil])
112
+ end
113
+ end
114
+
115
+ class TestString < self
116
+ def test_empty
117
+ assert_blank_value("")
118
+ end
119
+
120
+ def test_only_spaces
121
+ assert_blank_value(" \t\n")
122
+ end
123
+
124
+ def test_have_non_spaces
125
+ assert_not_blank_value("Taro")
126
+ end
127
+ end
128
+
129
+ class TestBoolean < self
130
+ def test_true
131
+ assert_not_blank_value(true)
132
+ end
133
+
134
+ def test_false
135
+ assert_not_blank_value(true)
136
+ end
137
+ end
138
+ end
139
+
140
+ class TestMassAssignment < self
141
+ def test_forbid
142
+ attributes = {:cn => "Alice"}
143
+ def attributes.permitted?
144
+ false
145
+ end
146
+ assert_raise(ActiveModel::ForbiddenAttributesError) do
147
+ @user_class.new(attributes)
148
+ end
149
+ end
150
+
151
+ def test_permit
152
+ attributes = {:cn => "Alice"}
153
+ def attributes.permitted?
154
+ true
155
+ end
156
+ alice = @user_class.new(attributes)
157
+ assert_equal("Alice", alice.cn)
158
+ end
159
+
160
+ def test_forbid_object_class
161
+ classes = @user_class.required_classes + ["inetOrgPerson"]
162
+ user = @user_class.new(:uid => "XXX", :object_class => classes)
163
+ assert_equal(["inetOrgPerson"],
164
+ user.classes - @user_class.required_classes)
165
+
166
+ user = @user_class.new(:uid => "XXX", :object_class => ['inetOrgPerson'])
167
+ assert_equal(["inetOrgPerson"],
168
+ user.classes - @user_class.required_classes)
169
+
170
+ user = @user_class.new("XXX")
171
+ assert_equal([], user.classes - @user_class.required_classes)
172
+ user.attributes = {:object_class => classes}
173
+ assert_equal([], user.classes - @user_class.required_classes)
174
+ end
175
+
176
+ def test_rename
177
+ make_temporary_user(:simple => true) do |user,|
178
+ assert_true(user.update_attributes(:id => "user2"))
179
+ assert_equal("user2", user.id)
180
+ end
181
+ end
182
+ end
117
183
  end
data/test/test_base.rb CHANGED
@@ -75,14 +75,6 @@ class TestBase < Test::Unit::TestCase
75
75
  end
76
76
  end
77
77
 
78
- def test_not_rename_by_mass_update
79
- make_temporary_user(:simple => true) do |user,|
80
- original_id = user.id
81
- assert_true(user.update_attributes(:id => "user2"))
82
- assert_equal(original_id, user.id)
83
- end
84
- end
85
-
86
78
  def test_attributes
87
79
  make_temporary_group do |group|
88
80
  assert_equal({
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'al-test-utils'
4
+
5
+ class TestEntry < Test::Unit::TestCase
6
+ include AlTestUtils
7
+
8
+ def test_all
9
+ make_temporary_group do |group|
10
+ make_temporary_user do |user, password|
11
+ all_entries = [ActiveLdap::Base.base]
12
+ all_entries += [user.dn, user.base]
13
+ all_entries += [group.dn, group.base]
14
+ assert_equal(all_entries.sort,
15
+ ActiveLdap::Entry.all.collect(&:dn).sort)
16
+ end
17
+ end
18
+ end
19
+ end
data/test/test_user.rb CHANGED
@@ -198,7 +198,8 @@ class TestUser < Test::Unit::TestCase
198
198
  assert_nothing_raised() { user.save! }
199
199
 
200
200
  user = @user_class.find(user.uid)
201
- assert_equal(cn, user.cn,
201
+ assert_equal(cn.sort_by {|value| value.to_s},
202
+ user.cn.sort_by {|value| value.to_s},
202
203
  'Making sure a modify with mixed subtypes works')
203
204
  end
204
205
  end
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeldap
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.3
4
+ version: 4.0.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Will Drewry
@@ -9,154 +10,172 @@ authors:
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2016-09-18 00:00:00.000000000 Z
13
+ date: 2013-07-13 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: activemodel
16
17
  requirement: !ruby/object:Gem::Requirement
18
+ none: false
17
19
  requirements:
18
- - - "~>"
20
+ - - ~>
19
21
  - !ruby/object:Gem::Version
20
- version: 3.2.8
22
+ version: 4.0.0
21
23
  type: :runtime
22
24
  prerelease: false
23
25
  version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
24
27
  requirements:
25
- - - "~>"
28
+ - - ~>
26
29
  - !ruby/object:Gem::Version
27
- version: 3.2.8
30
+ version: 4.0.0
28
31
  - !ruby/object:Gem::Dependency
29
32
  name: locale
30
33
  requirement: !ruby/object:Gem::Requirement
34
+ none: false
31
35
  requirements:
32
- - - ">="
36
+ - - ! '>='
33
37
  - !ruby/object:Gem::Version
34
38
  version: '0'
35
39
  type: :runtime
36
40
  prerelease: false
37
41
  version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
38
43
  requirements:
39
- - - ">="
44
+ - - ! '>='
40
45
  - !ruby/object:Gem::Version
41
46
  version: '0'
42
47
  - !ruby/object:Gem::Dependency
43
48
  name: gettext
44
49
  requirement: !ruby/object:Gem::Requirement
50
+ none: false
45
51
  requirements:
46
- - - ">="
52
+ - - ! '>='
47
53
  - !ruby/object:Gem::Version
48
54
  version: '0'
49
55
  type: :runtime
50
56
  prerelease: false
51
57
  version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
52
59
  requirements:
53
- - - ">="
60
+ - - ! '>='
54
61
  - !ruby/object:Gem::Version
55
62
  version: '0'
56
63
  - !ruby/object:Gem::Dependency
57
64
  name: gettext_i18n_rails
58
65
  requirement: !ruby/object:Gem::Requirement
66
+ none: false
59
67
  requirements:
60
- - - ">="
68
+ - - ! '>='
61
69
  - !ruby/object:Gem::Version
62
70
  version: '0'
63
71
  type: :runtime
64
72
  prerelease: false
65
73
  version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
66
75
  requirements:
67
- - - ">="
76
+ - - ! '>='
68
77
  - !ruby/object:Gem::Version
69
78
  version: '0'
70
79
  - !ruby/object:Gem::Dependency
71
80
  name: bundler
72
81
  requirement: !ruby/object:Gem::Requirement
82
+ none: false
73
83
  requirements:
74
- - - ">="
84
+ - - ! '>='
75
85
  - !ruby/object:Gem::Version
76
86
  version: '0'
77
87
  type: :development
78
88
  prerelease: false
79
89
  version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
80
91
  requirements:
81
- - - ">="
92
+ - - ! '>='
82
93
  - !ruby/object:Gem::Version
83
94
  version: '0'
84
95
  - !ruby/object:Gem::Dependency
85
96
  name: rake
86
97
  requirement: !ruby/object:Gem::Requirement
98
+ none: false
87
99
  requirements:
88
- - - ">="
100
+ - - ! '>='
89
101
  - !ruby/object:Gem::Version
90
102
  version: '0'
91
103
  type: :development
92
104
  prerelease: false
93
105
  version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
94
107
  requirements:
95
- - - ">="
108
+ - - ! '>='
96
109
  - !ruby/object:Gem::Version
97
110
  version: '0'
98
111
  - !ruby/object:Gem::Dependency
99
112
  name: test-unit
100
113
  requirement: !ruby/object:Gem::Requirement
114
+ none: false
101
115
  requirements:
102
- - - ">="
116
+ - - ! '>='
103
117
  - !ruby/object:Gem::Version
104
118
  version: '0'
105
119
  type: :development
106
120
  prerelease: false
107
121
  version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
108
123
  requirements:
109
- - - ">="
124
+ - - ! '>='
110
125
  - !ruby/object:Gem::Version
111
126
  version: '0'
112
127
  - !ruby/object:Gem::Dependency
113
128
  name: test-unit-notify
114
129
  requirement: !ruby/object:Gem::Requirement
130
+ none: false
115
131
  requirements:
116
- - - ">="
132
+ - - ! '>='
117
133
  - !ruby/object:Gem::Version
118
134
  version: '0'
119
135
  type: :development
120
136
  prerelease: false
121
137
  version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
122
139
  requirements:
123
- - - ">="
140
+ - - ! '>='
124
141
  - !ruby/object:Gem::Version
125
142
  version: '0'
126
143
  - !ruby/object:Gem::Dependency
127
144
  name: yard
128
145
  requirement: !ruby/object:Gem::Requirement
146
+ none: false
129
147
  requirements:
130
- - - ">="
148
+ - - ! '>='
131
149
  - !ruby/object:Gem::Version
132
150
  version: '0'
133
151
  type: :development
134
152
  prerelease: false
135
153
  version_requirements: !ruby/object:Gem::Requirement
154
+ none: false
136
155
  requirements:
137
- - - ">="
156
+ - - ! '>='
138
157
  - !ruby/object:Gem::Version
139
158
  version: '0'
140
159
  - !ruby/object:Gem::Dependency
141
160
  name: RedCloth
142
161
  requirement: !ruby/object:Gem::Requirement
162
+ none: false
143
163
  requirements:
144
- - - ">="
164
+ - - ! '>='
145
165
  - !ruby/object:Gem::Version
146
166
  version: '0'
147
167
  type: :development
148
168
  prerelease: false
149
169
  version_requirements: !ruby/object:Gem::Requirement
170
+ none: false
150
171
  requirements:
151
- - - ">="
172
+ - - ! '>='
152
173
  - !ruby/object:Gem::Version
153
174
  version: '0'
154
- description: |2
155
- 'ActiveLdap' is a ruby library which provides a clean
156
- objected oriented interface to the Ruby/LDAP library. It was inspired
157
- by ActiveRecord. This is not nearly as clean or as flexible as
158
- ActiveRecord, but it is still trivial to define new objects and manipulate
159
- them with minimal difficulty.
175
+ description: ! " 'ActiveLdap' is a ruby library which provides a clean\n objected
176
+ oriented interface to the Ruby/LDAP library. It was inspired\n by ActiveRecord.
177
+ This is not nearly as clean or as flexible as\n ActiveRecord, but it is still
178
+ trivial to define new objects and manipulate\n them with minimal difficulty.\n"
160
179
  email:
161
180
  - redpig@dataspill.org
162
181
  - kou@cozmixng.org
@@ -164,7 +183,7 @@ executables: []
164
183
  extensions: []
165
184
  extra_rdoc_files: []
166
185
  files:
167
- - ".yardopts"
186
+ - .yardopts
168
187
  - COPYING
169
188
  - Gemfile
170
189
  - LICENSE
@@ -232,6 +251,7 @@ files:
232
251
  - lib/active_ldap/configuration.rb
233
252
  - lib/active_ldap/connection.rb
234
253
  - lib/active_ldap/distinguished_name.rb
254
+ - lib/active_ldap/entry.rb
235
255
  - lib/active_ldap/entry_attribute.rb
236
256
  - lib/active_ldap/escape.rb
237
257
  - lib/active_ldap/get_text.rb
@@ -282,6 +302,7 @@ files:
282
302
  - test/test_connection_per_dn.rb
283
303
  - test/test_dirty.rb
284
304
  - test/test_dn.rb
305
+ - test/test_entry.rb
285
306
  - test/test_find.rb
286
307
  - test/test_groupadd.rb
287
308
  - test/test_groupdel.rb
@@ -310,26 +331,33 @@ files:
310
331
  homepage: http://ruby-activeldap.rubyforge.org/
311
332
  licenses:
312
333
  - Ruby's or GPLv2 or later
313
- metadata: {}
314
334
  post_install_message:
315
335
  rdoc_options: []
316
336
  require_paths:
317
337
  - lib
318
338
  required_ruby_version: !ruby/object:Gem::Requirement
339
+ none: false
319
340
  requirements:
320
- - - ">="
341
+ - - ! '>='
321
342
  - !ruby/object:Gem::Version
322
343
  version: '0'
344
+ segments:
345
+ - 0
346
+ hash: -4416735177306675209
323
347
  required_rubygems_version: !ruby/object:Gem::Requirement
348
+ none: false
324
349
  requirements:
325
- - - ">="
350
+ - - ! '>='
326
351
  - !ruby/object:Gem::Version
327
352
  version: '0'
353
+ segments:
354
+ - 0
355
+ hash: -4416735177306675209
328
356
  requirements: []
329
357
  rubyforge_project: ruby-activeldap
330
- rubygems_version: 2.5.1
358
+ rubygems_version: 1.8.23
331
359
  signing_key:
332
- specification_version: 4
360
+ specification_version: 3
333
361
  summary: ActiveLdap is a object-oriented API to LDAP
334
362
  test_files:
335
363
  - test/add-phonetic-attribute-options-to-slapd.ldif
@@ -352,6 +380,7 @@ test_files:
352
380
  - test/test_connection_per_dn.rb
353
381
  - test/test_dirty.rb
354
382
  - test/test_dn.rb
383
+ - test/test_entry.rb
355
384
  - test/test_find.rb
356
385
  - test/test_groupadd.rb
357
386
  - test/test_groupdel.rb
@@ -377,3 +406,4 @@ test_files:
377
406
  - test/test_usermod-lang-add.rb
378
407
  - test/test_usermod.rb
379
408
  - test/test_validation.rb
409
+ has_rdoc:
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 0848564f21de4b95f1d09fde5f6ec186edcb4d08
4
- data.tar.gz: 783377f08856388cdc329bf37f6f3784324e7f4f
5
- SHA512:
6
- metadata.gz: b5ea19b28a4fa0851d7e41d3a75ba7a3eed1390f7e599c3df9ffc9db1af7ad7aba6f2b5d84f2c709306b646317c9b30ac7ecfd99c28fbea8a37c02e53bb77a25
7
- data.tar.gz: 7875832eddc2347c17a0e3aa53c9f5328df8ce2f18d6a5f8473627772299bac8ea2a716f520fb3a665e8f026108b297c17cf9a857c70102aa99e9f68b3f54b24