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 +3 -0
- data/README.textile +4 -4
- data/doc/text/news.textile +50 -0
- data/lib/active_ldap.rb +3 -1
- data/lib/active_ldap/adapter/base.rb +11 -3
- data/lib/active_ldap/adapter/jndi.rb +6 -0
- data/lib/active_ldap/adapter/jndi_connection.rb +1 -0
- data/lib/active_ldap/adapter/ldap.rb +0 -4
- data/lib/active_ldap/adapter/net_ldap.rb +1 -1
- data/lib/active_ldap/attributes.rb +3 -32
- data/lib/active_ldap/base.rb +36 -29
- data/lib/active_ldap/callbacks.rb +2 -2
- data/lib/active_ldap/entry.rb +8 -0
- data/lib/active_ldap/persistence.rb +2 -1
- data/lib/active_ldap/schema.rb +2 -1
- data/lib/active_ldap/schema/syntaxes.rb +3 -8
- data/lib/active_ldap/user_password.rb +1 -1
- data/lib/active_ldap/validations.rb +5 -1
- data/lib/active_ldap/version.rb +1 -1
- data/lib/rails/generators/active_ldap/model/model_generator.rb +3 -3
- data/test/command.rb +2 -1
- data/test/test_attributes.rb +117 -51
- data/test/test_base.rb +0 -8
- data/test/test_entry.rb +19 -0
- data/test/test_user.rb +2 -1
- metadata +66 -36
- checksums.yaml +0 -7
data/Gemfile
CHANGED
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-
|
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
|
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.
|
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":
|
48
|
+
See "Rails":doc/text/rails.textile page for Rails integration.
|
49
49
|
|
50
50
|
h2. Licence
|
51
51
|
|
data/doc/text/news.textile
CHANGED
@@ -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::
|
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
|
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
|
@@ -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/
|
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
|
data/lib/active_ldap/base.rb
CHANGED
@@ -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
|
-
|
682
|
+
attributes = attributes.clone
|
683
|
+
classes = extract_object_class!(attributes)
|
683
684
|
self.classes = classes | initial_classes
|
684
|
-
|
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
|
829
|
+
def assign_attributes(new_attributes)
|
835
830
|
return if new_attributes.blank?
|
836
831
|
|
837
832
|
_schema = _local_entry_attribute = nil
|
838
|
-
|
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
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
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
|
-
|
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
|
-
|
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.
|
40
|
-
object.
|
39
|
+
object.run_callbacks(:find)
|
40
|
+
object.run_callbacks(:initialize)
|
41
41
|
object
|
42
42
|
end
|
43
43
|
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
|
94
|
+
classes = extract_object_class!(attributes)
|
94
95
|
self.classes = classes
|
95
96
|
self.attributes = attributes
|
96
97
|
@new_entry = false
|
data/lib/active_ldap/schema.rb
CHANGED
@@ -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.
|
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,
|
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-
|
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
|
data/lib/active_ldap/version.rb
CHANGED
@@ -33,10 +33,10 @@ module ActiveLdap
|
|
33
33
|
|
34
34
|
def ldap_mapping(indent=' ')
|
35
35
|
mapping = "ldap_mapping "
|
36
|
-
mapping_options = [
|
37
|
-
mapping_options <<
|
36
|
+
mapping_options = ["dn_attribute: #{options[:dn_attribute].dump}"]
|
37
|
+
mapping_options << "prefix: #{prefix.dump}"
|
38
38
|
if options[:classes]
|
39
|
-
mapping_options <<
|
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
|
52
|
+
exec(cmd, *args)
|
52
53
|
exit!(-1)
|
53
54
|
end
|
54
55
|
$VERBOSE = verbose
|
data/test/test_attributes.rb
CHANGED
@@ -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({
|
data/test/test_entry.rb
ADDED
@@ -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
|
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:
|
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:
|
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:
|
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:
|
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:
|
155
|
-
|
156
|
-
|
157
|
-
|
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
|
-
-
|
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:
|
358
|
+
rubygems_version: 1.8.23
|
331
359
|
signing_key:
|
332
|
-
specification_version:
|
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
|