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.

Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +15 -0
  3. data/.rubocop_todo.yml +471 -180
  4. data/.travis.yml +10 -5
  5. data/Contributors.rdoc +1 -0
  6. data/History.rdoc +60 -0
  7. data/README.rdoc +18 -11
  8. data/Rakefile +0 -1
  9. data/lib/net/ber/ber_parser.rb +4 -4
  10. data/lib/net/ber/core_ext/array.rb +1 -1
  11. data/lib/net/ber/core_ext/integer.rb +1 -1
  12. data/lib/net/ber/core_ext/string.rb +1 -1
  13. data/lib/net/ber.rb +37 -5
  14. data/lib/net/ldap/auth_adapter/gss_spnego.rb +41 -0
  15. data/lib/net/ldap/auth_adapter/sasl.rb +62 -0
  16. data/lib/net/ldap/auth_adapter/simple.rb +34 -0
  17. data/lib/net/ldap/auth_adapter.rb +29 -0
  18. data/lib/net/ldap/connection.rb +197 -187
  19. data/lib/net/ldap/dataset.rb +2 -2
  20. data/lib/net/ldap/dn.rb +4 -5
  21. data/lib/net/ldap/entry.rb +4 -5
  22. data/lib/net/ldap/error.rb +36 -1
  23. data/lib/net/ldap/filter.rb +6 -6
  24. data/lib/net/ldap/pdu.rb +26 -2
  25. data/lib/net/ldap/version.rb +1 -1
  26. data/lib/net/ldap.rb +189 -75
  27. data/lib/net/snmp.rb +18 -18
  28. data/net-ldap.gemspec +4 -2
  29. data/script/changelog +47 -0
  30. data/script/generate-fixture-ca +48 -0
  31. data/script/install-openldap +67 -44
  32. data/test/ber/core_ext/test_array.rb +1 -1
  33. data/test/ber/test_ber.rb +11 -3
  34. data/test/fixtures/ca/ca.info +4 -0
  35. data/test/fixtures/ca/cacert.pem +24 -0
  36. data/test/fixtures/ca/cakey.pem +190 -0
  37. data/test/fixtures/openldap/slapd.conf.ldif +1 -1
  38. data/test/integration/test_add.rb +1 -1
  39. data/test/integration/test_ber.rb +1 -1
  40. data/test/integration/test_bind.rb +220 -10
  41. data/test/integration/test_delete.rb +1 -1
  42. data/test/integration/test_open.rb +1 -1
  43. data/test/integration/test_password_modify.rb +80 -0
  44. data/test/integration/test_search.rb +1 -1
  45. data/test/support/vm/openldap/README.md +35 -3
  46. data/test/support/vm/openldap/Vagrantfile +1 -0
  47. data/test/test_auth_adapter.rb +15 -0
  48. data/test/test_dn.rb +3 -3
  49. data/test/test_filter.rb +4 -4
  50. data/test/test_filter_parser.rb +4 -0
  51. data/test/test_helper.rb +10 -2
  52. data/test/test_ldap.rb +64 -10
  53. data/test/test_ldap_connection.rb +115 -28
  54. data/test/test_ldif.rb +11 -11
  55. data/test/test_search.rb +2 -2
  56. data/test/test_snmp.rb +4 -4
  57. data/testserver/ldapserver.rb +11 -12
  58. metadata +50 -8
  59. 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(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "passworD1"), @ldap.get_operation_result.inspect
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(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: ""), @ldap.get_operation_result.inspect
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(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "not my password"), @ldap.get_operation_result.inspect
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
- tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(:ca_file => CA_FILE)
25
- @ldap.encryption(method: :start_tls, tls_options: tls_options)
26
- assert @ldap.bind(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "passworD1"), @ldap.get_operation_result.inspect
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
- def test_bind_tls_with_verify_none
30
- tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(:verify_mode => OpenSSL::SSL::VERIFY_NONE)
31
- @ldap.encryption(method: :start_tls, tls_options: tls_options)
32
- assert @ldap.bind(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "passworD1"), @ldap.get_operation_result.inspect
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
@@ -57,7 +57,7 @@ class TestSearchIntegration < LDAPIntegrationTestCase
57
57
  entries << entry
58
58
  end
59
59
 
60
- payload, _ = events.pop
60
+ payload, = events.pop
61
61
  assert_equal 5, payload[:time]
62
62
  assert_equal entries, result
63
63
  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 tests against OpenLDAP locally.
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
- To run integration tests locally:
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
- You may need to `gem install vagrant` first in order to provision the VM.
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.
@@ -10,6 +10,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
10
10
  config.vm.box = "hashicorp/precise64"
11
11
 
12
12
  config.vm.network "private_network", type: :dhcp
13
+ config.vm.network "forwarded_port", guest: 389, host: 9389
13
14
 
14
15
  config.ssh.forward_agent = true
15
16
 
@@ -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}")
@@ -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
- bind_result = flexmock(:bind_result, :success? => true)
19
- flexmock(@connection).should_receive(:bind).with(Hash).and_return(bind_result)
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
- flexmock(@connection).should_receive(:bind).and_return(flexmock(:bind_result, :result_code => Net::LDAP::ResultCodeSuccess))
32
- flexmock(@connection).should_receive(:search).with(Hash, Proc).
33
- yields(entry = Net::LDAP::Entry.new("uid=user1,ou=users,dc=example,dc=com")).
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
- flexmock(@connection).should_receive(:bind).and_return(flexmock(:bind_result, :result_code => Net::LDAP::ResultCodeSuccess))
48
- flexmock(@connection).should_receive(:search).with(Hash, Proc).
49
- yields(entry = Net::LDAP::Entry.new("uid=user1,ou=users,dc=example,dc=com")).
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