net-ldap 0.11 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
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
|