net-ldap 0.7.0 → 0.8.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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/Hacking.rdoc +1 -2
- data/Manifest.txt +1 -0
- data/README.rdoc +1 -1
- data/lib/net/ber/ber_parser.rb +5 -0
- data/lib/net/ldap.rb +305 -211
- data/lib/net/ldap/instrumentation.rb +23 -0
- data/lib/net/ldap/version.rb +1 -1
- data/net-ldap.gemspec +1 -1
- data/spec/spec_helper.rb +18 -0
- data/spec/unit/ldap/search_spec.rb +15 -1
- data/spec/unit/ldap_spec.rb +147 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 487807bc08da7baeb4941090020468a8e60fe14a
|
4
|
+
data.tar.gz: 047ccb6638a81c96eb1bfca1a684726a71bfc1a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d02d5a7af488a5f7ee8b8050c5d281d6e76b7c40baeb1a1275a18b103d2f76cf0fea8dfa865efe2ce243d92b87c3d6abdfa1b47615cf95fb5cd5e9b9806e70a
|
7
|
+
data.tar.gz: 380cc5961a9a85a1d196203b6712061b5c8b8a4c1008dcfcee67556029269e264d2d7463e2e98572c06020dbae44dbb8ace34f06d584d33a9f1b5f6169f90d9d
|
data/.travis.yml
CHANGED
data/Hacking.rdoc
CHANGED
@@ -25,7 +25,7 @@ patches being accepted, we recommend that you follow the guidelines below:
|
|
25
25
|
|
26
26
|
== Documentation
|
27
27
|
|
28
|
-
* Documentation: {net-ldap}[http://net-ldap
|
28
|
+
* Documentation: {net-ldap}[http://rubydoc.info/gems/net-ldap]
|
29
29
|
|
30
30
|
It is very important that, if you add new methods or objects, your code is
|
31
31
|
well-documented. The purpose of the changes should be clearly described so that
|
@@ -63,6 +63,5 @@ installed using RubyGems.
|
|
63
63
|
|
64
64
|
== Participation
|
65
65
|
|
66
|
-
* RubyForge: {net-ldap}[http://rubyforge.org/projects/net-ldap]
|
67
66
|
* GitHub: {ruby-ldap/ruby-net-ldap}[https://github.com/ruby-ldap/ruby-net-ldap/]
|
68
67
|
* Group: {ruby-ldap}[http://groups.google.com/group/ruby-ldap]
|
data/Manifest.txt
CHANGED
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Net::LDAP for Ruby {<img src="https://travis-ci.org/
|
1
|
+
= Net::LDAP for Ruby {<img src="https://travis-ci.org/github/ruby-net-ldap.png" />}[https://travis-ci.org/github/ruby-net-ldap]
|
2
2
|
|
3
3
|
== Description
|
4
4
|
|
data/lib/net/ber/ber_parser.rb
CHANGED
@@ -148,6 +148,9 @@ module Net::BER::BERParser
|
|
148
148
|
# implemented on the including object and that it returns a Fixnum value.
|
149
149
|
# Also requires #read(bytes) to work.
|
150
150
|
#
|
151
|
+
# Yields the object type `id` and the data `content_length` if a block is
|
152
|
+
# given. This is namely to support instrumentation.
|
153
|
+
#
|
151
154
|
# This does not work with non-blocking I/O.
|
152
155
|
def read_ber(syntax = nil)
|
153
156
|
# TODO: clean this up so it works properly with partial packets coming
|
@@ -157,6 +160,8 @@ module Net::BER::BERParser
|
|
157
160
|
id = getbyte or return nil # don't trash this value, we'll use it later
|
158
161
|
content_length = read_ber_length
|
159
162
|
|
163
|
+
yield id, content_length if block_given?
|
164
|
+
|
160
165
|
if -1 == content_length
|
161
166
|
raise Net::BER::BerError, "Indeterminite BER content length not implemented."
|
162
167
|
else
|
data/lib/net/ldap.rb
CHANGED
@@ -23,6 +23,7 @@ require 'net/ldap/filter'
|
|
23
23
|
require 'net/ldap/dataset'
|
24
24
|
require 'net/ldap/password'
|
25
25
|
require 'net/ldap/entry'
|
26
|
+
require 'net/ldap/instrumentation'
|
26
27
|
require 'net/ldap/version'
|
27
28
|
|
28
29
|
# == Quick-start for the Impatient
|
@@ -242,6 +243,7 @@ require 'net/ldap/version'
|
|
242
243
|
# and then keeps it open while it executes a user-supplied block.
|
243
244
|
# Net::LDAP#open closes the connection on completion of the block.
|
244
245
|
class Net::LDAP
|
246
|
+
include Net::LDAP::Instrumentation
|
245
247
|
|
246
248
|
class LdapError < StandardError; end
|
247
249
|
|
@@ -256,7 +258,7 @@ class Net::LDAP
|
|
256
258
|
DerefAliases_Find = 2
|
257
259
|
DerefAliases_Always = 3
|
258
260
|
DerefAliasesArray = [ DerefAliases_Never, DerefAliases_Search, DerefAliases_Find, DerefAliases_Always ]
|
259
|
-
|
261
|
+
|
260
262
|
primitive = { 2 => :null } # UnbindRequest body
|
261
263
|
constructed = {
|
262
264
|
0 => :array, # BindRequest
|
@@ -383,6 +385,8 @@ class Net::LDAP
|
|
383
385
|
# #encryption for details.
|
384
386
|
# * :force_no_page => Set to true to prevent paged results even if your
|
385
387
|
# server says it supports them. This is a fix for MS Active Directory
|
388
|
+
# * :instrumentation_service => An object responsible for instrumenting
|
389
|
+
# operations, compatible with ActiveSupport::Notifications' public API.
|
386
390
|
#
|
387
391
|
# Instantiating a Net::LDAP object does <i>not</i> result in network
|
388
392
|
# traffic to the LDAP server. It simply stores the connection and binding
|
@@ -400,6 +404,8 @@ class Net::LDAP
|
|
400
404
|
@auth[:password] = pr.call
|
401
405
|
end
|
402
406
|
|
407
|
+
@instrumentation_service = args[:instrumentation_service]
|
408
|
+
|
403
409
|
# This variable is only set when we are created with LDAP::open. All of
|
404
410
|
# our internal methods will connect using it, or else they will create
|
405
411
|
# their own.
|
@@ -571,16 +577,21 @@ class Net::LDAP
|
|
571
577
|
# all generate auth failures if the bind was unsuccessful.
|
572
578
|
raise Net::LDAP::LdapError, "Open already in progress" if @open_connection
|
573
579
|
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
580
|
+
instrument "open.net_ldap" do |payload|
|
581
|
+
begin
|
582
|
+
@open_connection =
|
583
|
+
Net::LDAP::Connection.new \
|
584
|
+
:host => @host,
|
585
|
+
:port => @port,
|
586
|
+
:encryption => @encryption,
|
587
|
+
:instrumentation_service => @instrumentation_service
|
588
|
+
payload[:connection] = @open_connection
|
589
|
+
payload[:bind] = @open_connection.bind(@auth)
|
590
|
+
yield self
|
591
|
+
ensure
|
592
|
+
@open_connection.close if @open_connection
|
593
|
+
@open_connection = nil
|
594
|
+
end
|
584
595
|
end
|
585
596
|
end
|
586
597
|
|
@@ -641,30 +652,35 @@ class Net::LDAP
|
|
641
652
|
return_result_set = args[:return_result] != false
|
642
653
|
result_set = return_result_set ? [] : nil
|
643
654
|
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
655
|
+
instrument "search.net_ldap", args do |payload|
|
656
|
+
if @open_connection
|
657
|
+
@result = @open_connection.search(args) { |entry|
|
658
|
+
result_set << entry if result_set
|
659
|
+
yield entry if block_given?
|
660
|
+
}
|
661
|
+
else
|
662
|
+
begin
|
663
|
+
conn = Net::LDAP::Connection.new \
|
664
|
+
:host => @host,
|
665
|
+
:port => @port,
|
666
|
+
:encryption => @encryption,
|
667
|
+
:instrumentation_service => @instrumentation_service
|
668
|
+
if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
|
669
|
+
@result = conn.search(args) { |entry|
|
670
|
+
result_set << entry if result_set
|
671
|
+
yield entry if block_given?
|
672
|
+
}
|
673
|
+
end
|
674
|
+
ensure
|
675
|
+
conn.close if conn
|
658
676
|
end
|
659
|
-
ensure
|
660
|
-
conn.close if conn
|
661
677
|
end
|
662
|
-
end
|
663
678
|
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
679
|
+
if return_result_set
|
680
|
+
(!@result.nil? && @result.result_code == 0) ? result_set : nil
|
681
|
+
else
|
682
|
+
@result.success?
|
683
|
+
end
|
668
684
|
end
|
669
685
|
end
|
670
686
|
|
@@ -726,19 +742,26 @@ class Net::LDAP
|
|
726
742
|
# the documentation for #auth, the password parameter can be a Ruby Proc
|
727
743
|
# instead of a String.
|
728
744
|
def bind(auth = @auth)
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
745
|
+
instrument "bind.net_ldap" do |payload|
|
746
|
+
if @open_connection
|
747
|
+
payload[:connection] = @open_connection
|
748
|
+
payload[:bind] = @result = @open_connection.bind(auth)
|
749
|
+
else
|
750
|
+
begin
|
751
|
+
conn = Connection.new \
|
752
|
+
:host => @host,
|
753
|
+
:port => @port,
|
754
|
+
:encryption => @encryption,
|
755
|
+
:instrumentation_service => @instrumentation_service
|
756
|
+
payload[:connection] = conn
|
757
|
+
payload[:bind] = @result = conn.bind(auth)
|
758
|
+
ensure
|
759
|
+
conn.close if conn
|
760
|
+
end
|
738
761
|
end
|
739
|
-
end
|
740
762
|
|
741
|
-
|
763
|
+
@result.success?
|
764
|
+
end
|
742
765
|
end
|
743
766
|
|
744
767
|
# #bind_as is for testing authentication credentials.
|
@@ -826,21 +849,26 @@ class Net::LDAP
|
|
826
849
|
# ldap.add(:dn => dn, :attributes => attr)
|
827
850
|
# end
|
828
851
|
def add(args)
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
852
|
+
instrument "add.net_ldap", args do |payload|
|
853
|
+
if @open_connection
|
854
|
+
@result = @open_connection.add(args)
|
855
|
+
else
|
856
|
+
@result = 0
|
857
|
+
begin
|
858
|
+
conn = Connection.new \
|
859
|
+
:host => @host,
|
860
|
+
:port => @port,
|
861
|
+
:encryption => @encryption,
|
862
|
+
:instrumentation_service => @instrumentation_service
|
863
|
+
if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
|
864
|
+
@result = conn.add(args)
|
865
|
+
end
|
866
|
+
ensure
|
867
|
+
conn.close if conn
|
838
868
|
end
|
839
|
-
ensure
|
840
|
-
conn.close if conn
|
841
869
|
end
|
870
|
+
@result.success?
|
842
871
|
end
|
843
|
-
@result.success?
|
844
872
|
end
|
845
873
|
|
846
874
|
# Modifies the attribute values of a particular entry on the LDAP
|
@@ -858,7 +886,7 @@ class Net::LDAP
|
|
858
886
|
# The LDAP protocol provides a full and well thought-out set of operations
|
859
887
|
# for changing the values of attributes, but they are necessarily somewhat
|
860
888
|
# complex and not always intuitive. If these instructions are confusing or
|
861
|
-
# incomplete, please send us email or create
|
889
|
+
# incomplete, please send us email or create an issue on GitHub.
|
862
890
|
#
|
863
891
|
# The :operations parameter to #modify takes an array of
|
864
892
|
# operation-descriptors. Each individual operation is specified in one
|
@@ -924,22 +952,27 @@ class Net::LDAP
|
|
924
952
|
# simultaneously by the server. It bears repeating that this concurrency
|
925
953
|
# does _not_ imply transactional atomicity, which LDAP does not provide.
|
926
954
|
def modify(args)
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
955
|
+
instrument "modify.net_ldap", args do |payload|
|
956
|
+
if @open_connection
|
957
|
+
@result = @open_connection.modify(args)
|
958
|
+
else
|
959
|
+
@result = 0
|
960
|
+
begin
|
961
|
+
conn = Connection.new \
|
962
|
+
:host => @host,
|
963
|
+
:port => @port,
|
964
|
+
:encryption => @encryption,
|
965
|
+
:instrumentation_service => @instrumentation_service
|
966
|
+
if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
|
967
|
+
@result = conn.modify(args)
|
968
|
+
end
|
969
|
+
ensure
|
970
|
+
conn.close if conn
|
936
971
|
end
|
937
|
-
ensure
|
938
|
-
conn.close if conn
|
939
972
|
end
|
940
|
-
end
|
941
973
|
|
942
|
-
|
974
|
+
@result.success?
|
975
|
+
end
|
943
976
|
end
|
944
977
|
|
945
978
|
# Add a value to an attribute. Takes the full DN of the entry to modify,
|
@@ -996,21 +1029,26 @@ class Net::LDAP
|
|
996
1029
|
#
|
997
1030
|
# _Documentation_ _stub_
|
998
1031
|
def rename(args)
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1032
|
+
instrument "rename.net_ldap", args do |payload|
|
1033
|
+
if @open_connection
|
1034
|
+
@result = @open_connection.rename(args)
|
1035
|
+
else
|
1036
|
+
@result = 0
|
1037
|
+
begin
|
1038
|
+
conn = Connection.new \
|
1039
|
+
:host => @host,
|
1040
|
+
:port => @port,
|
1041
|
+
:encryption => @encryption,
|
1042
|
+
:instrumentation_service => @instrumentation_service
|
1043
|
+
if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
|
1044
|
+
@result = conn.rename(args)
|
1045
|
+
end
|
1046
|
+
ensure
|
1047
|
+
conn.close if conn
|
1008
1048
|
end
|
1009
|
-
ensure
|
1010
|
-
conn.close if conn
|
1011
1049
|
end
|
1050
|
+
@result.success?
|
1012
1051
|
end
|
1013
|
-
@result.success?
|
1014
1052
|
end
|
1015
1053
|
alias_method :modify_rdn, :rename
|
1016
1054
|
|
@@ -1024,21 +1062,26 @@ class Net::LDAP
|
|
1024
1062
|
# dn = "mail=deleteme@example.com, ou=people, dc=example, dc=com"
|
1025
1063
|
# ldap.delete :dn => dn
|
1026
1064
|
def delete(args)
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1065
|
+
instrument "delete.net_ldap", args do |payload|
|
1066
|
+
if @open_connection
|
1067
|
+
@result = @open_connection.delete(args)
|
1068
|
+
else
|
1069
|
+
@result = 0
|
1070
|
+
begin
|
1071
|
+
conn = Connection.new \
|
1072
|
+
:host => @host,
|
1073
|
+
:port => @port,
|
1074
|
+
:encryption => @encryption,
|
1075
|
+
:instrumentation_service => @instrumentation_service
|
1076
|
+
if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
|
1077
|
+
@result = conn.delete(args)
|
1078
|
+
end
|
1079
|
+
ensure
|
1080
|
+
conn.close
|
1036
1081
|
end
|
1037
|
-
ensure
|
1038
|
-
conn.close
|
1039
1082
|
end
|
1083
|
+
@result.success?
|
1040
1084
|
end
|
1041
|
-
@result.success?
|
1042
1085
|
end
|
1043
1086
|
|
1044
1087
|
# Delete an entry from the LDAP directory along with all subordinate entries.
|
@@ -1125,7 +1168,7 @@ class Net::LDAP
|
|
1125
1168
|
def paged_searches_supported?
|
1126
1169
|
# active directory returns that it supports paged results. However
|
1127
1170
|
# it returns binary data in the rfc2696_cookie which throws an
|
1128
|
-
# encoding exception breaking searching.
|
1171
|
+
# encoding exception breaking searching.
|
1129
1172
|
return false if @force_no_page
|
1130
1173
|
@server_caps ||= search_root_dse
|
1131
1174
|
@server_caps[:supportedcontrol].include?(Net::LDAP::LDAPControls::PAGED_RESULTS)
|
@@ -1135,10 +1178,14 @@ end # class LDAP
|
|
1135
1178
|
# This is a private class used internally by the library. It should not
|
1136
1179
|
# be called by user code.
|
1137
1180
|
class Net::LDAP::Connection #:nodoc:
|
1181
|
+
include Net::LDAP::Instrumentation
|
1182
|
+
|
1138
1183
|
LdapVersion = 3
|
1139
1184
|
MaxSaslChallenges = 10
|
1140
1185
|
|
1141
1186
|
def initialize(server)
|
1187
|
+
@instrumentation_service = server[:instrumentation_service]
|
1188
|
+
|
1142
1189
|
begin
|
1143
1190
|
@conn = TCPSocket.new(server[:host], server[:port])
|
1144
1191
|
rescue SocketError
|
@@ -1218,8 +1265,8 @@ class Net::LDAP::Connection #:nodoc:
|
|
1218
1265
|
msgid = next_msgid.to_ber
|
1219
1266
|
request = [Net::LDAP::StartTlsOid.to_ber_contextspecific(0)].to_ber_appsequence(Net::LDAP::PDU::ExtendedRequest)
|
1220
1267
|
request_pkt = [msgid, request].to_ber_sequence
|
1221
|
-
|
1222
|
-
be =
|
1268
|
+
write request_pkt
|
1269
|
+
be = read
|
1223
1270
|
raise Net::LDAP::LdapError, "no start_tls result" if be.nil?
|
1224
1271
|
pdu = Net::LDAP::PDU.new(be)
|
1225
1272
|
raise Net::LDAP::LdapError, "no start_tls result" if pdu.nil?
|
@@ -1243,21 +1290,51 @@ class Net::LDAP::Connection #:nodoc:
|
|
1243
1290
|
@conn = nil
|
1244
1291
|
end
|
1245
1292
|
|
1293
|
+
# Internal: Reads and parses data from the configured connection.
|
1294
|
+
#
|
1295
|
+
# - syntax: the BER syntax to use to parse the read data with
|
1296
|
+
#
|
1297
|
+
# Returns basic BER objects.
|
1298
|
+
def read(syntax = Net::LDAP::AsnSyntax)
|
1299
|
+
instrument "read.net_ldap_connection", :syntax => syntax do |payload|
|
1300
|
+
@conn.read_ber(syntax) do |id, content_length|
|
1301
|
+
payload[:object_type_id] = id
|
1302
|
+
payload[:content_length] = content_length
|
1303
|
+
end
|
1304
|
+
end
|
1305
|
+
end
|
1306
|
+
private :read
|
1307
|
+
|
1308
|
+
# Internal: Writes the given packet to the configured connection.
|
1309
|
+
#
|
1310
|
+
# - packet: the BER data packet to write on the socket.
|
1311
|
+
#
|
1312
|
+
# Returns the return value from writing to the connection, which in some
|
1313
|
+
# cases is the Integer number of bytes written to the socket.
|
1314
|
+
def write(packet)
|
1315
|
+
instrument "write.net_ldap_connection" do |payload|
|
1316
|
+
payload[:content_length] = @conn.write(packet)
|
1317
|
+
end
|
1318
|
+
end
|
1319
|
+
private :write
|
1320
|
+
|
1246
1321
|
def next_msgid
|
1247
1322
|
@msgid ||= 0
|
1248
1323
|
@msgid += 1
|
1249
1324
|
end
|
1250
1325
|
|
1251
1326
|
def bind(auth)
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1327
|
+
instrument "bind.net_ldap_connection" do |payload|
|
1328
|
+
payload[:method] = meth = auth[:method]
|
1329
|
+
if [:simple, :anonymous, :anon].include?(meth)
|
1330
|
+
bind_simple auth
|
1331
|
+
elsif meth == :sasl
|
1332
|
+
bind_sasl(auth)
|
1333
|
+
elsif meth == :gss_spnego
|
1334
|
+
bind_gss_spnego(auth)
|
1335
|
+
else
|
1336
|
+
raise Net::LDAP::LdapError, "Unsupported auth method (#{meth})"
|
1337
|
+
end
|
1261
1338
|
end
|
1262
1339
|
end
|
1263
1340
|
|
@@ -1278,9 +1355,9 @@ class Net::LDAP::Connection #:nodoc:
|
|
1278
1355
|
request = [LdapVersion.to_ber, user.to_ber,
|
1279
1356
|
psw.to_ber_contextspecific(0)].to_ber_appsequence(0)
|
1280
1357
|
request_pkt = [msgid, request].to_ber_sequence
|
1281
|
-
|
1358
|
+
write request_pkt
|
1282
1359
|
|
1283
|
-
(be =
|
1360
|
+
(be = read and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
|
1284
1361
|
|
1285
1362
|
pdu
|
1286
1363
|
end
|
@@ -1317,9 +1394,9 @@ class Net::LDAP::Connection #:nodoc:
|
|
1317
1394
|
sasl = [mech.to_ber, cred.to_ber].to_ber_contextspecific(3)
|
1318
1395
|
request = [LdapVersion.to_ber, "".to_ber, sasl].to_ber_appsequence(0)
|
1319
1396
|
request_pkt = [msgid, request].to_ber_sequence
|
1320
|
-
|
1397
|
+
write request_pkt
|
1321
1398
|
|
1322
|
-
(be =
|
1399
|
+
(be = read and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
|
1323
1400
|
return pdu unless pdu.result_code == 14 # saslBindInProgress
|
1324
1401
|
raise Net::LDAP::LdapError, "sasl-challenge overflow" if ((n += 1) > MaxSaslChallenges)
|
1325
1402
|
|
@@ -1419,7 +1496,7 @@ class Net::LDAP::Connection #:nodoc:
|
|
1419
1496
|
deref = args[:deref] || Net::LDAP::DerefAliases_Never
|
1420
1497
|
raise Net::LDAP::LdapError.new( "invalid alias dereferencing value" ) unless Net::LDAP::DerefAliasesArray.include?(deref)
|
1421
1498
|
|
1422
|
-
|
1499
|
+
|
1423
1500
|
# An interesting value for the size limit would be close to A/D's
|
1424
1501
|
# built-in page limit of 1000 records, but openLDAP newer than version
|
1425
1502
|
# 2.2.0 chokes on anything bigger than 126. You get a silent error that
|
@@ -1444,110 +1521,127 @@ class Net::LDAP::Connection #:nodoc:
|
|
1444
1521
|
result_pdu = nil
|
1445
1522
|
n_results = 0
|
1446
1523
|
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1524
|
+
instrument "search.net_ldap_connection",
|
1525
|
+
:filter => search_filter,
|
1526
|
+
:base => search_base,
|
1527
|
+
:scope => scope,
|
1528
|
+
:limit => sizelimit,
|
1529
|
+
:sort => sort_control,
|
1530
|
+
:referrals => return_referrals,
|
1531
|
+
:deref => deref,
|
1532
|
+
:attributes => search_attributes do |payload|
|
1533
|
+
loop do
|
1534
|
+
# should collect this into a private helper to clarify the structure
|
1535
|
+
query_limit = 0
|
1536
|
+
if sizelimit > 0
|
1537
|
+
if paged_searches_supported
|
1538
|
+
query_limit = (((sizelimit - n_results) < 126) ? (sizelimit -
|
1539
|
+
n_results) : 0)
|
1540
|
+
else
|
1541
|
+
query_limit = sizelimit
|
1542
|
+
end
|
1456
1543
|
end
|
1457
|
-
end
|
1458
1544
|
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1545
|
+
request = [
|
1546
|
+
search_base.to_ber,
|
1547
|
+
scope.to_ber_enumerated,
|
1548
|
+
deref.to_ber_enumerated,
|
1549
|
+
query_limit.to_ber, # size limit
|
1550
|
+
0.to_ber,
|
1551
|
+
attributes_only.to_ber,
|
1552
|
+
search_filter.to_ber,
|
1553
|
+
search_attributes.to_ber_sequence
|
1554
|
+
].to_ber_appsequence(3)
|
1555
|
+
|
1556
|
+
# rfc2696_cookie sometimes contains binary data from Microsoft Active Directory
|
1557
|
+
# this breaks when calling to_ber. (Can't force binary data to UTF-8)
|
1558
|
+
# we have to disable paging (even though server supports it) to get around this...
|
1559
|
+
|
1560
|
+
controls = []
|
1561
|
+
controls <<
|
1562
|
+
[
|
1563
|
+
Net::LDAP::LDAPControls::PAGED_RESULTS.to_ber,
|
1564
|
+
# Criticality MUST be false to interoperate with normal LDAPs.
|
1565
|
+
false.to_ber,
|
1566
|
+
rfc2696_cookie.map{ |v| v.to_ber}.to_ber_sequence.to_s.to_ber
|
1567
|
+
].to_ber_sequence if paged_searches_supported
|
1568
|
+
controls << sort_control if sort_control
|
1569
|
+
controls = controls.empty? ? nil : controls.to_ber_contextspecific(0)
|
1570
|
+
|
1571
|
+
pkt = [next_msgid.to_ber, request, controls].compact.to_ber_sequence
|
1572
|
+
write pkt
|
1573
|
+
|
1574
|
+
result_pdu = nil
|
1575
|
+
controls = []
|
1576
|
+
|
1577
|
+
while (be = read) && (pdu = Net::LDAP::PDU.new(be))
|
1578
|
+
case pdu.app_tag
|
1579
|
+
when Net::LDAP::PDU::SearchReturnedData
|
1580
|
+
n_results += 1
|
1581
|
+
yield pdu.search_entry if block_given?
|
1582
|
+
when Net::LDAP::PDU::SearchResultReferral
|
1583
|
+
if return_referrals
|
1584
|
+
if block_given?
|
1585
|
+
se = Net::LDAP::Entry.new
|
1586
|
+
se[:search_referrals] = (pdu.search_referrals || [])
|
1587
|
+
yield se
|
1588
|
+
end
|
1502
1589
|
end
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1590
|
+
when Net::LDAP::PDU::SearchResult
|
1591
|
+
result_pdu = pdu
|
1592
|
+
controls = pdu.result_controls
|
1593
|
+
if return_referrals && pdu.result_code == 10
|
1594
|
+
if block_given?
|
1595
|
+
se = Net::LDAP::Entry.new
|
1596
|
+
se[:search_referrals] = (pdu.search_referrals || [])
|
1597
|
+
yield se
|
1598
|
+
end
|
1512
1599
|
end
|
1600
|
+
break
|
1601
|
+
else
|
1602
|
+
raise Net::LDAP::LdapError, "invalid response-type in search: #{pdu.app_tag}"
|
1513
1603
|
end
|
1514
|
-
break
|
1515
|
-
else
|
1516
|
-
raise Net::LDAP::LdapError, "invalid response-type in search: #{pdu.app_tag}"
|
1517
1604
|
end
|
1518
|
-
end
|
1519
1605
|
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1606
|
+
# count number of pages of results
|
1607
|
+
payload[:page_count] ||= 0
|
1608
|
+
payload[:page_count] += 1
|
1609
|
+
|
1610
|
+
# When we get here, we have seen a type-5 response. If there is no
|
1611
|
+
# error AND there is an RFC-2696 cookie, then query again for the next
|
1612
|
+
# page of results. If not, we're done. Don't screw this up or we'll
|
1613
|
+
# break every search we do.
|
1614
|
+
#
|
1615
|
+
# Noticed 02Sep06, look at the read_ber call in this loop, shouldn't
|
1616
|
+
# that have a parameter of AsnSyntax? Does this just accidentally
|
1617
|
+
# work? According to RFC-2696, the value expected in this position is
|
1618
|
+
# of type OCTET STRING, covered in the default syntax supported by
|
1619
|
+
# read_ber, so I guess we're ok.
|
1620
|
+
more_pages = false
|
1621
|
+
if result_pdu.result_code == 0 and controls
|
1622
|
+
controls.each do |c|
|
1623
|
+
if c.oid == Net::LDAP::LDAPControls::PAGED_RESULTS
|
1624
|
+
# just in case some bogus server sends us more than 1 of these.
|
1625
|
+
more_pages = false
|
1626
|
+
if c.value and c.value.length > 0
|
1627
|
+
cookie = c.value.read_ber[1]
|
1628
|
+
if cookie and cookie.length > 0
|
1629
|
+
rfc2696_cookie[1] = cookie
|
1630
|
+
more_pages = true
|
1631
|
+
end
|
1541
1632
|
end
|
1542
1633
|
end
|
1543
1634
|
end
|
1544
1635
|
end
|
1545
|
-
end
|
1546
1636
|
|
1547
|
-
|
1548
|
-
|
1637
|
+
break unless more_pages
|
1638
|
+
end # loop
|
1639
|
+
|
1640
|
+
# track total result count
|
1641
|
+
payload[:result_count] = n_results
|
1549
1642
|
|
1550
|
-
|
1643
|
+
result_pdu || OpenStruct.new(:status => :failure, :result_code => 1, :message => "Invalid search")
|
1644
|
+
end # instrument
|
1551
1645
|
end
|
1552
1646
|
|
1553
1647
|
MODIFY_OPERATIONS = { #:nodoc:
|
@@ -1584,9 +1678,9 @@ class Net::LDAP::Connection #:nodoc:
|
|
1584
1678
|
request = [ modify_dn.to_ber,
|
1585
1679
|
ops.to_ber_sequence ].to_ber_appsequence(6)
|
1586
1680
|
pkt = [ next_msgid.to_ber, request ].to_ber_sequence
|
1587
|
-
|
1681
|
+
write pkt
|
1588
1682
|
|
1589
|
-
(be =
|
1683
|
+
(be = read) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == Net::LDAP::PDU::ModifyResponse) or raise Net::LDAP::LdapError, "response missing or invalid"
|
1590
1684
|
|
1591
1685
|
pdu
|
1592
1686
|
end
|
@@ -1607,11 +1701,11 @@ class Net::LDAP::Connection #:nodoc:
|
|
1607
1701
|
|
1608
1702
|
request = [add_dn.to_ber, add_attrs.to_ber_sequence].to_ber_appsequence(8)
|
1609
1703
|
pkt = [next_msgid.to_ber, request].to_ber_sequence
|
1610
|
-
|
1704
|
+
write pkt
|
1611
1705
|
|
1612
|
-
(be =
|
1706
|
+
(be = read) &&
|
1613
1707
|
(pdu = Net::LDAP::PDU.new(be)) &&
|
1614
|
-
(pdu.app_tag ==
|
1708
|
+
(pdu.app_tag == Net::LDAP::PDU::AddResponse) or
|
1615
1709
|
raise Net::LDAP::LdapError, "response missing or invalid"
|
1616
1710
|
|
1617
1711
|
pdu
|
@@ -1630,10 +1724,10 @@ class Net::LDAP::Connection #:nodoc:
|
|
1630
1724
|
request << new_superior.to_ber_contextspecific(0) unless new_superior == nil
|
1631
1725
|
|
1632
1726
|
pkt = [next_msgid.to_ber, request.to_ber_appsequence(12)].to_ber_sequence
|
1633
|
-
|
1727
|
+
write pkt
|
1634
1728
|
|
1635
|
-
(be =
|
1636
|
-
(pdu = Net::LDAP::PDU.new( be )) && (pdu.app_tag ==
|
1729
|
+
(be = read) &&
|
1730
|
+
(pdu = Net::LDAP::PDU.new( be )) && (pdu.app_tag == Net::LDAP::PDU::ModifyRDNResponse) or
|
1637
1731
|
raise Net::LDAP::LdapError.new( "response missing or invalid" )
|
1638
1732
|
|
1639
1733
|
pdu
|
@@ -1647,9 +1741,9 @@ class Net::LDAP::Connection #:nodoc:
|
|
1647
1741
|
controls = args.include?(:control_codes) ? args[:control_codes].to_ber_control : nil #use nil so we can compact later
|
1648
1742
|
request = dn.to_s.to_ber_application_string(10)
|
1649
1743
|
pkt = [next_msgid.to_ber, request, controls].compact.to_ber_sequence
|
1650
|
-
|
1744
|
+
write pkt
|
1651
1745
|
|
1652
|
-
(be =
|
1746
|
+
(be = read) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == Net::LDAP::PDU::DeleteResponse) or raise Net::LDAP::LdapError, "response missing or invalid"
|
1653
1747
|
|
1654
1748
|
pdu
|
1655
1749
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Net::LDAP::Instrumentation
|
2
|
+
attr_reader :instrumentation_service
|
3
|
+
private :instrumentation_service
|
4
|
+
|
5
|
+
# Internal: Instrument a block with the defined instrumentation service.
|
6
|
+
#
|
7
|
+
# Yields the event payload if a block is given.
|
8
|
+
#
|
9
|
+
# Skips instrumentation if no service is set.
|
10
|
+
#
|
11
|
+
# Returns the return value of the block.
|
12
|
+
def instrument(event, payload = {})
|
13
|
+
payload = (payload || {}).dup
|
14
|
+
if instrumentation_service
|
15
|
+
instrumentation_service.instrument(event, payload) do |payload|
|
16
|
+
payload[:result] = yield(payload) if block_given?
|
17
|
+
end
|
18
|
+
else
|
19
|
+
yield(payload) if block_given?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
private :instrument
|
23
|
+
end
|
data/lib/net/ldap/version.rb
CHANGED
data/net-ldap.gemspec
CHANGED
@@ -24,7 +24,7 @@ Our roadmap for Net::LDAP 1.0 is to gain full <em>client</em> compliance with
|
|
24
24
|
the most recent LDAP RFCs (4510-4519, plutions of 4520-4532).}
|
25
25
|
s.email = ["blackhedd@rubyforge.org", "gemiel@gmail.com", "rory.ocon@gmail.com", "kaspar.schiess@absurd.li", "austin@rubyforge.org"]
|
26
26
|
s.extra_rdoc_files = ["Manifest.txt", "Contributors.rdoc", "Hacking.rdoc", "History.rdoc", "License.rdoc", "README.rdoc"]
|
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"]
|
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/instrumentation.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"]
|
28
28
|
s.homepage = %q{http://github.com/ruby-ldap/ruby-net-ldap}
|
29
29
|
s.rdoc_options = ["--main", "README.rdoc"]
|
30
30
|
s.require_paths = ["lib"]
|
data/spec/spec_helper.rb
CHANGED
@@ -8,3 +8,21 @@ RSpec.configure do |config|
|
|
8
8
|
s.respond_to?(:b) ? s.b : s
|
9
9
|
end
|
10
10
|
end
|
11
|
+
|
12
|
+
class MockInstrumentationService
|
13
|
+
def initialize
|
14
|
+
@events = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def instrument(event, payload)
|
18
|
+
result = yield(payload)
|
19
|
+
@events[event] ||= []
|
20
|
+
@events[event] << [payload, result]
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def subscribe(event)
|
25
|
+
@events[event] ||= []
|
26
|
+
@events[event]
|
27
|
+
end
|
28
|
+
end
|
@@ -8,7 +8,8 @@ describe Net::LDAP, "search method" do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
before(:each) do
|
11
|
-
@
|
11
|
+
@service = MockInstrumentationService.new
|
12
|
+
@connection = Net::LDAP.new :instrumentation_service => @service
|
12
13
|
@connection.instance_variable_set(:@open_connection, FakeConnection.new)
|
13
14
|
end
|
14
15
|
|
@@ -32,4 +33,17 @@ describe Net::LDAP, "search method" do
|
|
32
33
|
result_set.should be_nil
|
33
34
|
end
|
34
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
|
35
49
|
end
|
data/spec/unit/ldap_spec.rb
CHANGED
@@ -1,5 +1,54 @@
|
|
1
1
|
require 'spec_helper'
|
2
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
|
+
|
3
52
|
describe Net::LDAP::Connection do
|
4
53
|
describe "initialize" do
|
5
54
|
context "when host is not responding" do
|
@@ -57,7 +106,7 @@ describe Net::LDAP::Connection do
|
|
57
106
|
|
58
107
|
it "should get back error messages if operation fails" do
|
59
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"])
|
60
|
-
ber.ber_identifier =
|
109
|
+
ber.ber_identifier = Net::LDAP::PDU::ModifyResponse
|
61
110
|
@tcp_socket.should_receive(:read_ber).and_return([2, ber])
|
62
111
|
|
63
112
|
result = subject.modify(:dn => "1", :operations => [[:replace, "mail", "something@sothsdkf.com"]])
|
@@ -67,7 +116,7 @@ describe Net::LDAP::Connection do
|
|
67
116
|
|
68
117
|
it "shouldn't get back error messages if operation succeeds" do
|
69
118
|
ber = Net::BER::BerIdentifiedArray.new([0, "", ""])
|
70
|
-
ber.ber_identifier =
|
119
|
+
ber.ber_identifier = Net::LDAP::PDU::ModifyResponse
|
71
120
|
@tcp_socket.should_receive(:read_ber).and_return([2, ber])
|
72
121
|
|
73
122
|
result = subject.modify(:dn => "1", :operations => [[:replace, "mail", "something@sothsdkf.com"]])
|
@@ -75,4 +124,100 @@ describe Net::LDAP::Connection do
|
|
75
124
|
result.error_message.should == ""
|
76
125
|
end
|
77
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
|
78
223
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-ldap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Francis Cianfrocca
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2014-
|
16
|
+
date: 2014-09-10 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: rdoc
|
@@ -170,6 +170,7 @@ files:
|
|
170
170
|
- lib/net/ldap/dn.rb
|
171
171
|
- lib/net/ldap/entry.rb
|
172
172
|
- lib/net/ldap/filter.rb
|
173
|
+
- lib/net/ldap/instrumentation.rb
|
173
174
|
- lib/net/ldap/password.rb
|
174
175
|
- lib/net/ldap/pdu.rb
|
175
176
|
- lib/net/ldap/version.rb
|