activeldap 3.1.1 → 3.2.0

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.
Files changed (45) hide show
  1. data/Gemfile +1 -14
  2. data/benchmark/README.md +64 -0
  3. data/benchmark/{bench-al.rb → bench-backend.rb} +6 -22
  4. data/benchmark/bench-instantiate.rb +98 -0
  5. data/benchmark/config.yaml.sample +2 -2
  6. data/doc/text/news.textile +38 -0
  7. data/lib/active_ldap.rb +17 -8
  8. data/lib/active_ldap/association/has_many_wrap.rb +15 -2
  9. data/lib/active_ldap/attribute_methods.rb +23 -0
  10. data/lib/active_ldap/attribute_methods/before_type_cast.rb +24 -0
  11. data/lib/active_ldap/attribute_methods/dirty.rb +43 -0
  12. data/lib/active_ldap/attribute_methods/query.rb +31 -0
  13. data/lib/active_ldap/attribute_methods/read.rb +44 -0
  14. data/lib/active_ldap/attribute_methods/write.rb +38 -0
  15. data/lib/active_ldap/attributes.rb +18 -26
  16. data/lib/active_ldap/base.rb +42 -163
  17. data/lib/active_ldap/connection.rb +6 -1
  18. data/lib/active_ldap/get_text.rb +18 -7
  19. data/lib/active_ldap/operations.rb +63 -49
  20. data/lib/active_ldap/persistence.rb +17 -0
  21. data/lib/active_ldap/railtie.rb +3 -0
  22. data/lib/active_ldap/schema.rb +2 -0
  23. data/lib/active_ldap/schema/syntaxes.rb +7 -7
  24. data/lib/active_ldap/validations.rb +2 -2
  25. data/lib/active_ldap/version.rb +3 -0
  26. data/lib/active_ldap/xml.rb +24 -7
  27. data/lib/rails/generators/active_ldap/model/model_generator.rb +3 -3
  28. data/test/add-phonetic-attribute-options-to-slapd.ldif +10 -0
  29. data/test/al-test-utils.rb +428 -0
  30. data/test/command.rb +111 -0
  31. data/test/config.yaml.sample +6 -0
  32. data/test/fixtures/lower_case_object_class_schema.rb +802 -0
  33. data/test/run-test.rb +29 -0
  34. data/test/test_associations.rb +37 -0
  35. data/test/test_base.rb +113 -51
  36. data/test/test_dirty.rb +84 -0
  37. data/test/test_ldif.rb +0 -1
  38. data/test/test_load.rb +0 -1
  39. data/test/test_reflection.rb +7 -14
  40. data/test/test_syntax.rb +104 -43
  41. data/test/test_usermod-binary-del.rb +1 -1
  42. data/test/test_usermod-lang-add.rb +0 -1
  43. metadata +272 -224
  44. data/lib/active_ldap/get_text_fallback.rb +0 -60
  45. data/lib/active_ldap/get_text_support.rb +0 -22
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $VERBOSE = true
4
+
5
+ $KCODE = 'u' if RUBY_VERSION < "1.9"
6
+
7
+ base_dir = File.expand_path(File.dirname(__FILE__))
8
+ top_dir = File.expand_path(File.join(base_dir, ".."))
9
+ $LOAD_PATH.unshift(File.join(top_dir))
10
+ $LOAD_PATH.unshift(File.join(top_dir, "lib"))
11
+ $LOAD_PATH.unshift(File.join(top_dir, "test"))
12
+
13
+ require "rubygems"
14
+ require "bundler/setup"
15
+
16
+ require "test/unit"
17
+ require "test/unit/notify"
18
+ Test::Unit::Priority.enable
19
+
20
+ target_adapters = [ENV["ACTIVE_LDAP_TEST_ADAPTER"]]
21
+ # target_adapters << "ldap"
22
+ # target_adapters << "net-ldap"
23
+ # target_adapters << "jndi"
24
+ target_adapters.each do |adapter|
25
+ ENV["ACTIVE_LDAP_TEST_ADAPTER"] = adapter
26
+ puts "using adapter: #{adapter ? adapter : 'default'}"
27
+ Test::Unit::AutoRunner.run(true, File.dirname($0), ARGV.dup)
28
+ puts
29
+ end
@@ -411,6 +411,43 @@ EOX
411
411
  end
412
412
  end
413
413
 
414
+ def test_has_many_wrap_assign_new_entry
415
+ make_temporary_user do |user1, |
416
+ make_temporary_user do |user2, |
417
+ ensure_delete_group('test_new_group') do |cn|
418
+ group = @group_class.new(:cn => cn, :gid_number => default_gid)
419
+
420
+ assert_equal([], group.members.to_a)
421
+ assert_equal([], group.member_uid(true))
422
+
423
+ group.members = [user1, user2]
424
+
425
+ assert group.new_entry?
426
+ assert_equal([user1.uid, user2.uid].sort, group.members.map {|x| x.uid }.sort)
427
+ assert_equal([user1.uid, user2.uid].sort, group.member_uid(true).sort)
428
+
429
+ group.members = [user2]
430
+
431
+ assert group.new_entry?
432
+ assert_equal([user2.uid], group.members.map {|x| x.uid })
433
+ assert_equal(user2.uid, group.member_uid)
434
+
435
+ group.members << user1
436
+
437
+ assert group.new_entry?
438
+ assert_equal([user1.uid, user2.uid].sort, group.members.map {|x| x.uid }.sort)
439
+ assert_equal([user1.uid, user2.uid].sort, group.member_uid.sort)
440
+
441
+ assert(group.save)
442
+
443
+ group = @group_class.find(cn)
444
+ assert_equal([user1.uid, user2.uid].sort, group.members.map {|x| x.uid }.sort)
445
+ assert_equal([user1.uid, user2.uid].sort, group.member_uid.sort)
446
+ end
447
+ end
448
+ end
449
+ end
450
+
414
451
  def test_has_many_validation
415
452
  group_class = Class.new(ActiveLdap::Base)
416
453
  group_class.ldap_mapping :prefix => "ou=Groups",
@@ -158,11 +158,11 @@ class TestBase < Test::Unit::TestCase
158
158
  _dc_class = dc_class("ou=base")
159
159
 
160
160
  root1 = _ou_class.create("root1")
161
- child1 = _ou_class.create(:ou => "child1", :parent => root1)
162
- child2 = _ou_class.create(:ou => "child2", :parent => root1)
163
- domain = _dc_class.create(:dc => "domain", :o => "domain", :parent => root1)
164
- child3 = _ou_class.create(:ou => "child3", :parent => root1)
165
- root2 = _ou_class.create("root2")
161
+ _ou_class.create(:ou => "child1", :parent => root1)
162
+ _ou_class.create(:ou => "child2", :parent => root1)
163
+ _dc_class.create(:dc => "domain", :o => "domain", :parent => root1)
164
+ _ou_class.create(:ou => "child3", :parent => root1)
165
+ _ou_class.create("root2")
166
166
  assert_equal(["base",
167
167
  "root1", "child1", "child2", "domain", "child3",
168
168
  "root2"],
@@ -181,11 +181,11 @@ class TestBase < Test::Unit::TestCase
181
181
  _dc_class = dc_class("ou=base")
182
182
 
183
183
  root1 = _ou_class.create("root1")
184
- child1 = _ou_class.create(:ou => "child1", :parent => root1)
185
- child2 = _ou_class.create(:ou => "child2", :parent => root1)
186
- domain = _dc_class.create(:dc => "domain", :o => "domain", :parent => root1)
187
- child3 = _ou_class.create(:ou => "child3", :parent => root1)
188
- root2 = _ou_class.create("root2")
184
+ _ou_class.create(:ou => "child1", :parent => root1)
185
+ _ou_class.create(:ou => "child2", :parent => root1)
186
+ _dc_class.create(:dc => "domain", :o => "domain", :parent => root1)
187
+ _ou_class.create(:ou => "child3", :parent => root1)
188
+ _ou_class.create("root2")
189
189
  assert_equal(["base",
190
190
  "root1", "child1", "child2", "domain", "child3",
191
191
  "root2"],
@@ -201,9 +201,9 @@ class TestBase < Test::Unit::TestCase
201
201
  make_ou("base")
202
202
  _ou_class = ou_class("ou=base")
203
203
  root1 = _ou_class.create("root1")
204
- child1 = _ou_class.create(:ou => "child1", :parent => root1)
205
- child2 = _ou_class.create(:ou => "child2", :parent => root1)
206
- root2 = _ou_class.create("root2")
204
+ _ou_class.create(:ou => "child1", :parent => root1)
205
+ _ou_class.create(:ou => "child2", :parent => root1)
206
+ _ou_class.create("root2")
207
207
  assert_equal(["base", "root1", "child1", "child2", "root2"],
208
208
  _ou_class.find(:all).collect(&:ou))
209
209
  _ou_class.delete_all(:base => root1.dn)
@@ -221,11 +221,11 @@ class TestBase < Test::Unit::TestCase
221
221
 
222
222
  root1 = _ou_class.create("root1")
223
223
  child1 = _ou_class.create(:ou => "child1", :parent => root1)
224
- domain1 = domain_class.create(:dc => "domain1", :parent => child1)
225
- grandchild1 = _ou_class.create(:ou => "grandchild1", :parent => child1)
224
+ domain_class.create(:dc => "domain1", :parent => child1)
225
+ _ou_class.create(:ou => "grandchild1", :parent => child1)
226
226
  child2 = _ou_class.create(:ou => "child2", :parent => root1)
227
- domain2 = domain_class.create(:dc => "domain2", :parent => child2)
228
- root2 = _ou_class.create("root2")
227
+ domain_class.create(:dc => "domain2", :parent => child2)
228
+ _ou_class.create("root2")
229
229
 
230
230
  entry_class = Class.new(ActiveLdap::Base)
231
231
  entry_class.ldap_mapping :prefix => "ou=base",
@@ -583,7 +583,7 @@ class TestBase < Test::Unit::TestCase
583
583
  end
584
584
 
585
585
  def test_new_with_invalid_argument
586
- user = @user_class.new
586
+ @user_class.new
587
587
  assert_raises(ArgumentError) do
588
588
  @user_class.new(100)
589
589
  end
@@ -876,9 +876,10 @@ class TestBase < Test::Unit::TestCase
876
876
  end
877
877
  end
878
878
 
879
- def test_to_xml
880
- ou = ou_class.new("Sample")
881
- assert_equal(<<-EOX, ou.to_xml(:root => "ou"))
879
+ class TestToXML < self
880
+ def test_root
881
+ ou = ou_class.new("Sample")
882
+ assert_equal(<<-EOX, ou.to_xml(:root => "ou"))
882
883
  <ou>
883
884
  <dn>#{ou.dn}</dn>
884
885
  <objectClasses type="array">
@@ -890,8 +891,11 @@ class TestBase < Test::Unit::TestCase
890
891
  </ous>
891
892
  </ou>
892
893
  EOX
894
+ end
893
895
 
894
- assert_equal(<<-EOX, ou.to_xml)
896
+ def test_default
897
+ ou = ou_class.new("Sample")
898
+ assert_equal(<<-EOX, ou.to_xml)
895
899
  <anonymous>
896
900
  <dn>#{ou.dn}</dn>
897
901
  <objectClasses type="array">
@@ -903,10 +907,12 @@ EOX
903
907
  </ous>
904
908
  </anonymous>
905
909
  EOX
910
+ end
906
911
 
907
- make_temporary_user do |user, password|
908
- xml = normalize_attributes_order(user.to_xml(:root => "user"))
909
- assert_equal(<<-EOX, xml)
912
+ def test_complex
913
+ make_temporary_user do |user, password|
914
+ xml = normalize_attributes_order(user.to_xml(:root => "user"))
915
+ assert_equal(<<-EOX, xml)
910
916
  <user>
911
917
  <dn>#{user.dn}</dn>
912
918
  <cns type="array">
@@ -939,12 +945,13 @@ EOX
939
945
  </userPasswords>
940
946
  </user>
941
947
  EOX
948
+ end
942
949
  end
943
- end
944
950
 
945
- def test_to_xml_except
946
- ou = ou_class.new("Sample")
947
- assert_equal(<<-EOX, ou.to_xml(:root => "sample", :except => [:objectClass]))
951
+ def test_except
952
+ ou = ou_class.new("Sample")
953
+ except = [:objectClass]
954
+ assert_equal(<<-EOX, ou.to_xml(:root => "sample", :except => except))
948
955
  <sample>
949
956
  <dn>#{ou.dn}</dn>
950
957
  <ous type="array">
@@ -952,23 +959,53 @@ EOX
952
959
  </ous>
953
960
  </sample>
954
961
  EOX
962
+ end
955
963
 
956
- except = [:dn, :object_class]
957
- assert_equal(<<-EOX, ou.to_xml(:root => "sample", :except => except))
964
+ def test_except_dn
965
+ ou = ou_class.new("Sample")
966
+ except = [:dn, :object_class]
967
+ assert_equal(<<-EOX, ou.to_xml(:root => "sample", :except => except))
958
968
  <sample>
959
969
  <ous type="array">
960
970
  <ou>Sample</ou>
961
971
  </ous>
962
972
  </sample>
963
973
  EOX
964
- end
974
+ end
965
975
 
966
- def test_to_xml_escape
967
- make_temporary_user do |user, password|
968
- sn = user.sn
969
- user.sn = "<#{sn}>"
970
- except = [:jpeg_photo, :user_certificate]
971
- assert_equal(<<-EOX, user.to_xml(:root => "user", :except => except))
976
+ def test_only
977
+ ou = ou_class.new("Sample")
978
+ only = [:objectClass]
979
+ assert_equal(<<-EOX, ou.to_xml(:root => "sample", :only => only))
980
+ <sample>
981
+ <objectClasses type="array">
982
+ <objectClass>organizationalUnit</objectClass>
983
+ <objectClass>top</objectClass>
984
+ </objectClasses>
985
+ </sample>
986
+ EOX
987
+ end
988
+
989
+ def test_only_dn
990
+ ou = ou_class.new("Sample")
991
+ only = [:dn, :object_class]
992
+ assert_equal(<<-EOX, ou.to_xml(:root => "sample", :only => only))
993
+ <sample>
994
+ <dn>#{ou.dn}</dn>
995
+ <objectClasses type="array">
996
+ <objectClass>organizationalUnit</objectClass>
997
+ <objectClass>top</objectClass>
998
+ </objectClasses>
999
+ </sample>
1000
+ EOX
1001
+ end
1002
+
1003
+ def test_escape
1004
+ make_temporary_user do |user, password|
1005
+ sn = user.sn
1006
+ user.sn = "<#{sn}>"
1007
+ except = [:jpeg_photo, :user_certificate]
1008
+ assert_equal(<<-EOX, user.to_xml(:root => "user", :except => except))
972
1009
  <user>
973
1010
  <dn>#{user.dn}</dn>
974
1011
  <cns type="array">
@@ -995,16 +1032,16 @@ EOX
995
1032
  </userPasswords>
996
1033
  </user>
997
1034
  EOX
1035
+ end
998
1036
  end
999
- end
1000
1037
 
1001
- def test_to_xml_type_ldif
1002
- make_temporary_user do |user, password|
1003
- sn = user.sn
1004
- user.sn = "<#{sn}>"
1005
- except = [:jpeg_photo, :user_certificate]
1006
- options = {:root => "user", :except => except, :type => :ldif}
1007
- assert_equal(<<-EOX, user.to_xml(options))
1038
+ def test_type_ldif
1039
+ make_temporary_user do |user, password|
1040
+ sn = user.sn
1041
+ user.sn = "<#{sn}>"
1042
+ except = [:jpeg_photo, :user_certificate]
1043
+ options = {:root => "user", :except => except, :type => :ldif}
1044
+ assert_equal(<<-EOX, user.to_xml(options))
1008
1045
  <user>
1009
1046
  <dn>#{user.dn}</dn>
1010
1047
  <cn>#{user.cn}</cn>
@@ -1021,13 +1058,13 @@ EOX
1021
1058
  <userPassword>#{user.user_password}</userPassword>
1022
1059
  </user>
1023
1060
  EOX
1061
+ end
1024
1062
  end
1025
- end
1026
1063
 
1027
- def test_to_xml_nil
1028
- ou = ou_class.new("Sample")
1029
- ou.description = [nil]
1030
- assert_equal(<<-EOX, ou.to_xml(:root => "sample"))
1064
+ def test_nil
1065
+ ou = ou_class.new("Sample")
1066
+ ou.description = [nil]
1067
+ assert_equal(<<-EOX, ou.to_xml(:root => "sample"))
1031
1068
  <sample>
1032
1069
  <dn>#{ou.dn}</dn>
1033
1070
  <objectClasses type="array">
@@ -1039,6 +1076,31 @@ EOX
1039
1076
  </ous>
1040
1077
  </sample>
1041
1078
  EOX
1079
+ end
1080
+
1081
+ def test_single_value
1082
+ make_temporary_user do |user, password|
1083
+ only = [:dn, :uidNumber]
1084
+ assert_equal(<<-EOX, user.to_xml(:root => "user", :only => only))
1085
+ <user>
1086
+ <dn>#{user.dn}</dn>
1087
+ <uidNumber>#{user.uid_number}</uidNumber>
1088
+ </user>
1089
+ EOX
1090
+ end
1091
+ end
1092
+
1093
+ def test_single_value_nil
1094
+ make_temporary_user do |user, password|
1095
+ only = [:dn, :uidNumber]
1096
+ user.uid_number = nil
1097
+ assert_equal(<<-EOX, user.to_xml(:root => "user", :only => only))
1098
+ <user>
1099
+ <dn>#{user.dn}</dn>
1100
+ </user>
1101
+ EOX
1102
+ end
1103
+ end
1042
1104
  end
1043
1105
 
1044
1106
  def test_save
@@ -0,0 +1,84 @@
1
+ require 'al-test-utils'
2
+
3
+ class TestDirty < Test::Unit::TestCase
4
+ include AlTestUtils
5
+
6
+ priority :must
7
+
8
+ priority :normal
9
+ def test_clean_after_load
10
+ make_temporary_user do |user, password|
11
+ attributes = (user.must + user.may).collect(&:name) - ['objectClass']
12
+ _wrap_assertion do
13
+ attributes.each do |name|
14
+ assert_false(user.send("#{name}_changed?"))
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def test_clean_after_reload
21
+ make_temporary_user do |user, password|
22
+ attributes = (user.must + user.may).collect(&:name) - ['objectClass']
23
+
24
+ user.cn = 'New cn'
25
+ assert_true(user.cn_changed?)
26
+ user.reload
27
+ assert_false(user.cn_changed?)
28
+
29
+ _wrap_assertion do
30
+ attributes.each do |name|
31
+ assert_false(user.send("#{name}_changed?"))
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def test_setter
38
+ make_temporary_user do |user, password|
39
+ attributes = (user.must + user.may).collect(&:name) - ['objectClass', 'cn']
40
+ user.cn = 'New cn'
41
+ assert_true(user.cn_changed?)
42
+
43
+ _wrap_assertion do
44
+ (attributes - ['cn']).each do |name|
45
+ assert_false(user.send("#{name}_changed?"))
46
+ end
47
+
48
+ assert_true(user.cn_changed?)
49
+ end
50
+ end
51
+ end
52
+
53
+ def test_save
54
+ make_temporary_user do |user, password|
55
+ attributes = (user.must + user.may).collect(&:name) - ['objectClass', 'cn']
56
+ user.cn = 'New cn'
57
+ assert_true(user.cn_changed?)
58
+ user.save
59
+ assert_false(user.cn_changed?)
60
+
61
+ _wrap_assertion do
62
+ attributes.each do |name|
63
+ assert_false(user.send("#{name}_changed?"))
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ def test_save!
70
+ make_temporary_user do |user, password|
71
+ attributes = (user.must + user.may).collect(&:name) - ['objectClass', 'cn']
72
+ user.cn = 'New cn'
73
+ assert_true(user.cn_changed?)
74
+ user.save!
75
+ assert_false(user.cn_changed?)
76
+
77
+ _wrap_assertion do
78
+ attributes.each do |name|
79
+ assert_false(user.send("#{name}_changed?"))
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -4,7 +4,6 @@ require 'al-test-utils'
4
4
 
5
5
  class TestLDIF < Test::Unit::TestCase
6
6
  include ActiveLdap::GetTextSupport
7
- include AlTestUtils::Assertions
8
7
  include AlTestUtils::Config
9
8
  include AlTestUtils::ExampleFile
10
9
 
@@ -29,7 +29,6 @@ class TestLoad < Test::Unit::TestCase
29
29
 
30
30
  record.add_operation(:delete, "DisplayName", [], {})
31
31
 
32
- original_sn = user.sn
33
32
  new_sn = ["New SN1", "New SN2"]
34
33
  record.add_operation(:replace, "sn", [], {"sn" => new_sn})
35
34
 
@@ -50,9 +50,8 @@ class TestReflection < Test::Unit::TestCase
50
50
 
51
51
  make_temporary_user do |user, password|
52
52
  attributes = user.must.collect(&:name) + user.may.collect(&:name)
53
- attributes -= ["objectClass"]
53
+ attributes = (attributes - ["objectClass"]).map(&:to_sym)
54
54
  assert_equal([], attributes - user.methods)
55
- assert_equal([], attributes - user.methods(false))
56
55
 
57
56
  assert_methods_with_only_required_classes(user, attributes)
58
57
  end
@@ -60,17 +59,15 @@ class TestReflection < Test::Unit::TestCase
60
59
  make_temporary_user do |user, password|
61
60
  user.remove_class("inetOrgPerson")
62
61
  attributes = user.must.collect(&:name) + user.may.collect(&:name)
63
- attributes -= ["objectClass"]
62
+ attributes = (attributes - ["objectClass"]).map(&:to_sym)
64
63
  assert_equal([], attributes - user.methods)
65
- assert_equal([], attributes - user.methods(false))
66
64
 
67
65
  assert_methods_with_only_required_classes(user, attributes)
68
66
  end
69
67
 
70
68
  make_temporary_user do |user, password|
71
69
  attributes = user.must.collect(&:name) + user.may.collect(&:name)
72
- attributes -= ["objectClass"]
73
- attributes = attributes.collect {|x| x.downcase}
70
+ attributes = attributes.map(&:downcase).map(&:to_sym)
74
71
  assert_not_equal([], attributes - user.methods)
75
72
  assert_not_equal([], attributes - user.methods(false))
76
73
 
@@ -86,9 +83,8 @@ class TestReflection < Test::Unit::TestCase
86
83
  make_temporary_user do |user, password|
87
84
  attributes = user.must.collect(&:name) + user.may.collect(&:name)
88
85
  attributes -= ["objectClass"]
89
- attributes = attributes.collect(&:underscore)
86
+ attributes = attributes.collect(&:underscore).map(&:to_sym)
90
87
  assert_equal([], attributes - user.methods)
91
- assert_equal([], attributes - user.methods(false))
92
88
 
93
89
  normalize_attributes_list = Proc.new do |*attributes_list|
94
90
  attributes_list.collect do |attrs|
@@ -103,9 +99,8 @@ class TestReflection < Test::Unit::TestCase
103
99
  user.remove_class("inetOrgPerson")
104
100
  attributes = user.must.collect(&:name) + user.may.collect(&:name)
105
101
  attributes -= ["objectClass"]
106
- attributes = attributes.collect(&:underscore)
102
+ attributes = attributes.collect(&:underscore).map(&:to_sym)
107
103
  assert_equal([], attributes - user.methods)
108
- assert_equal([], attributes - user.methods(false))
109
104
 
110
105
  normalize_attributes_list = Proc.new do |*attributes_list|
111
106
  attributes_list.collect do |attrs|
@@ -136,16 +131,14 @@ class TestReflection < Test::Unit::TestCase
136
131
  yield(old_attributes, required_attributes)
137
132
  end
138
133
 
134
+ [old_attributes, required_attributes].map{|a| a.map!(&:to_sym)}
135
+
139
136
  object.replace_class(object.class.required_classes)
140
137
 
141
138
  assert_equal([],
142
139
  old_attributes -
143
140
  (attributes - object.methods - required_attributes) -
144
141
  required_attributes)
145
- assert_equal([],
146
- old_attributes -
147
- (attributes - object.methods(false) - required_attributes) -
148
- required_attributes)
149
142
  end
150
143
 
151
144
  def assert_respond_to(object, name)