Class ActiveLdap::Base
In: lib/active_ldap/base.rb
Parent: Object
Error AttributeAssignmentError AdapterNotSpecified OperationNotPermitted RequiredObjectClassMissed ConnectionError RequiredAttributeMissed LdifInvalid LdapError DistinguishedNameNotSetError EntryNotFound SaveError StrongAuthenticationRequired NotImplemented AdapterNotFound TimeoutError AuthenticationError AttributeValueInvalid EntryNotSaved DistinguishedNameInputInvalid EntryAlreadyExist ObjectClassError UnknownAttribute EntryInvalid DeleteError ConfigurationError ConnectionNotSetup DistinguishedNameInvalid Schema\n[lib/active_ldap/schema.rb\nlib/active_ldap/schema/syntaxes.rb] DistinguishedName Base Reloadable::Deprecated Reloadable::Subclasses Enumerable Ldif Collection EntryAttribute StandardError Children HasManyWrap HasMany BelongsToMany Proxy BelongsTo Common Find LDIF Delete Update GetText::Translation Normalizable GetText Parser ActiveRecord::Callbacks ActiveRecord::Validations Base\n[lib/active_ldap/adapter/base.rb\nlib/active_ldap/adapter/jndi.rb\nlib/active_ldap/adapter/ldap.rb\nlib/active_ldap/adapter/net_ldap.rb] Jndi Ldap NetLdap GetTextSupport Xml JndiConnection lib/active_ldap/distinguished_name.rb lib/active_ldap/base.rb lib/active_ldap/schema/syntaxes.rb lib/active_ldap/xml.rb lib/active_ldap/entry_attribute.rb lib/active_ldap/ldif.rb lib/active_ldap/ldap_error.rb Compatible ClassMethods Associations LdapBenchmarking ActionController Populate lib/active_ldap/association/has_many_wrap.rb lib/active_ldap/association/children.rb lib/active_ldap/association/collection.rb lib/active_ldap/association/proxy.rb lib/active_ldap/association/belongs_to_many.rb lib/active_ldap/association/belongs_to.rb lib/active_ldap/association/has_many.rb HasManyUtils Association ClassMethods Tree Acts Command Update Common ModifyNameRecordLoadable AddOperationModifiable DeleteOperationModifiable ReplaceOperationModifiable ModifyRecordLoadable DeleteRecordLoadable AddRecordLoadable ContentRecordLoadable LDIF Delete Find Operations GetTextSupport Escape ClassMethods Normalizable Attributes ClassMethods Configuration ClassMethods ObjectClass lib/active_ldap/get_text/parser.rb GetText ClassMethods Callbacks Validations lib/active_ldap/adapter/jndi_connection.rb lib/active_ldap/adapter/net_ldap.rb lib/active_ldap/adapter/ldap.rb lib/active_ldap/adapter/jndi.rb Adapter Helper Translation GetTextFallback ClassMethods HumanReadable Salt UserPassword ClassMethods Connection ActiveLdap dot/m_46_0.png

Base

Base is the primary class which contains all of the core ActiveLdap functionality. It is meant to only ever be subclassed by extension classes.

Methods

==   []   []=   abstract_class?   array_of   attribute_name_resolvable_without_connection?   attribute_names   attribute_present?   attributes   attributes=   base   base   base=   base=   base_class   bind   class_local_attr_accessor   class_of_active_ldap_descendant   clear_connection_based_cache   clear_object_class_based_cache   collect_all_attributes   collect_modified_attributes   compute_base   compute_base   compute_dn   create   create   create_or_update   default_dn_attribute   default_prefix   default_search_attribute   default_search_attribute   delete   delete_all   destroy   destroy_all   dn   dn=   dn_attribute   dn_attribute_with_fallback   each   enforce_type   ensure_logger   ensure_update_dn   entry_attribute   eql?   establish_connection   exist?   exists?   extract_object_class   false_value?   find_object_class_values   get_attribute   get_attribute_as_query   get_attribute_before_type_cast   has_attribute?   hash   have_attribute?   human_name   id   id=   inherited   init_base   init_instance_variables   initialize_by_ldap_data   inspect   inspect   inspect_attribute   inspect_attribute   inspect_attributes   instantiate   instantiate   ldap_mapping   local_entry_attribute   may   method_missing   methods   must   need_update_dn?   new   new_entry?   normalize_data   prefix   prefix=   prepare_data_for_saving   register_new_dn_attribute   reload   respond_to?   save   save!   schema   scope   scope=   scope=   self_and_descendants_from_active_ldap   set_attribute   setup_connection   simplify_data   split_dn_value   to_ldif   to_ldif_record   to_param   to_real_attribute_name   to_s   to_xml   type_cast   update   update_attribute   update_attributes   update_attributes!   update_dn   validate_ldap_mapping_options   validate_scope  

Included Modules

GetTextSupport Reloadable::Deprecated Reloadable::Subclasses GetTextSupport Enumerable

Constants

VALID_LDAP_MAPPING_OPTIONS = [:dn_attribute, :prefix, :scope, :classes, :recommended_classes, :excluded_classes, :sort_by, :order]

External Aliases

base -> parsed_base
scope= -> scope_without_validation=
dn_attribute -> dn_attribute_of_class
respond_to? -> respond_to_without_attributes?
scope -> scope_of_class

Attributes

abstract_class  [RW] 

Public Class methods

[Source]

     # File lib/active_ldap/base.rb, line 507
507:       def abstract_class?
508:         defined?(@abstract_class) && @abstract_class
509:       end

Base.base

This method when included into Base provides an inheritable, overwritable configuration setting

This should be a string with the base of the ldap server such as ‘dc=example,dc=com’, and it should be overwritten by including configuration.rb into this class. When subclassing, the specified prefix will be concatenated.

[Source]

     # File lib/active_ldap/base.rb, line 434
434:       def base
435:         @base ||= compute_base
436:       end

[Source]

     # File lib/active_ldap/base.rb, line 439
439:       def base=(value)
440:         self.inheritable_base = value
441:         @base = nil
442:       end

[Source]

     # File lib/active_ldap/base.rb, line 467
467:       def base_class
468:         if self == Base or superclass == Base
469:           self
470:         else
471:           superclass.base_class
472:         end
473:       end

[Source]

     # File lib/active_ldap/base.rb, line 298
298:     def self.class_local_attr_accessor(search_ancestors, *syms)
299:       syms.flatten.each do |sym|
300:         class_eval("def self.\#{sym}(search_superclasses=\#{search_ancestors})\n@\#{sym} ||= nil\nreturn @\#{sym} if @\#{sym}\nif search_superclasses\ntarget = superclass\nvalue = nil\nloop do\nbreak nil unless target.respond_to?(:\#{sym})\nvalue = target.\#{sym}\nbreak if value\ntarget = target.superclass\nend\nvalue\nelse\nnil\nend\nend\ndef \#{sym}; self.class.\#{sym}; end\ndef self.\#{sym}=(value); @\#{sym} = value; end\n", __FILE__, __LINE__ + 1)
301:       end
302:     end

[Source]

     # File lib/active_ldap/base.rb, line 511
511:       def class_of_active_ldap_descendant(klass)
512:         if klass.superclass == Base or klass.superclass.abstract_class?
513:           klass
514:         elsif klass.superclass.nil?
515:           raise Error, _("%s doesn't belong in a hierarchy descending " \
516:                          "from ActiveLdap") % (name || to_s)
517:         else
518:           class_of_active_ldap_descendant(klass.superclass)
519:         end
520:       end

[Source]

     # File lib/active_ldap/base.rb, line 390
390:       def create(attributes=nil, &block)
391:         if attributes.is_a?(Array)
392:           attributes.collect {|attrs| create(attrs, &block)}
393:         else
394:           object = new(attributes, &block)
395:           object.save
396:           object
397:         end
398:       end

[Source]

     # File lib/active_ldap/base.rb, line 475
475:       def default_search_attribute
476:         dn_attribute
477:       end

establish_connection is deprecated since 1.1.0. Please use setup_connection() instead.

[Source]

     # File lib/active_ldap/base.rb, line 381
381:       def establish_connection(config=nil)
382:         message =
383:           _("ActiveLdap::Base.establish_connection has been deprecated " \
384:             "since 1.1.0. " \
385:             "Please use ActiveLdap::Base.setup_connection instead.")
386:         ActiveSupport::Deprecation.warn(message)
387:         setup_connection(config)
388:       end

[Source]

     # File lib/active_ldap/base.rb, line 541
541:       def human_name(options={})
542:         defaults = self_and_descendants_from_active_ldap.collect do |klass|
543:           if klass.name.blank?
544:             nil
545:           else
546:             "#{klass.name.underscore}""#{klass.name.underscore}"
547:           end
548:         end
549:         defaults << name.humanize
550:         defaults = defaults.compact
551:         defaults.first || name || to_s
552:       end

Hide new in Base

[Source]

     # File lib/active_ldap/base.rb, line 334
334:       def inherited(sub_class)
335:         super
336:         sub_class.module_eval do
337:           include GetTextSupport
338:         end
339:       end

[Source]

     # File lib/active_ldap/base.rb, line 479
479:       def inspect
480:         if self == Base
481:           super
482:         elsif abstract_class?
483:           "#{super}(abstract)"
484:         else
485:           detail = nil
486:           begin
487:             must = []
488:             may = []
489:             class_names = classes.collect do |object_class|
490:               must.concat(object_class.must)
491:               may.concat(object_class.may)
492:               object_class.name
493:             end
494:             detail = ["objectClass:<#{class_names.join(', ')}>",
495:                       "must:<#{inspect_attributes(must)}>",
496:                       "may:<#{inspect_attributes(may)}>"].join(", ")
497:           rescue ActiveLdap::ConnectionNotSetup
498:             detail = "not-connected"
499:           rescue ActiveLdap::Error
500:             detail = "connection-failure"
501:           end
502:           "#{super}(#{detail})"
503:         end
504:       end

This class function is used to setup all mappings between the subclass and ldap for use in activeldap

Example:

  ldap_mapping :dn_attribute => 'uid', :prefix => 'ou=People',
               :classes => ['top', 'posixAccount'],
               :scope => :sub

[Source]

     # File lib/active_ldap/base.rb, line 407
407:       def ldap_mapping(options={})
408:         options = options.symbolize_keys
409:         validate_ldap_mapping_options(options)
410: 
411:         self.dn_attribute = options[:dn_attribute] || default_dn_attribute
412:         self.dn_attribute = dn_attribute.to_s if dn_attribute.is_a?(Symbol)
413:         self.prefix = options[:prefix] || default_prefix
414:         self.scope = options[:scope]
415:         self.required_classes = options[:classes]
416:         self.recommended_classes = options[:recommended_classes]
417:         self.excluded_classes = options[:excluded_classes]
418:         self.sort_by = options[:sort_by]
419:         self.order = options[:order]
420: 
421:         public_class_method :new
422:       end

new

Creates a new instance of Base initializing all class and all initialization. Defines local defaults. See examples If multiple values exist for dn_attribute, the first one put here will be authoritative

[Source]

     # File lib/active_ldap/base.rb, line 671
671:     def initialize(attributes=nil)
672:       init_base
673:       @new_entry = true
674:       initial_classes = required_classes | recommended_classes
675:       case attributes
676:       when nil
677:         self.classes = initial_classes
678:       when String, Array, DN
679:         self.classes = initial_classes
680:         self.dn = attributes
681:       when Hash
682:         classes, attributes = extract_object_class(attributes)
683:         self.classes = classes | initial_classes
684:         normalized_attributes = {}
685:         attributes.each do |key, value|
686:           real_key = to_real_attribute_name(key) || key
687:           normalized_attributes[real_key] = value
688:         end
689:         self.dn = normalized_attributes.delete(dn_attribute)
690:         self.attributes = normalized_attributes
691:       else
692:         format = _("'%s' must be either nil, DN value as ActiveLdap::DN, " \
693:                    "String or Array or attributes as Hash")
694:         raise ArgumentError, format % attributes.inspect
695:       end
696:       yield self if block_given?
697:     end

[Source]

     # File lib/active_ldap/base.rb, line 444
444:       def prefix
445:         @prefix ||= inheritable_prefix and DN.parse(inheritable_prefix)
446:       end

[Source]

     # File lib/active_ldap/base.rb, line 448
448:       def prefix=(value)
449:         self.inheritable_prefix = value
450:         @prefix = nil
451:         @base = nil
452:       end

[Source]

     # File lib/active_ldap/base.rb, line 455
455:       def scope=(scope)
456:         validate_scope(scope)
457:         self.scope_without_validation = scope
458:       end

[Source]

     # File lib/active_ldap/base.rb, line 522
522:       def self_and_descendants_from_active_ldap
523:         klass = self
524:         classes = [klass]
525:         while klass != klass.base_class
526:           classes << klass = klass.superclass
527:         end
528:         classes
529:       rescue
530:         [self]
531:       end

Connect and bind to LDAP creating a class variable for use by all ActiveLdap objects.

config

config must be a hash that may contain any of the following fields: :password_block, :logger, :host, :port, :base, :bind_dn, :try_sasl, :allow_anonymous :bind_dn specifies the DN to bind with. :password_block specifies a Proc object that will yield a String to

  be used as the password when called.

:logger specifies a logger object (Logger, Log4r::Logger and s on) :host sets the LDAP server hostname :port sets the LDAP server port :base overwrites Base.base - this affects EVERYTHING :try_sasl indicates that a SASL bind should be attempted when binding

  to the server (default: false)

:sasl_mechanisms is an array of SASL mechanism to try

  (default: ["GSSAPI", "CRAM-MD5", "EXTERNAL"])

:allow_anonymous indicates that a true anonymous bind is allowed when

  trying to bind to the server (default: true)

:retries - indicates the number of attempts to reconnect that will be

  undertaken when a stale connection occurs. -1 means infinite.

:sasl_quiet - if true, sets @sasl_quiet on the Ruby/LDAP connection :method - whether to use :ssl, :tls, or :plain (unencrypted) :retry_wait - seconds to wait before retrying a connection :scope - dictates how to find objects. ONELEVEL by default to

  avoid dn_attr collisions across OUs. Think before changing.

:timeout - time in seconds - defaults to disabled. This CAN interrupt

  search() requests. Be warned.

:retry_on_timeout - whether to reconnect when timeouts occur. Defaults

  to true

See lib/active_ldap/configuration.rb for defaults for each option

[Source]

     # File lib/active_ldap/base.rb, line 373
373:       def setup_connection(config=nil)
374:         super
375:         ensure_logger
376:         nil
377:       end

[Source]

     # File lib/active_ldap/base.rb, line 460
460:       def validate_scope(scope)
461:         scope = scope.to_sym if scope.is_a?(String)
462:         return if scope.nil? or scope.is_a?(Symbol)
463:         raise ConfigurationError,
464:                 _("scope '%s' must be a Symbol") % scope.inspect
465:       end

Private Class methods

[Source]

     # File lib/active_ldap/base.rb, line 634
634:       def compute_base
635:         _base = inheritable_base
636:         _base = configuration[:base] if _base.nil? and configuration
637:         if _base.nil?
638:           target = superclass
639:           loop do
640:             break unless target.respond_to?(:base)
641:             _base = target.base
642:             break if _base
643:             target = target.superclass
644:           end
645:         end
646:         _prefix = prefix
647: 
648:         _base ||= connection.naming_contexts.first
649:         return _prefix if _base.blank?
650: 
651:         _base = DN.parse(_base)
652:         _base = _prefix + _base if _prefix
653:         _base
654:       end

[Source]

     # File lib/active_ldap/base.rb, line 617
617:       def default_dn_attribute
618:         dn_attribute = nil
619:         parent_class = ancestors[1]
620:         if parent_class.respond_to?(:dn_attribute)
621:           dn_attribute = parent_class.dn_attribute
622:         end
623:         dn_attribute || "cn"
624:       end

[Source]

     # File lib/active_ldap/base.rb, line 626
626:       def default_prefix
627:         if name.blank?
628:           nil
629:         else
630:           "ou=#{name.demodulize.pluralize}"
631:         end
632:       end

[Source]

     # File lib/active_ldap/base.rb, line 585
585:       def ensure_logger
586:         @@logger ||= configuration[:logger]
587:         # Setup default logger to console
588:         if @@logger.nil?
589:           require 'logger'
590:           @@logger = Logger.new(STDERR)
591:           @@logger.progname = 'ActiveLdap'
592:           @@logger.level = Logger::ERROR
593:         end
594:         configuration[:logger] ||= @@logger
595:       end

[Source]

     # File lib/active_ldap/base.rb, line 567
567:       def inspect_attribute(attribute)
568:         syntax = attribute.syntax
569:         result = "#{attribute.name}"
570:         if syntax and !syntax.description.blank?
571:           result << ": #{syntax.description}"
572:         end
573:         properties = []
574:         properties << "read-only" if attribute.read_only?
575:         properties << "binary" if attribute.binary?
576:         properties << "binary-required" if attribute.binary_required?
577:         result << "(#{properties.join(', ')})" unless properties.empty?
578:         result
579:       end

[Source]

     # File lib/active_ldap/base.rb, line 555
555:       def inspect_attributes(attributes)
556:         inspected_attribute_names = {}
557:         attributes.collect do |attribute|
558:           if inspected_attribute_names.has_key?(attribute.name)
559:             nil
560:           else
561:             inspected_attribute_names[attribute.name] = true
562:             inspect_attribute(attribute)
563:           end
564:         end.compact.join(', ')
565:       end

[Source]

     # File lib/active_ldap/base.rb, line 597
597:       def instantiate(args)
598:         dn, attributes, options = args
599:         options ||= {}
600:         if self.class == Class
601:           klass = self.ancestors[0].to_s.split(':').last
602:           real_klass = self.ancestors[0]
603:         else
604:           klass = self.class.to_s.split(':').last
605:           real_klass = self.class
606:         end
607: 
608:         obj = real_klass.allocate
609:         conn = options[:connection] || connection
610:         obj.connection = conn if conn != connection
611:         obj.instance_eval do
612:           initialize_by_ldap_data(dn, attributes)
613:         end
614:         obj
615:       end

[Source]

     # File lib/active_ldap/base.rb, line 581
581:       def validate_ldap_mapping_options(options)
582:         options.assert_valid_keys(VALID_LDAP_MAPPING_OPTIONS)
583:       end

Public Instance methods

Returns true if the comparison_object is the same object, or is of the same type and has the same dn.

[Source]

     # File lib/active_ldap/base.rb, line 701
701:     def ==(comparison_object)
702:       comparison_object.equal?(self) or
703:         (comparison_object.instance_of?(self.class) and
704:          comparison_object.dn == dn and
705:          !comparison_object.new_entry?)
706:     end

[Source]

     # File lib/active_ldap/base.rb, line 984
984:     def [](name, force_array=false)
985:       if name == "dn"
986:         array_of(dn, force_array)
987:       else
988:         get_attribute(name, force_array)
989:       end
990:     end

[Source]

     # File lib/active_ldap/base.rb, line 992
992:     def []=(name, value)
993:       set_attribute(name, value)
994:     end

attributes

Return attribute methods so that a program can determine available attributes dynamically without schema awareness

[Source]

     # File lib/active_ldap/base.rb, line 743
743:     def attribute_names(normalize=false)
744:       entry_attribute.names(normalize)
745:     end

[Source]

     # File lib/active_ldap/base.rb, line 747
747:     def attribute_present?(name)
748:       values = get_attribute(name, true)
749:       !values.empty? or values.any? {|x| !(x and x.empty?)}
750:     end

This returns the key value pairs in @data with all values cloned

[Source]

     # File lib/active_ldap/base.rb, line 904
904:     def attributes
905:       @simplified_data ||= simplify_data(@data)
906:       @simplified_data.clone
907:     end

This allows a bulk update to the attributes of a record without forcing an immediate save or validation.

It is unwise to attempt objectClass updates this way. Also be sure to only pass in key-value pairs of your choosing. Do not let URL/form hackers supply the keys.

[Source]

     # File lib/active_ldap/base.rb, line 915
915:     def attributes=(new_attributes)
916:       return if new_attributes.blank?
917:       _schema = _local_entry_attribute = nil
918:       targets = remove_attributes_protected_from_mass_assignment(new_attributes)
919:       targets.each do |key, value|
920:         setter = "#{key}="
921:         unless respond_to?(setter)
922:           _schema ||= schema
923:           attribute = _schema.attribute(key)
924:           next if attribute.id.nil?
925:           _local_entry_attribute ||= local_entry_attribute
926:           _local_entry_attribute.register(attribute)
927:         end
928:         send(setter, value)
929:       end
930:     end

[Source]

      # File lib/active_ldap/base.rb, line 1042
1042:     def base
1043:       @base ||= compute_base
1044:     end

[Source]

      # File lib/active_ldap/base.rb, line 1046
1046:     def base=(object_local_base)
1047:       ensure_update_dn
1048:       @dn = nil
1049:       @base = nil
1050:       @base_value = object_local_base
1051:     end

[Source]

      # File lib/active_ldap/base.rb, line 1002
1002:     def bind(config_or_password={}, config_or_ignore=nil, &block)
1003:       if config_or_password.is_a?(String)
1004:         config = (config_or_ignore || {}).merge(:password => config_or_password)
1005:       else
1006:         config = config_or_password
1007:       end
1008:       config = {:bind_dn => dn, :allow_anonymous => false}.merge(config)
1009:       config[:password_block] ||= block if block_given?
1010:       setup_connection(config)
1011: 
1012:       before_connection = @connection
1013:       begin
1014:         @connection = nil
1015:         connection.connect
1016:         @connection = connection
1017:         clear_connection_based_cache
1018:         clear_association_cache
1019:       rescue ActiveLdap::Error
1020:         remove_connection
1021:         @connection = before_connection
1022:         raise
1023:       end
1024:       true
1025:     end

[Source]

      # File lib/active_ldap/base.rb, line 1027
1027:     def clear_connection_based_cache
1028:       @schema = nil
1029:       @local_entry_attribute = nil
1030:       clear_object_class_based_cache
1031:     end

[Source]

      # File lib/active_ldap/base.rb, line 1033
1033:     def clear_object_class_based_cache
1034:       @entry_attribute = nil
1035:       @real_names = {}
1036:     end

[Source]

     # File lib/active_ldap/base.rb, line 794
794:     def default_search_attribute
795:       self.class.default_search_attribute
796:     end

[Source]

     # File lib/active_ldap/base.rb, line 806
806:     def delete(options={})
807:       super(dn, options)
808:     end

[Source]

      # File lib/active_ldap/base.rb, line 1063
1063:     def delete_all(options={})
1064:       super({:base => dn}.merge(options || {}))
1065:     end

destroy

Delete this entry from LDAP

[Source]

     # File lib/active_ldap/base.rb, line 801
801:     def destroy
802:       self.class.delete(dn)
803:       @new_entry = true
804:     end

[Source]

      # File lib/active_ldap/base.rb, line 1067
1067:     def destroy_all(options={})
1068:       super({:base => dn}.merge(options || {}))
1069:     end

dn

Return the authoritative dn

[Source]

     # File lib/active_ldap/base.rb, line 770
770:     def dn
771:       @dn ||= compute_dn
772:     end

[Source]

     # File lib/active_ldap/base.rb, line 782
782:     def dn=(value)
783:       set_attribute(dn_attribute_with_fallback, value)
784:     end

[Source]

     # File lib/active_ldap/base.rb, line 788
788:     def dn_attribute
789:       ensure_update_dn
790:       _dn_attribute = @dn_attribute || dn_attribute_of_class
791:       to_real_attribute_name(_dn_attribute) || _dn_attribute
792:     end

[Source]

      # File lib/active_ldap/base.rb, line 996
 996:     def each
 997:       @data.each do |key, values|
 998:         yield(key.dup, values.dup)
 999:       end
1000:     end

Delegates to ==

[Source]

     # File lib/active_ldap/base.rb, line 709
709:     def eql?(comparison_object)
710:       self == (comparison_object)
711:     end

exist?

Return whether the entry exists in LDAP or not

[Source]

     # File lib/active_ldap/base.rb, line 755
755:     def exist?
756:       self.class.exists?(dn)
757:     end
exists?()

Alias for exist?

has_attribute?(name, except=[])

Alias for have_attribute?

Delegates to id in order to allow two records of the same type and id to work with something like:

  [ User.find("a"), User.find("b"), User.find("c") ] &
    [ User.find("a"), User.find("d") ] # => [ User.find("a") ]

[Source]

     # File lib/active_ldap/base.rb, line 717
717:     def hash
718:       return super if @_hashing # workaround for GetText :<
719:       _dn = nil
720:       begin
721:         @_hashing = true
722:         _dn = dn
723:       rescue DistinguishedNameInvalid, DistinguishedNameNotSetError
724:         return super
725:       ensure
726:         @_hashing = false
727:       end
728:       _dn.hash
729:     end

[Source]

     # File lib/active_ldap/base.rb, line 961
961:     def have_attribute?(name, except=[])
962:       real_name = to_real_attribute_name(name)
963:       !real_name.nil? and !except.include?(real_name)
964:     end

[Source]

     # File lib/active_ldap/base.rb, line 774
774:     def id
775:       get_attribute(dn_attribute_with_fallback)
776:     end
id=(value)

Alias for dn=

[Source]

      # File lib/active_ldap/base.rb, line 1071
1071:     def inspect
1072:       object_classes = entry_attribute.object_classes
1073:       inspected_object_classes = object_classes.collect do |object_class|
1074:         object_class.name
1075:       end.join(', ')
1076:       must_attributes = must.collect(&:name).sort.join(', ')
1077:       may_attributes = may.collect(&:name).sort.join(', ')
1078:       inspected_attributes = attribute_names.sort.collect do |name|
1079:         inspect_attribute(name)
1080:       end.join(', ')
1081:       result = "\#<#{self.class} objectClass:<#{inspected_object_classes}>, "
1082:       result << "must:<#{must_attributes}>, may:<#{may_attributes}>, "
1083:       result << "#{inspected_attributes}>"
1084:       result
1085:     end

[Source]

     # File lib/active_ldap/base.rb, line 731
731:     def may
732:       entry_attribute.may
733:     end

method_missing

If a given method matches an attribute or an attribute alias then call the appropriate method. TODO: Determine if it would be better to define each allowed method

      using class_eval instead of using method_missing.  This would
      give tab completion in irb.

[Source]

     # File lib/active_ldap/base.rb, line 832
832:     def method_missing(name, *args, &block)
833:       key = name.to_s
834:       case key
835:       when /=$/
836:         real_key = $PREMATCH
837:         if have_attribute?(real_key, ['objectClass'])
838:           if args.size != 1
839:             raise ArgumentError,
840:                     _("wrong number of arguments (%d for 1)") % args.size
841:           end
842:           return set_attribute(real_key, *args, &block)
843:         end
844:       when /(?:(_before_type_cast)|(\?))?$/
845:         real_key = $PREMATCH
846:         before_type_cast = !$1.nil?
847:         query = !$2.nil?
848:         if have_attribute?(real_key, ['objectClass'])
849:           if args.size > 1
850:             raise ArgumentError,
851:               _("wrong number of arguments (%d for 1)") % args.size
852:           end
853:           if before_type_cast
854:             return get_attribute_before_type_cast(real_key, *args)[1]
855:           elsif query
856:             return get_attribute_as_query(real_key, *args)
857:           else
858:             return get_attribute(real_key, *args)
859:           end
860:         end
861:       end
862:       super
863:     end

Add available attributes to the methods

[Source]

     # File lib/active_ldap/base.rb, line 866
866:     def methods(inherited_too=true)
867:       target_names = entry_attribute.all_names
868:       target_names -= ['objectClass', 'objectClass'.underscore]
869:       super + target_names.uniq.collect do |x|
870:         [x, "#{x}=", "#{x}?", "#{x}_before_type_cast"]
871:       end.flatten
872:     end

[Source]

     # File lib/active_ldap/base.rb, line 735
735:     def must
736:       entry_attribute.must
737:     end

new_entry?

Return whether the entry is new entry in LDAP or not

[Source]

     # File lib/active_ldap/base.rb, line 763
763:     def new_entry?
764:       @new_entry
765:     end

[Source]

     # File lib/active_ldap/base.rb, line 967
967:     def reload
968:       clear_association_cache
969:       _, attributes = search(:value => id).find do |_dn, _attributes|
970:         dn == _dn
971:       end
972:       if attributes.nil?
973:         raise EntryNotFound, _("Can't find DN '%s' to reload") % dn
974:       end
975: 
976:       @ldap_data.update(attributes)
977:       classes, attributes = extract_object_class(attributes)
978:       self.classes = classes
979:       self.attributes = attributes
980:       @new_entry = false
981:       self
982:     end

[Source]

     # File lib/active_ldap/base.rb, line 875
875:     def respond_to?(name, include_priv=false)
876:       return true if super
877: 
878:       name = name.to_s
879:       return true if have_attribute?(name, ["objectClass"])
880:       return false if /(?:=|\?|_before_type_cast)$/ !~ name
881:       have_attribute?($PREMATCH, ["objectClass"])
882:     end

save

Save and validate this object into LDAP either adding or replacing attributes TODO: Relative DN support

[Source]

     # File lib/active_ldap/base.rb, line 815
815:     def save
816:       create_or_update
817:     end

[Source]

     # File lib/active_ldap/base.rb, line 819
819:     def save!
820:       unless create_or_update
821:         raise EntryNotSaved, _("entry %s can't be saved") % dn
822:       end
823:     end

[Source]

      # File lib/active_ldap/base.rb, line 1038
1038:     def schema
1039:       @schema ||= super
1040:     end

[Source]

      # File lib/active_ldap/base.rb, line 1054
1054:     def scope
1055:       @scope || scope_of_class
1056:     end

[Source]

      # File lib/active_ldap/base.rb, line 1058
1058:     def scope=(scope)
1059:       self.class.validate_scope(scope)
1060:       @scope = scope
1061:     end

[Source]

     # File lib/active_ldap/base.rb, line 936
936:     def to_ldif
937:       Ldif.new([to_ldif_record]).to_s
938:     end

[Source]

     # File lib/active_ldap/base.rb, line 932
932:     def to_ldif_record
933:       super(dn, normalize_data(@data))
934:     end

[Source]

     # File lib/active_ldap/base.rb, line 778
778:     def to_param
779:       id
780:     end

[Source]

     # File lib/active_ldap/base.rb, line 957
957:     def to_s
958:       to_ldif
959:     end

[Source]

     # File lib/active_ldap/base.rb, line 940
940:     def to_xml(options={})
941:       options = options.dup
942:       options[:root] ||= (self.class.name || '').underscore
943:       options[:root] = 'anonymous' if options[:root].blank?
944:       except = options[:except]
945:       if except
946:         options[:except] = except.collect do |name|
947:           if name.to_s.downcase == "dn"
948:             "dn"
949:           else
950:             to_real_attribute_name(name)
951:           end
952:         end.compact
953:       end
954:       XML.new(dn, normalize_data(@data), schema).to_s(options)
955:     end

Updates a given attribute and saves immediately

[Source]

     # File lib/active_ldap/base.rb, line 885
885:     def update_attribute(name, value)
886:       send("#{name}=", value)
887:       save
888:     end

This performs a bulk update of attributes and immediately calls save.

[Source]

     # File lib/active_ldap/base.rb, line 892
892:     def update_attributes(attrs)
893:       self.attributes = attrs
894:       save
895:     end

[Source]

     # File lib/active_ldap/base.rb, line 897
897:     def update_attributes!(attrs)
898:       self.attributes = attrs
899:       save!
900:     end

Private Instance methods

array_of

Returns the array form of a value, or not an array if false is passed in.

[Source]

      # File lib/active_ldap/base.rb, line 1414
1414:     def array_of(value, to_a=true)
1415:       case value
1416:       when Array
1417:         if to_a or value.size > 1
1418:           value.collect {|v| array_of(v, false)}.compact
1419:         else
1420:           if value.empty?
1421:             nil
1422:           else
1423:             array_of(value.first, to_a)
1424:           end
1425:         end
1426:       when Hash
1427:         if to_a
1428:           [value]
1429:         else
1430:           result = {}
1431:           value.each {|k, v| result[k] = array_of(v, to_a)}
1432:           result
1433:         end
1434:       else
1435:         to_a ? [value] : value
1436:       end
1437:     end

[Source]

      # File lib/active_ldap/base.rb, line 1117
1117:     def attribute_name_resolvable_without_connection?
1118:       @entry_attribute and @local_entry_attribute
1119:     end

[Source]

      # File lib/active_ldap/base.rb, line 1511
1511:     def collect_all_attributes(data)
1512:       dn_attr = dn_attribute
1513:       dn_value = data[dn_attr]
1514: 
1515:       attributes = []
1516:       attributes.push([dn_attr, dn_value])
1517: 
1518:       oc_value = data['objectClass']
1519:       attributes.push(['objectClass', oc_value])
1520:       except_keys = ['objectClass', dn_attr].collect(&:downcase)
1521:       data.each do |key, value|
1522:         next if except_keys.include?(key.downcase)
1523:         value = self.class.remove_blank_value(value)
1524:         next if self.class.blank_value?(value)
1525: 
1526:         attributes.push([key, value])
1527:       end
1528: 
1529:       attributes
1530:     end

[Source]

      # File lib/active_ldap/base.rb, line 1467
1467:     def collect_modified_attributes(ldap_data, data)
1468:       klass = self.class
1469:       _dn_attribute = dn_attribute
1470:       new_dn_value = nil
1471:       attributes = []
1472: 
1473:       # Now that all the options will be treated as unique attributes
1474:       # we can see what's changed and add anything that is brand-spankin'
1475:       # new.
1476:       ldap_data.each do |k, v|
1477:         value = data[k] || []
1478: 
1479:         next if v == value
1480: 
1481:         value = klass.remove_blank_value(value) || []
1482:         next if v == value
1483: 
1484:         if klass.blank_value?(value) and
1485:             schema.attribute(k).binary_required?
1486:           value = [{'binary' => []}]
1487:         end
1488:         if k == _dn_attribute
1489:           new_dn_value = value[0]
1490:         else
1491:           attributes.push([:replace, k, value])
1492:         end
1493:       end
1494: 
1495:       data.each do |k, v|
1496:         value = v || []
1497:         next if ldap_data.has_key?(k)
1498: 
1499:         value = klass.remove_blank_value(value) || []
1500:         next if klass.blank_value?(value)
1501: 
1502:         # Detect subtypes and account for them
1503:         # REPLACE will function like ADD, but doesn't hit EQUALITY problems
1504:         # TODO: Added equality(attr) to Schema
1505:         attributes.push([:replace, k, value])
1506:       end
1507: 
1508:       [new_dn_value, attributes]
1509:     end

[Source]

      # File lib/active_ldap/base.rb, line 1399
1399:     def compute_base
1400:       base_of_class = self.class.base
1401:       if @base_value.nil?
1402:         base_of_class
1403:       else
1404:         base_of_object = DN.parse(@base_value)
1405:         base_of_object += base_of_class if base_of_class
1406:         base_of_object
1407:       end
1408:     end

[Source]

      # File lib/active_ldap/base.rb, line 1383
1383:     def compute_dn
1384:       return base if @dn_is_base
1385: 
1386:       ensure_update_dn
1387:       dn_value = id
1388:       if dn_value.nil?
1389:         format = _("%s's DN attribute (%s) isn't set")
1390:         message = format % [self.inspect, dn_attribute]
1391:         raise DistinguishedNameNotSetError.new, message
1392:       end
1393:       dn_value = DN.escape_value(dn_value.to_s)
1394:       _base = base
1395:       _base = nil if _base.blank?
1396:       DN.parse(["#{dn_attribute}=#{dn_value}", _base].compact.join(","))
1397:     end

[Source]

      # File lib/active_ldap/base.rb, line 1564
1564:     def create
1565:       prepare_data_for_saving do |data, ldap_data|
1566:         attributes = collect_all_attributes(data)
1567:         add_entry(dn, attributes)
1568:         @new_entry = false
1569:         true
1570:       end
1571:     end

[Source]

      # File lib/active_ldap/base.rb, line 1532
1532:     def create_or_update
1533:       new_entry? ? create : update
1534:     end

[Source]

      # File lib/active_ldap/base.rb, line 1088
1088:     def dn_attribute_with_fallback
1089:       begin
1090:         dn_attribute
1091:       rescue DistinguishedNameInvalid
1092:         _dn_attribute = @dn_attribute || dn_attribute_of_class
1093:         _dn_attribute = to_real_attribute_name(_dn_attribute) || _dn_attribute
1094:         raise if _dn_attribute.nil?
1095:         _dn_attribute
1096:       end
1097:     end

enforce_type

enforce_type applies your changes without attempting to write to LDAP. This means that if you set userCertificate to somebinary value, it will wrap it up correctly.

[Source]

      # File lib/active_ldap/base.rb, line 1195
1195:     def enforce_type(key, value)
1196:       # Enforce attribute value formatting
1197:       normalize_attribute(key, value)[1]
1198:     end

[Source]

      # File lib/active_ldap/base.rb, line 1373
1373:     def ensure_update_dn
1374:       return unless need_update_dn?
1375:       @mutex.synchronize do
1376:         if @dn_split_value
1377:           update_dn(*@dn_split_value)
1378:           @dn_split_value = nil
1379:         end
1380:       end
1381:     end

[Source]

      # File lib/active_ldap/base.rb, line 1121
1121:     def entry_attribute
1122:       @entry_attribute ||=
1123:         connection.entry_attribute(find_object_class_values(@data) || [])
1124:     end

[Source]

      # File lib/active_ldap/base.rb, line 1130
1130:     def extract_object_class(attributes)
1131:       classes = []
1132:       attrs = {}
1133:       attributes.each do |key, value|
1134:         key = key.to_s
1135:         if /\Aobject_?class\z/i =~ key
1136:           classes.concat(value.to_a)
1137:         else
1138:           attrs[key] = value
1139:         end
1140:       end
1141:       [classes, attributes]
1142:     end

[Source]

      # File lib/active_ldap/base.rb, line 1263
1263:     def false_value?(value)
1264:       value.nil? or value == false or value == [] or
1265:         value == "false" or value == "FALSE" or value == ""
1266:     end

[Source]

      # File lib/active_ldap/base.rb, line 1113
1113:     def find_object_class_values(data)
1114:       data["objectClass"] || data["objectclass"]
1115:     end

get_attribute

Return the value of the attribute called by method_missing?

[Source]

      # File lib/active_ldap/base.rb, line 1218
1218:     def get_attribute(name, force_array=false)
1219:       name, value = get_attribute_before_type_cast(name, force_array)
1220:       return value if name.nil?
1221:       attribute = schema.attribute(name)
1222:       type_cast(attribute, value)
1223:     end

[Source]

      # File lib/active_ldap/base.rb, line 1254
1254:     def get_attribute_as_query(name, force_array=false)
1255:       name, value = get_attribute_before_type_cast(name, force_array)
1256:       if force_array
1257:         value.collect {|x| !false_value?(x)}
1258:       else
1259:         !false_value?(value)
1260:       end
1261:     end

[Source]

      # File lib/active_ldap/base.rb, line 1246
1246:     def get_attribute_before_type_cast(name, force_array=false)
1247:       name = to_real_attribute_name(name)
1248: 
1249:       value = @data[name]
1250:       value = [] if value.nil?
1251:       [name, array_of(value, force_array)]
1252:     end

[Source]

      # File lib/active_ldap/base.rb, line 1144
1144:     def init_base
1145:       init_instance_variables
1146:     end

[Source]

      # File lib/active_ldap/base.rb, line 1200
1200:     def init_instance_variables
1201:       @mutex = Mutex.new
1202:       @data = {} # where the r/w entry data is stored
1203:       @ldap_data = {} # original ldap entry data
1204:       @dn_attribute = nil
1205:       @base = nil
1206:       @scope = nil
1207:       @dn = nil
1208:       @dn_is_base = false
1209:       @dn_split_value = nil
1210:       @connection ||= nil
1211:       @_hashing = false
1212:       clear_connection_based_cache
1213:     end

[Source]

      # File lib/active_ldap/base.rb, line 1148
1148:     def initialize_by_ldap_data(dn, attributes)
1149:       init_base
1150:       dn = Compatible.convert_to_utf8_encoded_object(dn)
1151:       attributes = Compatible.convert_to_utf8_encoded_object(attributes)
1152:       @original_dn = dn.clone
1153:       @dn = dn
1154:       @base = nil
1155:       @base_value = nil
1156:       @new_entry = false
1157:       @dn_is_base = false
1158:       @ldap_data = attributes
1159:       classes, attributes = extract_object_class(attributes)
1160:       self.classes = classes
1161:       self.dn = dn
1162:       self.attributes = attributes
1163:       yield self if block_given?
1164:     end

[Source]

      # File lib/active_ldap/base.rb, line 1099
1099:     def inspect_attribute(name)
1100:       values = get_attribute(name, true)
1101:       values.collect do |value|
1102:         if value.is_a?(String) and value.length > 50
1103:           "#{value[0, 50]}...".inspect
1104:         elsif value.is_a?(Date) || value.is_a?(Time)
1105:           "#{value.to_s(:db)}"
1106:         else
1107:           value.inspect
1108:         end
1109:       end
1110:       "#{name}: #{values.inspect}"
1111:     end

[Source]

      # File lib/active_ldap/base.rb, line 1166
1166:     def instantiate(args)
1167:       dn, attributes, options = args
1168:       options ||= {}
1169: 
1170:       obj = self.class.allocate
1171:       obj.connection = options[:connection] || @connection
1172:       obj.instance_eval do
1173:         initialize_by_ldap_data(dn, attributes)
1174:       end
1175:       obj
1176:     end

[Source]

      # File lib/active_ldap/base.rb, line 1126
1126:     def local_entry_attribute
1127:       @local_entry_attribute ||= connection.entry_attribute([])
1128:     end

[Source]

      # File lib/active_ldap/base.rb, line 1369
1369:     def need_update_dn?
1370:       not @dn_split_value.nil?
1371:     end

[Source]

      # File lib/active_ldap/base.rb, line 1439
1439:     def normalize_data(data, except=[])
1440:       _schema = schema
1441:       result = {}
1442:       data.each do |key, values|
1443:         next if except.include?(key)
1444:         real_name = to_real_attribute_name(key)
1445:         next if real_name and except.include?(real_name)
1446:         real_name ||= key
1447:         next if _schema.attribute(real_name).id.nil?
1448:         result[real_name] ||= []
1449:         result[real_name].concat(enforce_type(real_name, values))
1450:       end
1451:       result
1452:     end

[Source]

      # File lib/active_ldap/base.rb, line 1536
1536:     def prepare_data_for_saving
1537:       # Expand subtypes to real ldap_data attributes
1538:       # We can't reuse @ldap_data because an exception would leave
1539:       # an object in an unknown state
1540:       ldap_data = normalize_data(@ldap_data)
1541: 
1542:       # Expand subtypes to real data attributes, but leave @data alone
1543:       object_classes = find_object_class_values(@ldap_data) || []
1544:       original_attributes =
1545:         connection.entry_attribute(object_classes).names
1546:       bad_attrs = original_attributes - entry_attribute.names
1547:       data = normalize_data(@data, bad_attrs)
1548: 
1549:       success = yield(data, ldap_data)
1550: 
1551:       if success
1552:         @ldap_data = data.clone
1553:         # Delete items disallowed by objectclasses.
1554:         # They should have been removed from ldap.
1555:         bad_attrs.each do |remove_me|
1556:           @ldap_data.delete(remove_me)
1557:         end
1558:         @original_dn = dn.clone
1559:       end
1560: 
1561:       success
1562:     end

[Source]

      # File lib/active_ldap/base.rb, line 1289
1289:     def register_new_dn_attribute(name, value)
1290:       @dn = nil
1291:       @dn_is_base = false
1292:       if value.blank?
1293:         @dn_split_value = nil
1294:         [name, nil]
1295:       else
1296:         new_name, new_value, raw_new_value, new_bases = split_dn_value(value)
1297:         @dn_split_value = [new_name, new_value, new_bases]
1298:         if new_name.nil? and new_value.nil?
1299:           new_name, raw_new_value = new_bases[0].to_a[0]
1300:         end
1301:         [to_real_attribute_name(new_name) || name,
1302:          raw_new_value || value]
1303:       end
1304:     end

set_attribute

Set the value of the attribute called by method_missing?

[Source]

      # File lib/active_ldap/base.rb, line 1271
1271:     def set_attribute(name, value)
1272:       real_name = to_real_attribute_name(name)
1273:       _dn_attribute = nil
1274:       valid_dn_attribute = true
1275:       begin
1276:         _dn_attribute = dn_attribute
1277:       rescue DistinguishedNameInvalid
1278:         valid_dn_attribute = false
1279:       end
1280:       if valid_dn_attribute and real_name == _dn_attribute
1281:         real_name, value = register_new_dn_attribute(real_name, value)
1282:       end
1283:       raise UnknownAttribute.new(name) if real_name.nil?
1284: 
1285:       @data[real_name] = value
1286:       @simplified_data = nil
1287:     end

[Source]

      # File lib/active_ldap/base.rb, line 1454
1454:     def simplify_data(data)
1455:       _schema = schema
1456:       result = {}
1457:       data.each do |key, values|
1458:         attribute = _schema.attribute(key)
1459:         if attribute.single_value? and values.is_a?(Array) and values.size == 1
1460:           values = values[0]
1461:         end
1462:         result[key] = type_cast(attribute, values)
1463:       end
1464:       result
1465:     end

[Source]

      # File lib/active_ldap/base.rb, line 1332
1332:     def split_dn_value(value)
1333:       dn_value = relative_dn_value = nil
1334:       begin
1335:         dn_value = value if value.is_a?(DN)
1336:         dn_value ||= DN.parse(value)
1337:       rescue DistinguishedNameInvalid
1338:         begin
1339:           dn_value = DN.parse("#{dn_attribute}=#{value}")
1340:         rescue DistinguishedNameInvalid
1341:           return [nil, value, value, []]
1342:         end
1343:       end
1344: 
1345:       val = bases = nil
1346:       begin
1347:         relative_dn_value = dn_value
1348:         base_of_class = self.class.base
1349:         relative_dn_value -= base_of_class if base_of_class
1350:         if relative_dn_value.rdns.empty?
1351:           val = []
1352:           bases = dn_value.rdns
1353:         else
1354:           val, *bases = relative_dn_value.rdns
1355:         end
1356:       rescue ArgumentError
1357:         val, *bases = dn_value.rdns
1358:       end
1359: 
1360:       dn_attribute_name, dn_attribute_value = val.to_a[0]
1361:       escaped_dn_attribute_value = nil
1362:       unless dn_attribute_value.nil?
1363:         escaped_dn_attribute_value = DN.escape_value(dn_attribute_value)
1364:       end
1365:       [dn_attribute_name, escaped_dn_attribute_value,
1366:        dn_attribute_value, bases]
1367:     end

[Source]

      # File lib/active_ldap/base.rb, line 1178
1178:     def to_real_attribute_name(name, allow_normalized_name=true)
1179:       return name if name.nil?
1180:       if allow_normalized_name
1181:         entry_attribute.normalize(name, allow_normalized_name) ||
1182:           local_entry_attribute.normalize(name, allow_normalized_name)
1183:       else
1184:         @real_names[name] ||=
1185:           entry_attribute.normalize(name, false) ||
1186:           local_entry_attribute.normalize(name, false)
1187:       end
1188:     end

[Source]

      # File lib/active_ldap/base.rb, line 1225
1225:     def type_cast(attribute, value)
1226:       case value
1227:       when Hash
1228:         result = {}
1229:         value.each do |option, val|
1230:           result[option] = type_cast(attribute, val)
1231:         end
1232:         if result.size == 1 and result.has_key?("binary")
1233:           result["binary"]
1234:         else
1235:           result
1236:         end
1237:       when Array
1238:         value.collect do |val|
1239:           type_cast(attribute, val)
1240:         end
1241:       else
1242:         attribute.type_cast(value)
1243:       end
1244:     end

[Source]

      # File lib/active_ldap/base.rb, line 1573
1573:     def update
1574:       prepare_data_for_saving do |data, ldap_data|
1575:         new_dn_value, attributes = collect_modified_attributes(ldap_data, data)
1576:         modify_entry(@original_dn, attributes)
1577:         if new_dn_value
1578:           old_dn_base = DN.parse(@original_dn).parent
1579:           new_dn_base = dn.clone.parent
1580:           if old_dn_base == new_dn_base
1581:             new_superior = nil
1582:           else
1583:             new_superior = new_dn_base
1584:           end
1585:           modify_rdn_entry(@original_dn,
1586:                            "#{dn_attribute}=#{DN.escape_value(new_dn_value)}",
1587:                            true,
1588:                            new_superior)
1589:         end
1590:         true
1591:       end
1592:     end

[Source]

      # File lib/active_ldap/base.rb, line 1306
1306:     def update_dn(new_name, new_value, bases)
1307:       if new_name.nil? and new_value.nil?
1308:         @dn_is_base = true
1309:         @base = nil
1310:         @base_value = nil
1311:         attr, value = bases[0].to_a[0]
1312:         @dn_attribute = attr
1313:       else
1314:         new_name ||= @dn_attribute || dn_attribute_of_class
1315:         new_name = to_real_attribute_name(new_name)
1316:         if new_name.nil?
1317:           new_name = @dn_attribute || dn_attribute_of_class
1318:           new_name = to_real_attribute_name(new_name)
1319:         end
1320:         new_bases = bases.empty? ? nil : DN.new(*bases).to_s
1321:         dn_components = ["#{new_name}=#{new_value}",
1322:                          new_bases,
1323:                          self.class.base.to_s]
1324:         dn_components = dn_components.find_all {|component| !component.blank?}
1325:         DN.parse(dn_components.join(','))
1326:         @base = nil
1327:         @base_value = new_bases
1328:         @dn_attribute = new_name
1329:       end
1330:     end

[Validate]