Skip to content

Commit b94bba9

Browse files
committed
Merge pull request #2 from partnerpedia/better_response_message
Better response message
2 parents 63db8c8 + 40f0e18 commit b94bba9

File tree

4 files changed

+88
-36
lines changed

4 files changed

+88
-36
lines changed

lib/net/ldap.rb

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -629,11 +629,10 @@ def search(args = {})
629629
yield entry if block_given?
630630
}
631631
else
632-
@result = 0
633632
begin
634633
conn = Net::LDAP::Connection.new(:host => @host, :port => @port,
635634
:encryption => @encryption)
636-
if (@result = conn.bind(args[:auth] || @auth)) == 0
635+
if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
637636
@result = conn.search(args) { |entry|
638637
result_set << entry if result_set
639638
yield entry if block_given?
@@ -645,9 +644,9 @@ def search(args = {})
645644
end
646645

647646
if return_result_set
648-
@result == 0 ? result_set : nil
647+
(!@result.nil? && @result.result_code == 0) ? result_set : nil
649648
else
650-
@result == 0
649+
@result
651650
end
652651
end
653652

@@ -721,7 +720,7 @@ def bind(auth = @auth)
721720
end
722721
end
723722

724-
@result == 0
723+
@result
725724
end
726725

727726
# #bind_as is for testing authentication credentials.
@@ -816,14 +815,14 @@ def add(args)
816815
begin
817816
conn = Connection.new(:host => @host, :port => @port,
818817
:encryption => @encryption)
819-
if (@result = conn.bind(args[:auth] || @auth)) == 0
818+
if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
820819
@result = conn.add(args)
821820
end
822821
ensure
823822
conn.close if conn
824823
end
825824
end
826-
@result == 0
825+
@result
827826
end
828827

829828
# Modifies the attribute values of a particular entry on the LDAP
@@ -914,14 +913,15 @@ def modify(args)
914913
begin
915914
conn = Connection.new(:host => @host, :port => @port,
916915
:encryption => @encryption)
917-
if (@result = conn.bind(args[:auth] || @auth)) == 0
916+
if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
918917
@result = conn.modify(args)
919918
end
920919
ensure
921920
conn.close if conn
922921
end
923922
end
924-
@result == 0
923+
924+
@result
925925
end
926926

927927
# Add a value to an attribute. Takes the full DN of the entry to modify,
@@ -985,14 +985,14 @@ def rename(args)
985985
begin
986986
conn = Connection.new(:host => @host, :port => @port,
987987
:encryption => @encryption)
988-
if (@result = conn.bind(args[:auth] || @auth)) == 0
988+
if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
989989
@result = conn.rename(args)
990990
end
991991
ensure
992992
conn.close if conn
993993
end
994994
end
995-
@result == 0
995+
@result
996996
end
997997
alias_method :modify_rdn, :rename
998998

@@ -1013,14 +1013,14 @@ def delete(args)
10131013
begin
10141014
conn = Connection.new(:host => @host, :port => @port,
10151015
:encryption => @encryption)
1016-
if (@result = conn.bind(args[:auth] || @auth)) == 0
1016+
if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
10171017
@result = conn.delete(args)
10181018
end
10191019
ensure
10201020
conn.close
10211021
end
10221022
end
1023-
@result == 0
1023+
@result
10241024
end
10251025

10261026
# Delete an entry from the LDAP directory along with all subordinate entries.
@@ -1250,7 +1250,7 @@ def bind_simple(auth)
12501250

12511251
(be = @conn.read_ber(Net::LDAP::AsnSyntax) and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
12521252

1253-
pdu.result_code
1253+
pdu
12541254
end
12551255

12561256
#--
@@ -1288,7 +1288,7 @@ def bind_sasl(auth)
12881288
@conn.write request_pkt
12891289

12901290
(be = @conn.read_ber(Net::LDAP::AsnSyntax) and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
1291-
return pdu.result_code unless pdu.result_code == 14 # saslBindInProgress
1291+
return pdu unless pdu.result_code == 14 # saslBindInProgress
12921292
raise Net::LDAP::LdapError, "sasl-challenge overflow" if ((n += 1) > MaxSaslChallenges)
12931293

12941294
cred = chall.call(pdu.result_server_sasl_creds)
@@ -1374,7 +1374,7 @@ def search(args = {})
13741374
# to do a root-DSE record search and not do a paged search if the LDAP
13751375
# doesn't support it. Yuck.
13761376
rfc2696_cookie = [126, ""]
1377-
result_code = 0
1377+
result_pdu = nil
13781378
n_results = 0
13791379

13801380
loop {
@@ -1413,7 +1413,7 @@ def search(args = {})
14131413
pkt = [next_msgid.to_ber, request, controls].to_ber_sequence
14141414
@conn.write pkt
14151415

1416-
result_code = 0
1416+
result_pdu = nil
14171417
controls = []
14181418

14191419
while (be = @conn.read_ber(Net::LDAP::AsnSyntax)) && (pdu = Net::LDAP::PDU.new(be))
@@ -1430,7 +1430,7 @@ def search(args = {})
14301430
end
14311431
end
14321432
when 5 # search-result
1433-
result_code = pdu.result_code
1433+
result_pdu = pdu
14341434
controls = pdu.result_controls
14351435
break
14361436
else
@@ -1449,7 +1449,7 @@ def search(args = {})
14491449
# of type OCTET STRING, covered in the default syntax supported by
14501450
# read_ber, so I guess we're ok.
14511451
more_pages = false
1452-
if result_code == 0 and controls
1452+
if result_pdu.result_code == 0 and controls
14531453
controls.each do |c|
14541454
if c.oid == Net::LDAP::LDAPControls::PAGED_RESULTS
14551455
# just in case some bogus server sends us more than 1 of these.
@@ -1468,7 +1468,7 @@ def search(args = {})
14681468
break unless more_pages
14691469
} # loop
14701470

1471-
result_code
1471+
result_pdu || OpenStruct.new(:status => :failure, :result_code => 1, :message => "Invalid search")
14721472
end
14731473

14741474
MODIFY_OPERATIONS = { #:nodoc:
@@ -1508,7 +1508,8 @@ def modify(args)
15081508
@conn.write pkt
15091509

15101510
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == 7) or raise Net::LDAP::LdapError, "response missing or invalid"
1511-
pdu.result_code
1511+
1512+
pdu
15121513
end
15131514

15141515
#--
@@ -1529,8 +1530,12 @@ def add(args)
15291530
pkt = [next_msgid.to_ber, request].to_ber_sequence
15301531
@conn.write pkt
15311532

1532-
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == 9) or raise Net::LDAP::LdapError, "response missing or invalid"
1533-
pdu.result_code
1533+
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) &&
1534+
(pdu = Net::LDAP::PDU.new(be)) &&
1535+
(pdu.app_tag == 9) or
1536+
raise Net::LDAP::LdapError, "response missing or invalid"
1537+
1538+
pdu
15341539
end
15351540

15361541
#--
@@ -1551,7 +1556,8 @@ def rename args
15511556
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) &&
15521557
(pdu = Net::LDAP::PDU.new( be )) && (pdu.app_tag == 13) or
15531558
raise Net::LDAP::LdapError.new( "response missing or invalid" )
1554-
pdu.result_code
1559+
1560+
pdu
15551561
end
15561562

15571563
#--
@@ -1565,6 +1571,7 @@ def delete(args)
15651571
@conn.write pkt
15661572

15671573
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == 11) or raise Net::LDAP::LdapError, "response missing or invalid"
1568-
pdu.result_code
1574+
1575+
pdu
15691576
end
15701577
end # class Connection

lib/net/ldap/pdu.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ def result
112112
@ldap_result || {}
113113
end
114114

115+
def error_message
116+
result[:errorMessage] || ""
117+
end
118+
115119
##
116120
# This returns an LDAP result code taken from the PDU, but it will be nil
117121
# if there wasn't a result code. That can easily happen depending on the
@@ -120,6 +124,18 @@ def result_code(code = :resultCode)
120124
@ldap_result and @ldap_result[code]
121125
end
122126

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+
123139
##
124140
# Return serverSaslCreds, which are only present in BindResponse packets.
125141
#--

spec/unit/ldap/search_spec.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
describe Net::LDAP, "search method" do
44
class FakeConnection
55
def search(args)
6-
error_code = 1
7-
return error_code
6+
OpenStruct.new(:result_code => 1, :message => "error")
87
end
98
end
109

@@ -22,8 +21,8 @@ def search(args)
2221

2322
context "when :return_result => false" do
2423
it "should return false upon error" do
25-
success = @connection.search(:return_result => false)
26-
success.should == false
24+
result = @connection.search(:return_result => false)
25+
result.result_code.should == 1
2726
end
2827
end
2928

spec/unit/ldap_spec.rb

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
flexmock(TCPSocket).
88
should_receive(:new).and_raise(Errno::ECONNREFUSED)
99
end
10-
10+
1111
it "should raise LdapError" do
1212
lambda {
1313
Net::LDAP::Connection.new(
14-
:server => 'test.mocked.com',
14+
:server => 'test.mocked.com',
1515
:port => 636)
1616
}.should raise_error(Net::LDAP::LdapError)
1717
end
@@ -21,11 +21,11 @@
2121
flexmock(TCPSocket).
2222
should_receive(:new).and_raise(SocketError)
2323
end
24-
24+
2525
it "should raise LdapError" do
2626
lambda {
2727
Net::LDAP::Connection.new(
28-
:server => 'test.mocked.com',
28+
:server => 'test.mocked.com',
2929
:port => 636)
3030
}.should raise_error(Net::LDAP::LdapError)
3131
end
@@ -35,14 +35,44 @@
3535
flexmock(TCPSocket).
3636
should_receive(:new).and_raise(NameError)
3737
end
38-
38+
3939
it "should rethrow the exception" do
4040
lambda {
4141
Net::LDAP::Connection.new(
42-
:server => 'test.mocked.com',
42+
:server => 'test.mocked.com',
4343
:port => 636)
4444
}.should raise_error(NameError)
4545
end
4646
end
4747
end
48-
end
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", "[email protected]"]])
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", "[email protected]"]])
74+
result.should be_success
75+
result.error_message.should == ""
76+
end
77+
end
78+
end

0 commit comments

Comments
 (0)