activeldap 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. data/CHANGES +10 -0
  2. data/README +3 -2
  3. data/data/locale/en/LC_MESSAGES/active-ldap.mo +0 -0
  4. data/data/locale/ja/LC_MESSAGES/active-ldap.mo +0 -0
  5. data/examples/al-admin/po/en/al-admin.po +1 -1
  6. data/examples/al-admin/po/ja/al-admin.po +1 -1
  7. data/examples/al-admin/po/nl/al-admin.po +1 -1
  8. data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifier.rb +7 -8
  9. data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifier_helper.rb +2 -1
  10. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml +1 -1
  11. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml +2 -1
  12. data/lib/active_ldap.rb +9 -3
  13. data/lib/active_ldap/action_controller/ldap_benchmarking.rb +36 -0
  14. data/lib/active_ldap/adapter/jndi.rb +1 -1
  15. data/lib/active_ldap/adapter/jndi_connection.rb +2 -1
  16. data/lib/active_ldap/association/belongs_to_many.rb +10 -2
  17. data/lib/active_ldap/association/collection.rb +10 -0
  18. data/lib/active_ldap/association/has_many_utils.rb +13 -9
  19. data/lib/active_ldap/association/has_many_wrap.rb +10 -2
  20. data/lib/active_ldap/associations.rb +3 -3
  21. data/lib/active_ldap/base.rb +95 -32
  22. data/lib/active_ldap/connection.rb +1 -1
  23. data/lib/active_ldap/distinguished_name.rb +3 -0
  24. data/lib/active_ldap/entry_attribute.rb +2 -2
  25. data/lib/active_ldap/ldif.rb +2 -2
  26. data/lib/active_ldap/operations.rb +7 -3
  27. data/lib/active_ldap/user_password.rb +0 -1
  28. data/lib/active_ldap/validations.rb +2 -0
  29. data/po/en/active-ldap.po +1 -1
  30. data/po/ja/active-ldap.po +1 -1
  31. data/rails/plugin/active_ldap/init.rb +3 -34
  32. data/test-unit/History.txt +32 -0
  33. data/test-unit/Manifest.txt +70 -0
  34. data/test-unit/README.txt +32 -0
  35. data/test-unit/Rakefile +22 -0
  36. data/test-unit/bin/testrb +5 -0
  37. data/test-unit/lib/test/unit.rb +280 -0
  38. data/test-unit/lib/test/unit/assertionfailederror.rb +14 -0
  39. data/test-unit/lib/test/unit/assertions.rb +722 -0
  40. data/test-unit/lib/test/unit/attribute.rb +125 -0
  41. data/test-unit/lib/test/unit/autorunner.rb +250 -0
  42. data/test-unit/lib/test/unit/collector.rb +43 -0
  43. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  44. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  45. data/test-unit/lib/test/unit/collector/load.rb +135 -0
  46. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  47. data/test-unit/lib/test/unit/color.rb +61 -0
  48. data/test-unit/lib/test/unit/diff.rb +524 -0
  49. data/test-unit/lib/test/unit/error.rb +124 -0
  50. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  51. data/test-unit/lib/test/unit/failure.rb +110 -0
  52. data/test-unit/lib/test/unit/fixture.rb +185 -0
  53. data/test-unit/lib/test/unit/notification.rb +116 -0
  54. data/test-unit/lib/test/unit/omission.rb +129 -0
  55. data/test-unit/lib/test/unit/pending.rb +130 -0
  56. data/test-unit/lib/test/unit/priority.rb +146 -0
  57. data/test-unit/lib/test/unit/runner/console.rb +46 -0
  58. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  59. data/test-unit/lib/test/unit/testcase.rb +174 -0
  60. data/test-unit/lib/test/unit/testresult.rb +89 -0
  61. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  62. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  63. data/test-unit/lib/test/unit/ui/console/testrunner.rb +195 -0
  64. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +49 -0
  65. data/test-unit/lib/test/unit/ui/testrunner.rb +20 -0
  66. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  67. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  68. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  69. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  70. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  71. data/test-unit/lib/test/unit/version.rb +7 -0
  72. data/test-unit/sample/adder.rb +13 -0
  73. data/test-unit/sample/subtracter.rb +12 -0
  74. data/test-unit/sample/tc_adder.rb +18 -0
  75. data/test-unit/sample/tc_subtracter.rb +18 -0
  76. data/test-unit/sample/ts_examples.rb +7 -0
  77. data/test-unit/test/collector/test_descendant.rb +135 -0
  78. data/test-unit/test/collector/test_dir.rb +406 -0
  79. data/test-unit/test/collector/test_load.rb +333 -0
  80. data/test-unit/test/collector/test_objectspace.rb +98 -0
  81. data/test-unit/test/run-test.rb +13 -0
  82. data/test-unit/test/test_assertions.rb +693 -0
  83. data/test-unit/test/test_attribute.rb +86 -0
  84. data/{test-unit-ext → test-unit}/test/test_color.rb +3 -5
  85. data/{test-unit-ext → test-unit}/test/test_diff.rb +18 -16
  86. data/test-unit/test/test_emacs_runner.rb +60 -0
  87. data/test-unit/test/test_error.rb +26 -0
  88. data/test-unit/test/test_failure.rb +33 -0
  89. data/test-unit/test/test_fixture.rb +275 -0
  90. data/{test-unit-ext → test-unit}/test/test_notification.rb +7 -6
  91. data/test-unit/test/test_omission.rb +81 -0
  92. data/{test-unit-ext → test-unit}/test/test_pending.rb +15 -15
  93. data/{test-unit-ext → test-unit}/test/test_priority.rb +4 -3
  94. data/test-unit/test/test_testcase.rb +411 -0
  95. data/test-unit/test/test_testresult.rb +113 -0
  96. data/test-unit/test/test_testsuite.rb +129 -0
  97. data/test-unit/test/testunit_test_util.rb +12 -0
  98. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  99. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  100. data/test-unit/test/util/test_observable.rb +102 -0
  101. data/test-unit/test/util/test_procwrapper.rb +36 -0
  102. data/test/al-test-utils.rb +4 -4
  103. data/test/command.rb +1 -1
  104. data/test/run-test.rb +5 -4
  105. data/test/test_associations.rb +143 -9
  106. data/test/test_base.rb +25 -1
  107. data/test/test_dn.rb +2 -0
  108. data/test/test_find.rb +8 -1
  109. data/test/test_ldif.rb +51 -114
  110. data/test/test_reflection.rb +4 -8
  111. data/test/test_usermod-lang-add.rb +2 -1
  112. data/test/test_validation.rb +4 -3
  113. metadata +76 -31
  114. data/test-unit-ext/NEWS.en +0 -28
  115. data/test-unit-ext/NEWS.ja +0 -28
  116. data/test-unit-ext/README.en +0 -247
  117. data/test-unit-ext/README.ja +0 -246
  118. data/test-unit-ext/Rakefile +0 -111
  119. data/test-unit-ext/lib/test-unit-ext.rb +0 -16
  120. data/test-unit-ext/lib/test-unit-ext/always-show-result.rb +0 -28
  121. data/test-unit-ext/lib/test-unit-ext/assertions.rb +0 -40
  122. data/test-unit-ext/lib/test-unit-ext/attributes.rb +0 -129
  123. data/test-unit-ext/lib/test-unit-ext/backtrace-filter.rb +0 -17
  124. data/test-unit-ext/lib/test-unit-ext/color.rb +0 -59
  125. data/test-unit-ext/lib/test-unit-ext/colorized-runner.rb +0 -111
  126. data/test-unit-ext/lib/test-unit-ext/diff.rb +0 -516
  127. data/test-unit-ext/lib/test-unit-ext/long-display-for-emacs.rb +0 -25
  128. data/test-unit-ext/lib/test-unit-ext/notification.rb +0 -79
  129. data/test-unit-ext/lib/test-unit-ext/omission.rb +0 -96
  130. data/test-unit-ext/lib/test-unit-ext/pending.rb +0 -97
  131. data/test-unit-ext/lib/test-unit-ext/priority.rb +0 -158
  132. data/test-unit-ext/lib/test-unit-ext/version.rb +0 -3
  133. data/test-unit-ext/lib/test-unit-ext/xml-report.rb +0 -224
  134. data/test-unit-ext/test/run-test.rb +0 -14
  135. data/test-unit-ext/test/test_attributes.rb +0 -139
  136. data/test-unit-ext/test/test_omission.rb +0 -64
  137. data/test-unit-ext/test/test_xml_report.rb +0 -161
data/CHANGES CHANGED
@@ -1,3 +1,13 @@
1
+ 1.0.1:
2
+ * Fixed GetText integration.
3
+ * Fixed ActiveLdap::Base.find with ActiveLdap::DN. (Reported by Jeremy Pruitt)
4
+ * Fixed associated bugs. (Reported by CultureSpy)
5
+ * Supported ActiveLdap::Base#attribute_present? with nonexistence attribute.
6
+ (Reported by Matt Mencel)
7
+ * Added ActiveLdap::Base#.to_ldif_record.
8
+ * Improved inspect.
9
+ * Supported ActiveSupport 2.1.0.
10
+
1
11
  1.0.0:
2
12
  * Fixed GSSAPI auth failure. [#18764] (Reported by Lennon Day-Reynolds)
3
13
  * Supported Symbol as :dn_attribute_value. [#18921] (Requested by Nobody)
data/README CHANGED
@@ -29,7 +29,6 @@ PREREQUISITES
29
29
  NOTES
30
30
 
31
31
  * Only GSSAPI SASL support exists due to Ruby/LDAP limitations
32
- * The API is subject to change as this package slowly approaches 1.0.0
33
32
 
34
33
 
35
34
  INSTALL
@@ -100,7 +99,7 @@ list, please point out.
100
99
  * Kevin McCarthy: Patches.
101
100
  * Perry Smith: Patches, bug reports and indications.
102
101
  * Marc Dequènes: API suggestions.
103
- * Jeremy Pruitt: A bug report.
102
+ * Jeremy Pruitt: Bug reports.
104
103
  * Bodaniel Jeanes:
105
104
  * A suggestion for behavior on simple bind with empty password.
106
105
  * Bug reports.
@@ -108,3 +107,5 @@ list, please point out.
108
107
  * David Morton: An API improvement idea.
109
108
  * Lennon Day-Reynolds: Bug reports.
110
109
  * Tilo: A bug report.
110
+ * Matt Mencel: A bug report.
111
+ * CultureSpy: A bug report.
@@ -5,7 +5,7 @@
5
5
  #
6
6
  msgid ""
7
7
  msgstr ""
8
- "Project-Id-Version: AL Admin 1.0.0\n"
8
+ "Project-Id-Version: AL Admin 1.0.1\n"
9
9
  "POT-Creation-Date: 2008-02-09 14:25+0900\n"
10
10
  "PO-Revision-Date: 2007-08-19 09:44+0900\n"
11
11
  "Last-Translator: Kouhei Sutou <kou@cozmixng.org>\n"
@@ -5,7 +5,7 @@
5
5
  #
6
6
  msgid ""
7
7
  msgstr ""
8
- "Project-Id-Version: AL Admin 1.0.0\n"
8
+ "Project-Id-Version: AL Admin 1.0.1\n"
9
9
  "POT-Creation-Date: 2008-02-09 14:25+0900\n"
10
10
  "PO-Revision-Date: 2007-11-04 16:02+0900\n"
11
11
  "Last-Translator: Kouhei Sutou <kou@cozmixng.org>\n"
@@ -6,7 +6,7 @@
6
6
  # Ace Suares <ace@suares.an>, 2007,2008.
7
7
  msgid ""
8
8
  msgstr ""
9
- "Project-Id-Version: AL Admin 1.0.0\n"
9
+ "Project-Id-Version: AL Admin 1.0.1\n"
10
10
  "POT-Creation-Date: 2008-02-09 14:25+0900\n"
11
11
  "PO-Revision-Date: 2007-08-24 22:03+0900\n"
12
12
  "Last-Translator: Ace Suares <ace@suares.an>\n"
@@ -33,25 +33,25 @@ class ExceptionNotifier < ActionMailer::Base
33
33
  @@sections = %w(request session environment backtrace)
34
34
  cattr_accessor :sections
35
35
 
36
- def self.reloadable?; false; end
36
+ self.template_root = "#{File.dirname(__FILE__)}/../views"
37
+
38
+ def self.reloadable?() false end
37
39
 
38
40
  def exception_notification(exception, controller, request, data={})
41
+ content_type "text/plain"
42
+
39
43
  subject "#{email_prefix}#{controller.controller_name}##{controller.action_name} (#{exception.class}) #{exception.message.inspect}"
40
44
 
41
45
  recipients exception_recipients
42
46
  from sender_address
43
47
 
44
48
  body data.merge({ :controller => controller, :request => request,
45
- :exception => exception, :host => request.env["HTTP_HOST"],
49
+ :exception => exception, :host => (request.env["HTTP_X_FORWARDED_HOST"] || request.env["HTTP_HOST"]),
46
50
  :backtrace => sanitize_backtrace(exception.backtrace),
47
51
  :rails_root => rails_root, :data => data,
48
52
  :sections => sections })
49
53
  end
50
54
 
51
- def template_root
52
- "#{File.dirname(__FILE__)}/../views"
53
- end
54
-
55
55
  private
56
56
 
57
57
  def sanitize_backtrace(trace)
@@ -60,8 +60,7 @@ class ExceptionNotifier < ActionMailer::Base
60
60
  end
61
61
 
62
62
  def rails_root
63
- return @rails_root if @rails_root
64
- @rails_root = Pathname.new(RAILS_ROOT).cleanpath.to_s
63
+ @rails_root ||= Pathname.new(RAILS_ROOT).cleanpath.to_s
65
64
  end
66
65
 
67
66
  end
@@ -72,6 +72,7 @@ module ExceptionNotifierHelper
72
72
 
73
73
  def filter_sensitive_post_data_from_env(env_key, env_value)
74
74
  return env_value unless exclude_raw_post_parameters?
75
- (env_key =~ /RAW_POST_DATA/i) ? PARAM_FILTER_REPLACEMENT : env_value
75
+ return PARAM_FILTER_REPLACEMENT if (env_key =~ /RAW_POST_DATA/i)
76
+ return @controller.filter_parameters({env_key => env_value}).values[0]
76
77
  end
77
78
  end
@@ -1,6 +1,6 @@
1
1
  <% max = @request.env.keys.max { |a,b| a.length <=> b.length } -%>
2
2
  <% @request.env.keys.sort.each do |key| -%>
3
- * <%= "%*-s: %s" % [max.length, key, filter_sensitive_post_data_from_env(key, @request.env[key].to_s.strip)] %>
3
+ * <%= "%-*s: %s" % [max.length, key, filter_sensitive_post_data_from_env(key, @request.env[key].to_s.strip)] %>
4
4
  <% end -%>
5
5
 
6
6
  * Process: <%= $$ %>
@@ -1,3 +1,4 @@
1
- * URL: <%= @request.protocol %><%= @host %><%= @request.request_uri %>
1
+ * URL : <%= @request.protocol %><%= @host %><%= @request.request_uri %>
2
+ * IP address: <%= @request.env["HTTP_X_FORWARDED_FOR"] || @request.env["REMOTE_ADDR"] %>
2
3
  * Parameters: <%= filter_sensitive_post_data_parameters(@request.parameters).inspect %>
3
4
  * Rails root: <%= @rails_root %>
@@ -917,12 +917,18 @@ end
917
917
 
918
918
  require_gem_if_need.call("active_support", "activesupport")
919
919
 
920
- if Dependencies.respond_to?(:load_paths)
921
- Dependencies.load_paths << File.expand_path(File.dirname(__FILE__))
920
+ if ActiveSupport.const_defined?(:Dependencies)
921
+ dependencies = ActiveSupport::Dependencies
922
+ else
923
+ dependencies = Dependencies
924
+ end
925
+
926
+ if dependencies.respond_to?(:load_paths)
927
+ dependencies.load_paths << File.expand_path(File.dirname(__FILE__))
922
928
  end
923
929
 
924
930
  module ActiveLdap
925
- VERSION = "1.0.0"
931
+ VERSION = "1.0.1"
926
932
  end
927
933
 
928
934
  if RUBY_PLATFORM.match('linux')
@@ -0,0 +1,36 @@
1
+ module ActiveLdap
2
+ module ActionController
3
+ module LdapBenchmarking
4
+ def self.included(base)
5
+ base.class_eval do
6
+ alias_method_chain :render, :active_ldap_benchmark
7
+ alias_method_chain :rendering_runtime, :active_ldap
8
+ end
9
+ end
10
+
11
+ protected
12
+ def render_with_active_ldap_benchmark(*args, &block)
13
+ if logger
14
+ @ldap_runtime_before_render = ActiveLdap::Base.reset_runtime
15
+ result = render_without_active_ldap_benchmark(*args, &block)
16
+ @ldap_runtime_after_render = ActiveLdap::Base.reset_runtime
17
+ @rendering_runtime -= @ldap_runtime_after_render
18
+ result
19
+ else
20
+ render_without_active_ldap_benchmark(*args, &block)
21
+ end
22
+ end
23
+
24
+ private
25
+ def rendering_runtime_with_active_ldap(runtime)
26
+ result = rendering_runtime_without_active_ldap(runtime)
27
+ ldap_runtime = ActiveLdap::Base.reset_runtime
28
+ ldap_runtime += @ldap_runtime_before_render || 0
29
+ ldap_runtime += @ldap_runtime_after_render || 0
30
+ ldap_percentage = ldap_runtime * 100 / runtime
31
+ result + (" | LDAP: %.5f (%d%%)" % [ldap_runtime, ldap_percentage])
32
+ end
33
+ end
34
+ end
35
+ end
36
+
@@ -82,7 +82,7 @@ module ActiveLdap
82
82
  :name => "modify: RDN", :dn => dn, :new_rdn => new_rdn,
83
83
  :delete_old_rdn => delete_old_rdn,
84
84
  }
85
- execute(:modify_rdn, dn, new_rdn, delete_old_rdn)
85
+ execute(:modify_rdn, info, dn, new_rdn, delete_old_rdn)
86
86
  end
87
87
  end
88
88
 
@@ -103,7 +103,7 @@ module ActiveLdap
103
103
  controls = SearchControls.new
104
104
  controls.search_scope = scope
105
105
 
106
- if attrs && !attrs.empty?
106
+ unless attrs.blank?
107
107
  controls.returning_attributes = attrs.to_java(:string)
108
108
  end
109
109
 
@@ -168,6 +168,7 @@ module ActiveLdap
168
168
  if password
169
169
  context.add_to_environment(Context::SECURITY_CREDENTIALS, password)
170
170
  end
171
+ context.reconnect(nil)
171
172
  @context = context
172
173
  end
173
174
 
@@ -6,7 +6,11 @@ module ActiveLdap
6
6
  private
7
7
  def insert_entry(entry)
8
8
  old_value = entry[@options[:many], true]
9
- new_value = old_value + @owner[@options[:foreign_key_name], true]
9
+ foreign_key_name = @options[:foreign_key_name]
10
+ if foreign_key_name == "dn"
11
+ old_value = dn_values_to_string_values(old_value)
12
+ end
13
+ new_value = old_value + @owner[foreign_key_name, true]
10
14
  new_value = new_value.uniq.sort
11
15
  if old_value != new_value
12
16
  entry[@options[:many]] = new_value
@@ -17,7 +21,11 @@ module ActiveLdap
17
21
  def delete_entries(entries)
18
22
  entries.each do |entry|
19
23
  old_value = entry[@options[:many], true]
20
- new_value = old_value - @owner[@options[:foreign_key_name], true]
24
+ foreign_key_name = @options[:foreign_key_name]
25
+ if foreign_key_name == "dn"
26
+ old_value = dn_values_to_string_values(old_value)
27
+ end
28
+ new_value = old_value - @owner[foreign_key_name, true]
21
29
  new_value = new_value.uniq.sort
22
30
  if old_value != new_value
23
31
  entry[@options[:many]] = new_value
@@ -78,6 +78,16 @@ module ActiveLdap
78
78
 
79
79
  result && self
80
80
  end
81
+
82
+ def dn_values_to_string_values(values)
83
+ values.collect do |value|
84
+ if value.is_a?(DN)
85
+ value.to_s
86
+ else
87
+ value
88
+ end
89
+ end
90
+ end
81
91
  end
82
92
  end
83
93
  end
@@ -8,18 +8,22 @@ module ActiveLdap
8
8
 
9
9
  requested_targets = @owner[@options[requested_target_key], true]
10
10
 
11
- components = requested_targets.reject(&:nil?)
12
- unless foreign_base_key == "dn"
13
- components = components.collect do |value|
14
- [foreign_base_key, value]
15
- end
16
- end
17
-
18
- if components.empty?
11
+ requested_targets = requested_targets.reject(&:nil?)
12
+ if requested_targets.empty?
19
13
  targets = []
20
14
  elsif foreign_base_key == "dn"
21
- targets = foreign_class.find(components, find_options)
15
+ requested_targets = requested_targets.collect do |target|
16
+ if target.is_a?(DN)
17
+ target.to_s
18
+ else
19
+ target
20
+ end
21
+ end
22
+ targets = foreign_class.find(requested_targets, find_options)
22
23
  else
24
+ components = requested_targets.collect do |value|
25
+ [foreign_base_key, value]
26
+ end
23
27
  options = find_options(:filter => [:or, *components])
24
28
  targets = foreign_class.find(:all, options)
25
29
  end
@@ -9,7 +9,11 @@ module ActiveLdap
9
9
  private
10
10
  def insert_entry(entry)
11
11
  old_value = @owner[@options[:wrap], true]
12
- new_value = (old_value + entry[primary_key, true]).uniq.sort
12
+ _primary_key = primary_key
13
+ if _primary_key == "dn"
14
+ old_value = dn_values_to_string_values(old_value)
15
+ end
16
+ new_value = (old_value + entry[_primary_key, true]).uniq.sort
13
17
  if old_value != new_value
14
18
  @owner[@options[:wrap]] = new_value
15
19
  @owner.save
@@ -18,7 +22,11 @@ module ActiveLdap
18
22
 
19
23
  def delete_entries(entries)
20
24
  old_value = @owner[@options[:wrap], true]
21
- new_value = old_value - entries.collect {|entry| entry[primary_key]}
25
+ _primary_key = primary_key
26
+ if _primary_key == "dn"
27
+ old_value = dn_values_to_string_values(old_value)
28
+ end
29
+ new_value = old_value - entries.collect {|entry| entry[_primary_key]}
22
30
  new_value = new_value.uniq.sort
23
31
  if old_value != new_value
24
32
  @owner[@options[:wrap]] = new_value
@@ -44,7 +44,7 @@ module ActiveLdap
44
44
  #
45
45
  def belongs_to(association_id, options={})
46
46
  validate_belongs_to_options(options)
47
- klass = options[:class] || Inflector.classify(association_id)
47
+ klass = options[:class] || association_id.to_s.classify
48
48
  foreign_key = options[:foreign_key]
49
49
  primary_key = options[:primary_key]
50
50
  many = options[:many]
@@ -96,8 +96,8 @@ module ActiveLdap
96
96
  # :wrap => "memberUid" # Group#memberUid
97
97
  def has_many(association_id, options = {})
98
98
  validate_has_many_options(options)
99
- klass = options[:class] || Inflector.classify(association_id)
100
- foreign_key = options[:foreign_key] || association_id.to_s + "_id"
99
+ klass = options[:class] || association_id.to_s.classify
100
+ foreign_key = options[:foreign_key] || "#{association_id}_id"
101
101
  primary_key = options[:primary_key]
102
102
  set_associated_class(association_id, klass)
103
103
 
@@ -105,6 +105,14 @@ module ActiveLdap
105
105
  class StrongAuthenticationRequired < Error
106
106
  end
107
107
 
108
+ class DistinguishedNameInputInvalid < Error
109
+ attr_reader :input
110
+ def initialize(input=nil)
111
+ @input = input
112
+ super(_("invalid distinguished name (DN) to parse: %s") % @input.inspect)
113
+ end
114
+ end
115
+
108
116
  class DistinguishedNameInvalid < Error
109
117
  attr_reader :dn, :reason
110
118
  def initialize(dn, reason=nil)
@@ -293,6 +301,13 @@ module ActiveLdap
293
301
  # Hide new in Base
294
302
  private :new
295
303
 
304
+ def inherited(sub_class)
305
+ super
306
+ sub_class.module_eval do
307
+ include GetTextSupport
308
+ end
309
+ end
310
+
296
311
  # Connect and bind to LDAP creating a class variable for use by
297
312
  # all ActiveLdap objects.
298
313
  #
@@ -420,7 +435,52 @@ module ActiveLdap
420
435
  dn_attribute
421
436
  end
422
437
 
438
+ def inspect
439
+ if self == Base
440
+ super
441
+ else
442
+ class_names = []
443
+ must = []
444
+ may = []
445
+ class_names = classes.collect do |object_class|
446
+ must.concat(object_class.must)
447
+ may.concat(object_class.may)
448
+ object_class.name
449
+ end
450
+ detail = ["objectClass:<#{class_names.join(', ')}>",
451
+ "must:<#{inspect_attributes(must)}>",
452
+ "may:<#{inspect_attributes(may)}>"].join(", ")
453
+ "#{super}(#{detail})"
454
+ end
455
+ end
456
+
423
457
  private
458
+ def inspect_attributes(attributes)
459
+ inspected_attribute_names = {}
460
+ attributes.collect do |attribute|
461
+ if inspected_attribute_names.has_key?(attribute.name)
462
+ nil
463
+ else
464
+ inspected_attribute_names[attribute.name] = true
465
+ inspect_attribute(attribute)
466
+ end
467
+ end.compact.join(', ')
468
+ end
469
+
470
+ def inspect_attribute(attribute)
471
+ syntax = attribute.syntax
472
+ result = "#{attribute.name}"
473
+ if syntax and !syntax.description.blank?
474
+ result << ": #{syntax.description}"
475
+ end
476
+ properties = []
477
+ properties << "read-only" if attribute.read_only?
478
+ properties << "binary" if attribute.binary?
479
+ properties << "binary-required" if attribute.binary_required?
480
+ result << "(#{properties.join(', ')})" unless properties.empty?
481
+ result
482
+ end
483
+
424
484
  def validate_ldap_mapping_options(options)
425
485
  options.assert_valid_keys(VALID_LDAP_MAPPING_OPTIONS)
426
486
  end
@@ -466,7 +526,7 @@ module ActiveLdap
466
526
  end
467
527
  dn_attribute || "cn"
468
528
  else
469
- Inflector.underscore(Inflector.demodulize(name))
529
+ name.demodulize.underscore
470
530
  end
471
531
  end
472
532
 
@@ -474,7 +534,7 @@ module ActiveLdap
474
534
  if name.empty?
475
535
  nil
476
536
  else
477
- "ou=#{Inflector.pluralize(Inflector.demodulize(name))}"
537
+ "ou=#{name.demodulize.pluralize}"
478
538
  end
479
539
  end
480
540
  end
@@ -685,7 +745,7 @@ module ActiveLdap
685
745
  # Add available attributes to the methods
686
746
  def methods(inherited_too=true)
687
747
  target_names = entry_attribute.all_names
688
- target_names -= ['objectClass', Inflector.underscore('objectClass')]
748
+ target_names -= ['objectClass', 'objectClass'.underscore]
689
749
  super + target_names.uniq.collect do |x|
690
750
  [x, "#{x}=", "#{x}?", "#{x}_before_type_cast"]
691
751
  end.flatten
@@ -748,12 +808,16 @@ module ActiveLdap
748
808
  end
749
809
  end
750
810
 
811
+ def to_ldif_record
812
+ super(dn, normalize_data(@data))
813
+ end
814
+
751
815
  def to_ldif
752
- super(dn, @data)
816
+ Ldif.new([to_ldif_record]).to_s
753
817
  end
754
818
 
755
819
  def to_xml(options={})
756
- root = options[:root] || Inflector.underscore(self.class.name)
820
+ root = options[:root] || self.class.name.underscore
757
821
  result = "<#{root}>\n"
758
822
  result << " <dn>#{dn}</dn>\n"
759
823
  normalize_data(@data).sort_by {|key, values| key}.each do |key, values|
@@ -879,18 +943,36 @@ module ActiveLdap
879
943
  end
880
944
 
881
945
  def inspect
882
- abbreviate_instance_variables do
883
- super
884
- end
946
+ object_classes = entry_attribute.object_classes
947
+ inspected_object_classes = object_classes.collect do |object_class|
948
+ object_class.name
949
+ end.join(', ')
950
+ must_attributes = must.collect(&:name).sort.join(', ')
951
+ may_attributes = may.collect(&:name).sort.join(', ')
952
+ inspected_attributes = attribute_names.sort.collect do |name|
953
+ inspect_attribute(name)
954
+ end.join(', ')
955
+ result = "\#<#{self.class} objectClass:<#{inspected_object_classes}>, "
956
+ result << "must:<#{must_attributes}>, may:<#{may_attributes}>, "
957
+ result << "#{inspected_attributes}>"
958
+ result
885
959
  end
886
960
 
887
- def pretty_print(q)
888
- abbreviate_instance_variables do
889
- q.pp_object(self)
961
+ private
962
+ def inspect_attribute(name)
963
+ values = get_attribute(name, true)
964
+ values.collect do |value|
965
+ if value.is_a?(String) and value.length > 50
966
+ "#{value[0, 50]}...".inspect
967
+ elsif value.is_a?(Date) || value.is_a?(Time)
968
+ "#{value.to_s(:db)}"
969
+ else
970
+ value.inspect
971
+ end
890
972
  end
973
+ "#{name}: #{values.inspect}"
891
974
  end
892
975
 
893
- private
894
976
  def attribute_name_resolvable_without_connection?
895
977
  @entry_attribute and @local_entry_attribute
896
978
  end
@@ -903,26 +985,6 @@ module ActiveLdap
903
985
  @local_entry_attribute ||= connection.entry_attribute([])
904
986
  end
905
987
 
906
- def abbreviate_instance_variables
907
- @abbreviating ||= nil
908
- connection, @connection = @connection, nil
909
- schema, @schema = @schema, nil
910
- entry_attribute, @entry_attribute = @entry_attribute, nil
911
- local_entry_attribute, @local_entry_attribute = @local_entry_attribute, nil
912
- real_names, @real_names = @real_names, nil
913
- unless @abbreviating
914
- @abbreviating = true
915
- end
916
- yield
917
- ensure
918
- @connection = connection
919
- @schema = schema
920
- @entry_attribute = entry_attribute
921
- @local_entry_attribute = local_entry_attribute
922
- @real_names = real_names
923
- @abbreviating = false
924
- end
925
-
926
988
  def extract_object_class(attributes)
927
989
  classes = []
928
990
  attrs = {}
@@ -1006,6 +1068,7 @@ module ActiveLdap
1006
1068
  # Return the value of the attribute called by method_missing?
1007
1069
  def get_attribute(name, force_array=false)
1008
1070
  name, value = get_attribute_before_type_cast(name, force_array)
1071
+ return value if name.nil?
1009
1072
  attribute = schema.attribute(name)
1010
1073
  type_cast(attribute, value)
1011
1074
  end