Class ActiveLdap::Base
In: lib/active_ldap/base.rb
Parent: Object
Error AttributeAssignmentError AdapterNotSpecified OperationNotPermitted RequiredObjectClassMissed ConnectionError RequiredAttributeMissed LdifInvalid DistinguishedNameNotSetError EntryNotFound LdapError 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] Base DistinguishedName Reloadable::Deprecated Reloadable::Subclasses Enumerable Ldif Collection EntryAttribute StandardError Children HasManyWrap HasMany BelongsToMany Proxy BelongsTo Normalizable Common Find LDIF Delete Update ActiveRecord::Callbacks GetText Parser 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 ActiveRecord::Validations Xml JndiConnection lib/active_ldap/distinguished_name.rb lib/active_ldap/base.rb lib/active_ldap/xml.rb lib/active_ldap/schema.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 ClassMethods Normalizable Attributes Update Common ModifyNameRecordLoadable AddOperationModifiable DeleteOperationModifiable ReplaceOperationModifiable ModifyRecordLoadable DeleteRecordLoadable AddRecordLoadable ContentRecordLoadable LDIF Delete Find Operations GetTextSupport Escape ClassMethods Configuration ClassMethods ObjectClass ClassMethods Callbacks lib/active_ldap/get_text/parser.rb GetText lib/active_ldap/adapter/jndi_connection.rb lib/active_ldap/adapter/net_ldap.rb lib/active_ldap/adapter/ldap.rb lib/active_ldap/adapter/base.rb lib/active_ldap/adapter/jndi.rb Adapter Validations GetTextFallback Helper 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]