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.

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