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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e84cd86cc0974d9380b18caa917cfa8d8f3e8f2
4
- data.tar.gz: 6e6783c3b458b1c5b3abd72745a0e56b4e749d35
3
+ metadata.gz: 487807bc08da7baeb4941090020468a8e60fe14a
4
+ data.tar.gz: 047ccb6638a81c96eb1bfca1a684726a71bfc1a8
5
5
  SHA512:
6
- metadata.gz: 5c3b405a5086b6f33522fe611cff02ca6e325498db1b54b9d4415222c870eedae5466a3e9c65ba9d16cfc6db89392eafbbcee4537a0b70a79a6651a92695e9d6
7
- data.tar.gz: 81ce6fa1369f1a5bcbacd35efc939a8f9aa97ada21ef122314c029b9c0b3a32d6dddb8c9b43a3d2cf25d9fffad7d2fe97b992cd92c5597f8b26b72ceeacf1dc1
6
+ metadata.gz: 6d02d5a7af488a5f7ee8b8050c5d281d6e76b7c40baeb1a1275a18b103d2f76cf0fea8dfa865efe2ce243d92b87c3d6abdfa1b47615cf95fb5cd5e9b9806e70a
7
+ data.tar.gz: 380cc5961a9a85a1d196203b6712061b5c8b8a4c1008dcfcee67556029269e264d2d7463e2e98572c06020dbae44dbb8ace34f06d584d33a9f1b5f6169f90d9d
@@ -4,4 +4,7 @@ rvm:
4
4
  - 2.0.0
5
5
  - jruby-19mode
6
6
  - rbx-19mode
7
+ matrix:
8
+ allow_failures:
9
+ - rvm: jruby-19mode
7
10
  script: bundle exec rake spec
@@ -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.rubyforge.org/]
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]
@@ -25,6 +25,7 @@ lib/net/ldap/dataset.rb
25
25
  lib/net/ldap/dn.rb
26
26
  lib/net/ldap/entry.rb
27
27
  lib/net/ldap/filter.rb
28
+ lib/net/ldap/instrumentation.rb
28
29
  lib/net/ldap/password.rb
29
30
  lib/net/ldap/pdu.rb
30
31
  lib/net/ldap/version.rb
@@ -1,4 +1,4 @@
1
- = Net::LDAP for Ruby {<img src="https://travis-ci.org/ruby-ldap/ruby-net-ldap.png" />}[https://travis-ci.org/ruby-ldap/ruby-net-ldap]
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
 
@@ -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
@@ -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
- begin
575
- @open_connection = Net::LDAP::Connection.new(:host => @host,
576
- :port => @port,
577
- :encryption =>
578
- @encryption)
579
- @open_connection.bind(@auth)
580
- yield self
581
- ensure
582
- @open_connection.close if @open_connection
583
- @open_connection = nil
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
- if @open_connection
645
- @result = @open_connection.search(args) { |entry|
646
- result_set << entry if result_set
647
- yield entry if block_given?
648
- }
649
- else
650
- begin
651
- conn = Net::LDAP::Connection.new(:host => @host, :port => @port,
652
- :encryption => @encryption)
653
- if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
654
- @result = conn.search(args) { |entry|
655
- result_set << entry if result_set
656
- yield entry if block_given?
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
- if return_result_set
665
- (!@result.nil? && @result.result_code == 0) ? result_set : nil
666
- else
667
- @result.success?
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
- if @open_connection
730
- @result = @open_connection.bind(auth)
731
- else
732
- begin
733
- conn = Connection.new(:host => @host, :port => @port,
734
- :encryption => @encryption)
735
- @result = conn.bind(auth)
736
- ensure
737
- conn.close if conn
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
- @result.success?
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
- if @open_connection
830
- @result = @open_connection.add(args)
831
- else
832
- @result = 0
833
- begin
834
- conn = Connection.new(:host => @host, :port => @port,
835
- :encryption => @encryption)
836
- if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
837
- @result = conn.add(args)
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 a bug report on rubyforge.
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
- if @open_connection
928
- @result = @open_connection.modify(args)
929
- else
930
- @result = 0
931
- begin
932
- conn = Connection.new(:host => @host, :port => @port,
933
- :encryption => @encryption)
934
- if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
935
- @result = conn.modify(args)
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
- @result.success?
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
- if @open_connection
1000
- @result = @open_connection.rename(args)
1001
- else
1002
- @result = 0
1003
- begin
1004
- conn = Connection.new(:host => @host, :port => @port,
1005
- :encryption => @encryption)
1006
- if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
1007
- @result = conn.rename(args)
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
- if @open_connection
1028
- @result = @open_connection.delete(args)
1029
- else
1030
- @result = 0
1031
- begin
1032
- conn = Connection.new(:host => @host, :port => @port,
1033
- :encryption => @encryption)
1034
- if (@result = conn.bind(args[:auth] || @auth)).result_code == 0
1035
- @result = conn.delete(args)
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
- @conn.write request_pkt
1222
- be = @conn.read_ber(Net::LDAP::AsnSyntax)
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
- meth = auth[:method]
1253
- if [:simple, :anonymous, :anon].include?(meth)
1254
- bind_simple auth
1255
- elsif meth == :sasl
1256
- bind_sasl(auth)
1257
- elsif meth == :gss_spnego
1258
- bind_gss_spnego(auth)
1259
- else
1260
- raise Net::LDAP::LdapError, "Unsupported auth method (#{meth})"
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
- @conn.write request_pkt
1358
+ write request_pkt
1282
1359
 
1283
- (be = @conn.read_ber(Net::LDAP::AsnSyntax) and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
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
- @conn.write request_pkt
1397
+ write request_pkt
1321
1398
 
1322
- (be = @conn.read_ber(Net::LDAP::AsnSyntax) and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
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
- loop {
1448
- # should collect this into a private helper to clarify the structure
1449
- query_limit = 0
1450
- if sizelimit > 0
1451
- if paged_searches_supported
1452
- query_limit = (((sizelimit - n_results) < 126) ? (sizelimit -
1453
- n_results) : 0)
1454
- else
1455
- query_limit = sizelimit
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
- request = [
1460
- search_base.to_ber,
1461
- scope.to_ber_enumerated,
1462
- deref.to_ber_enumerated,
1463
- query_limit.to_ber, # size limit
1464
- 0.to_ber,
1465
- attributes_only.to_ber,
1466
- search_filter.to_ber,
1467
- search_attributes.to_ber_sequence
1468
- ].to_ber_appsequence(3)
1469
-
1470
- # rfc2696_cookie sometimes contains binary data from Microsoft Active Directory
1471
- # this breaks when calling to_ber. (Can't force binary data to UTF-8)
1472
- # we have to disable paging (even though server supports it) to get around this...
1473
-
1474
- controls = []
1475
- controls <<
1476
- [
1477
- Net::LDAP::LDAPControls::PAGED_RESULTS.to_ber,
1478
- # Criticality MUST be false to interoperate with normal LDAPs.
1479
- false.to_ber,
1480
- rfc2696_cookie.map{ |v| v.to_ber}.to_ber_sequence.to_s.to_ber
1481
- ].to_ber_sequence if paged_searches_supported
1482
- controls << sort_control if sort_control
1483
- controls = controls.empty? ? nil : controls.to_ber_contextspecific(0)
1484
-
1485
- pkt = [next_msgid.to_ber, request, controls].compact.to_ber_sequence
1486
- @conn.write pkt
1487
-
1488
- result_pdu = nil
1489
- controls = []
1490
-
1491
- while (be = @conn.read_ber(Net::LDAP::AsnSyntax)) && (pdu = Net::LDAP::PDU.new(be))
1492
- case pdu.app_tag
1493
- when 4 # search-data
1494
- n_results += 1
1495
- yield pdu.search_entry if block_given?
1496
- when 19 # search-referral
1497
- if return_referrals
1498
- if block_given?
1499
- se = Net::LDAP::Entry.new
1500
- se[:search_referrals] = (pdu.search_referrals || [])
1501
- yield se
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
- end
1504
- when 5 # search-result
1505
- result_pdu = pdu
1506
- controls = pdu.result_controls
1507
- if return_referrals && pdu.result_code == 10
1508
- if block_given?
1509
- se = Net::LDAP::Entry.new
1510
- se[:search_referrals] = (pdu.search_referrals || [])
1511
- yield se
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
- # When we get here, we have seen a type-5 response. If there is no
1521
- # error AND there is an RFC-2696 cookie, then query again for the next
1522
- # page of results. If not, we're done. Don't screw this up or we'll
1523
- # break every search we do.
1524
- #
1525
- # Noticed 02Sep06, look at the read_ber call in this loop, shouldn't
1526
- # that have a parameter of AsnSyntax? Does this just accidentally
1527
- # work? According to RFC-2696, the value expected in this position is
1528
- # of type OCTET STRING, covered in the default syntax supported by
1529
- # read_ber, so I guess we're ok.
1530
- more_pages = false
1531
- if result_pdu.result_code == 0 and controls
1532
- controls.each do |c|
1533
- if c.oid == Net::LDAP::LDAPControls::PAGED_RESULTS
1534
- # just in case some bogus server sends us more than 1 of these.
1535
- more_pages = false
1536
- if c.value and c.value.length > 0
1537
- cookie = c.value.read_ber[1]
1538
- if cookie and cookie.length > 0
1539
- rfc2696_cookie[1] = cookie
1540
- more_pages = true
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
- break unless more_pages
1548
- } # loop
1637
+ break unless more_pages
1638
+ end # loop
1639
+
1640
+ # track total result count
1641
+ payload[:result_count] = n_results
1549
1642
 
1550
- result_pdu || OpenStruct.new(:status => :failure, :result_code => 1, :message => "Invalid search")
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
- @conn.write pkt
1681
+ write pkt
1588
1682
 
1589
- (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"
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
- @conn.write pkt
1704
+ write pkt
1611
1705
 
1612
- (be = @conn.read_ber(Net::LDAP::AsnSyntax)) &&
1706
+ (be = read) &&
1613
1707
  (pdu = Net::LDAP::PDU.new(be)) &&
1614
- (pdu.app_tag == 9) or
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
- @conn.write pkt
1727
+ write pkt
1634
1728
 
1635
- (be = @conn.read_ber(Net::LDAP::AsnSyntax)) &&
1636
- (pdu = Net::LDAP::PDU.new( be )) && (pdu.app_tag == 13) or
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
- @conn.write pkt
1744
+ write pkt
1651
1745
 
1652
- (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"
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
@@ -1,5 +1,5 @@
1
1
  module Net
2
2
  class LDAP
3
- VERSION = "0.7.0"
3
+ VERSION = "0.8.0"
4
4
  end
5
5
  end
@@ -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"]
@@ -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
- @connection = Net::LDAP.new
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
@@ -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 = 7
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 = 7
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.7.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-08-04 00:00:00.000000000 Z
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