net-ldap 0.11 → 0.16.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.
Potentially problematic release.
This version of net-ldap might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +15 -0
- data/.rubocop_todo.yml +471 -180
- data/.travis.yml +10 -5
- data/Contributors.rdoc +1 -0
- data/History.rdoc +60 -0
- data/README.rdoc +18 -11
- data/Rakefile +0 -1
- data/lib/net/ber/ber_parser.rb +4 -4
- data/lib/net/ber/core_ext/array.rb +1 -1
- data/lib/net/ber/core_ext/integer.rb +1 -1
- data/lib/net/ber/core_ext/string.rb +1 -1
- data/lib/net/ber.rb +37 -5
- data/lib/net/ldap/auth_adapter/gss_spnego.rb +41 -0
- data/lib/net/ldap/auth_adapter/sasl.rb +62 -0
- data/lib/net/ldap/auth_adapter/simple.rb +34 -0
- data/lib/net/ldap/auth_adapter.rb +29 -0
- data/lib/net/ldap/connection.rb +197 -187
- data/lib/net/ldap/dataset.rb +2 -2
- data/lib/net/ldap/dn.rb +4 -5
- data/lib/net/ldap/entry.rb +4 -5
- data/lib/net/ldap/error.rb +36 -1
- data/lib/net/ldap/filter.rb +6 -6
- data/lib/net/ldap/pdu.rb +26 -2
- data/lib/net/ldap/version.rb +1 -1
- data/lib/net/ldap.rb +189 -75
- data/lib/net/snmp.rb +18 -18
- data/net-ldap.gemspec +4 -2
- data/script/changelog +47 -0
- data/script/generate-fixture-ca +48 -0
- data/script/install-openldap +67 -44
- data/test/ber/core_ext/test_array.rb +1 -1
- data/test/ber/test_ber.rb +11 -3
- data/test/fixtures/ca/ca.info +4 -0
- data/test/fixtures/ca/cacert.pem +24 -0
- data/test/fixtures/ca/cakey.pem +190 -0
- data/test/fixtures/openldap/slapd.conf.ldif +1 -1
- data/test/integration/test_add.rb +1 -1
- data/test/integration/test_ber.rb +1 -1
- data/test/integration/test_bind.rb +220 -10
- data/test/integration/test_delete.rb +1 -1
- data/test/integration/test_open.rb +1 -1
- data/test/integration/test_password_modify.rb +80 -0
- data/test/integration/test_search.rb +1 -1
- data/test/support/vm/openldap/README.md +35 -3
- data/test/support/vm/openldap/Vagrantfile +1 -0
- data/test/test_auth_adapter.rb +15 -0
- data/test/test_dn.rb +3 -3
- data/test/test_filter.rb +4 -4
- data/test/test_filter_parser.rb +4 -0
- data/test/test_helper.rb +10 -2
- data/test/test_ldap.rb +64 -10
- data/test/test_ldap_connection.rb +115 -28
- data/test/test_ldif.rb +11 -11
- data/test/test_search.rb +2 -2
- data/test/test_snmp.rb +4 -4
- data/testserver/ldapserver.rb +11 -12
- metadata +50 -8
- data/test/fixtures/cacert.pem +0 -20
@@ -2,11 +2,23 @@ require_relative '../test_helper'
|
|
2
2
|
|
3
3
|
class TestBindIntegration < LDAPIntegrationTestCase
|
4
4
|
def test_bind_success
|
5
|
-
assert @ldap.bind(
|
5
|
+
assert @ldap.bind(BIND_CREDS),
|
6
|
+
@ldap.get_operation_result.inspect
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_bind_timeout
|
10
|
+
@ldap.port = 8389
|
11
|
+
error = assert_raise Net::LDAP::Error do
|
12
|
+
@ldap.bind BIND_CREDS
|
13
|
+
end
|
14
|
+
msgs = ['Operation timed out - user specified timeout',
|
15
|
+
'Connection timed out - user specified timeout']
|
16
|
+
assert_send([msgs, :include?, error.message])
|
6
17
|
end
|
7
18
|
|
8
19
|
def test_bind_anonymous_fail
|
9
|
-
refute @ldap.bind(
|
20
|
+
refute @ldap.bind(BIND_CREDS.merge(password: '')),
|
21
|
+
@ldap.get_operation_result.inspect
|
10
22
|
|
11
23
|
result = @ldap.get_operation_result
|
12
24
|
assert_equal Net::LDAP::ResultCodeUnwillingToPerform, result.code
|
@@ -17,18 +29,216 @@ class TestBindIntegration < LDAPIntegrationTestCase
|
|
17
29
|
end
|
18
30
|
|
19
31
|
def test_bind_fail
|
20
|
-
refute @ldap.bind(
|
32
|
+
refute @ldap.bind(BIND_CREDS.merge(password: "not my password")),
|
33
|
+
@ldap.get_operation_result.inspect
|
21
34
|
end
|
22
35
|
|
23
36
|
def test_bind_tls_with_cafile
|
24
|
-
|
25
|
-
|
26
|
-
|
37
|
+
@ldap.encryption(
|
38
|
+
method: :start_tls,
|
39
|
+
tls_options: TLS_OPTS.merge(ca_file: CA_FILE),
|
40
|
+
)
|
41
|
+
assert @ldap.bind(BIND_CREDS),
|
42
|
+
@ldap.get_operation_result.inspect
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_bind_tls_with_bad_hostname_verify_none_no_ca_passes
|
46
|
+
@ldap.host = '127.0.0.1'
|
47
|
+
@ldap.encryption(
|
48
|
+
method: :start_tls,
|
49
|
+
tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE },
|
50
|
+
)
|
51
|
+
assert @ldap.bind(BIND_CREDS),
|
52
|
+
@ldap.get_operation_result.inspect
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_bind_tls_with_bad_hostname_verify_none_no_ca_opt_merge_passes
|
56
|
+
@ldap.host = '127.0.0.1'
|
57
|
+
@ldap.encryption(
|
58
|
+
method: :start_tls,
|
59
|
+
tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_NONE),
|
60
|
+
)
|
61
|
+
assert @ldap.bind(BIND_CREDS),
|
62
|
+
@ldap.get_operation_result.inspect
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_bind_tls_with_bad_hostname_verify_peer_ca_fails
|
66
|
+
@ldap.host = '127.0.0.1'
|
67
|
+
@ldap.encryption(
|
68
|
+
method: :start_tls,
|
69
|
+
tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER,
|
70
|
+
ca_file: CA_FILE },
|
71
|
+
)
|
72
|
+
error = assert_raise Net::LDAP::Error,
|
73
|
+
Net::LDAP::ConnectionRefusedError do
|
74
|
+
@ldap.bind BIND_CREDS
|
75
|
+
end
|
76
|
+
assert_equal(
|
77
|
+
"hostname \"#{@ldap.host}\" does not match the server certificate",
|
78
|
+
error.message,
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_bind_tls_with_bad_hostname_ca_default_opt_merge_fails
|
83
|
+
@ldap.host = '127.0.0.1'
|
84
|
+
@ldap.encryption(
|
85
|
+
method: :start_tls,
|
86
|
+
tls_options: TLS_OPTS.merge(ca_file: CA_FILE),
|
87
|
+
)
|
88
|
+
error = assert_raise Net::LDAP::Error,
|
89
|
+
Net::LDAP::ConnectionRefusedError do
|
90
|
+
@ldap.bind BIND_CREDS
|
91
|
+
end
|
92
|
+
assert_equal(
|
93
|
+
"hostname \"#{@ldap.host}\" does not match the server certificate",
|
94
|
+
error.message,
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_bind_tls_with_bad_hostname_ca_no_opt_merge_fails
|
99
|
+
@ldap.host = '127.0.0.1'
|
100
|
+
@ldap.encryption(
|
101
|
+
method: :start_tls,
|
102
|
+
tls_options: { ca_file: CA_FILE },
|
103
|
+
)
|
104
|
+
error = assert_raise Net::LDAP::Error,
|
105
|
+
Net::LDAP::ConnectionRefusedError do
|
106
|
+
@ldap.bind BIND_CREDS
|
107
|
+
end
|
108
|
+
assert_equal(
|
109
|
+
"hostname \"#{@ldap.host}\" does not match the server certificate",
|
110
|
+
error.message,
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_bind_tls_with_valid_hostname_default_opts_passes
|
115
|
+
@ldap.host = 'localhost'
|
116
|
+
@ldap.encryption(
|
117
|
+
method: :start_tls,
|
118
|
+
tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER,
|
119
|
+
ca_file: CA_FILE),
|
120
|
+
)
|
121
|
+
assert @ldap.bind(BIND_CREDS),
|
122
|
+
@ldap.get_operation_result.inspect
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_bind_tls_with_valid_hostname_just_verify_peer_ca_passes
|
126
|
+
@ldap.host = 'localhost'
|
127
|
+
@ldap.encryption(
|
128
|
+
method: :start_tls,
|
129
|
+
tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER,
|
130
|
+
ca_file: CA_FILE },
|
131
|
+
)
|
132
|
+
assert @ldap.bind(BIND_CREDS),
|
133
|
+
@ldap.get_operation_result.inspect
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_bind_tls_with_bogus_hostname_system_ca_fails
|
137
|
+
@ldap.host = '127.0.0.1'
|
138
|
+
@ldap.encryption(method: :start_tls, tls_options: {})
|
139
|
+
error = assert_raise Net::LDAP::Error,
|
140
|
+
Net::LDAP::ConnectionRefusedError do
|
141
|
+
@ldap.bind BIND_CREDS
|
142
|
+
end
|
143
|
+
assert_equal(
|
144
|
+
"hostname \"#{@ldap.host}\" does not match the server certificate",
|
145
|
+
error.message,
|
146
|
+
)
|
27
147
|
end
|
28
148
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
149
|
+
# The following depend on /etc/hosts hacking.
|
150
|
+
# We can do that on CI, but it's less than cool on people's dev boxes
|
151
|
+
def test_bind_tls_with_multiple_hosts
|
152
|
+
omit_unless ENV['TRAVIS'] == 'true'
|
153
|
+
|
154
|
+
@ldap.host = nil
|
155
|
+
@ldap.hosts = [['ldap01.example.com', 389], ['ldap02.example.com', 389]]
|
156
|
+
@ldap.encryption(
|
157
|
+
method: :start_tls,
|
158
|
+
tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER,
|
159
|
+
ca_file: CA_FILE),
|
160
|
+
)
|
161
|
+
assert @ldap.bind(BIND_CREDS),
|
162
|
+
@ldap.get_operation_result.inspect
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_bind_tls_with_multiple_bogus_hosts
|
166
|
+
omit_unless ENV['TRAVIS'] == 'true'
|
167
|
+
|
168
|
+
@ldap.host = nil
|
169
|
+
@ldap.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]]
|
170
|
+
@ldap.encryption(
|
171
|
+
method: :start_tls,
|
172
|
+
tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER,
|
173
|
+
ca_file: CA_FILE),
|
174
|
+
)
|
175
|
+
error = assert_raise Net::LDAP::Error,
|
176
|
+
Net::LDAP::ConnectionError do
|
177
|
+
@ldap.bind BIND_CREDS
|
178
|
+
end
|
179
|
+
assert_equal("Unable to connect to any given server: ",
|
180
|
+
error.message.split("\n").shift)
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_bind_tls_with_multiple_bogus_hosts_no_verification
|
184
|
+
omit_unless ENV['TRAVIS'] == 'true'
|
185
|
+
|
186
|
+
@ldap.host = nil
|
187
|
+
@ldap.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]]
|
188
|
+
@ldap.encryption(
|
189
|
+
method: :start_tls,
|
190
|
+
tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_NONE),
|
191
|
+
)
|
192
|
+
assert @ldap.bind(BIND_CREDS),
|
193
|
+
@ldap.get_operation_result.inspect
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_bind_tls_with_multiple_bogus_hosts_ca_check_only_fails
|
197
|
+
omit_unless ENV['TRAVIS'] == 'true'
|
198
|
+
|
199
|
+
@ldap.host = nil
|
200
|
+
@ldap.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]]
|
201
|
+
@ldap.encryption(
|
202
|
+
method: :start_tls,
|
203
|
+
tls_options: { ca_file: CA_FILE },
|
204
|
+
)
|
205
|
+
error = assert_raise Net::LDAP::Error,
|
206
|
+
Net::LDAP::ConnectionError do
|
207
|
+
@ldap.bind BIND_CREDS
|
208
|
+
end
|
209
|
+
assert_equal("Unable to connect to any given server: ",
|
210
|
+
error.message.split("\n").shift)
|
211
|
+
end
|
212
|
+
|
213
|
+
# This test is CI-only because we can't add the fixture CA
|
214
|
+
# to the system CA store on people's dev boxes.
|
215
|
+
def test_bind_tls_valid_hostname_system_ca_on_travis_passes
|
216
|
+
omit_unless ENV['TRAVIS'] == 'true'
|
217
|
+
|
218
|
+
@ldap.encryption(
|
219
|
+
method: :start_tls,
|
220
|
+
tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER },
|
221
|
+
)
|
222
|
+
assert @ldap.bind(BIND_CREDS),
|
223
|
+
@ldap.get_operation_result.inspect
|
224
|
+
end
|
225
|
+
|
226
|
+
# Inverse of the above! Don't run this on Travis, only on Vagrant.
|
227
|
+
# Since Vagrant's hypervisor *won't* have the CA in the system
|
228
|
+
# x509 store, we can assume validation will fail
|
229
|
+
def test_bind_tls_valid_hostname_system_on_vagrant_fails
|
230
|
+
omit_if ENV['TRAVIS'] == 'true'
|
231
|
+
|
232
|
+
@ldap.encryption(
|
233
|
+
method: :start_tls,
|
234
|
+
tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER },
|
235
|
+
)
|
236
|
+
error = assert_raise Net::LDAP::Error do
|
237
|
+
@ldap.bind BIND_CREDS
|
238
|
+
end
|
239
|
+
assert_equal(
|
240
|
+
"SSL_connect returned=1 errno=0 state=error: certificate verify failed",
|
241
|
+
error.message,
|
242
|
+
)
|
33
243
|
end
|
34
244
|
end
|
@@ -12,7 +12,7 @@ class TestDeleteIntegration < LDAPIntegrationTestCase
|
|
12
12
|
uid: "delete-user1",
|
13
13
|
cn: "delete-user1",
|
14
14
|
sn: "delete-user1",
|
15
|
-
mail: "delete-user1@rubyldap.com"
|
15
|
+
mail: "delete-user1@rubyldap.com",
|
16
16
|
}
|
17
17
|
unless @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
|
18
18
|
assert @ldap.add(dn: @dn, attributes: attrs), @ldap.get_operation_result.inspect
|
@@ -63,7 +63,7 @@ class TestBindIntegration < LDAPIntegrationTestCase
|
|
63
63
|
uid: "nested-open-added-user1",
|
64
64
|
cn: "nested-open-added-user1",
|
65
65
|
sn: "nested-open-added-user1",
|
66
|
-
mail: "nested-open-added-user1@rubyldap.com"
|
66
|
+
mail: "nested-open-added-user1@rubyldap.com",
|
67
67
|
}
|
68
68
|
|
69
69
|
@ldap.authenticate "cn=admin,dc=rubyldap,dc=com", "passworD1"
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class TestPasswordModifyIntegration < LDAPIntegrationTestCase
|
4
|
+
def setup
|
5
|
+
super
|
6
|
+
@ldap.authenticate 'cn=admin,dc=rubyldap,dc=com', 'passworD1'
|
7
|
+
|
8
|
+
@dn = 'uid=modify-password-user1,ou=People,dc=rubyldap,dc=com'
|
9
|
+
|
10
|
+
attrs = {
|
11
|
+
objectclass: %w(top inetOrgPerson organizationalPerson person),
|
12
|
+
uid: 'modify-password-user1',
|
13
|
+
cn: 'modify-password-user1',
|
14
|
+
sn: 'modify-password-user1',
|
15
|
+
mail: 'modify-password-user1@rubyldap.com',
|
16
|
+
userPassword: 'passworD1',
|
17
|
+
}
|
18
|
+
unless @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
|
19
|
+
assert @ldap.add(dn: @dn, attributes: attrs), @ldap.get_operation_result.inspect
|
20
|
+
end
|
21
|
+
assert @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
|
22
|
+
|
23
|
+
@auth = {
|
24
|
+
method: :simple,
|
25
|
+
username: @dn,
|
26
|
+
password: 'passworD1',
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_password_modify
|
31
|
+
assert @ldap.password_modify(dn: @dn,
|
32
|
+
auth: @auth,
|
33
|
+
old_password: 'passworD1',
|
34
|
+
new_password: 'passworD2')
|
35
|
+
|
36
|
+
assert @ldap.get_operation_result.extended_response.nil?,
|
37
|
+
'Should not have generated a new password'
|
38
|
+
|
39
|
+
refute @ldap.bind(username: @dn, password: 'passworD1', method: :simple),
|
40
|
+
'Old password should no longer be valid'
|
41
|
+
|
42
|
+
assert @ldap.bind(username: @dn, password: 'passworD2', method: :simple),
|
43
|
+
'New password should be valid'
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_password_modify_generate
|
47
|
+
assert @ldap.password_modify(dn: @dn,
|
48
|
+
auth: @auth,
|
49
|
+
old_password: 'passworD1')
|
50
|
+
|
51
|
+
generated_password = @ldap.get_operation_result.extended_response[0][0]
|
52
|
+
|
53
|
+
assert generated_password, 'Should have generated a password'
|
54
|
+
|
55
|
+
refute @ldap.bind(username: @dn, password: 'passworD1', method: :simple),
|
56
|
+
'Old password should no longer be valid'
|
57
|
+
|
58
|
+
assert @ldap.bind(username: @dn, password: generated_password, method: :simple),
|
59
|
+
'New password should be valid'
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_password_modify_generate_no_old_password
|
63
|
+
assert @ldap.password_modify(dn: @dn,
|
64
|
+
auth: @auth)
|
65
|
+
|
66
|
+
generated_password = @ldap.get_operation_result.extended_response[0][0]
|
67
|
+
|
68
|
+
assert generated_password, 'Should have generated a password'
|
69
|
+
|
70
|
+
refute @ldap.bind(username: @dn, password: 'passworD1', method: :simple),
|
71
|
+
'Old password should no longer be valid'
|
72
|
+
|
73
|
+
assert @ldap.bind(username: @dn, password: generated_password, method: :simple),
|
74
|
+
'New password should be valid'
|
75
|
+
end
|
76
|
+
|
77
|
+
def teardown
|
78
|
+
@ldap.delete dn: @dn
|
79
|
+
end
|
80
|
+
end
|
@@ -1,8 +1,31 @@
|
|
1
1
|
# Local OpenLDAP Integration Testing
|
2
2
|
|
3
|
-
Set up a [Vagrant](http://www.vagrantup.com/) VM to run integration
|
3
|
+
Set up a [Vagrant](http://www.vagrantup.com/) VM to run integration
|
4
|
+
tests against OpenLDAP locally. *NOTE*: To support some of the SSL tests,
|
5
|
+
Vagrant forwards localhost port 9389 to VM host port 9389. The port mapping
|
6
|
+
goes away when you run `vagrant destroy`.
|
4
7
|
|
5
|
-
|
8
|
+
## Install Vagrant
|
9
|
+
|
10
|
+
*NOTE*: The Vagrant gem (`gem install vagrant`) is
|
11
|
+
[no longer supported](https://www.vagrantup.com/docs/installation/). If you've
|
12
|
+
previously installed it, run `gem uninstall vagrant`. If you're an rbenv
|
13
|
+
user, you probably want to follow that up with `rbenv rehash; hash -r`.
|
14
|
+
|
15
|
+
If you use Homebrew on macOS:
|
16
|
+
``` bash
|
17
|
+
$ brew update
|
18
|
+
$ brew cask install virtualbox
|
19
|
+
$ brew cask install vagrant
|
20
|
+
$ brew cask install vagrant-manager
|
21
|
+
$ vagrant plugin install vagrant-vbguest
|
22
|
+
```
|
23
|
+
|
24
|
+
Installing Vagrant and virtualbox on other operating systems is left
|
25
|
+
as an exercise to the reader. Note the `vagrant-vbguest` plugin is required
|
26
|
+
to update the VirtualBox guest extensions in the guest VM image.
|
27
|
+
|
28
|
+
## Run the tests
|
6
29
|
|
7
30
|
``` bash
|
8
31
|
# start VM (from the correct directory)
|
@@ -15,6 +38,9 @@ $ ip=$(vagrant ssh -- "ifconfig eth1 | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]
|
|
15
38
|
# change back to root project directory
|
16
39
|
$ cd ../../../..
|
17
40
|
|
41
|
+
# set the TCP port for testing
|
42
|
+
$ export INTEGRATION_PORT=9389
|
43
|
+
|
18
44
|
# run all tests, including integration tests
|
19
45
|
$ time INTEGRATION=openldap INTEGRATION_HOST=$ip bundle exec rake
|
20
46
|
|
@@ -27,6 +53,12 @@ $ export INTEGRATION_HOST=$ip
|
|
27
53
|
|
28
54
|
# now run tests without having to set ENV variables
|
29
55
|
$ time bundle exec rake
|
56
|
+
|
57
|
+
# Once you're all done
|
58
|
+
$ cd test/support/vm/openldap
|
59
|
+
$ vagrant destroy
|
30
60
|
```
|
31
61
|
|
32
|
-
|
62
|
+
If at any point your VM appears to have broken itself, `vagrant destroy`
|
63
|
+
from the `test/support/vm/openldap` directory will blow it away. You can
|
64
|
+
then do `vagrant up` and start over.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestAuthAdapter < Test::Unit::TestCase
|
4
|
+
class FakeSocket
|
5
|
+
def initialize(*args)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_undefined_auth_adapter
|
10
|
+
conn = Net::LDAP::Connection.new(host: 'ldap.example.com', port: 379, :socket_class => FakeSocket)
|
11
|
+
assert_raise Net::LDAP::AuthMethodUnsupportedError, "Unsupported auth method (foo)" do
|
12
|
+
conn.bind(method: :foo)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/test/test_dn.rb
CHANGED
@@ -13,17 +13,17 @@ class TestDN < Test::Unit::TestCase
|
|
13
13
|
|
14
14
|
def test_to_a
|
15
15
|
dn = Net::LDAP::DN.new('cn=James, ou=Company\\,\\20LLC')
|
16
|
-
assert_equal ['cn','James','ou','Company, LLC'], dn.to_a
|
16
|
+
assert_equal ['cn', 'James', 'ou', 'Company, LLC'], dn.to_a
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_to_a_parenthesis
|
20
20
|
dn = Net::LDAP::DN.new('cn = \ James , ou = "Comp\28ny" ')
|
21
|
-
assert_equal ['cn',' James','ou','Comp(ny'], dn.to_a
|
21
|
+
assert_equal ['cn', ' James', 'ou', 'Comp(ny'], dn.to_a
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_to_a_hash_symbol
|
25
25
|
dn = Net::LDAP::DN.new('1.23.4= #A3B4D5 ,ou=Company')
|
26
|
-
assert_equal ['1.23.4','#A3B4D5','ou','Company'], dn.to_a
|
26
|
+
assert_equal ['1.23.4', '#A3B4D5', 'ou', 'Company'], dn.to_a
|
27
27
|
end
|
28
28
|
|
29
29
|
# TODO: raise a more specific exception than RuntimeError
|
data/test/test_filter.rb
CHANGED
@@ -13,11 +13,11 @@ class TestFilter < Test::Unit::TestCase
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_invalid_filter
|
16
|
-
assert_raises(Net::LDAP::OperatorError)
|
16
|
+
assert_raises(Net::LDAP::OperatorError) do
|
17
17
|
# This test exists to prove that our constructor blocks unknown filter
|
18
18
|
# types. All filters must be constructed using helpers.
|
19
19
|
Filter.__send__(:new, :xx, nil, nil)
|
20
|
-
|
20
|
+
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_to_s
|
@@ -144,7 +144,7 @@ class TestFilterRSpec < Test::Unit::TestCase
|
|
144
144
|
'(:dn:2.4.8.10:=Dino)',
|
145
145
|
'(cn:dn:1.2.3.4.5:=John Smith)',
|
146
146
|
'(sn:dn:2.4.6.8.10:=Barbara Jones)',
|
147
|
-
'(&(sn:dn:2.4.6.8.10:=Barbara Jones))'
|
147
|
+
'(&(sn:dn:2.4.6.8.10:=Barbara Jones))',
|
148
148
|
].each_with_index do |filter_str, index|
|
149
149
|
define_method "test_decode_filter_#{index}" do
|
150
150
|
filter = Net::LDAP::Filter.from_rfc2254(filter_str)
|
@@ -195,7 +195,7 @@ class TestFilterRSpec < Test::Unit::TestCase
|
|
195
195
|
"foo" "\\2A\\5C" "bar",
|
196
196
|
"foo" "\\2a\\5c" "bar",
|
197
197
|
"foo" "\\2A\\5c" "bar",
|
198
|
-
"foo" "\\2a\\5C" "bar"
|
198
|
+
"foo" "\\2a\\5C" "bar",
|
199
199
|
].each do |escaped|
|
200
200
|
# unescapes escaped characters
|
201
201
|
filter = Net::LDAP::Filter.eq("objectclass", "#{escaped}*#{escaped}*#{escaped}")
|
data/test/test_filter_parser.rb
CHANGED
@@ -14,6 +14,10 @@ class TestFilterParser < Test::Unit::TestCase
|
|
14
14
|
assert_kind_of Net::LDAP::Filter, Net::LDAP::Filter::FilterParser.parse("(cn=[{something}])")
|
15
15
|
end
|
16
16
|
|
17
|
+
def test_slash
|
18
|
+
assert_kind_of Net::LDAP::Filter, Net::LDAP::Filter::FilterParser.parse("(departmentNumber=FOO//BAR/FOO)")
|
19
|
+
end
|
20
|
+
|
17
21
|
def test_colons
|
18
22
|
assert_kind_of Net::LDAP::Filter, Net::LDAP::Filter::FilterParser.parse("(ismemberof=cn=edu:berkeley:app:calmessages:deans,ou=campus groups,dc=berkeley,dc=edu)")
|
19
23
|
end
|
data/test/test_helper.rb
CHANGED
@@ -14,10 +14,18 @@ CA_FILE =
|
|
14
14
|
if File.exist?("/etc/ssl/certs/cacert.pem")
|
15
15
|
"/etc/ssl/certs/cacert.pem"
|
16
16
|
else
|
17
|
-
File.expand_path("fixtures/cacert.pem", File.dirname(__FILE__))
|
17
|
+
File.expand_path("fixtures/ca/cacert.pem", File.dirname(__FILE__))
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
BIND_CREDS = {
|
22
|
+
method: :simple,
|
23
|
+
username: "uid=user1,ou=People,dc=rubyldap,dc=com",
|
24
|
+
password: "passworD1",
|
25
|
+
}.freeze
|
26
|
+
|
27
|
+
TLS_OPTS = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge({}).freeze
|
28
|
+
|
21
29
|
if RUBY_VERSION < "2.0"
|
22
30
|
class String
|
23
31
|
def b
|
@@ -56,7 +64,7 @@ class LDAPIntegrationTestCase < Test::Unit::TestCase
|
|
56
64
|
@service = MockInstrumentationService.new
|
57
65
|
@ldap = Net::LDAP.new \
|
58
66
|
host: ENV.fetch('INTEGRATION_HOST', 'localhost'),
|
59
|
-
port: 389,
|
67
|
+
port: ENV.fetch('INTEGRATION_PORT', 389),
|
60
68
|
admin_user: 'uid=admin,dc=rubyldap,dc=com',
|
61
69
|
admin_password: 'passworD1',
|
62
70
|
search_domains: %w(dc=rubyldap,dc=com),
|
data/test/test_ldap.rb
CHANGED
@@ -1,6 +1,28 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class TestLDAPInstrumentation < Test::Unit::TestCase
|
4
|
+
# Fake Net::LDAP::Connection for testing
|
5
|
+
class FakeConnection
|
6
|
+
# It's difficult to instantiate Net::LDAP::PDU objects. Faking out what we
|
7
|
+
# need here until that object is brought under test and has it's constructor
|
8
|
+
# cleaned up.
|
9
|
+
class Result < Struct.new(:success?, :result_code); end
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@bind_success = Result.new(true, Net::LDAP::ResultCodeSuccess)
|
13
|
+
@search_success = Result.new(true, Net::LDAP::ResultCodeSizeLimitExceeded)
|
14
|
+
end
|
15
|
+
|
16
|
+
def bind(args = {})
|
17
|
+
@bind_success
|
18
|
+
end
|
19
|
+
|
20
|
+
def search(*args)
|
21
|
+
yield @search_success if block_given?
|
22
|
+
@search_success
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
4
26
|
def setup
|
5
27
|
@connection = flexmock(:connection, :close => true)
|
6
28
|
flexmock(Net::LDAP::Connection).should_receive(:new).and_return(@connection)
|
@@ -15,8 +37,9 @@ class TestLDAPInstrumentation < Test::Unit::TestCase
|
|
15
37
|
def test_instrument_bind
|
16
38
|
events = @service.subscribe "bind.net_ldap"
|
17
39
|
|
18
|
-
|
19
|
-
|
40
|
+
fake_connection = FakeConnection.new
|
41
|
+
@subject.connection = fake_connection
|
42
|
+
bind_result = fake_connection.bind
|
20
43
|
|
21
44
|
assert @subject.bind
|
22
45
|
|
@@ -28,10 +51,9 @@ class TestLDAPInstrumentation < Test::Unit::TestCase
|
|
28
51
|
def test_instrument_search
|
29
52
|
events = @service.subscribe "search.net_ldap"
|
30
53
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
and_return(flexmock(:search_result, :success? => true, :result_code => Net::LDAP::ResultCodeSuccess))
|
54
|
+
fake_connection = FakeConnection.new
|
55
|
+
@subject.connection = fake_connection
|
56
|
+
entry = fake_connection.search
|
35
57
|
|
36
58
|
refute_nil @subject.search(:filter => "(uid=user1)")
|
37
59
|
|
@@ -44,10 +66,9 @@ class TestLDAPInstrumentation < Test::Unit::TestCase
|
|
44
66
|
def test_instrument_search_with_size
|
45
67
|
events = @service.subscribe "search.net_ldap"
|
46
68
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
and_return(flexmock(:search_result, :success? => true, :result_code => Net::LDAP::ResultCodeSizeLimitExceeded))
|
69
|
+
fake_connection = FakeConnection.new
|
70
|
+
@subject.connection = fake_connection
|
71
|
+
entry = fake_connection.search
|
51
72
|
|
52
73
|
refute_nil @subject.search(:filter => "(uid=user1)", :size => 1)
|
53
74
|
|
@@ -57,4 +78,37 @@ class TestLDAPInstrumentation < Test::Unit::TestCase
|
|
57
78
|
assert_equal "(uid=user1)", payload[:filter]
|
58
79
|
assert_equal result.size, payload[:size]
|
59
80
|
end
|
81
|
+
|
82
|
+
def test_obscure_auth
|
83
|
+
password = "opensesame"
|
84
|
+
assert_include(@subject.inspect, "anonymous")
|
85
|
+
@subject.auth "joe_user", password
|
86
|
+
assert_not_include(@subject.inspect, password)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_encryption
|
90
|
+
enc = @subject.encryption('start_tls')
|
91
|
+
|
92
|
+
assert_equal enc[:method], :start_tls
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_normalize_encryption_symbol
|
96
|
+
enc = @subject.send(:normalize_encryption, :start_tls)
|
97
|
+
assert_equal enc, {:method => :start_tls, :tls_options => {}}
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_normalize_encryption_nil
|
101
|
+
enc = @subject.send(:normalize_encryption, nil)
|
102
|
+
assert_equal enc, nil
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_normalize_encryption_string
|
106
|
+
enc = @subject.send(:normalize_encryption, 'start_tls')
|
107
|
+
assert_equal enc, {:method => :start_tls, :tls_options => {}}
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_normalize_encryption_hash
|
111
|
+
enc = @subject.send(:normalize_encryption, {:method => :start_tls, :tls_options => {:foo => :bar}})
|
112
|
+
assert_equal enc, {:method => :start_tls, :tls_options => {:foo => :bar}}
|
113
|
+
end
|
60
114
|
end
|