activeldap 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +34 -0
- data/README +13 -0
- data/Rakefile +2 -1
- data/TODO +6 -0
- data/benchmark/bench-al.rb +68 -17
- data/examples/al-admin/app/helpers/application_helper.rb +3 -5
- data/examples/al-admin/app/views/layouts/_footer.html.erb +2 -0
- data/examples/al-admin/config/boot.rb +7 -7
- data/examples/al-admin/config/environment.rb +27 -12
- data/examples/al-admin/config/environments/development.rb +0 -1
- data/examples/al-admin/config/environments/production.rb +6 -1
- data/examples/al-admin/config/environments/test.rb +1 -1
- data/examples/al-admin/config/initializers/gettext.rb +15 -1
- data/examples/al-admin/po/en/al-admin.po +1 -1
- data/examples/al-admin/po/ja/al-admin.po +1 -1
- data/examples/al-admin/po/nl/al-admin.po +1 -1
- data/examples/al-admin/public/dispatch.cgi +0 -0
- data/examples/al-admin/public/dispatch.fcgi +0 -0
- data/examples/al-admin/public/dispatch.rb +0 -0
- data/examples/al-admin/public/javascripts/controls.js +73 -73
- data/examples/al-admin/public/javascripts/dragdrop.js +166 -165
- data/examples/al-admin/public/javascripts/effects.js +174 -166
- data/examples/al-admin/public/javascripts/prototype.js +362 -267
- data/examples/al-admin/script/about +0 -0
- data/examples/al-admin/script/console +0 -0
- data/examples/al-admin/script/dbconsole +3 -0
- data/examples/al-admin/script/destroy +0 -0
- data/examples/al-admin/script/generate +0 -0
- data/examples/al-admin/script/performance/benchmarker +0 -0
- data/examples/al-admin/script/performance/profiler +0 -0
- data/examples/al-admin/script/performance/request +0 -0
- data/examples/al-admin/script/plugin +0 -0
- data/examples/al-admin/script/process/inspector +0 -0
- data/examples/al-admin/script/process/reaper +0 -0
- data/examples/al-admin/script/process/spawner +0 -0
- data/examples/al-admin/script/runner +0 -0
- data/examples/al-admin/script/server +0 -0
- data/examples/al-admin/test/run-test.sh +0 -0
- data/examples/groupadd +0 -0
- data/examples/groupdel +0 -0
- data/examples/groupls +0 -0
- data/examples/groupmod +0 -0
- data/examples/lpasswd +0 -0
- data/examples/ouadd +0 -0
- data/examples/useradd +0 -0
- data/examples/useradd-binary +0 -0
- data/examples/userdel +0 -0
- data/examples/userls +0 -0
- data/examples/usermod +0 -0
- data/examples/usermod-binary-add +0 -0
- data/examples/usermod-binary-add-time +0 -0
- data/examples/usermod-binary-del +0 -0
- data/examples/usermod-lang-add +0 -0
- data/lib/active_ldap.rb +10 -4
- data/lib/active_ldap/action_controller/ldap_benchmarking.rb +28 -9
- data/lib/active_ldap/adapter/base.rb +30 -17
- data/lib/active_ldap/adapter/jndi.rb +5 -1
- data/lib/active_ldap/adapter/ldap.rb +5 -1
- data/lib/active_ldap/association/has_many_utils.rb +7 -1
- data/lib/active_ldap/associations.rb +10 -5
- data/lib/active_ldap/attributes.rb +6 -1
- data/lib/active_ldap/base.rb +154 -52
- data/lib/active_ldap/configuration.rb +1 -1
- data/lib/active_ldap/connection.rb +7 -4
- data/lib/active_ldap/get_text.rb +11 -3
- data/lib/active_ldap/ldif.rb +16 -4
- data/lib/active_ldap/operations.rb +13 -5
- data/lib/active_ldap/schema.rb +6 -2
- data/lib/active_ldap/schema/syntaxes.rb +15 -3
- data/lib/active_ldap/user_password.rb +4 -4
- data/lib/active_ldap/validations.rb +32 -44
- data/lib/active_ldap/xml.rb +125 -0
- data/po/en/active-ldap.po +740 -85
- data/po/ja/active-ldap.po +748 -547
- data/rails/README +54 -0
- data/rails/init.rb +33 -0
- data/rails/plugin/active_ldap/generators/README +2 -0
- data/rails/plugin/active_ldap/generators/model_active_ldap/model_active_ldap_generator.rb +1 -1
- data/rails/plugin/active_ldap/init.rb +3 -0
- data/rails_generators/model_active_ldap/USAGE +17 -0
- data/rails_generators/model_active_ldap/model_active_ldap_generator.rb +69 -0
- data/rails_generators/model_active_ldap/templates/model_active_ldap.rb +3 -0
- data/rails_generators/model_active_ldap/templates/unit_test.rb +8 -0
- data/rails_generators/scaffold_active_ldap/scaffold_active_ldap_generator.rb +7 -0
- data/rails_generators/scaffold_active_ldap/templates/ldap.yml +18 -0
- data/rails_generators/scaffold_al/scaffold_al_generator.rb +20 -0
- data/test-unit/History.txt +50 -1
- data/test-unit/Manifest.txt +22 -12
- data/test-unit/README.txt +31 -12
- data/test-unit/Rakefile +14 -1
- data/test-unit/TODO +5 -0
- data/test-unit/bin/testrb +0 -0
- data/test-unit/lib/test/unit.rb +62 -0
- data/test-unit/lib/test/unit/assertions.rb +419 -75
- data/test-unit/lib/test/unit/autorunner.rb +70 -13
- data/test-unit/lib/test/unit/collector.rb +1 -1
- data/test-unit/lib/test/unit/collector/load.rb +1 -1
- data/test-unit/lib/test/unit/color-scheme.rb +86 -0
- data/test-unit/lib/test/unit/color.rb +40 -5
- data/test-unit/lib/test/unit/diff.rb +14 -0
- data/test-unit/lib/test/unit/fixture.rb +7 -16
- data/test-unit/lib/test/unit/notification.rb +9 -0
- data/test-unit/lib/test/unit/omission.rb +14 -0
- data/test-unit/lib/test/unit/pending.rb +16 -0
- data/test-unit/lib/test/unit/priority.rb +17 -2
- data/test-unit/lib/test/unit/runner/console.rb +8 -2
- data/test-unit/lib/test/unit/testcase.rb +188 -2
- data/test-unit/lib/test/unit/ui/console/testrunner.rb +51 -26
- data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
- data/test-unit/lib/test/unit/version.rb +1 -1
- data/test-unit/sample/test_user.rb +22 -0
- data/test-unit/test/collector/{test_descendant.rb → test-descendant.rb} +0 -0
- data/test-unit/test/collector/{test_load.rb → test-load.rb} +1 -1
- data/test-unit/test/run-test.rb +0 -0
- data/test-unit/test/{test_attribute.rb → test-attribute.rb} +0 -0
- data/test-unit/test/test-color-scheme.rb +56 -0
- data/test-unit/test/{test_color.rb → test-color.rb} +10 -0
- data/test-unit/test/{test_diff.rb → test-diff.rb} +0 -0
- data/test-unit/test/{test_emacs_runner.rb → test-emacs-runner.rb} +0 -0
- data/test-unit/test/test-fixture.rb +287 -0
- data/test-unit/test/{test_notification.rb → test-notification.rb} +4 -4
- data/test-unit/test/{test_omission.rb → test-omission.rb} +6 -6
- data/test-unit/test/{test_pending.rb → test-pending.rb} +12 -6
- data/test-unit/test/{test_priority.rb → test-priority.rb} +30 -0
- data/test-unit/test/test_assertions.rb +411 -69
- data/test-unit/test/test_testcase.rb +70 -3
- data/test-unit/test/{testunit_test_util.rb → testunit-test-util.rb} +4 -2
- data/test-unit/test/ui/test_testrunmediator.rb +1 -1
- data/test-unit/test/util/test-method-owner-finder.rb +38 -0
- data/test/run-test.rb +0 -0
- data/test/test_adapter.rb +3 -0
- data/test/test_associations.rb +50 -7
- data/test/test_base.rb +193 -11
- data/test/test_connection_per_dn.rb +1 -1
- data/test/test_ldif.rb +86 -0
- data/test/test_load.rb +7 -0
- data/test/test_schema.rb +31 -1
- data/test/test_syntax.rb +20 -0
- data/test/test_user_password.rb +22 -14
- data/test/test_validation.rb +70 -29
- metadata +99 -77
- 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/config/initializers/ralative_url_support.rb +0 -1
- data/examples/al-admin/lib/accept_http_rails_relative_url_root.rb +0 -9
- data/test-unit-ext/misc/rd2html.rb +0 -42
- data/test-unit/test/test_fixture.rb +0 -275
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/examples/groupadd
CHANGED
|
File without changes
|
data/examples/groupdel
CHANGED
|
File without changes
|
data/examples/groupls
CHANGED
|
File without changes
|
data/examples/groupmod
CHANGED
|
File without changes
|
data/examples/lpasswd
CHANGED
|
File without changes
|
data/examples/ouadd
CHANGED
|
File without changes
|
data/examples/useradd
CHANGED
|
File without changes
|
data/examples/useradd-binary
CHANGED
|
File without changes
|
data/examples/userdel
CHANGED
|
File without changes
|
data/examples/userls
CHANGED
|
File without changes
|
data/examples/usermod
CHANGED
|
File without changes
|
data/examples/usermod-binary-add
CHANGED
|
File without changes
|
|
File without changes
|
data/examples/usermod-binary-del
CHANGED
|
File without changes
|
data/examples/usermod-lang-add
CHANGED
|
File without changes
|
data/lib/active_ldap.rb
CHANGED
|
@@ -905,12 +905,15 @@
|
|
|
905
905
|
# package, and I'd like to see it prove helpful to more people than just myself.
|
|
906
906
|
#
|
|
907
907
|
|
|
908
|
-
require_gem_if_need = Proc.new do |library_name, gem_name|
|
|
908
|
+
require_gem_if_need = Proc.new do |library_name, gem_name, *gem_args|
|
|
909
909
|
begin
|
|
910
|
+
if !gem_args.empty? and Object.const_defined?(:Gem)
|
|
911
|
+
gem gem_name, *gem_args
|
|
912
|
+
end
|
|
910
913
|
require library_name
|
|
911
914
|
rescue LoadError
|
|
912
915
|
require 'rubygems'
|
|
913
|
-
gem gem_name
|
|
916
|
+
gem gem_name, *gem_args
|
|
914
917
|
require library_name
|
|
915
918
|
end
|
|
916
919
|
end
|
|
@@ -928,7 +931,7 @@ if dependencies.respond_to?(:load_paths)
|
|
|
928
931
|
end
|
|
929
932
|
|
|
930
933
|
module ActiveLdap
|
|
931
|
-
VERSION = "1.0.
|
|
934
|
+
VERSION = "1.0.2"
|
|
932
935
|
end
|
|
933
936
|
|
|
934
937
|
if RUBY_PLATFORM.match('linux')
|
|
@@ -939,7 +942,8 @@ end
|
|
|
939
942
|
|
|
940
943
|
require_gem_if_need.call("active_record", "activerecord")
|
|
941
944
|
begin
|
|
942
|
-
require_gem_if_need.call("
|
|
945
|
+
require_gem_if_need.call("locale")
|
|
946
|
+
require_gem_if_need.call("gettext", "gettext", ">= 1.94")
|
|
943
947
|
rescue LoadError
|
|
944
948
|
end
|
|
945
949
|
require 'active_ldap/get_text'
|
|
@@ -948,6 +952,7 @@ require 'active_ldap/base'
|
|
|
948
952
|
|
|
949
953
|
require 'active_ldap/distinguished_name'
|
|
950
954
|
require 'active_ldap/ldif'
|
|
955
|
+
require 'active_ldap/xml'
|
|
951
956
|
|
|
952
957
|
require 'active_ldap/associations'
|
|
953
958
|
require 'active_ldap/attributes'
|
|
@@ -961,6 +966,7 @@ require 'active_ldap/acts/tree'
|
|
|
961
966
|
|
|
962
967
|
require 'active_ldap/populate'
|
|
963
968
|
require 'active_ldap/escape'
|
|
969
|
+
require 'active_ldap/user_password'
|
|
964
970
|
require 'active_ldap/helper'
|
|
965
971
|
|
|
966
972
|
require 'active_ldap/validations'
|
|
@@ -3,22 +3,31 @@ module ActiveLdap
|
|
|
3
3
|
module LdapBenchmarking
|
|
4
4
|
def self.included(base)
|
|
5
5
|
base.class_eval do
|
|
6
|
-
alias_method_chain :
|
|
7
|
-
|
|
6
|
+
alias_method_chain :render_with_benchmark, :active_ldap
|
|
7
|
+
if private_method_defined?(:view_runtime)
|
|
8
|
+
alias_method_chain :view_runtime, :active_ldap
|
|
9
|
+
else
|
|
10
|
+
alias_method_chain :rendering_runtime, :active_ldap
|
|
11
|
+
end
|
|
8
12
|
end
|
|
9
13
|
end
|
|
10
14
|
|
|
11
15
|
protected
|
|
12
|
-
def
|
|
16
|
+
def render_with_benchmark_with_active_ldap(*args, &block)
|
|
13
17
|
if logger
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
ldap_runtime_before_render = ActiveLdap::Base.reset_runtime
|
|
19
|
+
end
|
|
20
|
+
result = render_with_benchmark_without_active_ldap(*args, &block)
|
|
21
|
+
if logger
|
|
22
|
+
@ldap_runtime_before_render = ldap_runtime_before_render
|
|
16
23
|
@ldap_runtime_after_render = ActiveLdap::Base.reset_runtime
|
|
17
|
-
@rendering_runtime
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
if defined?(@rendering_runtime)
|
|
25
|
+
@rendering_runtime -= @ldap_runtime_after_render
|
|
26
|
+
else
|
|
27
|
+
@view_runtime -= @ldap_runtime_after_render
|
|
28
|
+
end
|
|
21
29
|
end
|
|
30
|
+
result
|
|
22
31
|
end
|
|
23
32
|
|
|
24
33
|
private
|
|
@@ -30,6 +39,16 @@ module ActiveLdap
|
|
|
30
39
|
ldap_percentage = ldap_runtime * 100 / runtime
|
|
31
40
|
result + (" | LDAP: %.5f (%d%%)" % [ldap_runtime, ldap_percentage])
|
|
32
41
|
end
|
|
42
|
+
|
|
43
|
+
def view_runtime_with_active_ldap
|
|
44
|
+
result = view_runtime_without_active_ldap
|
|
45
|
+
ldap_runtime = ActiveLdap::Base.reset_runtime
|
|
46
|
+
@ldap_runtime_before_render ||= 0
|
|
47
|
+
@ldap_runtime_after_render ||= 0
|
|
48
|
+
ldap_runtime += @ldap_runtime_before_render
|
|
49
|
+
ldap_runtime += @ldap_runtime_after_render
|
|
50
|
+
result + (", LDAP: %.0f" % (ldap_runtime * 1000))
|
|
51
|
+
end
|
|
33
52
|
end
|
|
34
53
|
end
|
|
35
54
|
end
|
|
@@ -40,8 +40,9 @@ module ActiveLdap
|
|
|
40
40
|
|
|
41
41
|
def connect(options={})
|
|
42
42
|
host = options[:host] || @host
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
method = options[:method] || @method || :plain
|
|
44
|
+
port = options[:port] || @port || ensure_port(method)
|
|
45
|
+
method = ensure_method(method)
|
|
45
46
|
@disconnected = false
|
|
46
47
|
@connection, @uri, @with_start_tls = yield(host, port, method)
|
|
47
48
|
prepare_connection(options)
|
|
@@ -167,7 +168,11 @@ module ActiveLdap
|
|
|
167
168
|
begin
|
|
168
169
|
operation(options) do
|
|
169
170
|
targets.each do |target|
|
|
170
|
-
|
|
171
|
+
begin
|
|
172
|
+
yield(target)
|
|
173
|
+
rescue LdapError::UnwillingToPerform, LdapError::InsufficientAccess
|
|
174
|
+
raise OperationNotPermitted, _("%s: %s") % [$!.message, target]
|
|
175
|
+
end
|
|
171
176
|
end
|
|
172
177
|
end
|
|
173
178
|
rescue LdapError::NoSuchObject
|
|
@@ -198,7 +203,11 @@ module ActiveLdap
|
|
|
198
203
|
def modify(dn, entries, options={})
|
|
199
204
|
begin
|
|
200
205
|
operation(options) do
|
|
201
|
-
|
|
206
|
+
begin
|
|
207
|
+
yield(dn, entries)
|
|
208
|
+
rescue LdapError::UnwillingToPerform, LdapError::InsufficientAccess
|
|
209
|
+
raise OperationNotPermitted, _("%s: %s") % [$!.message, target]
|
|
210
|
+
end
|
|
202
211
|
end
|
|
203
212
|
rescue LdapError::UndefinedType
|
|
204
213
|
raise
|
|
@@ -213,14 +222,22 @@ module ActiveLdap
|
|
|
213
222
|
end
|
|
214
223
|
end
|
|
215
224
|
|
|
216
|
-
def log_info(name,
|
|
225
|
+
def log_info(name, runtime_in_seconds, info=nil)
|
|
217
226
|
return unless @logger
|
|
218
227
|
return unless @logger.debug?
|
|
219
|
-
message = "LDAP: #{name} (#{'
|
|
228
|
+
message = "LDAP: #{name} (#{'%.1f' % (runtime_in_seconds * 1000)}ms)"
|
|
220
229
|
@logger.debug(format_log_entry(message, info))
|
|
221
230
|
end
|
|
222
231
|
|
|
223
232
|
private
|
|
233
|
+
def ensure_port(method)
|
|
234
|
+
if method == :ssl
|
|
235
|
+
URI::LDAPS::DEFAULT_PORT
|
|
236
|
+
else
|
|
237
|
+
URI::LDAP::DEFAULT_PORT
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
224
241
|
def prepare_connection(options)
|
|
225
242
|
end
|
|
226
243
|
|
|
@@ -388,7 +405,7 @@ module ActiveLdap
|
|
|
388
405
|
when Hash
|
|
389
406
|
options = value[0]
|
|
390
407
|
value = value[1]
|
|
391
|
-
when "=", "~=", "<=", "
|
|
408
|
+
when "=", "~=", "<=", ">="
|
|
392
409
|
options[:operator] = value[0]
|
|
393
410
|
if value.size > 2
|
|
394
411
|
value = value[1..-1]
|
|
@@ -601,17 +618,13 @@ module ActiveLdap
|
|
|
601
618
|
|
|
602
619
|
def log(name, info=nil)
|
|
603
620
|
if block_given?
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
result
|
|
610
|
-
else
|
|
611
|
-
yield
|
|
612
|
-
end
|
|
621
|
+
result = nil
|
|
622
|
+
seconds = Benchmark.realtime {result = yield}
|
|
623
|
+
@runtime += seconds
|
|
624
|
+
log_info(name, seconds, info)
|
|
625
|
+
result
|
|
613
626
|
else
|
|
614
|
-
log_info(name,
|
|
627
|
+
log_info(name, 0, info)
|
|
615
628
|
nil
|
|
616
629
|
end
|
|
617
630
|
rescue Exception
|
|
@@ -153,8 +153,12 @@ module ActiveLdap
|
|
|
153
153
|
mod_type = ensure_mod_type(type)
|
|
154
154
|
binary = schema.attribute(key).binary?
|
|
155
155
|
attributes.each do |name, values|
|
|
156
|
+
real_binary = binary
|
|
157
|
+
if values.any? {|value| Ldif::Attribute.binary_value?(value)}
|
|
158
|
+
real_binary = true
|
|
159
|
+
end
|
|
156
160
|
result << JndiConnection::ModifyRecord.new(mod_type, name,
|
|
157
|
-
values,
|
|
161
|
+
values, real_binary)
|
|
158
162
|
end
|
|
159
163
|
end
|
|
160
164
|
result
|
|
@@ -257,7 +257,11 @@ module ActiveLdap
|
|
|
257
257
|
binary = schema.attribute(key).binary?
|
|
258
258
|
mod_type |= LDAP::LDAP_MOD_BVALUES if binary
|
|
259
259
|
attributes.each do |name, values|
|
|
260
|
-
|
|
260
|
+
additional_mod_type = 0
|
|
261
|
+
if values.any? {|value| Ldif::Attribute.binary_value?(value)}
|
|
262
|
+
additional_mod_type |= LDAP::LDAP_MOD_BVALUES
|
|
263
|
+
end
|
|
264
|
+
result << LDAP.mod(mod_type | additional_mod_type, name, values)
|
|
261
265
|
end
|
|
262
266
|
end
|
|
263
267
|
result
|
|
@@ -19,7 +19,13 @@ module ActiveLdap
|
|
|
19
19
|
target
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
-
targets =
|
|
22
|
+
targets = []
|
|
23
|
+
requested_targets.each do |target|
|
|
24
|
+
begin
|
|
25
|
+
targets << foreign_class.find(target, find_options)
|
|
26
|
+
rescue EntryNotFound
|
|
27
|
+
end
|
|
28
|
+
end
|
|
23
29
|
else
|
|
24
30
|
components = requested_targets.collect do |value|
|
|
25
31
|
[foreign_base_key, value]
|
|
@@ -31,7 +31,8 @@ module ActiveLdap
|
|
|
31
31
|
#
|
|
32
32
|
# This defines a method for an extension class map its DN key
|
|
33
33
|
# attribute value on to multiple items which reference it by
|
|
34
|
-
# |:foreign_key| in the other LDAP entry covered by class
|
|
34
|
+
# |:foreign_key| in the other LDAP entry covered by class
|
|
35
|
+
# |:class_name|.
|
|
35
36
|
#
|
|
36
37
|
# Example:
|
|
37
38
|
# belongs_to :groups, :class_name => "Group",
|
|
@@ -44,7 +45,8 @@ module ActiveLdap
|
|
|
44
45
|
#
|
|
45
46
|
def belongs_to(association_id, options={})
|
|
46
47
|
validate_belongs_to_options(options)
|
|
47
|
-
klass = options[:class]
|
|
48
|
+
klass = options[:class]
|
|
49
|
+
klass ||= (options[:class_name] || association_id.to_s).classify
|
|
48
50
|
foreign_key = options[:foreign_key]
|
|
49
51
|
primary_key = options[:primary_key]
|
|
50
52
|
many = options[:many]
|
|
@@ -96,7 +98,8 @@ module ActiveLdap
|
|
|
96
98
|
# :wrap => "memberUid" # Group#memberUid
|
|
97
99
|
def has_many(association_id, options = {})
|
|
98
100
|
validate_has_many_options(options)
|
|
99
|
-
klass = options[:class]
|
|
101
|
+
klass = options[:class]
|
|
102
|
+
klass ||= (options[:class_name] || association_id.to_s).classify
|
|
100
103
|
foreign_key = options[:foreign_key] || "#{association_id}_id"
|
|
101
104
|
primary_key = options[:primary_key]
|
|
102
105
|
set_associated_class(association_id, klass)
|
|
@@ -149,13 +152,15 @@ module ActiveLdap
|
|
|
149
152
|
EOM
|
|
150
153
|
end
|
|
151
154
|
|
|
152
|
-
VALID_BELONGS_TO_OPTIONS = [:class, :
|
|
155
|
+
VALID_BELONGS_TO_OPTIONS = [:class, :class_name,
|
|
156
|
+
:foreign_key, :primary_key, :many,
|
|
153
157
|
:extend]
|
|
154
158
|
def validate_belongs_to_options(options)
|
|
155
159
|
options.assert_valid_keys(VALID_BELONGS_TO_OPTIONS)
|
|
156
160
|
end
|
|
157
161
|
|
|
158
|
-
VALID_HAS_MANY_OPTIONS = [:class, :
|
|
162
|
+
VALID_HAS_MANY_OPTIONS = [:class, :class_name,
|
|
163
|
+
:foreign_key, :primary_key, :wrap,
|
|
159
164
|
:extend]
|
|
160
165
|
def validate_has_many_options(options)
|
|
161
166
|
options.assert_valid_keys(VALID_HAS_MANY_OPTIONS)
|
|
@@ -126,7 +126,12 @@ module ActiveLdap
|
|
|
126
126
|
end
|
|
127
127
|
|
|
128
128
|
def attributes_protected_by_default
|
|
129
|
-
|
|
129
|
+
_dn_attribute = nil
|
|
130
|
+
begin
|
|
131
|
+
_dn_attribute = dn_attribute_with_fallback
|
|
132
|
+
rescue DistinguishedNameInvalid
|
|
133
|
+
end
|
|
134
|
+
[_dn_attribute, 'objectClass'].compact
|
|
130
135
|
end
|
|
131
136
|
|
|
132
137
|
def normalize_attribute_name(name)
|
data/lib/active_ldap/base.rb
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
require 'English'
|
|
32
32
|
require 'thread'
|
|
33
|
+
require 'erb'
|
|
33
34
|
|
|
34
35
|
module ActiveLdap
|
|
35
36
|
# OO-interface to LDAP assuming pam/nss_ldap-style organization with
|
|
@@ -438,6 +439,8 @@ module ActiveLdap
|
|
|
438
439
|
def inspect
|
|
439
440
|
if self == Base
|
|
440
441
|
super
|
|
442
|
+
elsif abstract_class?
|
|
443
|
+
"#{super}(abstract)"
|
|
441
444
|
else
|
|
442
445
|
class_names = []
|
|
443
446
|
must = []
|
|
@@ -454,6 +457,48 @@ module ActiveLdap
|
|
|
454
457
|
end
|
|
455
458
|
end
|
|
456
459
|
|
|
460
|
+
attr_accessor :abstract_class
|
|
461
|
+
def abstract_class?
|
|
462
|
+
defined?(@abstract_class) && @abstract_class
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def class_of_active_ldap_descendant(klass)
|
|
466
|
+
if klass.superclass == Base or klass.superclass.abstract_class?
|
|
467
|
+
klass
|
|
468
|
+
elsif klass.superclass.nil?
|
|
469
|
+
raise Error, _("%s doesn't belong in a hierarchy descending " \
|
|
470
|
+
"from ActiveLdap") % (name || to_s)
|
|
471
|
+
else
|
|
472
|
+
class_of_active_ldap_descendant(klass.superclass)
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
def self_and_descendents_from_active_ldap
|
|
477
|
+
klass = self
|
|
478
|
+
classes = [klass]
|
|
479
|
+
while klass != klass.base_class
|
|
480
|
+
classes << klass = klass.superclass
|
|
481
|
+
end
|
|
482
|
+
classes
|
|
483
|
+
rescue
|
|
484
|
+
[self]
|
|
485
|
+
end
|
|
486
|
+
alias_method(:self_and_descendents_from_active_record,
|
|
487
|
+
:self_and_descendents_from_active_ldap)
|
|
488
|
+
|
|
489
|
+
def human_name(options={})
|
|
490
|
+
defaults = self_and_descendents_from_active_ldap.collect do |klass|
|
|
491
|
+
if klass.name.blank?
|
|
492
|
+
nil
|
|
493
|
+
else
|
|
494
|
+
:"#{klass.name.underscore}"
|
|
495
|
+
end
|
|
496
|
+
end
|
|
497
|
+
defaults << name.humanize
|
|
498
|
+
defaults = defaults.compact
|
|
499
|
+
defaults.first || name || to_s
|
|
500
|
+
end
|
|
501
|
+
|
|
457
502
|
private
|
|
458
503
|
def inspect_attributes(attributes)
|
|
459
504
|
inspected_attribute_names = {}
|
|
@@ -579,7 +624,6 @@ module ActiveLdap
|
|
|
579
624
|
raise ArgumentError, format % attributes.inspect
|
|
580
625
|
end
|
|
581
626
|
yield self if block_given?
|
|
582
|
-
assert_dn_attribute
|
|
583
627
|
end
|
|
584
628
|
|
|
585
629
|
# Returns true if the +comparison_object+ is the same object, or is of
|
|
@@ -648,7 +692,7 @@ module ActiveLdap
|
|
|
648
692
|
end
|
|
649
693
|
|
|
650
694
|
def id
|
|
651
|
-
get_attribute(
|
|
695
|
+
get_attribute(dn_attribute_with_fallback)
|
|
652
696
|
end
|
|
653
697
|
|
|
654
698
|
def to_param
|
|
@@ -656,13 +700,14 @@ module ActiveLdap
|
|
|
656
700
|
end
|
|
657
701
|
|
|
658
702
|
def dn=(value)
|
|
659
|
-
set_attribute(
|
|
703
|
+
set_attribute(dn_attribute_with_fallback, value)
|
|
660
704
|
@dn = nil
|
|
661
705
|
end
|
|
662
706
|
alias_method(:id=, :dn=)
|
|
663
707
|
|
|
664
708
|
alias_method(:dn_attribute_of_class, :dn_attribute)
|
|
665
709
|
def dn_attribute
|
|
710
|
+
ensure_update_dn
|
|
666
711
|
_dn_attribute = @dn_attribute || dn_attribute_of_class
|
|
667
712
|
to_real_attribute_name(_dn_attribute) || _dn_attribute
|
|
668
713
|
end
|
|
@@ -792,7 +837,7 @@ module ActiveLdap
|
|
|
792
837
|
# Also be sure to only pass in key-value pairs of your choosing.
|
|
793
838
|
# Do not let URL/form hackers supply the keys.
|
|
794
839
|
def attributes=(new_attributes)
|
|
795
|
-
return if new_attributes.
|
|
840
|
+
return if new_attributes.blank?
|
|
796
841
|
_schema = _local_entry_attribute = nil
|
|
797
842
|
targets = remove_attributes_protected_from_mass_assignment(new_attributes)
|
|
798
843
|
targets.each do |key, value|
|
|
@@ -817,26 +862,23 @@ module ActiveLdap
|
|
|
817
862
|
end
|
|
818
863
|
|
|
819
864
|
def to_xml(options={})
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
value.each do |option, real_value|
|
|
828
|
-
targets << [real_value, " #{option}=\"true\""]
|
|
829
|
-
end
|
|
865
|
+
options = options.dup
|
|
866
|
+
options[:root] ||= self.class.name.underscore
|
|
867
|
+
except = options[:except]
|
|
868
|
+
if except
|
|
869
|
+
options[:except] = except.collect do |name|
|
|
870
|
+
if name.to_s.downcase == "dn"
|
|
871
|
+
"dn"
|
|
830
872
|
else
|
|
831
|
-
|
|
873
|
+
to_real_attribute_name(name)
|
|
832
874
|
end
|
|
833
|
-
end
|
|
834
|
-
targets.sort_by {|value, attr| value}.each do |value, attr|
|
|
835
|
-
result << " <#{key}#{attr}>#{value}</#{key}>\n"
|
|
836
|
-
end
|
|
875
|
+
end.compact
|
|
837
876
|
end
|
|
838
|
-
|
|
839
|
-
|
|
877
|
+
XML.new(dn, normalize_data(@data), schema).to_s(options)
|
|
878
|
+
end
|
|
879
|
+
|
|
880
|
+
def to_s
|
|
881
|
+
to_ldif
|
|
840
882
|
end
|
|
841
883
|
|
|
842
884
|
def have_attribute?(name, except=[])
|
|
@@ -922,7 +964,10 @@ module ActiveLdap
|
|
|
922
964
|
|
|
923
965
|
alias_method :base_of_class, :base
|
|
924
966
|
def base
|
|
925
|
-
|
|
967
|
+
ensure_update_dn
|
|
968
|
+
[@base, base_of_class].find_all do |component|
|
|
969
|
+
not component.blank?
|
|
970
|
+
end.join(",")
|
|
926
971
|
end
|
|
927
972
|
|
|
928
973
|
undef_method :base=
|
|
@@ -959,6 +1004,17 @@ module ActiveLdap
|
|
|
959
1004
|
end
|
|
960
1005
|
|
|
961
1006
|
private
|
|
1007
|
+
def dn_attribute_with_fallback
|
|
1008
|
+
begin
|
|
1009
|
+
dn_attribute
|
|
1010
|
+
rescue DistinguishedNameInvalid
|
|
1011
|
+
_dn_attribute = @dn_attribute || dn_attribute_of_class
|
|
1012
|
+
_dn_attribute = to_real_attribute_name(_dn_attribute) || _dn_attribute
|
|
1013
|
+
raise if _dn_attribute.nil?
|
|
1014
|
+
_dn_attribute
|
|
1015
|
+
end
|
|
1016
|
+
end
|
|
1017
|
+
|
|
962
1018
|
def inspect_attribute(name)
|
|
963
1019
|
values = get_attribute(name, true)
|
|
964
1020
|
values.collect do |value|
|
|
@@ -1014,7 +1070,6 @@ module ActiveLdap
|
|
|
1014
1070
|
self.dn = dn
|
|
1015
1071
|
self.attributes = attributes
|
|
1016
1072
|
yield self if block_given?
|
|
1017
|
-
assert_dn_attribute
|
|
1018
1073
|
end
|
|
1019
1074
|
|
|
1020
1075
|
def instantiate(args)
|
|
@@ -1059,6 +1114,8 @@ module ActiveLdap
|
|
|
1059
1114
|
@base = nil
|
|
1060
1115
|
@scope = nil
|
|
1061
1116
|
@dn = nil
|
|
1117
|
+
@dn_is_base = false
|
|
1118
|
+
@dn_split_value = nil
|
|
1062
1119
|
@connection ||= nil
|
|
1063
1120
|
clear_connection_based_cache
|
|
1064
1121
|
end
|
|
@@ -1119,35 +1176,61 @@ module ActiveLdap
|
|
|
1119
1176
|
#
|
|
1120
1177
|
# Set the value of the attribute called by method_missing?
|
|
1121
1178
|
def set_attribute(name, value)
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1179
|
+
real_name = to_real_attribute_name(name)
|
|
1180
|
+
_dn_attribute = nil
|
|
1181
|
+
valid_dn_attribute = true
|
|
1182
|
+
begin
|
|
1183
|
+
_dn_attribute = dn_attribute
|
|
1184
|
+
rescue DistinguishedNameInvalid
|
|
1185
|
+
valid_dn_attribute = false
|
|
1186
|
+
end
|
|
1187
|
+
if valid_dn_attribute and real_name == _dn_attribute
|
|
1188
|
+
real_name, value = register_new_dn_attribute(real_name, value)
|
|
1189
|
+
end
|
|
1190
|
+
raise UnknownAttribute.new(name) if real_name.nil?
|
|
1125
1191
|
|
|
1126
|
-
@data[
|
|
1192
|
+
@data[real_name] = value
|
|
1127
1193
|
end
|
|
1128
1194
|
|
|
1129
|
-
def
|
|
1195
|
+
def register_new_dn_attribute(name, value)
|
|
1130
1196
|
@dn = nil
|
|
1131
1197
|
@dn_is_base = false
|
|
1132
|
-
|
|
1198
|
+
if value.blank?
|
|
1199
|
+
@dn_split_value = nil
|
|
1200
|
+
[name, nil]
|
|
1201
|
+
else
|
|
1202
|
+
new_name, new_value, raw_new_value, new_bases = split_dn_value(value)
|
|
1203
|
+
@dn_split_value = [new_name, new_value, new_bases]
|
|
1204
|
+
if new_name.nil? and new_value.nil?
|
|
1205
|
+
new_name, raw_new_value = new_bases[0].to_a[0]
|
|
1206
|
+
end
|
|
1207
|
+
[to_real_attribute_name(new_name) || name,
|
|
1208
|
+
raw_new_value || value]
|
|
1209
|
+
end
|
|
1210
|
+
end
|
|
1133
1211
|
|
|
1134
|
-
|
|
1135
|
-
if
|
|
1212
|
+
def update_dn(new_name, new_value, bases)
|
|
1213
|
+
if new_name.nil? and new_value.nil?
|
|
1136
1214
|
@dn_is_base = true
|
|
1137
1215
|
@base = nil
|
|
1138
1216
|
attr, value = bases[0].to_a[0]
|
|
1139
1217
|
@dn_attribute = attr
|
|
1140
1218
|
else
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
@dn_attribute = attr = new_dn_attribute
|
|
1147
|
-
end
|
|
1219
|
+
new_name ||= @dn_attribute || dn_attribute_of_class
|
|
1220
|
+
new_name = to_real_attribute_name(new_name)
|
|
1221
|
+
if new_name.nil?
|
|
1222
|
+
new_name = @dn_attribute || dn_attribute_of_class
|
|
1223
|
+
new_name = to_real_attribute_name(new_name)
|
|
1148
1224
|
end
|
|
1225
|
+
new_bases = bases.empty? ? nil : DN.new(*bases).to_s
|
|
1226
|
+
dn_components = ["#{new_name}=#{new_value}",
|
|
1227
|
+
new_bases,
|
|
1228
|
+
base_of_class]
|
|
1229
|
+
dn_components = dn_components.find_all {|component| !component.blank?}
|
|
1230
|
+
DN.parse(dn_components.join(','))
|
|
1231
|
+
@base = new_bases
|
|
1232
|
+
@dn_attribute = new_name
|
|
1149
1233
|
end
|
|
1150
|
-
[attr, value]
|
|
1151
1234
|
end
|
|
1152
1235
|
|
|
1153
1236
|
def split_dn_value(value)
|
|
@@ -1156,9 +1239,14 @@ module ActiveLdap
|
|
|
1156
1239
|
dn_value = value if value.is_a?(DN)
|
|
1157
1240
|
dn_value ||= DN.parse(value)
|
|
1158
1241
|
rescue DistinguishedNameInvalid
|
|
1159
|
-
|
|
1242
|
+
begin
|
|
1243
|
+
dn_value = DN.parse("#{dn_attribute}=#{value}")
|
|
1244
|
+
rescue DistinguishedNameInvalid
|
|
1245
|
+
return [nil, value, value, []]
|
|
1246
|
+
end
|
|
1160
1247
|
end
|
|
1161
1248
|
|
|
1249
|
+
val = bases = nil
|
|
1162
1250
|
begin
|
|
1163
1251
|
relative_dn_value = dn_value - self.class.parsed_base
|
|
1164
1252
|
if relative_dn_value.rdns.empty?
|
|
@@ -1172,20 +1260,41 @@ module ActiveLdap
|
|
|
1172
1260
|
end
|
|
1173
1261
|
|
|
1174
1262
|
dn_attribute_name, dn_attribute_value = val.to_a[0]
|
|
1175
|
-
|
|
1263
|
+
escaped_dn_attribute_value = nil
|
|
1264
|
+
unless dn_attribute_value.nil?
|
|
1265
|
+
escaped_dn_attribute_value = DN.escape_value(dn_attribute_value)
|
|
1266
|
+
end
|
|
1267
|
+
[dn_attribute_name, escaped_dn_attribute_value,
|
|
1268
|
+
dn_attribute_value, bases]
|
|
1269
|
+
end
|
|
1270
|
+
|
|
1271
|
+
def need_update_dn?
|
|
1272
|
+
not @dn_split_value.nil?
|
|
1273
|
+
end
|
|
1274
|
+
|
|
1275
|
+
def ensure_update_dn
|
|
1276
|
+
return unless need_update_dn?
|
|
1277
|
+
@mutex.synchronize do
|
|
1278
|
+
if @dn_split_value
|
|
1279
|
+
update_dn(*@dn_split_value)
|
|
1280
|
+
@dn_split_value = nil
|
|
1281
|
+
end
|
|
1282
|
+
end
|
|
1176
1283
|
end
|
|
1177
1284
|
|
|
1178
1285
|
def compute_dn(escape_dn_value=false)
|
|
1179
1286
|
return base if @dn_is_base
|
|
1180
1287
|
|
|
1288
|
+
ensure_update_dn
|
|
1181
1289
|
dn_value = id
|
|
1182
1290
|
if dn_value.nil?
|
|
1183
|
-
|
|
1184
|
-
|
|
1291
|
+
format =_("%s's DN attribute (%s) isn't set")
|
|
1292
|
+
message = format % [self.inspect, dn_attribute]
|
|
1293
|
+
raise DistinguishedNameNotSetError.new, message
|
|
1185
1294
|
end
|
|
1186
|
-
dn_value = DN.escape_value(dn_value) if escape_dn_value
|
|
1295
|
+
dn_value = DN.escape_value(dn_value.to_s) if escape_dn_value
|
|
1187
1296
|
_base = base
|
|
1188
|
-
_base = nil if _base.
|
|
1297
|
+
_base = nil if _base.blank?
|
|
1189
1298
|
["#{dn_attribute}=#{dn_value}", _base].compact.join(",")
|
|
1190
1299
|
end
|
|
1191
1300
|
|
|
@@ -1292,13 +1401,6 @@ module ActiveLdap
|
|
|
1292
1401
|
attributes
|
|
1293
1402
|
end
|
|
1294
1403
|
|
|
1295
|
-
def assert_dn_attribute
|
|
1296
|
-
unless dn_attribute
|
|
1297
|
-
raise ConfigurationError,
|
|
1298
|
-
_("dn_attribute isn't set for this class: %s") % self.class
|
|
1299
|
-
end
|
|
1300
|
-
end
|
|
1301
|
-
|
|
1302
1404
|
def create_or_update
|
|
1303
1405
|
new_entry? ? create : update
|
|
1304
1406
|
end
|