powerhome-activeldap 3.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +6 -0
  3. data/COPYING +340 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE +59 -0
  6. data/README.textile +140 -0
  7. data/TODO +32 -0
  8. data/benchmark/README.md +64 -0
  9. data/benchmark/bench-backend.rb +247 -0
  10. data/benchmark/bench-instantiate.rb +98 -0
  11. data/benchmark/config.yaml.sample +5 -0
  12. data/doc/text/development.textile +54 -0
  13. data/doc/text/news.textile +811 -0
  14. data/doc/text/rails.textile +144 -0
  15. data/doc/text/tutorial.textile +1010 -0
  16. data/examples/config.yaml.example +5 -0
  17. data/examples/example.der +0 -0
  18. data/examples/example.jpg +0 -0
  19. data/examples/groupadd +41 -0
  20. data/examples/groupdel +35 -0
  21. data/examples/groupls +49 -0
  22. data/examples/groupmod +42 -0
  23. data/examples/lpasswd +55 -0
  24. data/examples/objects/group.rb +13 -0
  25. data/examples/objects/ou.rb +4 -0
  26. data/examples/objects/user.rb +20 -0
  27. data/examples/ouadd +38 -0
  28. data/examples/useradd +45 -0
  29. data/examples/useradd-binary +53 -0
  30. data/examples/userdel +34 -0
  31. data/examples/userls +50 -0
  32. data/examples/usermod +42 -0
  33. data/examples/usermod-binary-add +50 -0
  34. data/examples/usermod-binary-add-time +54 -0
  35. data/examples/usermod-binary-del +48 -0
  36. data/examples/usermod-lang-add +43 -0
  37. data/lib/active_ldap.rb +85 -0
  38. data/lib/active_ldap/action_controller/ldap_benchmarking.rb +55 -0
  39. data/lib/active_ldap/acts/tree.rb +78 -0
  40. data/lib/active_ldap/adapter/base.rb +707 -0
  41. data/lib/active_ldap/adapter/jndi.rb +184 -0
  42. data/lib/active_ldap/adapter/jndi_connection.rb +185 -0
  43. data/lib/active_ldap/adapter/ldap.rb +290 -0
  44. data/lib/active_ldap/adapter/ldap_ext.rb +105 -0
  45. data/lib/active_ldap/adapter/net_ldap.rb +309 -0
  46. data/lib/active_ldap/adapter/net_ldap_ext.rb +23 -0
  47. data/lib/active_ldap/association/belongs_to.rb +47 -0
  48. data/lib/active_ldap/association/belongs_to_many.rb +58 -0
  49. data/lib/active_ldap/association/children.rb +21 -0
  50. data/lib/active_ldap/association/collection.rb +105 -0
  51. data/lib/active_ldap/association/has_many.rb +31 -0
  52. data/lib/active_ldap/association/has_many_utils.rb +44 -0
  53. data/lib/active_ldap/association/has_many_wrap.rb +75 -0
  54. data/lib/active_ldap/association/proxy.rb +107 -0
  55. data/lib/active_ldap/associations.rb +205 -0
  56. data/lib/active_ldap/attribute_methods.rb +23 -0
  57. data/lib/active_ldap/attribute_methods/before_type_cast.rb +24 -0
  58. data/lib/active_ldap/attribute_methods/dirty.rb +43 -0
  59. data/lib/active_ldap/attribute_methods/query.rb +31 -0
  60. data/lib/active_ldap/attribute_methods/read.rb +44 -0
  61. data/lib/active_ldap/attribute_methods/write.rb +38 -0
  62. data/lib/active_ldap/attributes.rb +176 -0
  63. data/lib/active_ldap/base.rb +1410 -0
  64. data/lib/active_ldap/callbacks.rb +71 -0
  65. data/lib/active_ldap/command.rb +49 -0
  66. data/lib/active_ldap/compatible.rb +44 -0
  67. data/lib/active_ldap/configuration.rb +147 -0
  68. data/lib/active_ldap/connection.rb +299 -0
  69. data/lib/active_ldap/distinguished_name.rb +291 -0
  70. data/lib/active_ldap/entry_attribute.rb +78 -0
  71. data/lib/active_ldap/escape.rb +12 -0
  72. data/lib/active_ldap/get_text.rb +20 -0
  73. data/lib/active_ldap/get_text/parser.rb +161 -0
  74. data/lib/active_ldap/helper.rb +92 -0
  75. data/lib/active_ldap/human_readable.rb +133 -0
  76. data/lib/active_ldap/ldap_error.rb +74 -0
  77. data/lib/active_ldap/ldif.rb +930 -0
  78. data/lib/active_ldap/log_subscriber.rb +50 -0
  79. data/lib/active_ldap/object_class.rb +95 -0
  80. data/lib/active_ldap/operations.rb +624 -0
  81. data/lib/active_ldap/persistence.rb +100 -0
  82. data/lib/active_ldap/populate.rb +53 -0
  83. data/lib/active_ldap/railtie.rb +43 -0
  84. data/lib/active_ldap/railties/controller_runtime.rb +48 -0
  85. data/lib/active_ldap/schema.rb +701 -0
  86. data/lib/active_ldap/schema/syntaxes.rb +422 -0
  87. data/lib/active_ldap/timeout.rb +75 -0
  88. data/lib/active_ldap/timeout_stub.rb +17 -0
  89. data/lib/active_ldap/user_password.rb +99 -0
  90. data/lib/active_ldap/validations.rb +200 -0
  91. data/lib/active_ldap/version.rb +3 -0
  92. data/lib/active_ldap/xml.rb +139 -0
  93. data/lib/rails/generators/active_ldap/model/USAGE +18 -0
  94. data/lib/rails/generators/active_ldap/model/model_generator.rb +47 -0
  95. data/lib/rails/generators/active_ldap/model/templates/model_active_ldap.rb +3 -0
  96. data/lib/rails/generators/active_ldap/scaffold/scaffold_generator.rb +14 -0
  97. data/lib/rails/generators/active_ldap/scaffold/templates/ldap.yml +19 -0
  98. data/po/en/active-ldap.po +4029 -0
  99. data/po/ja/active-ldap.po +4060 -0
  100. data/test/add-phonetic-attribute-options-to-slapd.ldif +10 -0
  101. data/test/al-test-utils.rb +428 -0
  102. data/test/command.rb +111 -0
  103. data/test/config.yaml.sample +6 -0
  104. data/test/fixtures/lower_case_object_class_schema.rb +802 -0
  105. data/test/run-test.rb +34 -0
  106. data/test/test_acts_as_tree.rb +60 -0
  107. data/test/test_adapter.rb +121 -0
  108. data/test/test_associations.rb +701 -0
  109. data/test/test_attributes.rb +117 -0
  110. data/test/test_base.rb +1214 -0
  111. data/test/test_base_per_instance.rb +61 -0
  112. data/test/test_bind.rb +62 -0
  113. data/test/test_callback.rb +31 -0
  114. data/test/test_configuration.rb +40 -0
  115. data/test/test_connection.rb +82 -0
  116. data/test/test_connection_per_class.rb +112 -0
  117. data/test/test_connection_per_dn.rb +112 -0
  118. data/test/test_dirty.rb +98 -0
  119. data/test/test_dn.rb +172 -0
  120. data/test/test_find.rb +176 -0
  121. data/test/test_groupadd.rb +50 -0
  122. data/test/test_groupdel.rb +46 -0
  123. data/test/test_groupls.rb +107 -0
  124. data/test/test_groupmod.rb +51 -0
  125. data/test/test_ldif.rb +1890 -0
  126. data/test/test_load.rb +133 -0
  127. data/test/test_lpasswd.rb +75 -0
  128. data/test/test_object_class.rb +74 -0
  129. data/test/test_persistence.rb +131 -0
  130. data/test/test_reflection.rb +175 -0
  131. data/test/test_schema.rb +559 -0
  132. data/test/test_syntax.rb +444 -0
  133. data/test/test_user.rb +217 -0
  134. data/test/test_user_password.rb +108 -0
  135. data/test/test_useradd-binary.rb +62 -0
  136. data/test/test_useradd.rb +57 -0
  137. data/test/test_userdel.rb +48 -0
  138. data/test/test_userls.rb +91 -0
  139. data/test/test_usermod-binary-add-time.rb +65 -0
  140. data/test/test_usermod-binary-add.rb +64 -0
  141. data/test/test_usermod-binary-del.rb +66 -0
  142. data/test/test_usermod-lang-add.rb +59 -0
  143. data/test/test_usermod.rb +58 -0
  144. data/test/test_validation.rb +274 -0
  145. metadata +379 -0
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/ruby
2
+
3
+ base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
4
+ $LOAD_PATH << File.join(base, "lib")
5
+ $LOAD_PATH << File.join(base, "examples")
6
+
7
+ require 'active_ldap'
8
+ require 'objects/user'
9
+ require 'objects/group'
10
+
11
+ require 'base64'
12
+
13
+ argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
14
+ opts.banner += " USER_NAME"
15
+ end
16
+
17
+ if argv.size == 1
18
+ name = argv.shift
19
+ else
20
+ $stderr.puts opts
21
+ exit 1
22
+ end
23
+
24
+ pwb = Proc.new do |user|
25
+ ActiveLdap::Command.read_password("[#{user}] Password: ")
26
+ end
27
+
28
+ ActiveLdap::Base.setup_connection(:password_block => pwb,
29
+ :allow_anonymous => false)
30
+
31
+ unless User.exists?(name)
32
+ $stderr.puts("User #{name} doesn't exist.")
33
+ exit 1
34
+ end
35
+
36
+ user = User.find(name)
37
+ puts user.to_ldif
38
+
39
+ groups = []
40
+ primary_group = user.primary_group
41
+ if primary_group.exists?
42
+ groups << "#{primary_group.cn}[#{primary_group.gid_number}]"
43
+ end
44
+ puts "Groups by name only: #{user.groups(false).join(', ')}"
45
+ user.groups.sort_by do |group|
46
+ group.id
47
+ end.collect do |group|
48
+ groups << "#{group.cn}[#{group.gid_number}]"
49
+ end
50
+ puts "Groups: #{groups.join(', ')}"
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/ruby
2
+
3
+ base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
4
+ $LOAD_PATH << File.join(base, "lib")
5
+ $LOAD_PATH << File.join(base, "examples")
6
+
7
+ require 'active_ldap'
8
+ require 'objects/user'
9
+ require 'objects/group'
10
+
11
+ argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
12
+ opts.banner += " USER_NAME CN UID"
13
+ end
14
+
15
+ if argv.size == 3
16
+ name, cn, uid = argv
17
+ else
18
+ $stderr.puts opts
19
+ exit 1
20
+ end
21
+
22
+ pwb = Proc.new do |user|
23
+ ActiveLdap::Command.read_password("[#{user}] Password: ")
24
+ end
25
+
26
+ ActiveLdap::Base.setup_connection(:password_block => pwb,
27
+ :allow_anonymous => false)
28
+
29
+ unless User.exists?(name)
30
+ $stderr.puts("User #{name} doesn't exist.")
31
+ exit 1
32
+ end
33
+
34
+ user = User.find(name)
35
+ user.cn = cn
36
+ user.uid_number = uid
37
+ user.gid_number = uid
38
+ unless user.save
39
+ puts "failed"
40
+ puts user.errors.full_messages
41
+ exit 1
42
+ end
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/ruby
2
+
3
+ base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
4
+ $LOAD_PATH << File.join(base, "lib")
5
+ $LOAD_PATH << File.join(base, "examples")
6
+
7
+ require 'active_ldap'
8
+ require 'objects/user'
9
+ require 'objects/group'
10
+
11
+ argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
12
+ opts.banner += " USER_NAME CN UID"
13
+ end
14
+
15
+ if argv.size == 3
16
+ name, cn, uid = argv
17
+ else
18
+ $stderr.puts opts
19
+ exit 1
20
+ end
21
+
22
+ pwb = Proc.new do |user|
23
+ ActiveLdap::Command.read_password("[#{user}] Password: ")
24
+ end
25
+
26
+ ActiveLdap::Base.setup_connection(:password_block => pwb,
27
+ :allow_anonymous => false)
28
+
29
+ unless User.exists?(name)
30
+ $stderr.puts("User #{name} doesn't exist.")
31
+ exit 1
32
+ end
33
+
34
+ user = User.find(name)
35
+ user.cn = cn
36
+ user.uid_number = uid
37
+ user.gid_number = uid
38
+
39
+ user.add_class('strongAuthenticationUser')
40
+ cert_file = File.join(File.dirname(__FILE__), 'example.der')
41
+ File.open(cert_file) do |input|
42
+ input.set_encoding("ascii-8bit") if input.respond_to?(:set_encoding)
43
+ user.user_certificate = input.read
44
+ end
45
+
46
+ unless user.save
47
+ puts "failed"
48
+ puts user.errors.full_messages
49
+ exit 1
50
+ end
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/ruby
2
+
3
+ base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
4
+ $LOAD_PATH << File.join(base, "lib")
5
+ $LOAD_PATH << File.join(base, "examples")
6
+
7
+ require 'active_ldap'
8
+ require 'objects/user'
9
+ require 'objects/group'
10
+
11
+ argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
12
+ opts.banner += " USER_NAME CN UID"
13
+ end
14
+
15
+ if argv.size == 3
16
+ name, cn, uid = argv
17
+ else
18
+ $stderr.puts opts
19
+ exit 1
20
+ end
21
+
22
+ pwb = Proc.new do |user|
23
+ ActiveLdap::Command.read_password("[#{user}] Password: ")
24
+ end
25
+
26
+ ActiveLdap::Base.setup_connection(:password_block => pwb,
27
+ :allow_anonymous => false)
28
+
29
+ unless User.exists?(name)
30
+ $stderr.puts("User #{name} doesn't exist.")
31
+ exit 1
32
+ end
33
+
34
+ 100.times do |i|
35
+ user = User.find(name)
36
+ user.cn = cn
37
+ user.uid_number = uid
38
+ user.gid_number = uid
39
+
40
+ user.add_class('strongAuthenticationUser')
41
+ cert_file = File.join(File.dirname(__FILE__), 'example.der')
42
+ File.open(cert_file) do |input|
43
+ input.set_encoding("ascii-8bit") if input.respond_to?(:set_encoding)
44
+ user.user_certificate = input.read
45
+ end
46
+
47
+ unless user.save
48
+ puts "failed #{i}"
49
+ puts user.errors.full_messages
50
+ exit 1
51
+ end
52
+
53
+ # puts "success [#{i}]"
54
+ end
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/ruby
2
+
3
+ base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
4
+ $LOAD_PATH << File.join(base, "lib")
5
+ $LOAD_PATH << File.join(base, "examples")
6
+
7
+ require 'active_ldap'
8
+ require 'objects/user'
9
+ require 'objects/group'
10
+
11
+ argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
12
+ opts.banner += " USER_NAME CN UID"
13
+ end
14
+
15
+ if argv.size == 3
16
+ name, cn, uid = argv
17
+ else
18
+ $stderr.puts opts
19
+ exit 1
20
+ end
21
+
22
+ pwb = Proc.new do |user|
23
+ ActiveLdap::Command.read_password("[#{user}] Password: ")
24
+ end
25
+
26
+ ActiveLdap::Base.setup_connection(:password_block => pwb,
27
+ :allow_anonymous => false)
28
+
29
+ unless User.exists?(name)
30
+ $stderr.puts("User #{name} doesn't exist.")
31
+ exit 1
32
+ end
33
+
34
+ user = User.find(name)
35
+ user.cn = cn
36
+ user.uid_number = uid
37
+ user.gid_number = uid
38
+
39
+ if user.classes.include?('strongAuthenticationUser')
40
+ user.user_certificate = nil
41
+ user.remove_class('strongAuthenticationUser')
42
+ end
43
+
44
+ unless user.save
45
+ puts "failed"
46
+ puts user.errors.full_messages
47
+ exit 1
48
+ end
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/ruby
2
+
3
+ base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
4
+ $LOAD_PATH << File.join(base, "lib")
5
+ $LOAD_PATH << File.join(base, "examples")
6
+
7
+ require 'active_ldap'
8
+ require 'objects/user'
9
+ require 'objects/group'
10
+
11
+ argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
12
+ opts.banner += " USER_NAME CN UID"
13
+ end
14
+
15
+ if argv.size == 3
16
+ name, cn, uid = argv
17
+ else
18
+ $stderr.puts opts
19
+ exit 1
20
+ end
21
+
22
+ pwb = Proc.new do |user|
23
+ ActiveLdap::Command.read_password("[#{user}] Password: ")
24
+ end
25
+
26
+ ActiveLdap::Base.setup_connection(:password_block => pwb,
27
+ :allow_anonymous => false)
28
+
29
+ unless User.exists?(name)
30
+ $stderr.puts("User #{name} doesn't exist.")
31
+ exit 1
32
+ end
33
+
34
+ user = User.find(name)
35
+ user.cn = [cn, {'lang-en-us' => cn}]
36
+ user.uid_number = uid
37
+ user.gid_number = uid
38
+
39
+ unless user.save
40
+ puts "failed"
41
+ puts user.errors.full_messages
42
+ exit 1
43
+ end
@@ -0,0 +1,85 @@
1
+ require "rubygems"
2
+ require "active_model"
3
+ require "active_support/core_ext"
4
+
5
+ require "active_ldap/version"
6
+
7
+ module ActiveLdap
8
+ autoload :Command, "active_ldap/command"
9
+ end
10
+
11
+ if RUBY_PLATFORM.match('linux')
12
+ require 'active_ldap/timeout'
13
+ else
14
+ require 'active_ldap/timeout_stub'
15
+ end
16
+
17
+ require 'active_ldap/get_text'
18
+
19
+ require 'active_ldap/compatible'
20
+
21
+ require 'active_ldap/base'
22
+
23
+ require 'active_ldap/distinguished_name'
24
+ require 'active_ldap/ldif'
25
+ require 'active_ldap/xml'
26
+
27
+ require 'active_ldap/persistence'
28
+
29
+ require 'active_ldap/associations'
30
+ require 'active_ldap/attributes'
31
+ require 'active_ldap/attribute_methods'
32
+ require 'active_ldap/attribute_methods/query'
33
+ require 'active_ldap/attribute_methods/before_type_cast'
34
+ require 'active_ldap/attribute_methods/read'
35
+ require 'active_ldap/attribute_methods/write'
36
+ require 'active_ldap/attribute_methods/dirty'
37
+ require 'active_ldap/configuration'
38
+ require 'active_ldap/connection'
39
+ require 'active_ldap/operations'
40
+ require 'active_ldap/object_class'
41
+ require 'active_ldap/human_readable'
42
+
43
+ require 'active_ldap/acts/tree'
44
+
45
+ require 'active_ldap/populate'
46
+ require 'active_ldap/escape'
47
+ require 'active_ldap/user_password'
48
+ require 'active_ldap/helper'
49
+
50
+ require 'active_ldap/validations'
51
+ require 'active_ldap/callbacks'
52
+
53
+
54
+ ActiveLdap::Base.class_eval do
55
+ include ActiveLdap::Persistence
56
+
57
+ include ActiveLdap::Associations
58
+ include ActiveModel::MassAssignmentSecurity
59
+ include ActiveLdap::Attributes
60
+ include ActiveLdap::AttributeMethods
61
+ include ActiveLdap::AttributeMethods::BeforeTypeCast
62
+ include ActiveLdap::AttributeMethods::Write
63
+ include ActiveLdap::AttributeMethods::Dirty
64
+ include ActiveLdap::AttributeMethods::Query
65
+ include ActiveLdap::AttributeMethods::Read
66
+ include ActiveLdap::Configuration
67
+ include ActiveLdap::Connection
68
+ include ActiveLdap::Operations
69
+ include ActiveLdap::ObjectClass
70
+
71
+ include ActiveLdap::Acts::Tree
72
+
73
+ include ActiveLdap::Validations
74
+ include ActiveLdap::Callbacks
75
+ include ActiveLdap::HumanReadable
76
+ end
77
+
78
+ unless defined?(ACTIVE_LDAP_CONNECTION_ADAPTERS)
79
+ ACTIVE_LDAP_CONNECTION_ADAPTERS = %w(ldap net_ldap jndi)
80
+ end
81
+
82
+ ACTIVE_LDAP_CONNECTION_ADAPTERS.each do |adapter|
83
+ require "active_ldap/adapter/#{adapter}"
84
+ end
85
+
@@ -0,0 +1,55 @@
1
+ module ActiveLdap
2
+ module ActionController
3
+ module LdapBenchmarking
4
+ def self.included(base)
5
+ base.class_eval do
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
12
+ end
13
+ end
14
+
15
+ protected
16
+ def render_with_benchmark_with_active_ldap(*args, &block)
17
+ if logger
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
23
+ @ldap_runtime_after_render = ActiveLdap::Base.reset_runtime
24
+ if defined?(@rendering_runtime)
25
+ @rendering_runtime -= @ldap_runtime_after_render
26
+ else
27
+ @view_runtime -= @ldap_runtime_after_render
28
+ end
29
+ end
30
+ result
31
+ end
32
+
33
+ private
34
+ def rendering_runtime_with_active_ldap(runtime)
35
+ result = rendering_runtime_without_active_ldap(runtime)
36
+ ldap_runtime = ActiveLdap::Base.reset_runtime
37
+ ldap_runtime += @ldap_runtime_before_render || 0
38
+ ldap_runtime += @ldap_runtime_after_render || 0
39
+ ldap_percentage = ldap_runtime * 100 / runtime
40
+ result + (" | LDAP: %.5f (%d%%)" % [ldap_runtime, ldap_percentage])
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
52
+ end
53
+ end
54
+ end
55
+
@@ -0,0 +1,78 @@
1
+ module ActiveLdap
2
+ module Acts
3
+ module Tree
4
+ def self.included(base)
5
+ base.class_eval do
6
+ extend(ClassMethods)
7
+ association_accessor(:children) do |target|
8
+ Association::Children.new(target, {})
9
+ end
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ def root(options={})
15
+ find(:first, options.merge(:scope => :base))
16
+ end
17
+ end
18
+
19
+ # Returns list of ancestors, starting from parent until root.
20
+ #
21
+ # subchild1.ancestors # => [child1, root]
22
+ def ancestors
23
+ node, nodes = self, []
24
+ nodes << node = node.parent while node.parent
25
+ nodes
26
+ end
27
+
28
+ # Returns the root node of the tree.
29
+ def root
30
+ node = self
31
+ node = node.parent while node.parent
32
+ node
33
+ end
34
+
35
+ # Returns all siblings of the current node.
36
+ #
37
+ # subchild1.siblings # => [subchild2]
38
+ def siblings
39
+ self_and_siblings - [self]
40
+ end
41
+
42
+ # Returns all siblings and a reference to the current node.
43
+ #
44
+ # subchild1.self_and_siblings # => [subchild1, subchild2]
45
+ def self_and_siblings
46
+ parent ? parent.children : [self]
47
+ end
48
+
49
+ def parent
50
+ if base == self.class.base
51
+ nil
52
+ else
53
+ find(:first, :base => base, :scope => :base)
54
+ end
55
+ end
56
+
57
+ def parent=(entry)
58
+ if entry.is_a?(String) or entry.is_a?(DN)
59
+ base = entry
60
+ elsif entry.respond_to?(:dn)
61
+ base = entry.dn
62
+ if entry.respond_to?(:clear_association_cache)
63
+ entry.clear_association_cache
64
+ end
65
+ else
66
+ message = _("parent must be an entry or parent DN: %s") % entry.inspect
67
+ raise ArgumentError, message
68
+ end
69
+ unless new_entry?
70
+ self.class.delete_entry(dn, :connection => connection)
71
+ @new_entry = true
72
+ end
73
+ self.dn = "#{dn_attribute}=#{id},#{base}"
74
+ save
75
+ end
76
+ end
77
+ end
78
+ end