net-ldap 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of net-ldap might be problematic. Click here for more details.

checksums.yaml 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