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 +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
|