activeldap 4.0.5 → 6.1.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.
- checksums.yaml +5 -5
- data/.yardopts +3 -1
- data/doc/text/development.md +26 -0
- data/doc/text/{news.textile → news.md} +451 -241
- data/doc/text/{rails.textile → rails.md} +44 -33
- data/doc/text/{tutorial.textile → tutorial.md} +177 -185
- data/lib/active_ldap/adapter/base.rb +40 -17
- data/lib/active_ldap/adapter/jndi.rb +21 -9
- data/lib/active_ldap/adapter/jndi_connection.rb +83 -20
- data/lib/active_ldap/adapter/ldap.rb +50 -28
- data/lib/active_ldap/adapter/ldap_ext.rb +32 -13
- data/lib/active_ldap/adapter/net_ldap.rb +26 -24
- data/lib/active_ldap/associations.rb +5 -5
- data/lib/active_ldap/attribute_methods/before_type_cast.rb +1 -1
- data/lib/active_ldap/attribute_methods/dirty.rb +4 -7
- data/lib/active_ldap/attribute_methods/query.rb +1 -1
- data/lib/active_ldap/attribute_methods/read.rb +5 -1
- data/lib/active_ldap/attribute_methods/write.rb +1 -1
- data/lib/active_ldap/attribute_methods.rb +1 -2
- data/lib/active_ldap/base.rb +61 -14
- data/lib/active_ldap/callbacks.rb +7 -8
- data/lib/active_ldap/configuration.rb +27 -3
- data/lib/active_ldap/connection.rb +4 -22
- data/lib/active_ldap/distinguished_name.rb +1 -1
- data/lib/active_ldap/human_readable.rb +5 -4
- data/lib/active_ldap/operations.rb +24 -4
- data/lib/active_ldap/persistence.rb +3 -2
- data/lib/active_ldap/populate.rb +5 -3
- data/lib/active_ldap/railties/controller_runtime.rb +1 -2
- data/lib/active_ldap/schema/syntaxes.rb +8 -4
- data/lib/active_ldap/validations.rb +12 -4
- data/lib/active_ldap/version.rb +1 -1
- data/lib/active_ldap.rb +0 -7
- data/po/en/active-ldap.po +2 -2
- data/po/ja/active-ldap.po +3 -3
- data/test/add-phonetic-attribute-options-to-slapd.ldif +3 -3
- data/test/al-test-utils.rb +125 -38
- data/test/command.rb +13 -16
- data/test/enable-dynamic-groups.ldif +22 -0
- data/test/enable-start-tls.ldif +27 -0
- data/test/run-test.rb +0 -4
- data/test/test_base.rb +223 -22
- data/test/test_base_per_instance.rb +33 -1
- data/test/test_callback.rb +10 -8
- data/test/test_connection.rb +4 -0
- data/test/test_connection_per_class.rb +34 -0
- data/test/test_dn.rb +7 -0
- data/test/test_entry.rb +1 -0
- data/test/test_find.rb +14 -3
- data/test/test_supported_control.rb +1 -1
- data/test/test_syntax.rb +5 -0
- data/test/test_validation.rb +28 -15
- metadata +23 -24
- data/README.textile +0 -141
- data/doc/text/development.textile +0 -54
- data/lib/active_ldap/timeout.rb +0 -75
- data/lib/active_ldap/timeout_stub.rb +0 -17
| @@ -9,8 +9,7 @@ module ActiveLdap | |
| 9 9 | 
             
                  def save(*) #:nodoc:
         | 
| 10 10 | 
             
                    succeeded = super
         | 
| 11 11 | 
             
                    if succeeded
         | 
| 12 | 
            -
                       | 
| 13 | 
            -
                      @changed_attributes.clear
         | 
| 12 | 
            +
                      changes_applied
         | 
| 14 13 | 
             
                    end
         | 
| 15 14 | 
             
                    succeeded
         | 
| 16 15 | 
             
                  end
         | 
| @@ -18,20 +17,18 @@ module ActiveLdap | |
| 18 17 | 
             
                  # Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
         | 
| 19 18 | 
             
                  def save!(*) #:nodoc:
         | 
| 20 19 | 
             
                    super.tap do
         | 
| 21 | 
            -
                       | 
| 22 | 
            -
                      @changed_attributes.clear
         | 
| 20 | 
            +
                      changes_applied
         | 
| 23 21 | 
             
                    end
         | 
| 24 22 | 
             
                  end
         | 
| 25 23 |  | 
| 26 24 | 
             
                  # <tt>reload</tt> the record and clears changed attributes.
         | 
| 27 25 | 
             
                  def reload(*) #:nodoc:
         | 
| 28 26 | 
             
                    super.tap do
         | 
| 29 | 
            -
                       | 
| 30 | 
            -
                      @changed_attributes.clear
         | 
| 27 | 
            +
                      clear_changes_information
         | 
| 31 28 | 
             
                    end
         | 
| 32 29 | 
             
                  end
         | 
| 33 30 |  | 
| 34 | 
            -
             | 
| 31 | 
            +
                  private
         | 
| 35 32 | 
             
                  def set_attribute(name, value)
         | 
| 36 33 | 
             
                    if name and name != "objectClass"
         | 
| 37 34 | 
             
                      attribute_will_change!(name) unless value == get_attribute(name)
         | 
| @@ -3,11 +3,15 @@ module ActiveLdap | |
| 3 3 | 
             
                module Read
         | 
| 4 4 | 
             
                  extend ActiveSupport::Concern
         | 
| 5 5 |  | 
| 6 | 
            -
             | 
| 6 | 
            +
                  private
         | 
| 7 7 | 
             
                  def attribute(attr, *args)
         | 
| 8 8 | 
             
                    return get_attribute(attr, args.first)
         | 
| 9 9 | 
             
                  end
         | 
| 10 10 |  | 
| 11 | 
            +
                  def _read_attribute(name)
         | 
| 12 | 
            +
                    get_attribute(name)
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
             | 
| 11 15 | 
             
                  # get_attribute
         | 
| 12 16 | 
             
                  #
         | 
| 13 17 | 
             
                  # Return the value of the attribute called by method_missing?
         | 
    
        data/lib/active_ldap/base.rb
    CHANGED
    
    | @@ -32,6 +32,7 @@ | |
| 32 32 | 
             
            require 'English'
         | 
| 33 33 | 
             
            require 'thread'
         | 
| 34 34 | 
             
            require 'erb'
         | 
| 35 | 
            +
            require 'set'
         | 
| 35 36 |  | 
| 36 37 | 
             
            module ActiveLdap
         | 
| 37 38 | 
             
              # OO-interface to LDAP assuming pam/nss_ldap-style organization with
         | 
| @@ -330,6 +331,7 @@ module ActiveLdap | |
| 330 331 | 
             
                class_local_attr_accessor true, :dn_attribute, :scope, :sort_by, :order
         | 
| 331 332 | 
             
                class_local_attr_accessor true, :required_classes, :recommended_classes
         | 
| 332 333 | 
             
                class_local_attr_accessor true, :excluded_classes
         | 
| 334 | 
            +
                class_local_attr_accessor false, :sub_classes
         | 
| 333 335 |  | 
| 334 336 | 
             
                class << self
         | 
| 335 337 | 
             
                  # Hide new in Base
         | 
| @@ -340,6 +342,7 @@ module ActiveLdap | |
| 340 342 | 
             
                    sub_class.module_eval do
         | 
| 341 343 | 
             
                      include GetTextSupport
         | 
| 342 344 | 
             
                    end
         | 
| 345 | 
            +
                    (self.sub_classes ||= []) << sub_class
         | 
| 343 346 | 
             
                  end
         | 
| 344 347 |  | 
| 345 348 | 
             
                  # Set LDAP connection configuration up. It doesn't connect
         | 
| @@ -548,6 +551,20 @@ module ActiveLdap | |
| 548 551 | 
             
                    defaults.first || name || to_s
         | 
| 549 552 | 
             
                  end
         | 
| 550 553 |  | 
| 554 | 
            +
                  protected
         | 
| 555 | 
            +
                  def find_real_class(object_classes)
         | 
| 556 | 
            +
                    (sub_classes || []).each do |sub_class|
         | 
| 557 | 
            +
                      real_class = sub_class.find_real_class(object_classes)
         | 
| 558 | 
            +
                      return real_class if real_class
         | 
| 559 | 
            +
                    end
         | 
| 560 | 
            +
             | 
| 561 | 
            +
                    if object_classes.superset?(Set.new(classes))
         | 
| 562 | 
            +
                      self
         | 
| 563 | 
            +
                    else
         | 
| 564 | 
            +
                      nil
         | 
| 565 | 
            +
                    end
         | 
| 566 | 
            +
                  end
         | 
| 567 | 
            +
             | 
| 551 568 | 
             
                  private
         | 
| 552 569 | 
             
                  def inspect_attributes(attributes)
         | 
| 553 570 | 
             
                    inspected_attribute_names = {}
         | 
| @@ -594,12 +611,19 @@ module ActiveLdap | |
| 594 611 | 
             
                  def instantiate(args)
         | 
| 595 612 | 
             
                    dn, attributes, options = args
         | 
| 596 613 | 
             
                    options ||= {}
         | 
| 597 | 
            -
             | 
| 598 | 
            -
             | 
| 599 | 
            -
                       | 
| 614 | 
            +
             | 
| 615 | 
            +
                    object_classes_raw =
         | 
| 616 | 
            +
                      attributes["objectClass"] ||
         | 
| 617 | 
            +
                      attributes["objectclass"] ||
         | 
| 618 | 
            +
                      []
         | 
| 619 | 
            +
                    if sub_classes.nil? or object_classes_raw.empty?
         | 
| 620 | 
            +
                      real_klass = self
         | 
| 600 621 | 
             
                    else
         | 
| 601 | 
            -
                       | 
| 602 | 
            -
                       | 
| 622 | 
            +
                      object_classes = Set.new
         | 
| 623 | 
            +
                      object_classes_raw.each do |object_class_raw|
         | 
| 624 | 
            +
                        object_classes << schema.object_class(object_class_raw)
         | 
| 625 | 
            +
                      end
         | 
| 626 | 
            +
                      real_klass = find_real_class(object_classes) || self
         | 
| 603 627 | 
             
                    end
         | 
| 604 628 |  | 
| 605 629 | 
             
                    obj = real_klass.allocate
         | 
| @@ -827,6 +851,8 @@ module ActiveLdap | |
| 827 851 |  | 
| 828 852 | 
             
                  _schema = _local_entry_attribute = nil
         | 
| 829 853 | 
             
                  targets = sanitize_for_mass_assignment(new_attributes)
         | 
| 854 | 
            +
                  have_dn = false
         | 
| 855 | 
            +
                  dn_value = nil
         | 
| 830 856 | 
             
                  targets.each do |key, value|
         | 
| 831 857 | 
             
                    setter = "#{key}="
         | 
| 832 858 | 
             
                    unless respond_to?(setter)
         | 
| @@ -836,8 +862,15 @@ module ActiveLdap | |
| 836 862 | 
             
                      _local_entry_attribute ||= local_entry_attribute
         | 
| 837 863 | 
             
                      _local_entry_attribute.register(attribute)
         | 
| 838 864 | 
             
                    end
         | 
| 839 | 
            -
                     | 
| 865 | 
            +
                    case setter
         | 
| 866 | 
            +
                    when "dn=", "id="
         | 
| 867 | 
            +
                      have_dn = true
         | 
| 868 | 
            +
                      dn_value = value
         | 
| 869 | 
            +
                    else
         | 
| 870 | 
            +
                      send(setter, value)
         | 
| 871 | 
            +
                    end
         | 
| 840 872 | 
             
                  end
         | 
| 873 | 
            +
                  self.dn = dn_value if have_dn
         | 
| 841 874 | 
             
                end
         | 
| 842 875 |  | 
| 843 876 | 
             
                def to_ldif_record
         | 
| @@ -922,9 +955,7 @@ module ActiveLdap | |
| 922 955 | 
             
                def clear_object_class_based_cache
         | 
| 923 956 | 
             
                  @entry_attribute = nil
         | 
| 924 957 | 
             
                  @real_names = {}
         | 
| 925 | 
            -
                   | 
| 926 | 
            -
                    not attribute_method?(key)
         | 
| 927 | 
            -
                  end
         | 
| 958 | 
            +
                  clear_changes_information
         | 
| 928 959 | 
             
                end
         | 
| 929 960 |  | 
| 930 961 | 
             
                def clear_removed_attributes_data(removed_attributes)
         | 
| @@ -1093,7 +1124,7 @@ module ActiveLdap | |
| 1093 1124 | 
             
                    end
         | 
| 1094 1125 | 
             
                    set_attribute(key, value)
         | 
| 1095 1126 | 
             
                  end
         | 
| 1096 | 
            -
                   | 
| 1127 | 
            +
                  clear_changes_information
         | 
| 1097 1128 | 
             
                end
         | 
| 1098 1129 | 
             
                private :initialize_attributes
         | 
| 1099 1130 |  | 
| @@ -1143,8 +1174,6 @@ module ActiveLdap | |
| 1143 1174 | 
             
                  @dn_split_value = nil
         | 
| 1144 1175 | 
             
                  @connection ||= nil
         | 
| 1145 1176 | 
             
                  @_hashing = false
         | 
| 1146 | 
            -
                  @previously_changed = []
         | 
| 1147 | 
            -
                  @changed_attributes = {}
         | 
| 1148 1177 | 
             
                  clear_connection_based_cache
         | 
| 1149 1178 | 
             
                end
         | 
| 1150 1179 |  | 
| @@ -1261,6 +1290,7 @@ module ActiveLdap | |
| 1261 1290 | 
             
                end
         | 
| 1262 1291 |  | 
| 1263 1292 | 
             
                def compute_base
         | 
| 1293 | 
            +
                  ensure_update_dn
         | 
| 1264 1294 | 
             
                  base_of_class = self.class.base
         | 
| 1265 1295 | 
             
                  if @base_value.nil?
         | 
| 1266 1296 | 
             
                    base_of_class
         | 
| @@ -1352,7 +1382,14 @@ module ActiveLdap | |
| 1352 1382 | 
             
                    if k == _dn_attribute
         | 
| 1353 1383 | 
             
                      new_dn_value = value[0]
         | 
| 1354 1384 | 
             
                    else
         | 
| 1355 | 
            -
                       | 
| 1385 | 
            +
                      if (v.size == 1 and value.size == 1) or force_replace?(k)
         | 
| 1386 | 
            +
                        attributes.push([:replace, k, value])
         | 
| 1387 | 
            +
                      else
         | 
| 1388 | 
            +
                        removed_values = v - value
         | 
| 1389 | 
            +
                        added_values = value - v
         | 
| 1390 | 
            +
                        attributes.push([:delete, k, removed_values]) unless removed_values.empty?
         | 
| 1391 | 
            +
                        attributes.push([:add, k, added_values]) unless added_values.empty?
         | 
| 1392 | 
            +
                      end
         | 
| 1356 1393 | 
             
                    end
         | 
| 1357 1394 | 
             
                  end
         | 
| 1358 1395 |  | 
| @@ -1366,12 +1403,22 @@ module ActiveLdap | |
| 1366 1403 | 
             
                    # Detect subtypes and account for them
         | 
| 1367 1404 | 
             
                    # REPLACE will function like ADD, but doesn't hit EQUALITY problems
         | 
| 1368 1405 | 
             
                    # TODO: Added equality(attr) to Schema
         | 
| 1369 | 
            -
                     | 
| 1406 | 
            +
                    if force_replace?(k)
         | 
| 1407 | 
            +
                      attributes.push([:replace, k, value])
         | 
| 1408 | 
            +
                    else
         | 
| 1409 | 
            +
                      attributes.push([:add, k, value])
         | 
| 1410 | 
            +
                    end
         | 
| 1370 1411 | 
             
                  end
         | 
| 1371 1412 |  | 
| 1372 1413 | 
             
                  [new_dn_value, attributes]
         | 
| 1373 1414 | 
             
                end
         | 
| 1374 1415 |  | 
| 1416 | 
            +
                def force_replace?(k)
         | 
| 1417 | 
            +
                  attribute = schema.attribute(k)
         | 
| 1418 | 
            +
                  attribute.single_value? or
         | 
| 1419 | 
            +
                    attribute.binary? # TODO: this should probably explicitly check for fields with no equality matching rule instead
         | 
| 1420 | 
            +
                end
         | 
| 1421 | 
            +
             | 
| 1375 1422 | 
             
                def collect_all_attributes(data)
         | 
| 1376 1423 | 
             
                  dn_attr = dn_attribute
         | 
| 1377 1424 | 
             
                  dn_value = data[dn_attr]
         | 
| @@ -14,13 +14,12 @@ module ActiveLdap | |
| 14 14 | 
             
                included do
         | 
| 15 15 | 
             
                  extend ActiveModel::Callbacks
         | 
| 16 16 | 
             
                  include ActiveModel::Validations::Callbacks
         | 
| 17 | 
            -
                  
         | 
| 17 | 
            +
                  singleton_class.class_eval do
         | 
| 18 | 
            +
                    prepend CallbackedInstantiatable
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 18 21 | 
             
                  define_model_callbacks :initialize, :find, :touch, :only => :after
         | 
| 19 22 | 
             
                  define_model_callbacks :save, :create, :update, :destroy
         | 
| 20 | 
            -
                  
         | 
| 21 | 
            -
                  class << self
         | 
| 22 | 
            -
                    alias_method_chain :instantiate, :callbacks
         | 
| 23 | 
            -
                  end
         | 
| 24 23 | 
             
                end
         | 
| 25 24 |  | 
| 26 25 | 
             
                module ClassMethods
         | 
| @@ -33,9 +32,9 @@ module ActiveLdap | |
| 33 32 | 
             
                  end
         | 
| 34 33 | 
             
                end
         | 
| 35 34 |  | 
| 36 | 
            -
                module  | 
| 37 | 
            -
                  def  | 
| 38 | 
            -
                    object =  | 
| 35 | 
            +
                module CallbackedInstantiatable
         | 
| 36 | 
            +
                  def instantiate(record)
         | 
| 37 | 
            +
                    object = super(record)
         | 
| 39 38 | 
             
                    object.run_callbacks(:find)
         | 
| 40 39 | 
             
                    object.run_callbacks(:initialize)
         | 
| 41 40 | 
             
                    object
         | 
| @@ -27,6 +27,7 @@ module ActiveLdap | |
| 27 27 | 
             
                DEFAULT_CONFIG[:host] = '127.0.0.1'
         | 
| 28 28 | 
             
                DEFAULT_CONFIG[:port] = nil
         | 
| 29 29 | 
             
                DEFAULT_CONFIG[:method] = :plain  # :ssl, :tls, :plain allowed
         | 
| 30 | 
            +
                DEFAULT_CONFIG[:tls_options] = nil
         | 
| 30 31 |  | 
| 31 32 | 
             
                DEFAULT_CONFIG[:bind_dn] = nil
         | 
| 32 33 | 
             
                DEFAULT_CONFIG[:password_block] = nil
         | 
| @@ -47,6 +48,15 @@ module ActiveLdap | |
| 47 48 | 
             
                DEFAULT_CONFIG[:retry_on_timeout] = true
         | 
| 48 49 | 
             
                DEFAULT_CONFIG[:follow_referrals] = true
         | 
| 49 50 |  | 
| 51 | 
            +
                # 500 is the default size limit value of OpenLDAP 2.4:
         | 
| 52 | 
            +
                #   https://openldap.org/doc/admin24/limits.html#Global%20Limits
         | 
| 53 | 
            +
                #
         | 
| 54 | 
            +
                # We may change this when we find LDAP server that its the default
         | 
| 55 | 
            +
                # size limit is smaller than 500.
         | 
| 56 | 
            +
                DEFAULT_CONFIG[:page_size] = 500
         | 
| 57 | 
            +
                # Whether using paged results if available.
         | 
| 58 | 
            +
                DEFAULT_CONFIG[:use_paged_results] = true
         | 
| 59 | 
            +
             | 
| 50 60 | 
             
                DEFAULT_CONFIG[:logger] = nil
         | 
| 51 61 |  | 
| 52 62 | 
             
                module ClassMethods
         | 
| @@ -91,8 +101,8 @@ module ActiveLdap | |
| 91 101 | 
             
                    @@defined_configurations
         | 
| 92 102 | 
             
                  end
         | 
| 93 103 |  | 
| 94 | 
            -
                  def  | 
| 95 | 
            -
                    @@defined_configurations. | 
| 104 | 
            +
                  def remove_configuration_by_key(key)
         | 
| 105 | 
            +
                    @@defined_configurations.delete(key)
         | 
| 96 106 | 
             
                  end
         | 
| 97 107 |  | 
| 98 108 | 
             
                  CONNECTION_CONFIGURATION_KEYS = [:uri, :base, :adapter]
         | 
| @@ -102,8 +112,22 @@ module ActiveLdap | |
| 102 112 | 
             
                    end
         | 
| 103 113 | 
             
                  end
         | 
| 104 114 |  | 
| 115 | 
            +
                  def parent_configuration(target)
         | 
| 116 | 
            +
                    if target.is_a?(Base)
         | 
| 117 | 
            +
                      target = target.class
         | 
| 118 | 
            +
                    else
         | 
| 119 | 
            +
                      target = target.superclass
         | 
| 120 | 
            +
                    end
         | 
| 121 | 
            +
                    while target <= Base
         | 
| 122 | 
            +
                      config = defined_configurations[target.active_connection_key]
         | 
| 123 | 
            +
                      return config if config
         | 
| 124 | 
            +
                      target = target.superclass
         | 
| 125 | 
            +
                    end
         | 
| 126 | 
            +
                    default_configuration
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
             | 
| 105 129 | 
             
                  def merge_configuration(user_configuration, target=self)
         | 
| 106 | 
            -
                    configuration =  | 
| 130 | 
            +
                    configuration = parent_configuration(target).dup
         | 
| 107 131 | 
             
                    prepare_configuration(user_configuration).each do |key, value|
         | 
| 108 132 | 
             
                      case key
         | 
| 109 133 | 
             
                      when :base
         | 
| @@ -6,7 +6,7 @@ module ActiveLdap | |
| 6 6 |  | 
| 7 7 | 
             
                module ClassMethods
         | 
| 8 8 | 
             
                  @@active_connections = {}
         | 
| 9 | 
            -
                  @@allow_concurrency =  | 
| 9 | 
            +
                  @@allow_concurrency = true
         | 
| 10 10 |  | 
| 11 11 | 
             
                  def thread_safe_active_connections
         | 
| 12 12 | 
             
                    @@active_connections[Thread.current.object_id] ||= {}
         | 
| @@ -135,7 +135,7 @@ module ActiveLdap | |
| 135 135 | 
             
                    end
         | 
| 136 136 | 
             
                    config = configuration(key)
         | 
| 137 137 | 
             
                    conn = active_connections[key]
         | 
| 138 | 
            -
                     | 
| 138 | 
            +
                    remove_configuration_by_key(key)
         | 
| 139 139 | 
             
                    active_connections.delete_if {|_key, value| value == conn}
         | 
| 140 140 | 
             
                    conn.disconnect! if conn
         | 
| 141 141 | 
             
                    config
         | 
| @@ -165,11 +165,11 @@ module ActiveLdap | |
| 165 165 | 
             
                    connection.schema
         | 
| 166 166 | 
             
                  end
         | 
| 167 167 |  | 
| 168 | 
            -
                  private
         | 
| 169 168 | 
             
                  def active_connection_key(k=self)
         | 
| 170 169 | 
             
                    k.name.blank? ? k.object_id : k.name
         | 
| 171 170 | 
             
                  end
         | 
| 172 171 |  | 
| 172 | 
            +
                  private
         | 
| 173 173 | 
             
                  def determine_active_connection_name
         | 
| 174 174 | 
             
                    key = active_connection_key
         | 
| 175 175 | 
             
                    if active_connections[key] or configuration(key)
         | 
| @@ -197,27 +197,9 @@ module ActiveLdap | |
| 197 197 | 
             
                    if Object.respond_to?(:java)
         | 
| 198 198 | 
             
                      "jndi"
         | 
| 199 199 | 
             
                    else
         | 
| 200 | 
            -
                       | 
| 201 | 
            -
                      $LOAD_PATH.each do |path|
         | 
| 202 | 
            -
                        if File.exist?(File.join(path, "ldap", "ldif.rb"))
         | 
| 203 | 
            -
                          ruby_ldap_available = true
         | 
| 204 | 
            -
                          break
         | 
| 205 | 
            -
                        end
         | 
| 206 | 
            -
                      end
         | 
| 207 | 
            -
                      if !ruby_ldap_available and Object.const_defined?(:Gem)
         | 
| 208 | 
            -
                        ruby_ldap_available = gem_available?("ruby-ldap")
         | 
| 209 | 
            -
                      end
         | 
| 210 | 
            -
                      if ruby_ldap_available
         | 
| 211 | 
            -
                        "ldap"
         | 
| 212 | 
            -
                      else
         | 
| 213 | 
            -
                        "net-ldap"
         | 
| 214 | 
            -
                      end
         | 
| 200 | 
            +
                      "net-ldap"
         | 
| 215 201 | 
             
                    end
         | 
| 216 202 | 
             
                  end
         | 
| 217 | 
            -
             | 
| 218 | 
            -
                  def gem_available?(name)
         | 
| 219 | 
            -
                    not Gem::Specification.find_all_by_name(name).empty?
         | 
| 220 | 
            -
                  end
         | 
| 221 203 | 
             
                end
         | 
| 222 204 |  | 
| 223 205 | 
             
                def setup_connection(config=nil)
         | 
| @@ -62,7 +62,7 @@ module ActiveLdap | |
| 62 62 |  | 
| 63 63 | 
             
                  HEX_PAIR = "(?:[\\da-fA-F]{2})"
         | 
| 64 64 | 
             
                  STRING_CHARS_RE = /[^,=\+<>\#;\\\"]*/ #
         | 
| 65 | 
            -
                  PAIR_RE = /\\([,=\+<>\#;]|\\|\"|(#{HEX_PAIR}))/ #
         | 
| 65 | 
            +
                  PAIR_RE = /\\([,=\+<>\#;]|\\|\"| |(#{HEX_PAIR}))/ #
         | 
| 66 66 | 
             
                  HEX_STRING_RE = /\#(#{HEX_PAIR}+)/ #
         | 
| 67 67 | 
             
                  def scan_attribute_value(scanner)
         | 
| 68 68 | 
             
                    if scanner.scan(HEX_STRING_RE)
         | 
| @@ -17,11 +17,12 @@ module ActiveLdap | |
| 17 17 | 
             
                    if attribute_or_name.is_a?(Schema::Attribute)
         | 
| 18 18 | 
             
                      name = attribute_or_name.name
         | 
| 19 19 | 
             
                    else
         | 
| 20 | 
            -
                       | 
| 20 | 
            +
                      attribute_name = attribute_or_name.to_s
         | 
| 21 | 
            +
                      attribute = schema.attribute(attribute_name)
         | 
| 21 22 | 
             
                      return nil if attribute.id.nil?
         | 
| 22 | 
            -
                      if attribute.name ==  | 
| 23 | 
            -
                          attribute.aliases.include?( | 
| 24 | 
            -
                        name =  | 
| 23 | 
            +
                      if attribute.name == attribute_name or
         | 
| 24 | 
            +
                          attribute.aliases.include?(attribute_name)
         | 
| 25 | 
            +
                        name = attribute_name
         | 
| 25 26 | 
             
                      else
         | 
| 26 27 | 
             
                        return nil
         | 
| 27 28 | 
             
                      end
         | 
| @@ -22,9 +22,23 @@ module ActiveLdap | |
| 22 22 | 
             
                end
         | 
| 23 23 |  | 
| 24 24 | 
             
                module Common
         | 
| 25 | 
            -
                  VALID_SEARCH_OPTIONS = [ | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 25 | 
            +
                  VALID_SEARCH_OPTIONS = [
         | 
| 26 | 
            +
                    :attribute,
         | 
| 27 | 
            +
                    :value,
         | 
| 28 | 
            +
                    :filter,
         | 
| 29 | 
            +
                    :prefix,
         | 
| 30 | 
            +
                    :classes,
         | 
| 31 | 
            +
                    :scope,
         | 
| 32 | 
            +
                    :limit,
         | 
| 33 | 
            +
                    :attributes,
         | 
| 34 | 
            +
                    :sort_by,
         | 
| 35 | 
            +
                    :order,
         | 
| 36 | 
            +
                    :connection,
         | 
| 37 | 
            +
                    :base,
         | 
| 38 | 
            +
                    :offset,
         | 
| 39 | 
            +
                    :use_paged_results,
         | 
| 40 | 
            +
                    :page_size,
         | 
| 41 | 
            +
                  ]
         | 
| 28 42 |  | 
| 29 43 | 
             
                  def search(options={}, &block)
         | 
| 30 44 | 
             
                    validate_search_options(options)
         | 
| @@ -62,6 +76,8 @@ module ActiveLdap | |
| 62 76 | 
             
                      :attributes => requested_attributes,
         | 
| 63 77 | 
             
                      :sort_by => options[:sort_by] || sort_by,
         | 
| 64 78 | 
             
                      :order => options[:order] || order,
         | 
| 79 | 
            +
                      :use_paged_results => options[:use_paged_results],
         | 
| 80 | 
            +
                      :page_size => options[:page_size],
         | 
| 65 81 | 
             
                    }
         | 
| 66 82 | 
             
                    options[:connection] ||= connection
         | 
| 67 83 | 
             
                    values = []
         | 
| @@ -96,10 +112,11 @@ module ActiveLdap | |
| 96 112 | 
             
                    }
         | 
| 97 113 |  | 
| 98 114 | 
             
                    attribute = attr || ensure_search_attribute
         | 
| 115 | 
            +
                    escaped_value = DN.escape_value(value)
         | 
| 99 116 | 
             
                    options_for_non_leaf = {
         | 
| 100 117 | 
             
                      :attribute => attr,
         | 
| 101 118 | 
             
                      :value => value,
         | 
| 102 | 
            -
                      :prefix => ["#{attribute}=#{ | 
| 119 | 
            +
                      :prefix => ["#{attribute}=#{escaped_value}", prefix].compact.join(","),
         | 
| 103 120 | 
             
                      :limit => 1,
         | 
| 104 121 | 
             
                      :scope => :base,
         | 
| 105 122 | 
             
                    }
         | 
| @@ -291,6 +308,9 @@ module ActiveLdap | |
| 291 308 | 
             
                    offset = options.delete(:offset) || offset
         | 
| 292 309 | 
             
                    options[:attributes] = options.delete(:attributes) || ['*']
         | 
| 293 310 | 
             
                    options[:attributes] |= ['objectClass']
         | 
| 311 | 
            +
                    if options.delete(:include_operational_attributes)
         | 
| 312 | 
            +
                      options[:attributes] |= ["+"]
         | 
| 313 | 
            +
                    end
         | 
| 294 314 | 
             
                    results = search(options).collect do |dn, attrs|
         | 
| 295 315 | 
             
                      instantiate([dn, attrs, {:connection => options[:connection]}])
         | 
| 296 316 | 
             
                    end
         | 
| @@ -81,9 +81,10 @@ module ActiveLdap | |
| 81 81 | 
             
                  end
         | 
| 82 82 | 
             
                end
         | 
| 83 83 |  | 
| 84 | 
            -
                def reload
         | 
| 84 | 
            +
                def reload(options={})
         | 
| 85 85 | 
             
                  clear_association_cache
         | 
| 86 | 
            -
                   | 
| 86 | 
            +
                  search_options = options.merge(value: id)
         | 
| 87 | 
            +
                  _, attributes = search(search_options).find do |_dn, _attributes|
         | 
| 87 88 | 
             
                    dn == _dn
         | 
| 88 89 | 
             
                  end
         | 
| 89 90 | 
             
                  if attributes.nil?
         | 
    
        data/lib/active_ldap/populate.rb
    CHANGED
    
    | @@ -1,9 +1,11 @@ | |
| 1 1 | 
             
            module ActiveLdap
         | 
| 2 2 | 
             
              module Populate
         | 
| 3 3 | 
             
                module_function
         | 
| 4 | 
            -
                def ensure_base(base_class=nil)
         | 
| 4 | 
            +
                def ensure_base(base_class=nil, options={})
         | 
| 5 5 | 
             
                  base_class ||= Base
         | 
| 6 6 | 
             
                  return unless base_class.search(:scope => :base).empty?
         | 
| 7 | 
            +
                  dc_base_class = options[:dc_base_class] || base_class
         | 
| 8 | 
            +
                  ou_base_class = options[:ou_base_class] || base_class
         | 
| 7 9 |  | 
| 8 10 | 
             
                  base_dn = DN.parse(base_class.base)
         | 
| 9 11 | 
             
                  suffixes = []
         | 
| @@ -15,11 +17,11 @@ module ActiveLdap | |
| 15 17 | 
             
                    begin
         | 
| 16 18 | 
             
                      case name.downcase
         | 
| 17 19 | 
             
                      when "dc"
         | 
| 18 | 
            -
                        ensure_dc(value, prefix,  | 
| 20 | 
            +
                        ensure_dc(value, prefix, dc_base_class)
         | 
| 19 21 | 
             
                      when "ou"
         | 
| 20 22 | 
             
                        ensure_ou(value,
         | 
| 21 23 | 
             
                                  :base => prefix,
         | 
| 22 | 
            -
                                  :base_class =>  | 
| 24 | 
            +
                                  :base_class => ou_base_class)
         | 
| 23 25 | 
             
                      end
         | 
| 24 26 | 
             
                    rescue ActiveLdap::OperationNotPermitted
         | 
| 25 27 | 
             
                    end
         | 
| @@ -192,11 +192,11 @@ module ActiveLdap | |
| 192 192 | 
             
                        fraction = fraction.to_f if fraction
         | 
| 193 193 | 
             
                        time_zone = match_data[-1]
         | 
| 194 194 | 
             
                        arguments = [
         | 
| 195 | 
            -
                          year, month, day, hour, minute, second, fraction, time_zone,
         | 
| 195 | 
            +
                          value, year, month, day, hour, minute, second, fraction, time_zone,
         | 
| 196 196 | 
             
                          Time.now,
         | 
| 197 197 | 
             
                        ]
         | 
| 198 | 
            -
                        if Time.method(:make_time).arity ==  | 
| 199 | 
            -
                          arguments | 
| 198 | 
            +
                        if Time.method(:make_time).arity == 11
         | 
| 199 | 
            +
                          arguments[2, 0] = nil
         | 
| 200 200 | 
             
                        end
         | 
| 201 201 | 
             
                        begin
         | 
| 202 202 | 
             
                          Time.send(:make_time, *arguments)
         | 
| @@ -222,7 +222,11 @@ module ActiveLdap | |
| 222 222 | 
             
                        if value.gmt?
         | 
| 223 223 | 
             
                          normalized_value + "Z"
         | 
| 224 224 | 
             
                        else
         | 
| 225 | 
            -
                           | 
| 225 | 
            +
                          # for timezones with non-zero minutes, such as IST which is +0530,
         | 
| 226 | 
            +
                          # divmod(3600) will give wrong value of 1800
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                          offset = value.gmtoff / 60 # in minutes
         | 
| 229 | 
            +
                          normalized_value + ("%+03d%02d" % offset.divmod(60))
         | 
| 226 230 | 
             
                        end
         | 
| 227 231 | 
             
                      else
         | 
| 228 232 | 
             
                        value
         | 
| @@ -53,15 +53,23 @@ module ActiveLdap | |
| 53 53 | 
             
                  errors.empty? && output
         | 
| 54 54 | 
             
                end
         | 
| 55 55 |  | 
| 56 | 
            -
                def save( | 
| 57 | 
            -
                   | 
| 56 | 
            +
                def save(**options)
         | 
| 57 | 
            +
                  perform_validations(options) ? super : false
         | 
| 58 58 | 
             
                end
         | 
| 59 59 |  | 
| 60 | 
            -
                def save!( | 
| 61 | 
            -
                   | 
| 60 | 
            +
                def save!(**options)
         | 
| 61 | 
            +
                  perform_validations(options) ? super : raise(EntryInvalid.new(self))
         | 
| 62 62 | 
             
                end
         | 
| 63 63 |  | 
| 64 64 | 
             
                private
         | 
| 65 | 
            +
                def perform_validations(options)
         | 
| 66 | 
            +
                  if options[:validate] == false
         | 
| 67 | 
            +
                    true
         | 
| 68 | 
            +
                  else
         | 
| 69 | 
            +
                    valid?(options[:context])
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 65 73 | 
             
                def format_validation_message(format, parameters)
         | 
| 66 74 | 
             
                  format % parameters
         | 
| 67 75 | 
             
                end
         | 
    
        data/lib/active_ldap/version.rb
    CHANGED
    
    
    
        data/lib/active_ldap.rb
    CHANGED
    
    | @@ -1,4 +1,3 @@ | |
| 1 | 
            -
            require "rubygems"
         | 
| 2 1 | 
             
            require "active_model"
         | 
| 3 2 | 
             
            require "active_support/core_ext"
         | 
| 4 3 |  | 
| @@ -8,12 +7,6 @@ module ActiveLdap | |
| 8 7 | 
             
              autoload :Command, "active_ldap/command"
         | 
| 9 8 | 
             
            end
         | 
| 10 9 |  | 
| 11 | 
            -
            if RUBY_PLATFORM.match('linux')
         | 
| 12 | 
            -
              require 'active_ldap/timeout'
         | 
| 13 | 
            -
            else
         | 
| 14 | 
            -
              require 'active_ldap/timeout_stub'
         | 
| 15 | 
            -
            end
         | 
| 16 | 
            -
             | 
| 17 10 | 
             
            require 'active_ldap/get_text'
         | 
| 18 11 |  | 
| 19 12 | 
             
            require 'active_ldap/compatible'
         | 
    
        data/po/en/active-ldap.po
    CHANGED
    
    | @@ -7,7 +7,7 @@ msgid "" | |
| 7 7 | 
             
            msgstr ""
         | 
| 8 8 | 
             
            "Project-Id-Version: Ruby/ActiveLdap 1.1.1\n"
         | 
| 9 9 | 
             
            "POT-Creation-Date: 2009-08-04 23:26+0900\n"
         | 
| 10 | 
            -
            "PO-Revision-Date:  | 
| 10 | 
            +
            "PO-Revision-Date: 2016-05-13 21:52+0900\n"
         | 
| 11 11 | 
             
            "Last-Translator: Kouhei Sutou <kou@cozmixng.org>\n"
         | 
| 12 12 | 
             
            "Language-Team: English\n"
         | 
| 13 13 | 
             
            "MIME-Version: 1.0\n"
         | 
| @@ -3524,7 +3524,7 @@ msgstr "" | |
| 3524 3524 |  | 
| 3525 3525 | 
             
            #: lib/active_ldap/adapter/base.rb:579
         | 
| 3526 3526 | 
             
            msgid ""
         | 
| 3527 | 
            -
            "Reconnect to server failed: %s\n"
         | 
| 3527 | 
            +
            "Reconnect to server failed: %s: %s\n"
         | 
| 3528 3528 | 
             
            "Reconnect to server failed backtrace:\n"
         | 
| 3529 3529 | 
             
            "%s"
         | 
| 3530 3530 | 
             
            msgstr ""
         | 
    
        data/po/ja/active-ldap.po
    CHANGED
    
    | @@ -7,7 +7,7 @@ msgid "" | |
| 7 7 | 
             
            msgstr ""
         | 
| 8 8 | 
             
            "Project-Id-Version: Ruby/ActiveLdap 1.1.1\n"
         | 
| 9 9 | 
             
            "POT-Creation-Date: 2009-08-04 23:26+0900\n"
         | 
| 10 | 
            -
            "PO-Revision-Date:  | 
| 10 | 
            +
            "PO-Revision-Date: 2016-05-13 21:53+0900\n"
         | 
| 11 11 | 
             
            "Last-Translator: Kouhei Sutou <kou@cozmixng.org>\n"
         | 
| 12 12 | 
             
            "Language-Team: Japanese\n"
         | 
| 13 13 | 
             
            "MIME-Version: 1.0\n"
         | 
| @@ -3533,11 +3533,11 @@ msgstr "再接続を試みています" | |
| 3533 3533 |  | 
| 3534 3534 | 
             
            #: lib/active_ldap/adapter/base.rb:579
         | 
| 3535 3535 | 
             
            msgid ""
         | 
| 3536 | 
            -
            "Reconnect to server failed: %s\n"
         | 
| 3536 | 
            +
            "Reconnect to server failed: %s: %s\n"
         | 
| 3537 3537 | 
             
            "Reconnect to server failed backtrace:\n"
         | 
| 3538 3538 | 
             
            "%s"
         | 
| 3539 3539 | 
             
            msgstr ""
         | 
| 3540 | 
            -
            "サーバへの再接続が失敗しました: %s\n"
         | 
| 3540 | 
            +
            "サーバへの再接続が失敗しました: %s: %s\n"
         | 
| 3541 3541 | 
             
            "サーバへの再接続失敗時のバックトレース:\n"
         | 
| 3542 3542 | 
             
            "%s"
         | 
| 3543 3543 |  | 
| @@ -1,6 +1,6 @@ | |
| 1 | 
            -
            # Your LDAP server  | 
| 2 | 
            -
            # This is a LDIF file for OpenLDAP to do the  | 
| 3 | 
            -
            # You can use this file by the following command  | 
| 1 | 
            +
            # Your LDAP server needs to accept 'phonetic' attribute option for test.
         | 
| 2 | 
            +
            # This is a LDIF file for OpenLDAP to do the configuration.
         | 
| 3 | 
            +
            # You can use this file by the following command line on Debian GNU/Linux
         | 
| 4 4 | 
             
            # or Ubuntu:
         | 
| 5 5 | 
             
            #   % sudo -H ldapmodify -Y EXTERNAL -H ldapi:/// -f test/add-phonetic-attribute-options-to-slapd.ldif
         | 
| 6 6 | 
             
            version: 1
         |