net-ldap 0.8.0 → 0.9.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -0
  3. data/.travis.yml +19 -1
  4. data/CONTRIBUTING.md +54 -0
  5. data/Hacking.rdoc +2 -4
  6. data/History.rdoc +37 -0
  7. data/Manifest.txt +0 -4
  8. data/README.rdoc +8 -0
  9. data/Rakefile +1 -3
  10. data/lib/net/ber/core_ext.rb +5 -5
  11. data/lib/net/ber/core_ext/string.rb +7 -7
  12. data/lib/net/ber/core_ext/true_class.rb +2 -3
  13. data/lib/net/ldap.rb +134 -620
  14. data/lib/net/ldap/connection.rb +692 -0
  15. data/lib/net/ldap/dataset.rb +18 -4
  16. data/lib/net/ldap/entry.rb +1 -1
  17. data/lib/net/ldap/filter.rb +7 -7
  18. data/lib/net/ldap/password.rb +11 -11
  19. data/lib/net/ldap/pdu.rb +28 -4
  20. data/lib/net/ldap/version.rb +1 -1
  21. data/lib/net/snmp.rb +235 -241
  22. data/net-ldap.gemspec +7 -33
  23. data/script/install-openldap +47 -0
  24. data/script/package +7 -0
  25. data/script/release +16 -0
  26. data/test/ber/core_ext/test_array.rb +22 -0
  27. data/test/ber/core_ext/test_string.rb +25 -0
  28. data/test/ber/test_ber.rb +126 -0
  29. data/test/fixtures/openldap/memberof.ldif +33 -0
  30. data/test/fixtures/openldap/retcode.ldif +76 -0
  31. data/test/fixtures/openldap/slapd.conf.ldif +67 -0
  32. data/test/fixtures/seed.ldif +374 -0
  33. data/test/integration/test_add.rb +28 -0
  34. data/test/integration/test_ber.rb +30 -0
  35. data/test/integration/test_bind.rb +22 -0
  36. data/test/integration/test_delete.rb +31 -0
  37. data/test/integration/test_open.rb +88 -0
  38. data/test/integration/test_return_codes.rb +38 -0
  39. data/test/integration/test_search.rb +77 -0
  40. data/test/support/vm/openldap/.gitignore +1 -0
  41. data/test/support/vm/openldap/README.md +32 -0
  42. data/test/support/vm/openldap/Vagrantfile +33 -0
  43. data/test/test_dn.rb +44 -0
  44. data/test/test_entry.rb +62 -56
  45. data/test/test_filter.rb +98 -2
  46. data/test/test_filter_parser.rb +16 -0
  47. data/test/test_helper.rb +54 -0
  48. data/test/test_ldap.rb +60 -0
  49. data/test/test_ldap_connection.rb +382 -2
  50. data/test/test_ldif.rb +26 -1
  51. data/test/test_password.rb +3 -10
  52. data/test/test_rename.rb +2 -2
  53. data/test/test_search.rb +39 -0
  54. data/test/test_snmp.rb +1 -1
  55. data/test/test_ssl_ber.rb +40 -0
  56. metadata +70 -75
  57. data/.autotest +0 -11
  58. data/.gemtest +0 -0
  59. data/.rspec +0 -2
  60. data/autotest/discover.rb +0 -1
  61. data/spec/integration/ssl_ber_spec.rb +0 -39
  62. data/spec/spec.opts +0 -2
  63. data/spec/spec_helper.rb +0 -28
  64. data/spec/unit/ber/ber_spec.rb +0 -141
  65. data/spec/unit/ber/core_ext/array_spec.rb +0 -24
  66. data/spec/unit/ber/core_ext/string_spec.rb +0 -51
  67. data/spec/unit/ldap/dn_spec.rb +0 -80
  68. data/spec/unit/ldap/entry_spec.rb +0 -51
  69. data/spec/unit/ldap/filter_parser_spec.rb +0 -26
  70. data/spec/unit/ldap/filter_spec.rb +0 -115
  71. data/spec/unit/ldap/search_spec.rb +0 -49
  72. data/spec/unit/ldap_spec.rb +0 -223
  73. data/test/common.rb +0 -3
@@ -0,0 +1,31 @@
1
+ require_relative '../test_helper'
2
+
3
+ class TestDeleteIntegration < LDAPIntegrationTestCase
4
+ def setup
5
+ super
6
+ @ldap.authenticate "cn=admin,dc=rubyldap,dc=com", "passworD1"
7
+
8
+ @dn = "uid=delete-user1,ou=People,dc=rubyldap,dc=com"
9
+
10
+ attrs = {
11
+ objectclass: %w(top inetOrgPerson organizationalPerson person),
12
+ uid: "delete-user1",
13
+ cn: "delete-user1",
14
+ sn: "delete-user1",
15
+ mail: "delete-user1@rubyldap.com"
16
+ }
17
+ unless @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
18
+ assert @ldap.add(dn: @dn, attributes: attrs), @ldap.get_operation_result.inspect
19
+ end
20
+ assert @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
21
+ end
22
+
23
+ def test_delete
24
+ assert @ldap.delete(dn: @dn), @ldap.get_operation_result.inspect
25
+ refute @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
26
+
27
+ result = @ldap.get_operation_result
28
+ assert_equal Net::LDAP::ResultCodeNoSuchObject, result.code
29
+ assert_equal Net::LDAP::ResultStrings[Net::LDAP::ResultCodeNoSuchObject], result.message
30
+ end
31
+ end
@@ -0,0 +1,88 @@
1
+ require_relative '../test_helper'
2
+
3
+ class TestBindIntegration < LDAPIntegrationTestCase
4
+ def test_binds_without_open
5
+ events = @service.subscribe "bind.net_ldap_connection"
6
+
7
+ @ldap.search(filter: "uid=user1", base: "ou=People,dc=rubyldap,dc=com", ignore_server_caps: true)
8
+ @ldap.search(filter: "uid=user1", base: "ou=People,dc=rubyldap,dc=com", ignore_server_caps: true)
9
+
10
+ assert_equal 2, events.size
11
+ end
12
+
13
+ def test_binds_with_open
14
+ events = @service.subscribe "bind.net_ldap_connection"
15
+
16
+ @ldap.open do
17
+ @ldap.search(filter: "uid=user1", base: "ou=People,dc=rubyldap,dc=com", ignore_server_caps: true)
18
+ @ldap.search(filter: "uid=user1", base: "ou=People,dc=rubyldap,dc=com", ignore_server_caps: true)
19
+ end
20
+
21
+ assert_equal 1, events.size
22
+ end
23
+
24
+ # NOTE: query for two or more entries so that the socket must be read
25
+ # multiple times.
26
+ # See The Problem: https://github.com/ruby-ldap/ruby-net-ldap/issues/136
27
+
28
+ def test_nested_search_without_open
29
+ entries = []
30
+ nested_entry = nil
31
+
32
+ @ldap.search(filter: "(|(uid=user1)(uid=user2))", base: "ou=People,dc=rubyldap,dc=com") do |entry|
33
+ entries << entry.uid.first
34
+ nested_entry ||= @ldap.search(filter: "uid=user3", base: "ou=People,dc=rubyldap,dc=com").first
35
+ end
36
+
37
+ assert_equal "user3", nested_entry.uid.first
38
+ assert_equal %w(user1 user2), entries
39
+ end
40
+
41
+ def test_nested_search_with_open
42
+ entries = []
43
+ nested_entry = nil
44
+
45
+ @ldap.open do
46
+ @ldap.search(filter: "(|(uid=user1)(uid=user2))", base: "ou=People,dc=rubyldap,dc=com") do |entry|
47
+ entries << entry.uid.first
48
+ nested_entry ||= @ldap.search(filter: "uid=user3", base: "ou=People,dc=rubyldap,dc=com").first
49
+ end
50
+ end
51
+
52
+ assert_equal "user3", nested_entry.uid.first
53
+ assert_equal %w(user1 user2), entries
54
+ end
55
+
56
+ def test_nested_add_with_open
57
+ entries = []
58
+ nested_entry = nil
59
+
60
+ dn = "uid=nested-open-added-user1,ou=People,dc=rubyldap,dc=com"
61
+ attrs = {
62
+ objectclass: %w(top inetOrgPerson organizationalPerson person),
63
+ uid: "nested-open-added-user1",
64
+ cn: "nested-open-added-user1",
65
+ sn: "nested-open-added-user1",
66
+ mail: "nested-open-added-user1@rubyldap.com"
67
+ }
68
+
69
+ @ldap.authenticate "cn=admin,dc=rubyldap,dc=com", "passworD1"
70
+ @ldap.delete dn: dn
71
+
72
+ @ldap.open do
73
+ @ldap.search(filter: "(|(uid=user1)(uid=user2))", base: "ou=People,dc=rubyldap,dc=com") do |entry|
74
+ entries << entry.uid.first
75
+
76
+ nested_entry ||= begin
77
+ assert @ldap.add(dn: dn, attributes: attrs), @ldap.get_operation_result.inspect
78
+ @ldap.search(base: dn, scope: Net::LDAP::SearchScope_BaseObject).first
79
+ end
80
+ end
81
+ end
82
+
83
+ assert_equal %w(user1 user2), entries
84
+ assert_equal "nested-open-added-user1", nested_entry.uid.first
85
+ ensure
86
+ @ldap.delete dn: dn
87
+ end
88
+ end
@@ -0,0 +1,38 @@
1
+ require_relative '../test_helper'
2
+
3
+ # NOTE: These tests depend on the OpenLDAP retcode overlay.
4
+ # See: section 12.12 http://www.openldap.org/doc/admin24/overlays.html
5
+
6
+ class TestReturnCodeIntegration < LDAPIntegrationTestCase
7
+ def test_operations_error
8
+ refute @ldap.search(filter: "cn=operationsError", base: "ou=Retcodes,dc=rubyldap,dc=com")
9
+ assert result = @ldap.get_operation_result
10
+
11
+ assert_equal Net::LDAP::ResultCodeOperationsError, result.code
12
+ assert_equal Net::LDAP::ResultStrings[Net::LDAP::ResultCodeOperationsError], result.message
13
+ end
14
+
15
+ def test_protocol_error
16
+ refute @ldap.search(filter: "cn=protocolError", base: "ou=Retcodes,dc=rubyldap,dc=com")
17
+ assert result = @ldap.get_operation_result
18
+
19
+ assert_equal Net::LDAP::ResultCodeProtocolError, result.code
20
+ assert_equal Net::LDAP::ResultStrings[Net::LDAP::ResultCodeProtocolError], result.message
21
+ end
22
+
23
+ def test_time_limit_exceeded
24
+ assert @ldap.search(filter: "cn=timeLimitExceeded", base: "ou=Retcodes,dc=rubyldap,dc=com")
25
+ assert result = @ldap.get_operation_result
26
+
27
+ assert_equal Net::LDAP::ResultCodeTimeLimitExceeded, result.code
28
+ assert_equal Net::LDAP::ResultStrings[Net::LDAP::ResultCodeTimeLimitExceeded], result.message
29
+ end
30
+
31
+ def test_size_limit_exceeded
32
+ assert @ldap.search(filter: "cn=sizeLimitExceeded", base: "ou=Retcodes,dc=rubyldap,dc=com")
33
+ assert result = @ldap.get_operation_result
34
+
35
+ assert_equal Net::LDAP::ResultCodeSizeLimitExceeded, result.code
36
+ assert_equal Net::LDAP::ResultStrings[Net::LDAP::ResultCodeSizeLimitExceeded], result.message
37
+ end
38
+ end
@@ -0,0 +1,77 @@
1
+ require_relative '../test_helper'
2
+
3
+ class TestSearchIntegration < LDAPIntegrationTestCase
4
+ def test_search
5
+ entries = []
6
+
7
+ result = @ldap.search(base: "dc=rubyldap,dc=com") do |entry|
8
+ assert_kind_of Net::LDAP::Entry, entry
9
+ entries << entry
10
+ end
11
+
12
+ refute entries.empty?
13
+ assert_equal entries, result
14
+ end
15
+
16
+ def test_search_without_result
17
+ entries = []
18
+
19
+ result = @ldap.search(base: "dc=rubyldap,dc=com", return_result: false) do |entry|
20
+ assert_kind_of Net::LDAP::Entry, entry
21
+ entries << entry
22
+ end
23
+
24
+ assert result
25
+ refute_equal entries, result
26
+ end
27
+
28
+ def test_search_filter_string
29
+ entries = @ldap.search(base: "dc=rubyldap,dc=com", filter: "(uid=user1)")
30
+ assert_equal 1, entries.size
31
+ end
32
+
33
+ def test_search_filter_object
34
+ filter = Net::LDAP::Filter.eq("uid", "user1") | Net::LDAP::Filter.eq("uid", "user2")
35
+ entries = @ldap.search(base: "dc=rubyldap,dc=com", filter: filter)
36
+ assert_equal 2, entries.size
37
+ end
38
+
39
+ def test_search_constrained_attributes
40
+ entry = @ldap.search(base: "uid=user1,ou=People,dc=rubyldap,dc=com", attributes: ["cn", "sn"]).first
41
+ assert_equal [:cn, :dn, :sn], entry.attribute_names.sort # :dn is always included
42
+ assert_empty entry[:mail]
43
+ end
44
+
45
+ def test_search_attributes_only
46
+ entry = @ldap.search(base: "uid=user1,ou=People,dc=rubyldap,dc=com", attributes_only: true).first
47
+
48
+ assert_empty entry[:cn], "unexpected attribute value: #{entry[:cn]}"
49
+ end
50
+
51
+ def test_search_timeout
52
+ entries = []
53
+ events = @service.subscribe "search.net_ldap_connection"
54
+
55
+ result = @ldap.search(base: "dc=rubyldap,dc=com", time: 5) do |entry|
56
+ assert_kind_of Net::LDAP::Entry, entry
57
+ entries << entry
58
+ end
59
+
60
+ payload, _ = events.pop
61
+ assert_equal 5, payload[:time]
62
+ assert_equal entries, result
63
+ end
64
+
65
+ # http://tools.ietf.org/html/rfc4511#section-4.5.1.4
66
+ def test_search_with_size
67
+ entries = []
68
+
69
+ result = @ldap.search(base: "dc=rubyldap,dc=com", size: 1) do |entry|
70
+ assert_kind_of Net::LDAP::Entry, entry
71
+ entries << entry
72
+ end
73
+
74
+ assert_equal 1, result.size
75
+ assert_equal entries, result
76
+ end
77
+ end
@@ -0,0 +1 @@
1
+ /.vagrant
@@ -0,0 +1,32 @@
1
+ # Local OpenLDAP Integration Testing
2
+
3
+ Set up a [Vagrant](http://www.vagrantup.com/) VM to run integration tests against OpenLDAP locally.
4
+
5
+ To run integration tests locally:
6
+
7
+ ``` bash
8
+ # start VM (from the correct directory)
9
+ $ cd test/support/vm/openldap/
10
+ $ vagrant up
11
+
12
+ # get the IP address of the VM
13
+ $ ip=$(vagrant ssh -- "ifconfig eth1 | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -n1")
14
+
15
+ # change back to root project directory
16
+ $ cd ../../../..
17
+
18
+ # run all tests, including integration tests
19
+ $ time INTEGRATION=openldap INTEGRATION_HOST=$ip bundle exec rake
20
+
21
+ # run a specific integration test file
22
+ $ time INTEGRATION=openldap INTEGRATION_HOST=$ip bundle exec ruby test/integration/test_search.rb
23
+
24
+ # run integration tests by default
25
+ $ export INTEGRATION=openldap
26
+ $ export INTEGRATION_HOST=$ip
27
+
28
+ # now run tests without having to set ENV variables
29
+ $ time bundle exec rake
30
+ ```
31
+
32
+ You may need to `gem install vagrant` first in order to provision the VM.
@@ -0,0 +1,33 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5
+ VAGRANTFILE_API_VERSION = "2"
6
+
7
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8
+ config.vm.hostname = "rubyldap.com"
9
+
10
+ config.vm.box = "hashicorp/precise64"
11
+
12
+ config.vm.network "private_network", type: :dhcp
13
+
14
+ config.ssh.forward_agent = true
15
+
16
+ config.vm.provision "shell", inline: "apt-get update; exec env /vagrant_data/script/install-openldap"
17
+
18
+ config.vm.synced_folder "../../../..", "/vagrant_data"
19
+
20
+ config.vm.provider "vmware_fusion" do |vb, override|
21
+ override.vm.box = "hashicorp/precise64"
22
+ vb.memory = 4596
23
+ vb.vmx["displayname"] = "integration tests vm"
24
+ vb.vmx["numvcpus"] = "2"
25
+ end
26
+
27
+ config.vm.provider "virtualbox" do |vb, override|
28
+ vb.memory = 4096
29
+ vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
30
+ vb.customize ["modifyvm", :id, "--chipset", "ich9"]
31
+ vb.customize ["modifyvm", :id, "--vram", "16"]
32
+ end
33
+ end
@@ -0,0 +1,44 @@
1
+ require_relative 'test_helper'
2
+ require 'net/ldap/dn'
3
+
4
+ class TestDN < Test::Unit::TestCase
5
+ def test_escape
6
+ assert_equal '\\,\\+\\"\\\\\\<\\>\\;', Net::LDAP::DN.escape(',+"\\<>;')
7
+ end
8
+
9
+ def test_escape_on_initialize
10
+ dn = Net::LDAP::DN.new('cn', ',+"\\<>;', 'ou=company')
11
+ assert_equal 'cn=\\,\\+\\"\\\\\\<\\>\\;,ou=company', dn.to_s
12
+ end
13
+
14
+ def test_to_a
15
+ dn = Net::LDAP::DN.new('cn=James, ou=Company\\,\\20LLC')
16
+ assert_equal ['cn','James','ou','Company, LLC'], dn.to_a
17
+ end
18
+
19
+ def test_to_a_parenthesis
20
+ dn = Net::LDAP::DN.new('cn = \ James , ou = "Comp\28ny" ')
21
+ assert_equal ['cn',' James','ou','Comp(ny'], dn.to_a
22
+ end
23
+
24
+ def test_to_a_hash_symbol
25
+ dn = Net::LDAP::DN.new('1.23.4= #A3B4D5 ,ou=Company')
26
+ assert_equal ['1.23.4','#A3B4D5','ou','Company'], dn.to_a
27
+ end
28
+
29
+ # TODO: raise a more specific exception than RuntimeError
30
+ def test_bad_input_raises_error
31
+ [
32
+ 'cn=James,',
33
+ 'cn=#aa aa',
34
+ 'cn="James',
35
+ 'cn=J\ames',
36
+ 'cn=\\',
37
+ '1.2.d=Value',
38
+ 'd1.2=Value',
39
+ ].each do |input|
40
+ dn = Net::LDAP::DN.new(input)
41
+ assert_raises(RuntimeError) { dn.to_a }
42
+ end
43
+ end
44
+ end
@@ -1,59 +1,65 @@
1
- require 'common'
1
+ require_relative 'test_helper'
2
2
 
3
- =begin
4
3
  class TestEntry < Test::Unit::TestCase
5
- Commented out until I can make it a spec.
6
- context "An instance of Entry" do
7
- setup do
8
- @entry = Net::LDAP::Entry.new 'cn=Barbara,o=corp'
9
- end
10
-
11
- should "be initialized with the DN" do
12
- assert_equal 'cn=Barbara,o=corp', @entry.dn
13
- end
14
-
15
- should 'return an empty array when accessing a nonexistent attribute (index lookup)' do
16
- assert_equal [], @entry['sn']
17
- end
18
-
19
- should 'return an empty array when accessing a nonexistent attribute (method call)' do
20
- assert_equal [], @entry.sn
21
- end
22
-
23
- should 'create an attribute on assignment (index lookup)' do
24
- @entry['sn'] = 'Jensen'
25
- assert_equal ['Jensen'], @entry['sn']
26
- end
27
-
28
- should 'create an attribute on assignment (method call)' do
29
- @entry.sn = 'Jensen'
30
- assert_equal ['Jensen'], @entry.sn
31
- end
32
-
33
- should 'have attributes accessible by index lookup' do
34
- @entry['sn'] = 'Jensen'
35
- assert_equal ['Jensen'], @entry['sn']
36
- end
37
-
38
- should 'have attributes accessible using a Symbol as the index' do
39
- @entry[:sn] = 'Jensen'
40
- assert_equal ['Jensen'], @entry[:sn]
41
- end
42
-
43
- should 'have attributes accessible by method call' do
44
- @entry['sn'] = 'Jensen'
45
- assert_equal ['Jensen'], @entry.sn
46
- end
47
-
48
- should 'ignore case of attribute names' do
49
- @entry['sn'] = 'Jensen'
50
- assert_equal ['Jensen'], @entry.sn
51
- assert_equal ['Jensen'], @entry.Sn
52
- assert_equal ['Jensen'], @entry.SN
53
- assert_equal ['Jensen'], @entry['sn']
54
- assert_equal ['Jensen'], @entry['Sn']
55
- assert_equal ['Jensen'], @entry['SN']
56
- end
57
- end
4
+ def setup
5
+ @entry = Net::LDAP::Entry.new 'cn=Barbara,o=corp'
6
+ end
7
+
8
+ def test_dn
9
+ assert_equal 'cn=Barbara,o=corp', @entry.dn
10
+ end
11
+
12
+ def test_empty_array_when_accessing_nonexistent_attribute
13
+ assert_equal [], @entry['sn']
14
+ end
15
+
16
+ def test_attribute_assignment
17
+ @entry['sn'] = 'Jensen'
18
+ assert_equal ['Jensen'], @entry['sn']
19
+ assert_equal ['Jensen'], @entry.sn
20
+ assert_equal ['Jensen'], @entry[:sn]
21
+
22
+ @entry[:sn] = 'Jensen'
23
+ assert_equal ['Jensen'], @entry['sn']
24
+ assert_equal ['Jensen'], @entry.sn
25
+ assert_equal ['Jensen'], @entry[:sn]
26
+
27
+ @entry.sn = 'Jensen'
28
+ assert_equal ['Jensen'], @entry['sn']
29
+ assert_equal ['Jensen'], @entry.sn
30
+ assert_equal ['Jensen'], @entry[:sn]
31
+ end
32
+
33
+ def test_case_insensitive_attribute_names
34
+ @entry['sn'] = 'Jensen'
35
+ assert_equal ['Jensen'], @entry.sn
36
+ assert_equal ['Jensen'], @entry.Sn
37
+ assert_equal ['Jensen'], @entry.SN
38
+ assert_equal ['Jensen'], @entry['sn']
39
+ assert_equal ['Jensen'], @entry['Sn']
40
+ assert_equal ['Jensen'], @entry['SN']
41
+ end
42
+ end
43
+
44
+ class TestEntryLDIF < Test::Unit::TestCase
45
+ def setup
46
+ @entry = Net::LDAP::Entry.from_single_ldif_string(
47
+ %Q{dn: something
48
+ foo: foo
49
+ barAttribute: bar
50
+ })
51
+ end
52
+
53
+ def test_attribute
54
+ assert_equal ['foo'], @entry.foo
55
+ assert_equal ['foo'], @entry.Foo
56
+ end
57
+
58
+ def test_modify_attribute
59
+ @entry.foo = 'bar'
60
+ assert_equal ['bar'], @entry.foo
61
+
62
+ @entry.fOo= 'baz'
63
+ assert_equal ['baz'], @entry.foo
64
+ end
58
65
  end
59
- =end