socialcast-net-ldap 0.1.5

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.
Files changed (47) hide show
  1. data/.gemtest +0 -0
  2. data/COPYING +272 -0
  3. data/Gemfile +10 -0
  4. data/Gemfile.lock +29 -0
  5. data/Hacking.rdoc +16 -0
  6. data/History.txt +137 -0
  7. data/LICENSE +56 -0
  8. data/Manifest.txt +45 -0
  9. data/README.txt +70 -0
  10. data/Rakefile +124 -0
  11. data/lib/net-ldap.rb +1 -0
  12. data/lib/net/ber.rb +341 -0
  13. data/lib/net/ber/ber_parser.rb +168 -0
  14. data/lib/net/ber/core_ext.rb +72 -0
  15. data/lib/net/ber/core_ext/array.rb +79 -0
  16. data/lib/net/ber/core_ext/bignum.rb +19 -0
  17. data/lib/net/ber/core_ext/false_class.rb +7 -0
  18. data/lib/net/ber/core_ext/fixnum.rb +63 -0
  19. data/lib/net/ber/core_ext/string.rb +57 -0
  20. data/lib/net/ber/core_ext/true_class.rb +9 -0
  21. data/lib/net/ldap.rb +1539 -0
  22. data/lib/net/ldap/dataset.rb +174 -0
  23. data/lib/net/ldap/entry.rb +208 -0
  24. data/lib/net/ldap/filter.rb +781 -0
  25. data/lib/net/ldap/password.rb +52 -0
  26. data/lib/net/ldap/pdu.rb +279 -0
  27. data/lib/net/ldif.rb +34 -0
  28. data/lib/net/snmp.rb +295 -0
  29. data/spec/integration/ssl_ber_spec.rb +33 -0
  30. data/spec/spec.opts +2 -0
  31. data/spec/spec_helper.rb +5 -0
  32. data/spec/unit/ber/ber_spec.rb +109 -0
  33. data/spec/unit/ber/core_ext/string_spec.rb +51 -0
  34. data/spec/unit/ldap/entry_spec.rb +51 -0
  35. data/spec/unit/ldap/filter_spec.rb +83 -0
  36. data/spec/unit/ldap_spec.rb +48 -0
  37. data/test/common.rb +3 -0
  38. data/test/test_entry.rb +59 -0
  39. data/test/test_filter.rb +115 -0
  40. data/test/test_ldif.rb +68 -0
  41. data/test/test_password.rb +17 -0
  42. data/test/test_rename.rb +79 -0
  43. data/test/test_snmp.rb +114 -0
  44. data/test/testdata.ldif +101 -0
  45. data/testserver/ldapserver.rb +210 -0
  46. data/testserver/testdata.ldif +101 -0
  47. metadata +178 -0
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ require 'net/ldap'
4
+
5
+ describe "BER serialisation (SSL)" do
6
+ # Transmits str to #to and reads it back from #from.
7
+ #
8
+ def transmit(str)
9
+ to.write(str)
10
+ to.close
11
+
12
+ from.read
13
+ end
14
+
15
+ attr_reader :to, :from
16
+ before(:each) do
17
+ @from, @to = IO.pipe
18
+
19
+ flexmock(OpenSSL::SSL::SSLSocket).
20
+ new_instances.should_receive(:connect => nil)
21
+
22
+ @to = Net::LDAP::Connection.wrap_with_ssl(to)
23
+ @from = Net::LDAP::Connection.wrap_with_ssl(from)
24
+ end
25
+
26
+ it "should transmit strings" do
27
+ transmit('foo').should == 'foo'
28
+ end
29
+ it "should correctly transmit numbers" do
30
+ to.write 1234.to_ber
31
+ from.read_ber.should == 1234
32
+ end
33
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --format specdoc
2
+ --colour
@@ -0,0 +1,5 @@
1
+ require 'net/ldap'
2
+
3
+ RSpec.configure do |config|
4
+ config.mock_with :flexmock
5
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ require 'net/ber'
4
+ require 'net/ldap'
5
+
6
+ describe "BER encoding of" do
7
+
8
+ RSpec::Matchers.define :properly_encode_and_decode do
9
+ match do |given|
10
+ given.to_ber.read_ber.should == given
11
+ end
12
+ end
13
+
14
+ context "arrays" do
15
+ it "should properly encode/decode []" do
16
+ [].should properly_encode_and_decode
17
+ end
18
+ it "should properly encode/decode [1,2,3]" do
19
+ ary = [1,2,3]
20
+ encoded_ary = ary.map { |el| el.to_ber }.to_ber
21
+
22
+ encoded_ary.read_ber.should == ary
23
+ end
24
+ end
25
+ context "booleans" do
26
+ it "should encode true" do
27
+ true.to_ber.should == "\x01\x01\x01"
28
+ end
29
+ it "should encode false" do
30
+ false.to_ber.should == "\x01\x01\x00"
31
+ end
32
+ end
33
+ context "numbers" do
34
+ # Sample based
35
+ {
36
+ 0 => "\x02\x01\x00",
37
+ 1 => "\x02\x01\x01",
38
+ 127 => "\x02\x01\x7F",
39
+ 128 => "\x02\x01\x80",
40
+ 255 => "\x02\x01\xFF",
41
+ 256 => "\x02\x02\x01\x00",
42
+ 65535 => "\x02\x02\xFF\xFF",
43
+ 65536 => "\x02\x03\x01\x00\x00",
44
+ 16_777_215 => "\x02\x03\xFF\xFF\xFF",
45
+ 0x01000000 => "\x02\x04\x01\x00\x00\x00",
46
+ 0x3FFFFFFF => "\x02\x04\x3F\xFF\xFF\xFF",
47
+ 0x4FFFFFFF => "\x02\x04\x4F\xFF\xFF\xFF",
48
+
49
+ # Some odd samples...
50
+ 5 => "\002\001\005",
51
+ 500 => "\002\002\001\364",
52
+ 50_000 => "\x02\x02\xC3P",
53
+ 5_000_000_000 => "\002\005\001*\005\362\000"
54
+ }.each do |number, expected_encoding|
55
+ it "should encode #{number} as #{expected_encoding.inspect}" do
56
+ number.to_ber.should == expected_encoding
57
+ end
58
+ end
59
+
60
+ # Round-trip encoding: This is mostly to be sure to cover Bignums well.
61
+ context "when decoding with #read_ber" do
62
+ it "should correctly handle powers of two" do
63
+ 100.times do |p|
64
+ n = 2 << p
65
+
66
+ n.should properly_encode_and_decode
67
+ end
68
+ end
69
+ it "should correctly handle powers of ten" do
70
+ 100.times do |p|
71
+ n = 5 * 10**p
72
+
73
+ n.should properly_encode_and_decode
74
+ end
75
+ end
76
+ end
77
+ end
78
+ if "Ruby 1.9".respond_to?(:encoding)
79
+ context "strings" do
80
+ it "should properly encode UTF-8 strings" do
81
+ "\u00e5".force_encoding("UTF-8").to_ber.should ==
82
+ "\x04\x02\xC3\xA5"
83
+ end
84
+ it "should properly encode strings encodable as UTF-8" do
85
+ "teststring".encode("US-ASCII").to_ber.should == "\x04\nteststring"
86
+ end
87
+ it "should fail on strings that can not be converted to UTF-8" do
88
+ error = Encoding::UndefinedConversionError
89
+ lambda {"\x81".to_ber }.should raise_exception(error)
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "BER decoding of" do
96
+ context "numbers" do
97
+ it "should decode #{"\002\001\006".inspect} (6)" do
98
+ "\002\001\006".read_ber(Net::LDAP::AsnSyntax).should == 6
99
+ end
100
+ it "should decode #{"\004\007testing".inspect} ('testing')" do
101
+ "\004\007testing".read_ber(Net::LDAP::AsnSyntax).should == 'testing'
102
+ end
103
+ it "should decode an ldap bind request" do
104
+ "0$\002\001\001`\037\002\001\003\004\rAdministrator\200\vad_is_bogus".
105
+ read_ber(Net::LDAP::AsnSyntax).should ==
106
+ [1, [3, "Administrator", "ad_is_bogus"]]
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'metaid'
3
+
4
+ describe String, "when extended with BER core extensions" do
5
+ describe "<- #read_ber! (consuming read_ber method)" do
6
+ context "when passed an ldap bind request and some extra data" do
7
+ attr_reader :str, :result
8
+ before(:each) do
9
+ @str = "0$\002\001\001`\037\002\001\003\004\rAdministrator\200\vad_is_bogus UNCONSUMED"
10
+ @result = str.read_ber!(Net::LDAP::AsnSyntax)
11
+ end
12
+
13
+ it "should correctly parse the ber message" do
14
+ result.should == [1, [3, "Administrator", "ad_is_bogus"]]
15
+ end
16
+ it "should leave unconsumed part of message in place" do
17
+ str.should == " UNCONSUMED"
18
+ end
19
+
20
+ context "if an exception occurs during #read_ber" do
21
+ attr_reader :initial_value
22
+ before(:each) do
23
+ stub_exception_class = Class.new(StandardError)
24
+
25
+ @initial_value = "0$\002\001\001`\037\002\001\003\004\rAdministrator\200\vad_is_bogus"
26
+ @str = initial_value.dup
27
+
28
+ # Defines a string
29
+ io = StringIO.new(initial_value)
30
+ io.meta_def :read_ber do |syntax|
31
+ read
32
+ raise stub_exception_class
33
+ end
34
+ flexmock(StringIO).should_receive(:new).and_return(io)
35
+
36
+ begin
37
+ str.read_ber!(Net::LDAP::AsnSyntax)
38
+ rescue stub_exception_class
39
+ # EMPTY ON PURPOSE
40
+ else
41
+ raise "The stub code should raise an exception!"
42
+ end
43
+ end
44
+
45
+ it "should not modify string" do
46
+ str.should == initial_value
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe Net::LDAP::Entry do
4
+ attr_reader :entry
5
+ before(:each) do
6
+ @entry = Net::LDAP::Entry.from_single_ldif_string(
7
+ %Q{dn: something
8
+ foo: foo
9
+ barAttribute: bar
10
+ }
11
+ )
12
+ end
13
+
14
+ describe "entry access" do
15
+ it "should always respond to #dn" do
16
+ entry.should respond_to(:dn)
17
+ end
18
+
19
+ context "<- #foo" do
20
+ it "should respond_to?" do
21
+ entry.should respond_to(:foo)
22
+ end
23
+ it "should return 'foo'" do
24
+ entry.foo.should == ['foo']
25
+ end
26
+ end
27
+ context "<- #Foo" do
28
+ it "should respond_to?" do
29
+ entry.should respond_to(:Foo)
30
+ end
31
+ it "should return 'foo'" do
32
+ entry.foo.should == ['foo']
33
+ end
34
+ end
35
+ context "<- #foo=" do
36
+ it "should respond_to?" do
37
+ entry.should respond_to(:foo=)
38
+ end
39
+ it "should set 'foo'" do
40
+ entry.foo= 'bar'
41
+ entry.foo.should == ['bar']
42
+ end
43
+ end
44
+ context "<- #fOo=" do
45
+ it "should return 'foo'" do
46
+ entry.fOo= 'bar'
47
+ entry.fOo.should == ['bar']
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,83 @@
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
+ ].each do |filter_str|
29
+ context "from_rfc2254(#{filter_str.inspect})" do
30
+ attr_reader :filter
31
+ before(:each) do
32
+ @filter = Net::LDAP::Filter.from_rfc2254(filter_str)
33
+ end
34
+
35
+ it "should decode into a Net::LDAP::Filter" do
36
+ filter.should be_an_instance_of(Net::LDAP::Filter)
37
+ end
38
+ it "should survive roundtrip conversion to/from ber" do
39
+ ber = filter.to_ber
40
+ Net::LDAP::Filter.parse_ber(ber.read_ber(Net::LDAP::AsnSyntax)).should ==
41
+ filter
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ describe "<- .construct" do
48
+ it "should accept apostrophes in filters (regression)" do
49
+ Net::LDAP::Filter.construct("uid=O'Keefe").to_rfc2254.should == "(uid=O'Keefe)"
50
+ end
51
+ end
52
+
53
+ describe "convenience filter constructors" do
54
+ def eq(attribute, value)
55
+ described_class.eq(attribute, value)
56
+ end
57
+ describe "<- .equals(attr, val)" do
58
+ it "should delegate to .eq with escaping" do
59
+ described_class.equals('dn', 'f*oo').should == eq('dn', 'f\2Aoo')
60
+ end
61
+ end
62
+ describe "<- .begins(attr, val)" do
63
+ it "should delegate to .eq with escaping" do
64
+ described_class.begins('dn', 'f*oo').should == eq('dn', 'f\2Aoo*')
65
+ end
66
+ end
67
+ describe "<- .ends(attr, val)" do
68
+ it "should delegate to .eq with escaping" do
69
+ described_class.ends('dn', 'f*oo').should == eq('dn', '*f\2Aoo')
70
+ end
71
+ end
72
+ describe "<- .contains(attr, val)" do
73
+ it "should delegate to .eq with escaping" do
74
+ described_class.contains('dn', 'f*oo').should == eq('dn', '*f\2Aoo*')
75
+ end
76
+ end
77
+ end
78
+ describe "<- .escape(str)" do
79
+ it "should escape !, &, *, :, | and ~" do
80
+ Net::LDAP::Filter.escape('!&*:|~').should == "\\21\\26\\2A\\3A\\7C\\7E"
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Net::LDAP::Connection do
4
+ describe "initialize" do
5
+ context "when host is not responding" do
6
+ before(:each) do
7
+ flexmock(TCPSocket).
8
+ should_receive(:new).and_raise(Errno::ECONNREFUSED)
9
+ end
10
+
11
+ it "should raise LdapError" do
12
+ lambda {
13
+ Net::LDAP::Connection.new(
14
+ :server => 'test.mocked.com',
15
+ :port => 636)
16
+ }.should raise_error(Net::LDAP::LdapError)
17
+ end
18
+ end
19
+ context "when host is blocking the port" do
20
+ before(:each) do
21
+ flexmock(TCPSocket).
22
+ should_receive(:new).and_raise(SocketError)
23
+ end
24
+
25
+ it "should raise LdapError" do
26
+ lambda {
27
+ Net::LDAP::Connection.new(
28
+ :server => 'test.mocked.com',
29
+ :port => 636)
30
+ }.should raise_error(Net::LDAP::LdapError)
31
+ end
32
+ end
33
+ context "on other exceptions" do
34
+ before(:each) do
35
+ flexmock(TCPSocket).
36
+ should_receive(:new).and_raise(NameError)
37
+ end
38
+
39
+ it "should rethrow the exception" do
40
+ lambda {
41
+ Net::LDAP::Connection.new(
42
+ :server => 'test.mocked.com',
43
+ :port => 636)
44
+ }.should raise_error(NameError)
45
+ end
46
+ end
47
+ end
48
+ end
data/test/common.rb ADDED
@@ -0,0 +1,3 @@
1
+ # Add 'lib' to load path.
2
+ require 'test/unit'
3
+ require 'net/ldap'
@@ -0,0 +1,59 @@
1
+ require 'common'
2
+
3
+ =begin
4
+ 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
58
+ end
59
+ =end