net-ldap 0.3.1 → 0.5.1
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.
- checksums.yaml +7 -0
- data/.travis.yml +7 -0
- data/Contributors.rdoc +1 -0
- data/Gemfile +2 -0
- data/History.rdoc +12 -0
- data/Manifest.txt +6 -0
- data/README.rdoc +2 -7
- data/Rakefile +5 -3
- data/lib/net/ber.rb +4 -2
- data/lib/net/ber/core_ext/array.rb +14 -0
- data/lib/net/ber/core_ext/string.rb +22 -4
- data/lib/net/ldap.rb +125 -43
- data/lib/net/ldap/filter.rb +30 -8
- data/lib/net/ldap/password.rb +20 -14
- data/lib/net/ldap/pdu.rb +16 -0
- data/lib/net/ldap/version.rb +5 -0
- data/lib/net/snmp.rb +3 -1
- data/net-ldap.gemspec +14 -9
- data/spec/unit/ber/ber_spec.rb +34 -2
- data/spec/unit/ber/core_ext/array_spec.rb +24 -0
- data/spec/unit/ldap/filter_parser_spec.rb +20 -0
- data/spec/unit/ldap/filter_spec.rb +31 -0
- data/spec/unit/ldap/search_spec.rb +35 -0
- data/spec/unit/ldap_spec.rb +37 -7
- metadata +83 -64
data/lib/net/ldap/filter.rb
CHANGED
@@ -23,7 +23,7 @@
|
|
23
23
|
class Net::LDAP::Filter
|
24
24
|
##
|
25
25
|
# Known filter types.
|
26
|
-
FilterTypes = [ :ne, :eq, :ge, :le, :and, :or, :not, :ex ]
|
26
|
+
FilterTypes = [ :ne, :eq, :ge, :le, :and, :or, :not, :ex, :bineq ]
|
27
27
|
|
28
28
|
def initialize(op, left, right) #:nodoc:
|
29
29
|
unless FilterTypes.include?(op)
|
@@ -65,6 +65,23 @@ class Net::LDAP::Filter
|
|
65
65
|
new(:eq, attribute, value)
|
66
66
|
end
|
67
67
|
|
68
|
+
##
|
69
|
+
# Creates a Filter object indicating a binary comparison.
|
70
|
+
# this prevents the search data from being forced into a UTF-8 string.
|
71
|
+
#
|
72
|
+
# This is primarily used for Microsoft Active Directory to compare
|
73
|
+
# GUID values.
|
74
|
+
#
|
75
|
+
# # for guid represented as hex charecters
|
76
|
+
# guid = "6a31b4a12aa27a41aca9603f27dd5116"
|
77
|
+
# guid_bin = [guid].pack("H*")
|
78
|
+
# f = Net::LDAP::Filter.bineq("objectGUID", guid_bin)
|
79
|
+
#
|
80
|
+
# This filter does not perform any escaping.
|
81
|
+
def bineq(attribute, value)
|
82
|
+
new(:bineq, attribute, value)
|
83
|
+
end
|
84
|
+
|
68
85
|
##
|
69
86
|
# Creates a Filter object indicating extensible comparison. This Filter
|
70
87
|
# object is currently considered EXPERIMENTAL.
|
@@ -274,11 +291,11 @@ class Net::LDAP::Filter
|
|
274
291
|
case b.ber_identifier
|
275
292
|
when 0x80 # context-specific primitive 0, SubstringFilter "initial"
|
276
293
|
raise Net::LDAP::LdapError, "Unrecognized substring filter; bad initial value." if str.length > 0
|
277
|
-
str += b
|
294
|
+
str += escape(b)
|
278
295
|
when 0x81 # context-specific primitive 0, SubstringFilter "any"
|
279
|
-
str += "*#{b}"
|
296
|
+
str += "*#{escape(b)}"
|
280
297
|
when 0x82 # context-specific primitive 0, SubstringFilter "final"
|
281
|
-
str += "*#{b}"
|
298
|
+
str += "*#{escape(b)}"
|
282
299
|
final = true
|
283
300
|
end
|
284
301
|
}
|
@@ -399,6 +416,8 @@ class Net::LDAP::Filter
|
|
399
416
|
"!(#{@left}=#{@right})"
|
400
417
|
when :eq
|
401
418
|
"#{@left}=#{@right}"
|
419
|
+
when :bineq
|
420
|
+
"#{@left}=#{@right}"
|
402
421
|
when :ex
|
403
422
|
"#{@left}:=#{@right}"
|
404
423
|
when :ge
|
@@ -490,17 +509,17 @@ class Net::LDAP::Filter
|
|
490
509
|
first = nil
|
491
510
|
ary.shift
|
492
511
|
else
|
493
|
-
first = ary.shift.to_ber_contextspecific(0)
|
512
|
+
first = unescape(ary.shift).to_ber_contextspecific(0)
|
494
513
|
end
|
495
514
|
|
496
515
|
if ary.last.empty?
|
497
516
|
last = nil
|
498
517
|
ary.pop
|
499
518
|
else
|
500
|
-
last = ary.pop.to_ber_contextspecific(2)
|
519
|
+
last = unescape(ary.pop).to_ber_contextspecific(2)
|
501
520
|
end
|
502
521
|
|
503
|
-
seq = ary.map { |e| e.to_ber_contextspecific(1) }
|
522
|
+
seq = ary.map { |e| unescape(e).to_ber_contextspecific(1) }
|
504
523
|
seq.unshift first if first
|
505
524
|
seq.push last if last
|
506
525
|
|
@@ -508,6 +527,9 @@ class Net::LDAP::Filter
|
|
508
527
|
else # equality
|
509
528
|
[@left.to_s.to_ber, unescape(@right).to_ber].to_ber_contextspecific(3)
|
510
529
|
end
|
530
|
+
when :bineq
|
531
|
+
# make sure data is not forced to UTF-8
|
532
|
+
[@left.to_s.to_ber, unescape(@right).to_ber_bin].to_ber_contextspecific(3)
|
511
533
|
when :ex
|
512
534
|
seq = []
|
513
535
|
|
@@ -733,7 +755,7 @@ class Net::LDAP::Filter
|
|
733
755
|
scanner.scan(/\s*/)
|
734
756
|
if op = scanner.scan(/<=|>=|!=|:=|=/)
|
735
757
|
scanner.scan(/\s*/)
|
736
|
-
if value = scanner.scan(/(?:[-\w*.+@=,#\$%&!'\s]|\\[a-fA-F\d]{2})+/)
|
758
|
+
if value = scanner.scan(/(?:[-\w*.+@=,#\$%&!'\s\xC3\x80-\xCA\xAF]|[^\x00-\x7F]|\\[a-fA-F\d]{2})+/u)
|
737
759
|
# 20100313 AZ: Assumes that "(uid=george*)" is the same as
|
738
760
|
# "(uid=george* )". The standard doesn't specify, but I can find
|
739
761
|
# no examples that suggest otherwise.
|
data/lib/net/ldap/password.rb
CHANGED
@@ -1,31 +1,37 @@
|
|
1
1
|
# -*- ruby encoding: utf-8 -*-
|
2
2
|
require 'digest/sha1'
|
3
3
|
require 'digest/md5'
|
4
|
+
require 'base64'
|
4
5
|
|
5
6
|
class Net::LDAP::Password
|
6
7
|
class << self
|
7
8
|
# Generate a password-hash suitable for inclusion in an LDAP attribute.
|
8
|
-
# Pass a hash type
|
9
|
+
# Pass a hash type as a symbol (:md5, :sha, :ssha) and a plaintext
|
9
10
|
# password. This function will return a hashed representation.
|
10
11
|
#
|
11
12
|
#--
|
12
13
|
# STUB: This is here to fulfill the requirements of an RFC, which
|
13
14
|
# one?
|
14
15
|
#
|
15
|
-
# TODO
|
16
|
-
#
|
17
|
-
# provide
|
16
|
+
# TODO:
|
17
|
+
# * maybe salted-md5
|
18
|
+
# * Should we provide sha1 as a synonym for sha1? I vote no because then
|
19
|
+
# should you also provide ssha1 for symmetry?
|
20
|
+
#
|
21
|
+
attribute_value = ""
|
18
22
|
def generate(type, str)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
case type
|
24
|
+
when :md5
|
25
|
+
attribute_value = '{MD5}' + Base64.encode64(Digest::MD5.digest(str)).chomp!
|
26
|
+
when :sha
|
27
|
+
attribute_value = '{SHA}' + Base64.encode64(Digest::SHA1.digest(str)).chomp!
|
28
|
+
when :ssha
|
29
|
+
srand; salt = (rand * 1000).to_i.to_s
|
30
|
+
attribute_value = '{SSHA}' + Base64.encode64(Digest::SHA1.digest(str + salt) + salt).chomp!
|
31
|
+
else
|
32
|
+
raise Net::LDAP::LdapError, "Unsupported password-hash type (#{type})"
|
33
|
+
end
|
34
|
+
return attribute_value
|
29
35
|
end
|
30
36
|
end
|
31
37
|
end
|
data/lib/net/ldap/pdu.rb
CHANGED
@@ -112,6 +112,10 @@ class Net::LDAP::PDU
|
|
112
112
|
@ldap_result || {}
|
113
113
|
end
|
114
114
|
|
115
|
+
def error_message
|
116
|
+
result[:errorMessage] || ""
|
117
|
+
end
|
118
|
+
|
115
119
|
##
|
116
120
|
# This returns an LDAP result code taken from the PDU, but it will be nil
|
117
121
|
# if there wasn't a result code. That can easily happen depending on the
|
@@ -120,6 +124,18 @@ class Net::LDAP::PDU
|
|
120
124
|
@ldap_result and @ldap_result[code]
|
121
125
|
end
|
122
126
|
|
127
|
+
def status
|
128
|
+
result_code == 0 ? :success : :failure
|
129
|
+
end
|
130
|
+
|
131
|
+
def success?
|
132
|
+
status == :success
|
133
|
+
end
|
134
|
+
|
135
|
+
def failure?
|
136
|
+
!success?
|
137
|
+
end
|
138
|
+
|
123
139
|
##
|
124
140
|
# Return serverSaslCreds, which are only present in BindResponse packets.
|
125
141
|
#--
|
data/lib/net/snmp.rb
CHANGED
data/net-ldap.gemspec
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'net/ldap/version'
|
5
|
+
|
2
6
|
Gem::Specification.new do |s|
|
3
7
|
s.name = %q{net-ldap}
|
4
|
-
s.version =
|
8
|
+
s.version = Net::LDAP::VERSION
|
9
|
+
s.license = "MIT"
|
5
10
|
|
6
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
7
|
-
s.authors = ["Francis Cianfrocca", "Emiel van de Laar", "Rory O'Connell", "Kaspar Schiess", "Austin Ziegler"]
|
8
|
-
s.date = %q{
|
12
|
+
s.authors = ["Francis Cianfrocca", "Emiel van de Laar", "Rory O'Connell", "Kaspar Schiess", "Austin Ziegler", "Michael Schaarschmidt"]
|
13
|
+
s.date = %q{2012-02-28}
|
9
14
|
s.description = %q{Net::LDAP for Ruby (also called net-ldap) implements client access for the
|
10
15
|
Lightweight Directory Access Protocol (LDAP), an IETF standard protocol for
|
11
16
|
accessing distributed directory services. Net::LDAP is written completely in
|
@@ -14,12 +19,12 @@ subset of server features as well.
|
|
14
19
|
|
15
20
|
Net::LDAP has been tested against modern popular LDAP servers including
|
16
21
|
OpenLDAP and Active Directory. The current release is mostly compliant with
|
17
|
-
earlier versions of the IETF LDAP RFCs (2251
|
22
|
+
earlier versions of the IETF LDAP RFCs (2251-2256, 2829-2830, 3377, and 3771).
|
18
23
|
Our roadmap for Net::LDAP 1.0 is to gain full <em>client</em> compliance with
|
19
|
-
the most recent LDAP RFCs (4510
|
24
|
+
the most recent LDAP RFCs (4510-4519, plutions of 4520-4532).}
|
20
25
|
s.email = ["blackhedd@rubyforge.org", "gemiel@gmail.com", "rory.ocon@gmail.com", "kaspar.schiess@absurd.li", "austin@rubyforge.org"]
|
21
26
|
s.extra_rdoc_files = ["Manifest.txt", "Contributors.rdoc", "Hacking.rdoc", "History.rdoc", "License.rdoc", "README.rdoc"]
|
22
|
-
s.files = [".autotest", ".rspec", "Contributors.rdoc", "Hacking.rdoc", "History.rdoc", "License.rdoc", "Manifest.txt", "README.rdoc", "Rakefile", "autotest/discover.rb", "lib/net-ldap.rb", "lib/net/ber.rb", "lib/net/ber/ber_parser.rb", "lib/net/ber/core_ext.rb", "lib/net/ber/core_ext/array.rb", "lib/net/ber/core_ext/bignum.rb", "lib/net/ber/core_ext/false_class.rb", "lib/net/ber/core_ext/fixnum.rb", "lib/net/ber/core_ext/string.rb", "lib/net/ber/core_ext/true_class.rb", "lib/net/ldap.rb", "lib/net/ldap/dataset.rb", "lib/net/ldap/dn.rb", "lib/net/ldap/entry.rb", "lib/net/ldap/filter.rb", "lib/net/ldap/password.rb", "lib/net/ldap/pdu.rb", "lib/net/snmp.rb", "net-ldap.gemspec", "spec/integration/ssl_ber_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/unit/ber/ber_spec.rb", "spec/unit/ber/core_ext/string_spec.rb", "spec/unit/ldap/dn_spec.rb", "spec/unit/ldap/entry_spec.rb", "spec/unit/ldap/filter_spec.rb", "spec/unit/ldap_spec.rb", "test/common.rb", "test/test_entry.rb", "test/test_filter.rb", "test/test_ldap_connection.rb", "test/test_ldif.rb", "test/test_password.rb", "test/test_rename.rb", "test/test_snmp.rb", "test/testdata.ldif", "testserver/ldapserver.rb", "testserver/testdata.ldif"]
|
27
|
+
s.files = [".autotest", ".rspec", "Contributors.rdoc", "Hacking.rdoc", "History.rdoc", "License.rdoc", "Manifest.txt", "README.rdoc", "Rakefile", "autotest/discover.rb", "lib/net-ldap.rb", "lib/net/ber.rb", "lib/net/ber/ber_parser.rb", "lib/net/ber/core_ext.rb", "lib/net/ber/core_ext/array.rb", "lib/net/ber/core_ext/bignum.rb", "lib/net/ber/core_ext/false_class.rb", "lib/net/ber/core_ext/fixnum.rb", "lib/net/ber/core_ext/string.rb", "lib/net/ber/core_ext/true_class.rb", "lib/net/ldap.rb", "lib/net/ldap/dataset.rb", "lib/net/ldap/dn.rb", "lib/net/ldap/entry.rb", "lib/net/ldap/filter.rb", "lib/net/ldap/password.rb", "lib/net/ldap/pdu.rb", "lib/net/snmp.rb", "net-ldap.gemspec", "spec/integration/ssl_ber_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/unit/ber/ber_spec.rb", "spec/unit/ber/core_ext/string_spec.rb", "spec/unit/ldap/dn_spec.rb", "spec/unit/ldap/entry_spec.rb", "spec/unit/ldap/filter_spec.rb", "spec/unit/ldap_spec.rb", "test/common.rb", "test/test_entry.rb", "test/test_filter.rb", "test/test_ldap_connection.rb", "test/test_ldif.rb", "test/test_password.rb", "test/test_rename.rb", "test/test_snmp.rb", "test/testdata.ldif", "testserver/ldapserver.rb", "testserver/testdata.ldif", "lib/net/ldap/version.rb"]
|
23
28
|
s.homepage = %q{http://github.com.org/ruby-ldap/ruby-net-ldap}
|
24
29
|
s.rdoc_options = ["--main", "README.rdoc"]
|
25
30
|
s.require_paths = ["lib"]
|
@@ -36,14 +41,14 @@ the most recent LDAP RFCs (4510–4519, plutions of 4520–4532).}
|
|
36
41
|
s.add_development_dependency(%q<hoe-git>, ["~> 1"])
|
37
42
|
s.add_development_dependency(%q<hoe-gemspec>, ["~> 1"])
|
38
43
|
s.add_development_dependency(%q<metaid>, ["~> 1"])
|
39
|
-
s.add_development_dependency(%q<flexmock>, ["
|
44
|
+
s.add_development_dependency(%q<flexmock>, [">= 1.3.0"])
|
40
45
|
s.add_development_dependency(%q<rspec>, ["~> 2.0"])
|
41
46
|
s.add_development_dependency(%q<hoe>, [">= 2.9.1"])
|
42
47
|
else
|
43
48
|
s.add_dependency(%q<hoe-git>, ["~> 1"])
|
44
49
|
s.add_dependency(%q<hoe-gemspec>, ["~> 1"])
|
45
50
|
s.add_dependency(%q<metaid>, ["~> 1"])
|
46
|
-
s.add_dependency(%q<flexmock>, ["
|
51
|
+
s.add_dependency(%q<flexmock>, [">= 1.3.0"])
|
47
52
|
s.add_dependency(%q<rspec>, ["~> 2.0"])
|
48
53
|
s.add_dependency(%q<hoe>, [">= 2.9.1"])
|
49
54
|
end
|
@@ -51,7 +56,7 @@ the most recent LDAP RFCs (4510–4519, plutions of 4520–4532).}
|
|
51
56
|
s.add_dependency(%q<hoe-git>, ["~> 1"])
|
52
57
|
s.add_dependency(%q<hoe-gemspec>, ["~> 1"])
|
53
58
|
s.add_dependency(%q<metaid>, ["~> 1"])
|
54
|
-
s.add_dependency(%q<flexmock>, ["
|
59
|
+
s.add_dependency(%q<flexmock>, [">= 1.3.0"])
|
55
60
|
s.add_dependency(%q<rspec>, ["~> 2.0"])
|
56
61
|
s.add_dependency(%q<hoe>, [">= 2.9.1"])
|
57
62
|
end
|
data/spec/unit/ber/ber_spec.rb
CHANGED
@@ -84,9 +84,14 @@ describe "BER encoding of" do
|
|
84
84
|
it "should properly encode strings encodable as UTF-8" do
|
85
85
|
"teststring".encode("US-ASCII").to_ber.should == "\x04\nteststring"
|
86
86
|
end
|
87
|
-
|
87
|
+
it "should properly encode binary data strings using to_ber_bin" do
|
88
|
+
# This is used for searching for GUIDs in Active Directory
|
89
|
+
["6a31b4a12aa27a41aca9603f27dd5116"].pack("H*").to_ber_bin.should ==
|
90
|
+
"\x04\x10" + "j1\xB4\xA1*\xA2zA\xAC\xA9`?'\xDDQ\x16"
|
91
|
+
end
|
92
|
+
it "should not fail on strings that can not be converted to UTF-8" do
|
88
93
|
error = Encoding::UndefinedConversionError
|
89
|
-
lambda {"\x81".to_ber }.
|
94
|
+
lambda {"\x81".to_ber }.should_not raise_exception(error)
|
90
95
|
end
|
91
96
|
end
|
92
97
|
end
|
@@ -107,3 +112,30 @@ describe "BER decoding of" do
|
|
107
112
|
end
|
108
113
|
end
|
109
114
|
end
|
115
|
+
|
116
|
+
describe Net::BER::BerIdentifiedString do
|
117
|
+
describe "initialize" do
|
118
|
+
subject { Net::BER::BerIdentifiedString.new(data) }
|
119
|
+
|
120
|
+
context "binary data" do
|
121
|
+
let(:data) { ["6a31b4a12aa27a41aca9603f27dd5116"].pack("H*").force_encoding("ASCII-8BIT") }
|
122
|
+
|
123
|
+
its(:valid_encoding?) { should be_true }
|
124
|
+
specify { subject.encoding.name.should == "ASCII-8BIT" }
|
125
|
+
end
|
126
|
+
|
127
|
+
context "ascii data in UTF-8" do
|
128
|
+
let(:data) { "some text".force_encoding("UTF-8") }
|
129
|
+
|
130
|
+
its(:valid_encoding?) { should be_true }
|
131
|
+
specify { subject.encoding.name.should == "UTF-8" }
|
132
|
+
end
|
133
|
+
|
134
|
+
context "UTF-8 data in UTF-8" do
|
135
|
+
let(:data) { ["e4b8ad"].pack("H*").force_encoding("UTF-8") }
|
136
|
+
|
137
|
+
its(:valid_encoding?) { should be_true }
|
138
|
+
specify { subject.encoding.name.should == "UTF-8" }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'metaid'
|
3
|
+
|
4
|
+
describe Array, "when extended with BER core extensions" do
|
5
|
+
|
6
|
+
it "should correctly convert a control code array" do
|
7
|
+
control_codes = []
|
8
|
+
control_codes << ['1.2.3'.to_ber, true.to_ber].to_ber_sequence
|
9
|
+
control_codes << ['1.7.9'.to_ber, false.to_ber].to_ber_sequence
|
10
|
+
control_codes = control_codes.to_ber_sequence
|
11
|
+
res = [['1.2.3', true],['1.7.9',false]].to_ber_control
|
12
|
+
res.should eq(control_codes)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should wrap the array in another array if a nested array is not passed" do
|
16
|
+
result1 = ['1.2.3', true].to_ber_control
|
17
|
+
result2 = [['1.2.3', true]].to_ber_control
|
18
|
+
result1.should eq(result2)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return an empty string if an empty array is passed" do
|
22
|
+
[].to_ber_control.should be_empty
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
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
|
+
end
|
20
|
+
end
|
@@ -81,4 +81,35 @@ describe Net::LDAP::Filter do
|
|
81
81
|
Net::LDAP::Filter.escape("\0*()\\").should == "\\00\\2A\\28\\29\\5C"
|
82
82
|
end
|
83
83
|
end
|
84
|
+
|
85
|
+
context 'with a well-known BER string' do
|
86
|
+
ber = "\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
|
84
115
|
end
|
@@ -0,0 +1,35 @@
|
|
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
|
+
@connection = Net::LDAP.new
|
12
|
+
@connection.instance_variable_set(:@open_connection, FakeConnection.new)
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when :return_result => true" do
|
16
|
+
it "should return nil upon error" do
|
17
|
+
result_set = @connection.search(:return_result => true)
|
18
|
+
result_set.should be_nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when :return_result => false" do
|
23
|
+
it "should return false upon error" do
|
24
|
+
result = @connection.search(:return_result => false)
|
25
|
+
result.should be_false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "When :return_result is not given" do
|
30
|
+
it "should return nil upon error" do
|
31
|
+
result_set = @connection.search
|
32
|
+
result_set.should be_nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/unit/ldap_spec.rb
CHANGED
@@ -7,11 +7,11 @@ describe Net::LDAP::Connection do
|
|
7
7
|
flexmock(TCPSocket).
|
8
8
|
should_receive(:new).and_raise(Errno::ECONNREFUSED)
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
it "should raise LdapError" do
|
12
12
|
lambda {
|
13
13
|
Net::LDAP::Connection.new(
|
14
|
-
:server => 'test.mocked.com',
|
14
|
+
:server => 'test.mocked.com',
|
15
15
|
:port => 636)
|
16
16
|
}.should raise_error(Net::LDAP::LdapError)
|
17
17
|
end
|
@@ -21,11 +21,11 @@ describe Net::LDAP::Connection do
|
|
21
21
|
flexmock(TCPSocket).
|
22
22
|
should_receive(:new).and_raise(SocketError)
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it "should raise LdapError" do
|
26
26
|
lambda {
|
27
27
|
Net::LDAP::Connection.new(
|
28
|
-
:server => 'test.mocked.com',
|
28
|
+
:server => 'test.mocked.com',
|
29
29
|
:port => 636)
|
30
30
|
}.should raise_error(Net::LDAP::LdapError)
|
31
31
|
end
|
@@ -35,14 +35,44 @@ describe Net::LDAP::Connection do
|
|
35
35
|
flexmock(TCPSocket).
|
36
36
|
should_receive(:new).and_raise(NameError)
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
it "should rethrow the exception" do
|
40
40
|
lambda {
|
41
41
|
Net::LDAP::Connection.new(
|
42
|
-
:server => 'test.mocked.com',
|
42
|
+
:server => 'test.mocked.com',
|
43
43
|
:port => 636)
|
44
44
|
}.should raise_error(NameError)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
|
+
context "populate error messages" do
|
50
|
+
before do
|
51
|
+
@tcp_socket = flexmock(:connection)
|
52
|
+
@tcp_socket.should_receive(:write)
|
53
|
+
flexmock(TCPSocket).should_receive(:new).and_return(@tcp_socket)
|
54
|
+
end
|
55
|
+
|
56
|
+
subject { Net::LDAP::Connection.new(:server => 'test.mocked.com', :port => 636) }
|
57
|
+
|
58
|
+
it "should get back error messages if operation fails" do
|
59
|
+
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"])
|
60
|
+
ber.ber_identifier = 7
|
61
|
+
@tcp_socket.should_receive(:read_ber).and_return([2, ber])
|
62
|
+
|
63
|
+
result = subject.modify(:dn => "1", :operations => [[:replace, "mail", "something@sothsdkf.com"]])
|
64
|
+
result.should be_failure
|
65
|
+
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"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "shouldn't get back error messages if operation succeeds" do
|
69
|
+
ber = Net::BER::BerIdentifiedArray.new([0, "", ""])
|
70
|
+
ber.ber_identifier = 7
|
71
|
+
@tcp_socket.should_receive(:read_ber).and_return([2, ber])
|
72
|
+
|
73
|
+
result = subject.modify(:dn => "1", :operations => [[:replace, "mail", "something@sothsdkf.com"]])
|
74
|
+
result.should be_success
|
75
|
+
result.error_message.should == ""
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|