ruby-net-ldap 0.0.3 → 0.0.4

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.
Files changed (4) hide show
  1. data/ChangeLog +12 -0
  2. data/lib/net/ldap.rb +76 -17
  3. data/lib/net/ldap/filter.rb +6 -2
  4. metadata +2 -2
data/ChangeLog CHANGED
@@ -1,5 +1,17 @@
1
1
  = Net::LDAP Changelog
2
2
 
3
+ == Net::LDAP 0.0.4: August 15, 2006
4
+ * Undeprecated Net::LDAP#modify. Thanks to Justin Forder for
5
+ providing the rationale for this.
6
+ * Added a much-expanded set of special characters to the parser
7
+ for RFC-2254 filters. Thanks to Andre Nathan.
8
+ * Changed Net::LDAP#search so you can pass it a filter in string form.
9
+ The conversion to a Net::LDAP::Filter now happens automatically.
10
+ * Implemented Net::LDAP#bind_as (preliminary and subject to change).
11
+ Thanks for Simon Claret for valuable suggestions and for helping test.
12
+ * Fixed bug in Net::LDAP#open that was preventing #open from being
13
+ called more than one on a given Net::LDAP object.
14
+
3
15
  == Net::LDAP 0.0.3: July 26, 2006
4
16
  * Added simple TLS encryption.
5
17
  Thanks to Garett Shulman for suggestions and for helping test.
@@ -1,4 +1,4 @@
1
- # $Id: ldap.rb 144 2006-07-26 21:35:38Z blackhedd $
1
+ # $Id: ldap.rb 154 2006-08-15 09:35:43Z blackhedd $
2
2
  #
3
3
  # Net::LDAP for Ruby
4
4
  #
@@ -263,7 +263,7 @@ module Net
263
263
 
264
264
  class LdapError < Exception; end
265
265
 
266
- VERSION = "0.0.3"
266
+ VERSION = "0.0.4"
267
267
 
268
268
 
269
269
  SearchScope_BaseObject = 0
@@ -543,6 +543,7 @@ module Net
543
543
  @open_connection.bind @auth
544
544
  yield self
545
545
  @open_connection.close
546
+ @open_connection = nil
546
547
  end
547
548
 
548
549
 
@@ -692,9 +693,9 @@ module Net
692
693
  # on it. Otherwise, connect, bind, and disconnect.
693
694
  # The latter operation is obviously useful only as an auth check.
694
695
  #
695
- def bind
696
+ def bind auth=@auth
696
697
  if @open_connection
697
- @result = @open_connection.bind @auth
698
+ @result = @open_connection.bind auth
698
699
  else
699
700
  conn = Connection.new( :host => @host, :port => @port , :encryption => @encryption)
700
701
  @result = conn.bind @auth
@@ -706,18 +707,64 @@ module Net
706
707
 
707
708
  #
708
709
  # #bind_as is for testing authentication credentials.
709
- # Most likely a "standard" name (like a CN or an email
710
- # address) will be presented along with a password.
711
- # We'll bind with the main credential given in the
712
- # constructor, query the full DN of the user given
713
- # to us as a parameter, then unbind and rebind as the
714
- # new user.
715
710
  #
716
- # <i>This method is currently an unimplemented stub.</i>
711
+ # As described under #bind, most LDAP servers require that you supply a complete DN
712
+ # as a binding-credential, along with an authenticator such as a password.
713
+ # But for many applications (such as authenticating users to a Rails application),
714
+ # you often don't have a full DN to identify the user. You usually get a simple
715
+ # identifier like a username or an email address, along with a password.
716
+ # #bind_as allows you to authenticate these user-identifiers.
717
+ #
718
+ # #bind_as is a combination of a search and an LDAP binding. First, it connects and
719
+ # binds to the directory as normal. Then it searches the directory for an entry
720
+ # corresponding to the email address, username, or other string that you supply.
721
+ # If the entry exists, then #bind_as will <b>re-bind</b> as that user with the
722
+ # password (or other authenticator) that you supply.
723
+ #
724
+ # #bind_as takes the same parameters as #search, <i>with the addition of an
725
+ # authenticator.</i> Currently, this authenticator must be <tt>:password</tt>.
726
+ # Its value may be either a String, or a +proc+ that returns a String.
727
+ # #bind_as returns +false+ on failure. On success, it returns a result set,
728
+ # just as #search does. This result set is an Array of objects of
729
+ # type Net::LDAP::Entry. It contains the directory attributes corresponding to
730
+ # the user. (Just test whether the return value is logically true, if you don't
731
+ # need this additional information.)
732
+ #
733
+ # Here's how you would use #bind_as to authenticate an email address and password:
717
734
  #
718
- def bind_as
735
+ # require 'net/ldap'
736
+ #
737
+ # user,psw = "joe_user@yourcompany.com", "joes_psw"
738
+ #
739
+ # ldap = Net::LDAP.new
740
+ # ldap.host = "192.168.0.100"
741
+ # ldap.port = 389
742
+ # ldap.auth "cn=manager,dc=yourcompany,dc=com", "topsecret"
743
+ #
744
+ # result = ldap.bind_as(
745
+ # :base => "dc=yourcompany,dc=com",
746
+ # :filter => "(mail=#{user})",
747
+ # :password => psw
748
+ # )
749
+ # if result
750
+ # puts "Authenticated #{result.first.dn}"
751
+ # else
752
+ # puts "Authentication FAILED."
753
+ # end
754
+ def bind_as args={}
755
+ result = false
756
+ open {|me|
757
+ rs = search args
758
+ if rs and rs.first and dn = rs.first.dn
759
+ password = args[:password]
760
+ password = password.call if password.respond_to?(:call)
761
+ result = rs if bind :method => :simple, :username => dn, :password => password
762
+ end
763
+ }
764
+ result
719
765
  end
720
766
 
767
+
721
768
  # Adds a new entry to the remote LDAP server.
722
769
  # Supported arguments:
723
770
  # :dn :: Full DN of the new entry
@@ -757,8 +804,6 @@ module Net
757
804
  end
758
805
 
759
806
 
760
- # _DEPRECATED_ - Please use #add_attribute, #replace_attribute, or #delete_attribute.
761
- #
762
807
  # Modifies the attribute values of a particular entry on the LDAP directory.
763
808
  # Takes a hash with arguments. Supported arguments are:
764
809
  # :dn :: (the full DN of the entry whose attributes are to be modified)
@@ -768,6 +813,9 @@ module Net
768
813
  # succeeded or failed, with extended information available by calling
769
814
  # #get_operation_result.
770
815
  #
816
+ # Also see #add_attribute, #replace_attribute, or #delete_attribute, which
817
+ # provide simpler interfaces to this functionality.
818
+ #
771
819
  # The LDAP protocol provides a full and well thought-out set of operations
772
820
  # for changing the values of attributes, but they are necessarily somewhat complex
773
821
  # and not always intuitive. If these instructions are confusing or incomplete,
@@ -786,14 +834,15 @@ module Net
786
834
  # The :add operator will, unsurprisingly, add the specified values to
787
835
  # the specified attribute. If the attribute does not already exist,
788
836
  # :add will create it. Most LDAP servers will generate an error if you
789
- # to add a value that already exists.
837
+ # try to add a value that already exists.
790
838
  #
791
839
  # :replace will erase the current value(s) for the specified attribute,
792
840
  # if there are any, and replace them with the specified value(s).
793
841
  #
794
842
  # :delete will remove the specified value(s) from the specified attribute.
795
843
  # If you pass nil, an empty string, or an empty array as the value parameter
796
- # to a :delete operation, the _entire_ _attribute_ will be deleted.
844
+ # to a :delete operation, the _entire_ _attribute_ will be deleted, along
845
+ # with all of its values.
797
846
  #
798
847
  # For example:
799
848
  #
@@ -808,13 +857,14 @@ module Net
808
857
  # <i>(This example is contrived since you probably wouldn't add a mail
809
858
  # value right before replacing the whole attribute, but it shows that order
810
859
  # of execution matters. Also, many LDAP servers won't let you delete SN
811
- # because it would be a schema violation.)</i>
860
+ # because that would be a schema violation.)</i>
812
861
  #
813
862
  # It's essential to keep in mind that if you specify more than one operation in
814
863
  # a call to #modify, most LDAP servers will attempt to perform all of the operations
815
864
  # in the order you gave them.
816
865
  # This matters because you may specify operations on the
817
866
  # same attribute which must be performed in a certain order.
867
+ #
818
868
  # Most LDAP servers will _stop_ processing your modifications if one of them
819
869
  # causes an error on the server (such as a schema-constraint violation).
820
870
  # If this happens, you will probably get a result code from the server that
@@ -825,6 +875,14 @@ module Net
825
875
  # not be "rolled back," resulting in a partial update. This is a limitation
826
876
  # of the LDAP protocol, not of Net::LDAP.
827
877
  #
878
+ # The lack of transactional atomicity in LDAP means that you're usually
879
+ # better off using the convenience methods #add_attribute, #replace_attribute,
880
+ # and #delete_attribute, which are are wrappers over #modify. However, certain
881
+ # LDAP servers may provide concurrency semantics, in which the several operations
882
+ # contained in a single #modify call are not interleaved with other
883
+ # modification-requests received simultaneously by the server.
884
+ # It bears repeating that this concurrency does _not_ imply transactional
885
+ # atomicity, which LDAP does not provide.
828
886
  #
829
887
  def modify args
830
888
  if @open_connection
@@ -1067,6 +1125,7 @@ module Net
1067
1125
  #
1068
1126
  def search args = {}
1069
1127
  search_filter = (args && args[:filter]) || Filter.eq( "objectclass", "*" )
1128
+ search_filter = Filter.construct(search_filter) if search_filter.is_a?(String)
1070
1129
  search_base = (args && args[:base]) || "dc=example,dc=com"
1071
1130
  search_attributes = ((args && args[:attributes]) || []).map {|attr| attr.to_s.to_ber}
1072
1131
  return_referrals = args && args[:return_referrals] == true
@@ -1,4 +1,4 @@
1
- # $Id: filter.rb 132 2006-06-27 17:35:18Z blackhedd $
1
+ # $Id: filter.rb 151 2006-08-15 08:34:53Z blackhedd $
2
2
  #
3
3
  #
4
4
  #----------------------------------------------------------------------------
@@ -292,6 +292,7 @@ class Filter
292
292
  end # class Net::LDAP::Filter
293
293
 
294
294
 
295
+
295
296
  class FilterParser #:nodoc:
296
297
 
297
298
  attr_reader :filter
@@ -349,13 +350,16 @@ class FilterParser #:nodoc:
349
350
  end
350
351
  end
351
352
 
353
+ # Added a greatly-augmented filter contributed by Andre Nathan
354
+ # for detecting special characters in values. (15Aug06)
352
355
  def parse_filter_branch scanner
353
356
  scanner.scan /\s*/
354
357
  if token = scanner.scan( /[\w\-_]+/ )
355
358
  scanner.scan /\s*/
356
359
  if op = scanner.scan( /\=|\<\=|\<|\>\=|\>|\!\=/ )
357
360
  scanner.scan /\s*/
358
- if value = scanner.scan( /[\w\*\.]+/ )
361
+ #if value = scanner.scan( /[\w\*\.]+/ ) (ORG)
362
+ if value = scanner.scan( /[\w\*\.\+\-@=#\$%&!]+/ )
359
363
  case op
360
364
  when "="
361
365
  Filter.eq( token, value )
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: ruby-net-ldap
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.3
7
- date: 2006-07-27 00:00:00 -04:00
6
+ version: 0.0.4
7
+ date: 2006-08-15 00:00:00 -04:00
8
8
  summary: A pure Ruby LDAP client library.
9
9
  require_paths:
10
10
  - lib