ruby-activeldap 0.7.4 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/CHANGES +375 -0
  2. data/COPYING +340 -0
  3. data/LICENSE +58 -0
  4. data/Manifest.txt +33 -0
  5. data/README +63 -0
  6. data/Rakefile +37 -0
  7. data/TODO +31 -0
  8. data/benchmark/bench-al.rb +152 -0
  9. data/lib/{activeldap.rb → active_ldap.rb} +280 -263
  10. data/lib/active_ldap/adaptor/base.rb +29 -0
  11. data/lib/active_ldap/adaptor/ldap.rb +466 -0
  12. data/lib/active_ldap/association/belongs_to.rb +38 -0
  13. data/lib/active_ldap/association/belongs_to_many.rb +40 -0
  14. data/lib/active_ldap/association/collection.rb +80 -0
  15. data/lib/active_ldap/association/has_many.rb +48 -0
  16. data/lib/active_ldap/association/has_many_wrap.rb +56 -0
  17. data/lib/active_ldap/association/proxy.rb +89 -0
  18. data/lib/active_ldap/associations.rb +162 -0
  19. data/lib/active_ldap/attributes.rb +199 -0
  20. data/lib/active_ldap/base.rb +1343 -0
  21. data/lib/active_ldap/callbacks.rb +19 -0
  22. data/lib/active_ldap/command.rb +46 -0
  23. data/lib/active_ldap/configuration.rb +96 -0
  24. data/lib/active_ldap/connection.rb +137 -0
  25. data/lib/{activeldap → active_ldap}/ldap.rb +1 -1
  26. data/lib/active_ldap/object_class.rb +70 -0
  27. data/lib/active_ldap/schema.rb +258 -0
  28. data/lib/{activeldap → active_ldap}/timeout.rb +0 -0
  29. data/lib/{activeldap → active_ldap}/timeout_stub.rb +0 -0
  30. data/lib/active_ldap/user_password.rb +92 -0
  31. data/lib/active_ldap/validations.rb +78 -0
  32. data/rails/plugin/active_ldap/README +54 -0
  33. data/rails/plugin/active_ldap/init.rb +6 -0
  34. data/test/TODO +2 -0
  35. data/test/al-test-utils.rb +337 -0
  36. data/test/command.rb +62 -0
  37. data/test/config.yaml +8 -0
  38. data/test/config.yaml.sample +6 -0
  39. data/test/run-test.rb +17 -0
  40. data/test/test-unit-ext.rb +2 -0
  41. data/test/test_associations.rb +334 -0
  42. data/test/test_attributes.rb +71 -0
  43. data/test/test_base.rb +345 -0
  44. data/test/test_base_per_instance.rb +32 -0
  45. data/test/test_bind.rb +53 -0
  46. data/test/test_callback.rb +35 -0
  47. data/test/test_connection.rb +38 -0
  48. data/test/test_connection_per_class.rb +50 -0
  49. data/test/test_find.rb +36 -0
  50. data/test/test_groupadd.rb +50 -0
  51. data/test/test_groupdel.rb +46 -0
  52. data/test/test_groupls.rb +107 -0
  53. data/test/test_groupmod.rb +51 -0
  54. data/test/test_lpasswd.rb +75 -0
  55. data/test/test_object_class.rb +32 -0
  56. data/test/test_reflection.rb +173 -0
  57. data/test/test_schema.rb +166 -0
  58. data/test/test_user.rb +209 -0
  59. data/test/test_user_password.rb +93 -0
  60. data/test/test_useradd-binary.rb +59 -0
  61. data/test/test_useradd.rb +55 -0
  62. data/test/test_userdel.rb +48 -0
  63. data/test/test_userls.rb +86 -0
  64. data/test/test_usermod-binary-add-time.rb +62 -0
  65. data/test/test_usermod-binary-add.rb +61 -0
  66. data/test/test_usermod-binary-del.rb +64 -0
  67. data/test/test_usermod-lang-add.rb +57 -0
  68. data/test/test_usermod.rb +56 -0
  69. data/test/test_validation.rb +38 -0
  70. metadata +94 -21
  71. data/lib/activeldap/associations.rb +0 -170
  72. data/lib/activeldap/base.rb +0 -1456
  73. data/lib/activeldap/configuration.rb +0 -59
  74. data/lib/activeldap/schema2.rb +0 -217
@@ -0,0 +1,32 @@
1
+ require 'al-test-utils'
2
+
3
+ class TestObjectClass < Test::Unit::TestCase
4
+ include AlTestUtils
5
+
6
+ priority :must
7
+
8
+ priority :normal
9
+ def test_unknown_object_class
10
+ make_temporary_group do |group|
11
+ assert_raises(ActiveLdap::ObjectClassError) do
12
+ group.add_class("unknownObjectClass")
13
+ end
14
+ end
15
+ end
16
+
17
+ def test_remove_required_class
18
+ make_temporary_group do |group|
19
+ assert_raises(ActiveLdap::RequiredObjectClassMissed) do
20
+ group.remove_class("posixGroup")
21
+ end
22
+ end
23
+ end
24
+
25
+ def test_invalid_object_class_value
26
+ make_temporary_group do |group|
27
+ assert_raises(TypeError) {group.add_class(:posixAccount)}
28
+ end
29
+ end
30
+
31
+ priority :normal
32
+ end
@@ -0,0 +1,173 @@
1
+ require 'al-test-utils'
2
+
3
+ class TestReflection < Test::Unit::TestCase
4
+ include AlTestUtils
5
+
6
+ priority :must
7
+
8
+ priority :normal
9
+ def test_base_class
10
+ assert_equal(ActiveLdap::Base, ActiveLdap::Base.base_class)
11
+ assert_equal(@user_class, @user_class.base_class)
12
+ sub_user_class = Class.new(@user_class)
13
+ assert_equal(@user_class, sub_user_class.base_class)
14
+ end
15
+
16
+ def test_respond_to?
17
+ make_temporary_user do |user, password|
18
+ attributes = user.must + user.may
19
+ _wrap_assertion do
20
+ attributes.each do |name|
21
+ assert(user.respond_to?(name), name)
22
+ assert(user.respond_to?("#{name}="), "#{name}=")
23
+ assert(user.respond_to?("#{name}?"), "#{name}?")
24
+ assert(user.respond_to?("#{name}_before_type_cast"),
25
+ "#{name}_before_type_cast")
26
+ end
27
+ end
28
+
29
+ user.replace_class(user.class.required_classes)
30
+ new_attributes = collect_attributes(user.class.required_classes)
31
+
32
+ _wrap_assertion do
33
+ assert_not_equal([], new_attributes)
34
+ new_attributes.each do |name|
35
+ assert(user.respond_to?(name), name)
36
+ assert(user.respond_to?("#{name}="), "#{name}=")
37
+ assert(user.respond_to?("#{name}?"), "#{name}?")
38
+ assert(user.respond_to?("#{name}_before_type_cast"),
39
+ "#{name}_before_type_cast")
40
+ end
41
+
42
+ remained_attributes = (attributes - new_attributes)
43
+ assert_not_equal([], remained_attributes)
44
+ remained_attributes.each do |name|
45
+ assert(!user.respond_to?(name), name)
46
+ assert(!user.respond_to?("#{name}="), "#{name}=")
47
+ assert(!user.respond_to?("#{name}?"), "#{name}?")
48
+ assert(!user.respond_to?("#{name}_before_type_cast"),
49
+ "#{name}_before_type_cast")
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def test_methods
56
+ make_temporary_user do |user, password|
57
+ assert_equal(user.methods.uniq.size, user.methods.size)
58
+ assert_equal(user.methods(false).uniq.size, user.methods(false).size)
59
+ end
60
+
61
+ make_temporary_user do |user, password|
62
+ attributes = user.must + user.may - ["objectClass"]
63
+ assert_equal([], attributes - user.methods)
64
+ assert_equal([], attributes - user.methods(false))
65
+
66
+ assert_methods_with_only_required_classes(user, attributes)
67
+ end
68
+
69
+ make_temporary_user do |user, password|
70
+ user.remove_class("inetOrgPerson")
71
+ attributes = user.must + user.may - ["objectClass"]
72
+ assert_equal([], attributes - user.methods)
73
+ assert_equal([], attributes - user.methods(false))
74
+
75
+ assert_methods_with_only_required_classes(user, attributes)
76
+ end
77
+
78
+ make_temporary_user do |user, password|
79
+ attributes = user.must + user.may - ["objectClass"]
80
+ attributes = attributes.collect {|x| x.downcase}
81
+ assert_not_equal([], attributes - user.methods)
82
+ assert_not_equal([], attributes - user.methods(false))
83
+
84
+ normalize_attributes_list = Proc.new do |*attributes_list|
85
+ attributes_list.collect do |attrs|
86
+ attrs.collect {|x| x.downcase}
87
+ end
88
+ end
89
+ assert_methods_with_only_required_classes(user, attributes,
90
+ &normalize_attributes_list)
91
+ end
92
+
93
+ make_temporary_user do |user, password|
94
+ attributes = user.must + user.may - ["objectClass"]
95
+ attributes = attributes.collect do |x|
96
+ Inflector.underscore(x)
97
+ end
98
+ assert_equal([], attributes - user.methods)
99
+ assert_equal([], attributes - user.methods(false))
100
+
101
+ normalize_attributes_list = Proc.new do |*attributes_list|
102
+ attributes_list.collect do |attrs|
103
+ attrs.collect {|x| Inflector.underscore(x)}
104
+ end
105
+ end
106
+ assert_methods_with_only_required_classes(user, attributes,
107
+ &normalize_attributes_list)
108
+ end
109
+
110
+ make_temporary_user do |user, password|
111
+ user.remove_class("inetOrgPerson")
112
+ attributes = user.must + user.may - ["objectClass"]
113
+ attributes = attributes.collect do |x|
114
+ Inflector.underscore(x)
115
+ end
116
+ assert_equal([], attributes - user.methods)
117
+ assert_equal([], attributes - user.methods(false))
118
+
119
+ normalize_attributes_list = Proc.new do |*attributes_list|
120
+ attributes_list.collect do |attrs|
121
+ attrs.collect {|x| Inflector.underscore(x)}
122
+ end
123
+ end
124
+ assert_methods_with_only_required_classes(user, attributes,
125
+ &normalize_attributes_list)
126
+ end
127
+ end
128
+
129
+ def test_attribute_names
130
+ make_temporary_user do |user, password|
131
+ attributes = collect_attributes(user.classes)
132
+ assert_equal([], attributes.uniq - user.attribute_names)
133
+ assert_equal([], user.attribute_names - attributes.uniq)
134
+ end
135
+ end
136
+
137
+ def assert_methods_with_only_required_classes(object, attributes)
138
+ old_classes = (object.classes - object.class.required_classes).uniq
139
+ old_attributes = collect_attributes(old_classes, false).uniq.sort
140
+ required_attributes = collect_attributes(object.class.required_classes,
141
+ false).uniq.sort
142
+ if block_given?
143
+ old_attributes, required_attributes =
144
+ yield(old_attributes, required_attributes)
145
+ end
146
+
147
+ object.replace_class(object.class.required_classes)
148
+
149
+ assert_equal([],
150
+ old_attributes -
151
+ (attributes - object.methods - required_attributes) -
152
+ required_attributes)
153
+ assert_equal([],
154
+ old_attributes -
155
+ (attributes - object.methods(false) - required_attributes) -
156
+ required_attributes)
157
+ end
158
+
159
+ def collect_attributes(object_classes, with_aliases=true)
160
+ attributes = []
161
+ object_classes.each do |object_class|
162
+ attrs = ActiveLdap::Base.schema.class_attributes(object_class)
163
+ if with_aliases
164
+ (attrs[:must] + attrs[:may]).each do |name|
165
+ attributes.concat(ActiveLdap::Base.schema.attribute_aliases(name))
166
+ end
167
+ else
168
+ attributes.concat(attrs[:must] + attrs[:may])
169
+ end
170
+ end
171
+ attributes
172
+ end
173
+ end
@@ -0,0 +1,166 @@
1
+ require 'al-test-utils'
2
+
3
+ class TestSchema < Test::Unit::TestCase
4
+ def test_name_as_key
5
+ top_schema = "( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' " +
6
+ "ABSTRACT MUST objectClass )"
7
+ expect = {
8
+ :name => ["top"],
9
+ :desc => ['top of the superclass chain'],
10
+ :abstract => ["TRUE"],
11
+ :must => ["objectClass"]
12
+ }
13
+ assert_schema(expect, "2.5.6.0", top_schema)
14
+ assert_schema(expect, "top", top_schema)
15
+ end
16
+
17
+ def test_name_as_key_for_multiple_name
18
+ uid_schema = "( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' ) " +
19
+ "DESC 'RFC1274: user identifier' EQUALITY caseIgnoreMatch " +
20
+ "SUBSTR caseIgnoreSubstringsMatch " +
21
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )"
22
+
23
+ expect = {
24
+ :name => ["uid", "userid"],
25
+ :desc => ['RFC1274: user identifier'],
26
+ :equality => ["caseIgnoreMatch"],
27
+ :substr => ["caseIgnoreSubstringsMatch"],
28
+ :syntax => ["1.3.6.1.4.1.1466.115.121.1.15{256}"],
29
+ }
30
+ assert_schema(expect, "0.9.2342.19200300.100.1.1", uid_schema)
31
+ assert_schema(expect, "uid", uid_schema)
32
+ assert_schema(expect, "userid", uid_schema)
33
+ end
34
+
35
+ def test_dollar
36
+ dn_match_schema = "( 2.5.13.1 NAME 'distinguishedNameMatch' APPLIES " +
37
+ "( creatorsName $ modifiersName $ subschemaSubentry " +
38
+ "$ namingContexts $ aliasedObjectName $ " +
39
+ "distinguishedName $ seeAlso $ olcDefaultSearchBase $ " +
40
+ "olcRootDN $ olcSchemaDN $ olcSuffix $ olcUpdateDN $ " +
41
+ "member $ owner $ roleOccupant $ manager $ " +
42
+ "documentAuthor $ secretary $ associatedName $ " +
43
+ "dITRedirect ) )"
44
+
45
+ expect = {
46
+ :name => ["distinguishedNameMatch"],
47
+ :applies => %w(creatorsName modifiersName subschemaSubentry
48
+ namingContexts aliasedObjectName
49
+ distinguishedName seeAlso olcDefaultSearchBase
50
+ olcRootDN olcSchemaDN olcSuffix olcUpdateDN
51
+ member owner roleOccupant manager
52
+ documentAuthor secretary associatedName
53
+ dITRedirect),
54
+ }
55
+ assert_schema(expect, "2.5.13.1", dn_match_schema)
56
+ assert_schema(expect, "distinguishedNameMatch", dn_match_schema)
57
+ end
58
+
59
+ def test_dc_object
60
+ dc_object_schema = "( 1.3.6.1.4.1.1466.344 NAME 'dcObject' DESC " +
61
+ "'RFC2247: domain component object' SUP top " +
62
+ "AUXILIARY MUST dc )"
63
+
64
+ expect = {
65
+ :name => ["dcObject"],
66
+ :desc => ['RFC2247: domain component object'],
67
+ :auxiliary => ["TRUE"],
68
+ :must => ["dc"],
69
+ }
70
+ assert_schema(expect, "1.3.6.1.4.1.1466.344", dc_object_schema)
71
+ assert_schema(expect, "dcObject", dc_object_schema)
72
+ end
73
+
74
+ def test_organization
75
+ organization_schema = "( 2.5.6.4 NAME 'organization' DESC " +
76
+ "'RFC2256: an organization' SUP top STRUCTURAL " +
77
+ "MUST o MAY ( userPassword $ searchGuide $ " +
78
+ "seeAlso $ businessCategory $ x121Address $ " +
79
+ "registeredAddress $ destinationIndicator $ " +
80
+ "preferredDeliveryMethod $ telexNumber $ " +
81
+ "teletexTerminalIdentifier $ telephoneNumber $ " +
82
+ "internationaliSDNNumber $ " +
83
+ "facsimileTelephoneNumber $ street $ " +
84
+ "postOfficeBox $ postalCode $ postalAddress $ " +
85
+ "physicalDeliveryOfficeName $ st $ l $ " +
86
+ "description ) )"
87
+
88
+ expect = {
89
+ :name => ["organization"],
90
+ :desc => ['RFC2256: an organization'],
91
+ :sup => ["top"],
92
+ :structural => ["TRUE"],
93
+ :must => ["o"],
94
+ :may => %w(userPassword searchGuide seeAlso businessCategory
95
+ x121Address registeredAddress destinationIndicator
96
+ preferredDeliveryMethod telexNumber
97
+ teletexTerminalIdentifier telephoneNumber
98
+ internationaliSDNNumber
99
+ facsimileTelephoneNumber street
100
+ postOfficeBox postalCode postalAddress
101
+ physicalDeliveryOfficeName st l description),
102
+ }
103
+ assert_schema(expect, "2.5.6.4", organization_schema)
104
+ assert_schema(expect, "organization", organization_schema)
105
+ end
106
+
107
+ def test_posix_account
108
+ posix_account_schema = "( 1.3.6.1.1.1.2.0 NAME 'posixAccount' DESC " +
109
+ "'Abstraction of an account with POSIX " +
110
+ "attributes' SUP top AUXILIARY MUST ( cn $ " +
111
+ "uid $ uidNumber $ gidNumber $ homeDirectory " +
112
+ ") MAY ( userPassword $ loginShell $ gecos $ " +
113
+ "description ) )"
114
+ expect = {
115
+ :name => ["posixAccount"],
116
+ :desc => ['Abstraction of an account with POSIX attributes'],
117
+ :sup => ["top"],
118
+ :auxiliary => ["TRUE"],
119
+ :must => %w(cn uid uidNumber gidNumber homeDirectory),
120
+ :may => %w(userPassword loginShell gecos description),
121
+ }
122
+ assert_schema(expect, "1.3.6.1.1.1.2.0", posix_account_schema)
123
+ assert_schema(expect, "posixAccount", posix_account_schema)
124
+ end
125
+
126
+ def test_jpeg_photo
127
+ jpeg_photo_schema = "( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' " +
128
+ "DESC 'RFC2798: a JPEG image' SYNTAX " +
129
+ "1.3.6.1.4.1.1466.115.121.1.28 )"
130
+ expect = {
131
+ :name => ["jpegPhoto"],
132
+ :desc => ['RFC2798: a JPEG image'],
133
+ :syntax => ["1.3.6.1.4.1.1466.115.121.1.28"],
134
+ }
135
+ assert_schema(expect, "0.9.2342.19200300.100.1.60", jpeg_photo_schema)
136
+ assert_schema(expect, "jpegPhoto", jpeg_photo_schema)
137
+
138
+ jpeg_schema = "( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " +
139
+ "X-NOT-HUMAN-READABLE 'TRUE' )"
140
+
141
+ expect = {
142
+ :desc => ['JPEG'],
143
+ :x_not_human_readable => ["TRUE"],
144
+ }
145
+ assert_schema(expect, "1.3.6.1.4.1.1466.115.121.1.28", jpeg_schema)
146
+
147
+ schema = ActiveLdap::Schema.new({"attributeTypes" => [jpeg_photo_schema],
148
+ "ldapSyntaxes" => [jpeg_schema]})
149
+ assert(schema.binary?("jpegPhoto"))
150
+ end
151
+
152
+ private
153
+ def assert_schema(expect, name, schema)
154
+ sub = "objectClass"
155
+ entry = {sub => [schema]}
156
+ schema = ActiveLdap::Schema.new(entry)
157
+ actual = {}
158
+ normalized_expect = {}
159
+ expect.each do |key, value|
160
+ normalized_key = key.to_s.gsub(/_/, "-")
161
+ normalized_expect[normalized_key] = value
162
+ actual[normalized_key] = schema.attr(sub, name, normalized_key)
163
+ end
164
+ assert_equal(normalized_expect, actual)
165
+ end
166
+ end
data/test/test_user.rb ADDED
@@ -0,0 +1,209 @@
1
+ require 'al-test-utils'
2
+
3
+ class TestUser < Test::Unit::TestCase
4
+ include AlTestUtils
5
+
6
+ # This adds all required attributes and writes
7
+ def test_add
8
+ ensure_delete_user("test-user") do |uid|
9
+ user = @user_class.new(uid)
10
+
11
+ assert(user.new_entry?, "#{uid} must not exist in LDAP prior to testing")
12
+
13
+ assert_equal(['posixAccount', 'person'].sort, user.classes.sort,
14
+ "Class User's ldap_mapping should specify " +
15
+ "['posixAccount', 'person']. This was not returned.")
16
+
17
+ user.add_class('posixAccount', 'shadowAccount',
18
+ 'person', 'inetOrgPerson', 'organizationalPerson')
19
+
20
+ cn = 'Test User (Default Language)'
21
+ user.cn = cn
22
+ assert_equal(cn, user.cn, 'user.cn should have returned "#{cn}"')
23
+
24
+ # test force_array
25
+ assert_equal([cn], user.cn(true),
26
+ 'user.cn(true) should have returned "[#{cn}]"')
27
+
28
+ cn = {'lang-en-us' => 'Test User (EN-US Language)'}
29
+ user.cn = cn
30
+ # Test subtypes
31
+ assert_equal(cn, user.cn, 'user.cn should match')
32
+
33
+ cn = ['Test User (Default Language)',
34
+ {'lang-en-us' => ['Test User (EN-US Language)', 'Foo']}]
35
+ user.cn = cn
36
+ # Test multiple entries with subtypes
37
+ assert_equal(cn, user.cn,
38
+ 'This should have returned an array of a ' +
39
+ 'normal cn and a lang-en-us cn.')
40
+
41
+ uid_number = 9000
42
+ user.uid_number = uid_number
43
+ # Test to_s on Fixnums
44
+ assert_equal(uid_number.to_s, user.uid_number)
45
+
46
+ gid_number = 9000
47
+ user.gid_number = gid_number
48
+ # Test to_s on Fixnums
49
+ assert_equal(gid_number.to_s, user.gid_number)
50
+
51
+ home_directory = '/home/foo'
52
+ user.home_directory = home_directory
53
+ # just for sanity's sake
54
+ assert_equal(home_directory, user.home_directory,
55
+ 'This should be #{home_directory.dump}.')
56
+ assert_equal([home_directory], user.home_directory(true),
57
+ 'This should be [#{home_directory.dump}].')
58
+
59
+
60
+ assert(!user.valid?)
61
+ assert(user.errors.invalid?(:sn))
62
+ errors = %w(person organizationalPerson
63
+ inetOrgPerson).collect do |object_class|
64
+ "is required attribute (aliases: surname) by " +
65
+ "objectClass '#{object_class}'"
66
+ end
67
+ assert_equal(errors.sort, user.errors.on(:sn).sort)
68
+ user.sn = ['User']
69
+ assert(user.valid?)
70
+ assert_equal(0, user.errors.size)
71
+
72
+ assert_nothing_raised {user.save!}
73
+
74
+ user.user_certificate = certificate
75
+ user.jpeg_photo = jpeg_photo
76
+
77
+ assert(ActiveLdap::Base.schema.binary?('jpegPhoto'),
78
+ 'jpegPhoto is binary?')
79
+
80
+ assert(ActiveLdap::Base.schema.binary?('userCertificate'),
81
+ 'userCertificate is binary?')
82
+ assert_nothing_raised {user.save!}
83
+ end
84
+ end
85
+
86
+
87
+ # This tests the reload of a binary_required type
88
+ def test_binary_required
89
+ make_temporary_user do |user, password|
90
+ # validate add
91
+ user.user_certificate = nil
92
+ assert_equal({'binary' => nil}, user.user_certificate)
93
+ assert_nothing_raised() { user.save! }
94
+ assert_equal({'binary' => nil}, user.user_certificate)
95
+
96
+ user.user_certificate = {"binary" => [certificate]}
97
+ assert_equal({'binary' => certificate},
98
+ user.user_certificate,
99
+ 'This should have been forced to be a binary subtype.')
100
+ assert_nothing_raised() { user.save! }
101
+ assert_equal({'binary' => certificate},
102
+ user.user_certificate,
103
+ 'This should have been forced to be a binary subtype.')
104
+
105
+ # now test modify
106
+ user.user_certificate = nil
107
+ assert_equal({"binary" => nil}, user.user_certificate)
108
+ assert_nothing_raised() { user.save! }
109
+ assert_equal({"binary" => nil}, user.user_certificate)
110
+
111
+ user.user_certificate = certificate
112
+ assert_equal({'binary' => certificate},
113
+ user.user_certificate,
114
+ 'This should have been forced to be a binary subtype.')
115
+ assert_nothing_raised() { user.save! }
116
+
117
+ # validate modify
118
+ user = @user_class.find(user.uid)
119
+ assert_equal({'binary' => certificate},
120
+ user.user_certificate,
121
+ 'This should have been forced to be a binary subtype.')
122
+
123
+ expected_cert = OpenSSL::X509::Certificate.new(certificate)
124
+ actual_cert = user.user_certificate['binary']
125
+ actual_cert = OpenSSL::X509::Certificate.new(actual_cert)
126
+ assert_equal(expected_cert.subject.to_s,
127
+ actual_cert.subject.to_s,
128
+ 'Cert must parse correctly still')
129
+ end
130
+ end
131
+
132
+ def test_binary_required_nested
133
+ make_temporary_user do |user, password|
134
+ user.user_certificate = {"lang-en" => [certificate]}
135
+ assert_equal({'lang-en' => {'binary' => certificate}},
136
+ user.user_certificate)
137
+ assert_nothing_raised() { user.save! }
138
+ assert_equal({'lang-en' => {'binary' => certificate}},
139
+ user.user_certificate)
140
+ end
141
+ end
142
+
143
+ # This tests the reload of a binary type (not forced!)
144
+ def test_binary
145
+ make_temporary_user do |user, password|
146
+ # reload and see what happens
147
+ assert_equal(jpeg_photo, user.jpeg_photo,
148
+ "This should have been equal to #{jpeg_photo_path.dump}")
149
+
150
+ # now test modify
151
+ user.jpeg_photo = nil
152
+ assert_nil(user.jpeg_photo)
153
+ assert_nothing_raised() { user.save! }
154
+ assert_nil(user.jpeg_photo)
155
+
156
+ user.jpeg_photo = jpeg_photo
157
+ assert_equal(jpeg_photo, user.jpeg_photo)
158
+ assert_nothing_raised() { user.save! }
159
+
160
+ # now validate modify
161
+ user = @user_class.find(user.uid)
162
+ assert_equal(jpeg_photo, user.jpeg_photo)
163
+ end
164
+ end
165
+
166
+ # This tests the removal of a objectclass
167
+ def test_remove_object_class
168
+ make_temporary_user do |user, password|
169
+ assert_nil(user.shadow_max,
170
+ 'Should get the default nil value for shadowMax')
171
+
172
+ # Remove shadowAccount
173
+ user.remove_class('shadowAccount')
174
+ assert(user.valid?)
175
+ assert_nothing_raised() { user.save! }
176
+
177
+ assert_raise(NoMethodError,
178
+ 'shadowMax should not be defined anymore' ) do
179
+ user.shadow_max
180
+ end
181
+ end
182
+ end
183
+
184
+
185
+ # Just modify a few random attributes
186
+ def test_modify_with_subtypes
187
+ make_temporary_user do |user, password|
188
+ cn = ['Test User', {'lang-en-us' => ['Test User', 'wad']}]
189
+ user.cn = cn
190
+ assert_nothing_raised() { user.save! }
191
+
192
+ user = @user_class.find(user.uid)
193
+ assert_equal(cn, user.cn,
194
+ 'Making sure a modify with mixed subtypes works')
195
+ end
196
+ end
197
+
198
+ # This tests some invalid input handling
199
+ def test_invalid_input
200
+ end
201
+
202
+ # This tests deletion
203
+ def test_destroy
204
+ make_temporary_user do |user, password|
205
+ user.destroy
206
+ assert(user.new_entry?, 'user should no longer exist')
207
+ end
208
+ end
209
+ end