net-ldap 0.8.0 → 0.9.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 (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
@@ -1,26 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe Net::LDAP::Filter::FilterParser do
5
-
6
- describe "#parse" do
7
- context "Given ASCIIs as filter string" do
8
- let(:filter_string) { "(cn=name)" }
9
- specify "should generate filter object" do
10
- expect(Net::LDAP::Filter::FilterParser.parse(filter_string)).to be_a Net::LDAP::Filter
11
- end
12
- end
13
- context "Given string including multibyte chars as filter string" do
14
- let(:filter_string) { "(cn=名前)" }
15
- specify "should generate filter object" do
16
- expect(Net::LDAP::Filter::FilterParser.parse(filter_string)).to be_a Net::LDAP::Filter
17
- end
18
- end
19
- context "Given string including colons ':'" do
20
- let(:filter_string) { "(ismemberof=cn=edu:berkeley:app:calmessages:deans,ou=campus groups,dc=berkeley,dc=edu)" }
21
- specify "should generate filter object" do
22
- expect(Net::LDAP::Filter::FilterParser.parse(filter_string)).to be_a Net::LDAP::Filter
23
- end
24
- end
25
- end
26
- end
@@ -1,115 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Net::LDAP::Filter do
4
- describe "<- .ex(attr, value)" do
5
- context "('foo', 'bar')" do
6
- attr_reader :filter
7
- before(:each) do
8
- @filter = Net::LDAP::Filter.ex('foo', 'bar')
9
- end
10
- it "should convert to 'foo:=bar'" do
11
- filter.to_s.should == '(foo:=bar)'
12
- end
13
- it "should survive roundtrip via to_s/from_rfc2254" do
14
- Net::LDAP::Filter.from_rfc2254(filter.to_s).should == filter
15
- end
16
- it "should survive roundtrip conversion to/from ber" do
17
- ber = filter.to_ber
18
- Net::LDAP::Filter.parse_ber(ber.read_ber(Net::LDAP::AsnSyntax)).should ==
19
- filter
20
- end
21
- end
22
- context "various legal inputs" do
23
- [
24
- '(o:dn:=Ace Industry)',
25
- '(:dn:2.4.8.10:=Dino)',
26
- '(cn:dn:1.2.3.4.5:=John Smith)',
27
- '(sn:dn:2.4.6.8.10:=Barbara Jones)',
28
- '(&(sn:dn:2.4.6.8.10:=Barbara Jones))'
29
- ].each do |filter_str|
30
- context "from_rfc2254(#{filter_str.inspect})" do
31
- attr_reader :filter
32
- before(:each) do
33
- @filter = Net::LDAP::Filter.from_rfc2254(filter_str)
34
- end
35
-
36
- it "should decode into a Net::LDAP::Filter" do
37
- filter.should be_an_instance_of(Net::LDAP::Filter)
38
- end
39
- it "should survive roundtrip conversion to/from ber" do
40
- ber = filter.to_ber
41
- Net::LDAP::Filter.parse_ber(ber.read_ber(Net::LDAP::AsnSyntax)).should ==
42
- filter
43
- end
44
- end
45
- end
46
- end
47
- end
48
- describe "<- .construct" do
49
- it "should accept apostrophes in filters (regression)" do
50
- Net::LDAP::Filter.construct("uid=O'Keefe").to_rfc2254.should == "(uid=O'Keefe)"
51
- end
52
- end
53
-
54
- describe "convenience filter constructors" do
55
- def eq(attribute, value)
56
- described_class.eq(attribute, value)
57
- end
58
- describe "<- .equals(attr, val)" do
59
- it "should delegate to .eq with escaping" do
60
- described_class.equals('dn', 'f*oo').should == eq('dn', 'f\2Aoo')
61
- end
62
- end
63
- describe "<- .begins(attr, val)" do
64
- it "should delegate to .eq with escaping" do
65
- described_class.begins('dn', 'f*oo').should == eq('dn', 'f\2Aoo*')
66
- end
67
- end
68
- describe "<- .ends(attr, val)" do
69
- it "should delegate to .eq with escaping" do
70
- described_class.ends('dn', 'f*oo').should == eq('dn', '*f\2Aoo')
71
- end
72
- end
73
- describe "<- .contains(attr, val)" do
74
- it "should delegate to .eq with escaping" do
75
- described_class.contains('dn', 'f*oo').should == eq('dn', '*f\2Aoo*')
76
- end
77
- end
78
- end
79
- describe "<- .escape(str)" do
80
- it "should escape nul, *, (, ) and \\" do
81
- Net::LDAP::Filter.escape("\0*()\\").should == "\\00\\2A\\28\\29\\5C"
82
- end
83
- end
84
-
85
- context 'with a well-known BER string' do
86
- ber = raw_string("\xa4\x2d" \
87
- "\x04\x0b" "objectclass" \
88
- "\x30\x1e" \
89
- "\x80\x08" "foo" "*\\" "bar" \
90
- "\x81\x08" "foo" "*\\" "bar" \
91
- "\x82\x08" "foo" "*\\" "bar")
92
-
93
- describe "<- .to_ber" do
94
- [
95
- "foo" "\\2A\\5C" "bar",
96
- "foo" "\\2a\\5c" "bar",
97
- "foo" "\\2A\\5c" "bar",
98
- "foo" "\\2a\\5C" "bar"
99
- ].each do |escaped|
100
- it 'unescapes escaped characters' do
101
- filter = Net::LDAP::Filter.eq("objectclass", "#{escaped}*#{escaped}*#{escaped}")
102
- filter.to_ber.should == ber
103
- end
104
- end
105
- end
106
-
107
- describe '<- .parse_ber' do
108
- it 'escapes characters' do
109
- escaped = Net::LDAP::Filter.escape("foo" "*\\" "bar")
110
- filter = Net::LDAP::Filter.parse_ber(ber.read_ber(Net::LDAP::AsnSyntax))
111
- filter.to_s.should == "(objectclass=#{escaped}*#{escaped}*#{escaped})"
112
- end
113
- end
114
- end
115
- end
@@ -1,49 +0,0 @@
1
- # -*- ruby encoding: utf-8 -*-
2
-
3
- describe Net::LDAP, "search method" do
4
- class FakeConnection
5
- def search(args)
6
- OpenStruct.new(:result_code => 1, :message => "error", :success? => false)
7
- end
8
- end
9
-
10
- before(:each) do
11
- @service = MockInstrumentationService.new
12
- @connection = Net::LDAP.new :instrumentation_service => @service
13
- @connection.instance_variable_set(:@open_connection, FakeConnection.new)
14
- end
15
-
16
- context "when :return_result => true" do
17
- it "should return nil upon error" do
18
- result_set = @connection.search(:return_result => true)
19
- result_set.should be_nil
20
- end
21
- end
22
-
23
- context "when :return_result => false" do
24
- it "should return false upon error" do
25
- result = @connection.search(:return_result => false)
26
- result.should be_false
27
- end
28
- end
29
-
30
- context "When :return_result is not given" do
31
- it "should return nil upon error" do
32
- result_set = @connection.search
33
- result_set.should be_nil
34
- end
35
- end
36
-
37
- context "when instrumentation_service is configured" do
38
- it "should publish a search.net_ldap event" do
39
- events = @service.subscribe "search.net_ldap"
40
-
41
- @connection.search :filter => "test"
42
-
43
- payload, result = events.pop
44
- payload.should have_key(:result)
45
- payload.should have_key(:filter)
46
- payload[:filter].should == "test"
47
- end
48
- end
49
- end
@@ -1,223 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Net::LDAP do
4
- describe "initialize" do
5
- context "when instrumentation is configured" do
6
- before do
7
- @connection = flexmock(:connection, :close => true)
8
- flexmock(Net::LDAP::Connection).should_receive(:new).and_return(@connection)
9
-
10
- @service = MockInstrumentationService.new
11
- end
12
-
13
- subject do
14
- Net::LDAP.new \
15
- :server => "test.mocked.com", :port => 636,
16
- :force_no_page => true, # so server capabilities are not queried
17
- :instrumentation_service => @service
18
- end
19
-
20
- it "should instrument bind" do
21
- events = @service.subscribe "bind.net_ldap"
22
-
23
- bind_result = flexmock(:bind_result, :success? => true)
24
- @connection.should_receive(:bind).with(Hash).and_return(bind_result)
25
-
26
- subject.bind.should be_true
27
-
28
- payload, result = events.pop
29
- result.should be_true
30
- payload[:bind].should == bind_result
31
- end
32
-
33
- it "should instrument search" do
34
- events = @service.subscribe "search.net_ldap"
35
-
36
- @connection.should_receive(:bind).and_return(flexmock(:bind_result, :result_code => 0))
37
- @connection.should_receive(:search).with(Hash, Proc).
38
- yields(entry = Net::LDAP::Entry.new("uid=user1,ou=users,dc=example,dc=com")).
39
- and_return(flexmock(:search_result, :success? => true, :result_code => 0))
40
-
41
- subject.search(:filter => "(uid=user1)").should be_true
42
-
43
- payload, result = events.pop
44
- result.should == [entry]
45
- payload[:result].should == [entry]
46
- payload[:filter].should == "(uid=user1)"
47
- end
48
- end
49
- end
50
- end
51
-
52
- describe Net::LDAP::Connection do
53
- describe "initialize" do
54
- context "when host is not responding" do
55
- before(:each) do
56
- flexmock(TCPSocket).
57
- should_receive(:new).and_raise(Errno::ECONNREFUSED)
58
- end
59
-
60
- it "should raise LdapError" do
61
- lambda {
62
- Net::LDAP::Connection.new(
63
- :server => 'test.mocked.com',
64
- :port => 636)
65
- }.should raise_error(Net::LDAP::LdapError)
66
- end
67
- end
68
- context "when host is blocking the port" do
69
- before(:each) do
70
- flexmock(TCPSocket).
71
- should_receive(:new).and_raise(SocketError)
72
- end
73
-
74
- it "should raise LdapError" do
75
- lambda {
76
- Net::LDAP::Connection.new(
77
- :server => 'test.mocked.com',
78
- :port => 636)
79
- }.should raise_error(Net::LDAP::LdapError)
80
- end
81
- end
82
- context "on other exceptions" do
83
- before(:each) do
84
- flexmock(TCPSocket).
85
- should_receive(:new).and_raise(NameError)
86
- end
87
-
88
- it "should rethrow the exception" do
89
- lambda {
90
- Net::LDAP::Connection.new(
91
- :server => 'test.mocked.com',
92
- :port => 636)
93
- }.should raise_error(NameError)
94
- end
95
- end
96
- end
97
-
98
- context "populate error messages" do
99
- before do
100
- @tcp_socket = flexmock(:connection)
101
- @tcp_socket.should_receive(:write)
102
- flexmock(TCPSocket).should_receive(:new).and_return(@tcp_socket)
103
- end
104
-
105
- subject { Net::LDAP::Connection.new(:server => 'test.mocked.com', :port => 636) }
106
-
107
- it "should get back error messages if operation fails" do
108
- ber = Net::BER::BerIdentifiedArray.new([53, "", "The provided password value was rejected by a password validator: The provided password did not contain enough characters from the character set 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. The minimum number of characters from that set that must be present in user passwords is 1"])
109
- ber.ber_identifier = Net::LDAP::PDU::ModifyResponse
110
- @tcp_socket.should_receive(:read_ber).and_return([2, ber])
111
-
112
- result = subject.modify(:dn => "1", :operations => [[:replace, "mail", "something@sothsdkf.com"]])
113
- result.should be_failure
114
- result.error_message.should == "The provided password value was rejected by a password validator: The provided password did not contain enough characters from the character set 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. The minimum number of characters from that set that must be present in user passwords is 1"
115
- end
116
-
117
- it "shouldn't get back error messages if operation succeeds" do
118
- ber = Net::BER::BerIdentifiedArray.new([0, "", ""])
119
- ber.ber_identifier = Net::LDAP::PDU::ModifyResponse
120
- @tcp_socket.should_receive(:read_ber).and_return([2, ber])
121
-
122
- result = subject.modify(:dn => "1", :operations => [[:replace, "mail", "something@sothsdkf.com"]])
123
- result.should be_success
124
- result.error_message.should == ""
125
- end
126
- end
127
-
128
- context "instrumentation" do
129
- before do
130
- @tcp_socket = flexmock(:connection)
131
- # handle write
132
- @tcp_socket.should_receive(:write)
133
- # return this mock
134
- flexmock(TCPSocket).should_receive(:new).and_return(@tcp_socket)
135
-
136
- @service = MockInstrumentationService.new
137
- end
138
-
139
- subject do
140
- Net::LDAP::Connection.new(:server => 'test.mocked.com', :port => 636,
141
- :instrumentation_service => @service)
142
- end
143
-
144
- it "should publish a write.net_ldap_connection event" do
145
- ber = Net::BER::BerIdentifiedArray.new([0, "", ""])
146
- ber.ber_identifier = Net::LDAP::PDU::BindResult
147
- read_result = [2, ber]
148
- @tcp_socket.should_receive(:read_ber).and_return(read_result)
149
-
150
- events = @service.subscribe "write.net_ldap_connection"
151
-
152
- result = subject.bind(method: :anon)
153
- result.should be_success
154
-
155
- # a write event
156
- payload, result = events.pop
157
- payload.should have_key(:result)
158
- payload.should have_key(:content_length)
159
- end
160
-
161
- it "should publish a read.net_ldap_connection event" do
162
- ber = Net::BER::BerIdentifiedArray.new([0, "", ""])
163
- ber.ber_identifier = Net::LDAP::PDU::BindResult
164
- read_result = [2, ber]
165
- @tcp_socket.should_receive(:read_ber).and_return(read_result)
166
-
167
- events = @service.subscribe "read.net_ldap_connection"
168
-
169
- result = subject.bind(method: :anon)
170
- result.should be_success
171
-
172
- # a read event
173
- payload, result = events.pop
174
- payload.should have_key(:result)
175
- result.should == read_result
176
- end
177
-
178
- it "should publish a bind.net_ldap_connection event" do
179
- ber = Net::BER::BerIdentifiedArray.new([0, "", ""])
180
- ber.ber_identifier = Net::LDAP::PDU::BindResult
181
- bind_result = [2, ber]
182
- @tcp_socket.should_receive(:read_ber).and_return(bind_result)
183
-
184
- events = @service.subscribe "bind.net_ldap_connection"
185
-
186
- result = subject.bind(method: :anon)
187
- result.should be_success
188
-
189
- # a read event
190
- payload, result = events.pop
191
- payload.should have_key(:result)
192
- result.should be_success
193
- end
194
-
195
- it "should publish a search.net_ldap_connection event" do
196
- # search data
197
- search_data_ber = Net::BER::BerIdentifiedArray.new([2, [
198
- "uid=user1,ou=OrgUnit2,ou=OrgUnitTop,dc=openldap,dc=ghe,dc=local",
199
- [ ["uid", ["user1"]] ]
200
- ]])
201
- search_data_ber.ber_identifier = Net::LDAP::PDU::SearchReturnedData
202
- search_data = [2, search_data_ber]
203
- # search result (end of results)
204
- search_result_ber = Net::BER::BerIdentifiedArray.new([0, "", ""])
205
- search_result_ber.ber_identifier = Net::LDAP::PDU::SearchResult
206
- search_result = [2, search_result_ber]
207
- @tcp_socket.should_receive(:read_ber).and_return(search_data).
208
- and_return(search_result)
209
-
210
- events = @service.subscribe "search.net_ldap_connection"
211
-
212
- result = subject.search(filter: "(uid=user1)")
213
- result.should be_success
214
-
215
- # a search event
216
- payload, result = events.pop
217
- payload.should have_key(:result)
218
- payload.should have_key(:filter)
219
- payload[:filter].to_s.should == "(uid=user1)"
220
- result.should be_truthy
221
- end
222
- end
223
- end
@@ -1,3 +0,0 @@
1
- # Add 'lib' to load path.
2
- require 'test/unit'
3
- require 'net/ldap'