Class ActiveLdap::Base
In: lib/active_ldap/base.rb
Parent: Object
Error AttributeAssignmentError AdapterNotSpecified OperationNotPermitted RequiredObjectClassMissed ConnectionError RequiredAttributeMissed LdifInvalid LdapError DistinguishedNameNotSetError EntryNotFound SaveError StrongAuthenticationRequired 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 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/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 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 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_dn   create   create   create_or_update   default_dn_attribute   default_prefix   default_search_attribute   default_search_attribute   delete   destroy   dn   dn=   dn_attribute   dn_attribute_with_fallback   each   enforce_type   ensure_logger   ensure_update_dn   entry_attribute   eql?   escaped_dn   establish_connection   exist?   exists?   extract_object_class   false_value?   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   parsed_base   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   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 -> base_inheritable
base= -> base_without_parsed_cache_clear=
scope= -> scope_without_validation=
dn_attribute -> dn_attribute_of_class
respond_to? -> respond_to_without_attributes?
base -> base_of_class
scope -> scope_of_class

Attributes

abstract_class  [RW] 

Public Class methods

[Source]

     # File lib/active_ldap/base.rb, line 493
493:       def abstract_class?
494:         defined?(@abstract_class) && @abstract_class
495:       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 427
427:       def base
428:         _base = base_inheritable
429:         _base = configuration[:base] if _base.nil? and configuration
430:         _base ||= base_inheritable(true)
431:         [prefix, _base].find_all do |component|
432:           !component.blank?
433:         end.join(",")
434:       end

[Source]

     # File lib/active_ldap/base.rb, line 437
437:       def base=(value)
438:         self.base_without_parsed_cache_clear = value
439:         @parsed_base = nil
440:       end

[Source]

     # File lib/active_ldap/base.rb, line 459
459:       def base_class
460:         if self == Base or superclass == Base
461:           self
462:         else
463:           superclass.base_class
464:         end
465:       end

[Source]

     # File lib/active_ldap/base.rb, line 290
290:     def self.class_local_attr_accessor(search_ancestors, *syms)
291:       syms.flatten.each do |sym|
292:         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)
293:       end
294:     end

[Source]

     # File lib/active_ldap/base.rb, line 497
497:       def class_of_active_ldap_descendant(klass)
498:         if klass.superclass == Base or klass.superclass.abstract_class?
499:           klass
500:         elsif klass.superclass.nil?
501:           raise Error, _("%s doesn't belong in a hierarchy descending " \
502:                          "from ActiveLdap") % (name || to_s)
503:         else
504:           class_of_active_ldap_descendant(klass.superclass)
505:         end
506:       end

[Source]

     # File lib/active_ldap/base.rb, line 382
382:       def create(attributes=nil, &block)
383:         if attributes.is_a?(Array)
384:           attributes.collect {|attrs| create(attrs, &block)}
385:         else
386:           object = new(attributes, &block)
387:           object.save
388:           object
389:         end
390:       end

[Source]

     # File lib/active_ldap/base.rb, line 467
467:       def default_search_attribute
468:         dn_attribute
469:       end

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

[Source]

     # File lib/active_ldap/base.rb, line 373
373:       def establish_connection(config=nil)
374:         message =
375:           _("ActiveLdap::Base.establish_connection has been deprecated " \
376:             "since 1.1.0. " \
377:             "Please use ActiveLdap::Base.setup_connection instead.")
378:         ActiveSupport::Deprecation.warn(message)
379:         setup_connection(config)
380:       end

[Source]

     # File lib/active_ldap/base.rb, line 527
527:       def human_name(options={})
528:         defaults = self_and_descendants_from_active_ldap.collect do |klass|
529:           if klass.name.blank?
530:             nil
531:           else
532:             "#{klass.name.underscore}""#{klass.name.underscore}"
533:           end
534:         end
535:         defaults << name.humanize
536:         defaults = defaults.compact
537:         defaults.first || name || to_s
538:       end

Hide new in Base

[Source]

     # File lib/active_ldap/base.rb, line 326
326:       def inherited(sub_class)
327:         super
328:         sub_class.module_eval do
329:           include GetTextSupport
330:         end
331:       end

[Source]

     # File lib/active_ldap/base.rb, line 471
471:       def inspect
472:         if self == Base
473:           super
474:         elsif abstract_class?
475:           "#{super}(abstract)"
476:         else
477:           class_names = []
478:           must = []
479:           may = []
480:           class_names = classes.collect do |object_class|
481:             must.concat(object_class.must)
482:             may.concat(object_class.may)
483:             object_class.name
484:           end
485:           detail = ["objectClass:<#{class_names.join(', ')}>",
486:                     "must:<#{inspect_attributes(must)}>",
487:                     "may:<#{inspect_attributes(may)}>"].join(", ")
488:           "#{super}(#{detail})"
489:         end
490:       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 399
399:       def ldap_mapping(options={})
400:         options = options.symbolize_keys
401:         validate_ldap_mapping_options(options)
402: 
403:         self.dn_attribute = options[:dn_attribute] || default_dn_attribute
404:         self.dn_attribute = dn_attribute.to_s if dn_attribute.is_a?(Symbol)
405:         self.prefix = options[:prefix] || default_prefix
406:         self.scope = options[:scope]
407:         self.required_classes = options[:classes]
408:         self.recommended_classes = options[:recommended_classes]
409:         self.excluded_classes = options[:excluded_classes]
410:         self.sort_by = options[:sort_by]
411:         self.order = options[:order]
412: 
413:         public_class_method :new
414:       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 635
635:     def initialize(attributes=nil)
636:       init_base
637:       @new_entry = true
638:       initial_classes = required_classes | recommended_classes
639:       case attributes
640:       when nil
641:         self.classes = initial_classes
642:       when String, Array, DN
643:         self.classes = initial_classes
644:         self.dn = attributes
645:       when Hash
646:         classes, attributes = extract_object_class(attributes)
647:         self.classes = classes | initial_classes
648:         normalized_attributes = {}
649:         attributes.each do |key, value|
650:           real_key = to_real_attribute_name(key) || key
651:           normalized_attributes[real_key] = value
652:         end
653:         self.dn = normalized_attributes.delete(dn_attribute)
654:         self.attributes = normalized_attributes
655:       else
656:         format = _("'%s' must be either nil, DN value as ActiveLdap::DN, " \
657:                    "String or Array or attributes as Hash")
658:         raise ArgumentError, format % attributes.inspect
659:       end
660:       yield self if block_given?
661:     end

[Source]

     # File lib/active_ldap/base.rb, line 442
442:       def parsed_base
443:         @parsed_base ||= DN.parse(base)
444:       end

[Source]

     # File lib/active_ldap/base.rb, line 447
447:       def scope=(scope)
448:         validate_scope(scope)
449:         self.scope_without_validation = scope
450:       end

[Source]

     # File lib/active_ldap/base.rb, line 508
508:       def self_and_descendants_from_active_ldap
509:         klass = self
510:         classes = [klass]
511:         while klass != klass.base_class
512:           classes << klass = klass.superclass
513:         end
514:         classes
515:       rescue
516:         [self]
517:       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 365
365:       def setup_connection(config=nil)
366:         super
367:         ensure_logger
368:         nil
369:       end

[Source]

     # File lib/active_ldap/base.rb, line 452
452:       def validate_scope(scope)
453:         scope = scope.to_sym if scope.is_a?(String)
454:         return if scope.nil? or scope.is_a?(Symbol)
455:         raise ConfigurationError,
456:                 _("scope '%s' must be a Symbol") % scope.inspect
457:       end

Private Class methods

[Source]

     # File lib/active_ldap/base.rb, line 603
603:       def default_dn_attribute
604:         dn_attribute = nil
605:         parent_class = ancestors[1]
606:         if parent_class.respond_to?(:dn_attribute)
607:           dn_attribute = parent_class.dn_attribute
608:         end
609:         dn_attribute || "cn"
610:       end

[Source]

     # File lib/active_ldap/base.rb, line 612
612:       def default_prefix
613:         if name.blank?
614:           nil
615:         else
616:           "ou=#{name.demodulize.pluralize}"
617:         end
618:       end

[Source]

     # File lib/active_ldap/base.rb, line 571
571:       def ensure_logger
572:         @@logger ||= configuration[:logger]
573:         # Setup default logger to console
574:         if @@logger.nil?
575:           require 'logger'
576:           @@logger = Logger.new(STDERR)
577:           @@logger.progname = 'ActiveLdap'
578:           @@logger.level = Logger::UNKNOWN
579:         end
580:         configuration[:logger] ||= @@logger
581:       end

[Source]

     # File lib/active_ldap/base.rb, line 553
553:       def inspect_attribute(attribute)
554:         syntax = attribute.syntax
555:         result = "#{attribute.name}"
556:         if syntax and !syntax.description.blank?
557:           result << ": #{syntax.description}"
558:         end
559:         properties = []
560:         properties << "read-only" if attribute.read_only?
561:         properties << "binary" if attribute.binary?
562:         properties << "binary-required" if attribute.binary_required?
563:         result << "(#{properties.join(', ')})" unless properties.empty?
564:         result
565:       end

[Source]

     # File lib/active_ldap/base.rb, line 541
541:       def inspect_attributes(attributes)
542:         inspected_attribute_names = {}
543:         attributes.collect do |attribute|
544:           if inspected_attribute_names.has_key?(attribute.name)
545:             nil
546:           else
547:             inspected_attribute_names[attribute.name] = true
548:             inspect_attribute(attribute)
549:           end
550:         end.compact.join(', ')
551:       end

[Source]

     # File lib/active_ldap/base.rb, line 583
583:       def instantiate(args)
584:         dn, attributes, options = args
585:         options ||= {}
586:         if self.class == Class
587:           klass = self.ancestors[0].to_s.split(':').last
588:           real_klass = self.ancestors[0]
589:         else
590:           klass = self.class.to_s.split(':').last
591:           real_klass = self.class
592:         end
593: 
594:         obj = real_klass.allocate
595:         conn = options[:connection] || connection
596:         obj.connection = conn if conn != connection
597:         obj.instance_eval do
598:           initialize_by_ldap_data(dn, attributes)
599:         end
600:         obj
601:       end

[Source]

     # File lib/active_ldap/base.rb, line 567
567:       def validate_ldap_mapping_options(options)
568:         options.assert_valid_keys(VALID_LDAP_MAPPING_OPTIONS)
569:       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 665
665:     def ==(comparison_object)
666:       comparison_object.equal?(self) or
667:         (comparison_object.instance_of?(self.class) and
668:          comparison_object.dn == dn and
669:          !comparison_object.new_entry?)
670:     end

[Source]

     # File lib/active_ldap/base.rb, line 941
941:     def [](name, force_array=false)
942:       if name == "dn"
943:         array_of(dn, force_array)
944:       else
945:         get_attribute(name, force_array)
946:       end
947:     end

[Source]

     # File lib/active_ldap/base.rb, line 949
949:     def []=(name, value)
950:       set_attribute(name, value)
951:     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 697
697:     def attribute_names(normalize=false)
698:       entry_attribute.names(normalize)
699:     end

[Source]

     # File lib/active_ldap/base.rb, line 701
701:     def attribute_present?(name)
702:       values = get_attribute(name, true)
703:       !values.empty? or values.any? {|x| !(x and x.empty?)}
704:     end

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

[Source]

     # File lib/active_ldap/base.rb, line 863
863:     def attributes
864:       Marshal.load(Marshal.dump(@data))
865:     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 873
873:     def attributes=(new_attributes)
874:       return if new_attributes.blank?
875:       _schema = _local_entry_attribute = nil
876:       targets = remove_attributes_protected_from_mass_assignment(new_attributes)
877:       targets.each do |key, value|
878:         setter = "#{key}="
879:         unless respond_to?(setter)
880:           _schema ||= schema
881:           attribute = _schema.attribute(key)
882:           next if attribute.id.nil?
883:           _local_entry_attribute ||= local_entry_attribute
884:           _local_entry_attribute.register(attribute)
885:         end
886:         send(setter, value)
887:       end
888:     end

[Source]

      # File lib/active_ldap/base.rb, line 1000
1000:     def base
1001:       ensure_update_dn
1002:       [@base, base_of_class].find_all do |component|
1003:         not component.blank?
1004:       end.join(",")
1005:     end

[Source]

      # File lib/active_ldap/base.rb, line 1007
1007:     def base=(object_local_base)
1008:       ensure_update_dn
1009:       @dn = nil
1010:       @base = object_local_base
1011:     end

[Source]

     # File lib/active_ldap/base.rb, line 959
959:     def bind(config_or_password={}, config_or_ignore=nil, &block)
960:       if config_or_password.is_a?(String)
961:         config = (config_or_ignore || {}).merge(:password => config_or_password)
962:       else
963:         config = config_or_password
964:       end
965:       config = {:bind_dn => dn, :allow_anonymous => false}.merge(config)
966:       config[:password_block] ||= block if block_given?
967:       setup_connection(config)
968: 
969:       before_connection = @connection
970:       begin
971:         @connection = nil
972:         connection.connect
973:         @connection = connection
974:         clear_connection_based_cache
975:         clear_association_cache
976:       rescue ActiveLdap::Error
977:         remove_connection
978:         @connection = before_connection
979:         raise
980:       end
981:       true
982:     end

[Source]

     # File lib/active_ldap/base.rb, line 984
984:     def clear_connection_based_cache
985:       @schema = nil
986:       @local_entry_attribute = nil
987:       clear_object_class_based_cache
988:     end

[Source]

     # File lib/active_ldap/base.rb, line 990
990:     def clear_object_class_based_cache
991:       @entry_attribute = nil
992:       @real_names = {}
993:     end

[Source]

     # File lib/active_ldap/base.rb, line 749
749:     def default_search_attribute
750:       self.class.default_search_attribute
751:     end

[Source]

     # File lib/active_ldap/base.rb, line 765
765:     def delete(options={})
766:       super(dn, options)
767:     end

destroy

Delete this entry from LDAP

[Source]

     # File lib/active_ldap/base.rb, line 756
756:     def destroy
757:       begin
758:         self.class.delete(dn)
759:         @new_entry = true
760:       rescue Error
761:         raise DeleteError.new(_("Failed to delete LDAP entry: %s") % dn)
762:       end
763:     end

dn

Return the authoritative dn

[Source]

     # File lib/active_ldap/base.rb, line 724
724:     def dn
725:       @dn ||= compute_dn
726:     end

[Source]

     # File lib/active_ldap/base.rb, line 736
736:     def dn=(value)
737:       set_attribute(dn_attribute_with_fallback, value)
738:       @dn = nil
739:     end

[Source]

     # File lib/active_ldap/base.rb, line 743
743:     def dn_attribute
744:       ensure_update_dn
745:       _dn_attribute = @dn_attribute || dn_attribute_of_class
746:       to_real_attribute_name(_dn_attribute) || _dn_attribute
747:     end

[Source]

     # File lib/active_ldap/base.rb, line 953
953:     def each
954:       @data.each do |key, values|
955:         yield(key.dup, values.dup)
956:       end
957:     end

Delegates to ==

[Source]

     # File lib/active_ldap/base.rb, line 673
673:     def eql?(comparison_object)
674:       self == (comparison_object)
675:     end

exist?

Return whether the entry exists in LDAP or not

[Source]

     # File lib/active_ldap/base.rb, line 709
709:     def exist?
710:       self.class.exists?(dn)
711:     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 681
681:     def hash
682:       dn.hash
683:     end

[Source]

     # File lib/active_ldap/base.rb, line 918
918:     def have_attribute?(name, except=[])
919:       real_name = to_real_attribute_name(name)
920:       !real_name.nil? and !except.include?(real_name)
921:     end

[Source]

     # File lib/active_ldap/base.rb, line 728
728:     def id
729:       get_attribute(dn_attribute_with_fallback)
730:     end
id=(value)

Alias for dn=

[Source]

      # File lib/active_ldap/base.rb, line 1023
1023:     def inspect
1024:       object_classes = entry_attribute.object_classes
1025:       inspected_object_classes = object_classes.collect do |object_class|
1026:         object_class.name
1027:       end.join(', ')
1028:       must_attributes = must.collect(&:name).sort.join(', ')
1029:       may_attributes = may.collect(&:name).sort.join(', ')
1030:       inspected_attributes = attribute_names.sort.collect do |name|
1031:         inspect_attribute(name)
1032:       end.join(', ')
1033:       result = "\#<#{self.class} objectClass:<#{inspected_object_classes}>, "
1034:       result << "must:<#{must_attributes}>, may:<#{may_attributes}>, "
1035:       result << "#{inspected_attributes}>"
1036:       result
1037:     end

[Source]

     # File lib/active_ldap/base.rb, line 685
685:     def may
686:       entry_attribute.may
687:     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 791
791:     def method_missing(name, *args, &block)
792:       key = name.to_s
793:       case key
794:       when /=$/
795:         real_key = $PREMATCH
796:         if have_attribute?(real_key, ['objectClass'])
797:           if args.size != 1
798:             raise ArgumentError,
799:                     _("wrong number of arguments (%d for 1)") % args.size
800:           end
801:           return set_attribute(real_key, *args, &block)
802:         end
803:       when /(?:(_before_type_cast)|(\?))?$/
804:         real_key = $PREMATCH
805:         before_type_cast = !$1.nil?
806:         query = !$2.nil?
807:         if have_attribute?(real_key, ['objectClass'])
808:           if args.size > 1
809:             raise ArgumentError,
810:               _("wrong number of arguments (%d for 1)") % args.size
811:           end
812:           if before_type_cast
813:             return get_attribute_before_type_cast(real_key, *args)[1]
814:           elsif query
815:             return get_attribute_as_query(real_key, *args)
816:           else
817:             return get_attribute(real_key, *args)
818:           end
819:         end
820:       end
821:       super
822:     end

Add available attributes to the methods

[Source]

     # File lib/active_ldap/base.rb, line 825
825:     def methods(inherited_too=true)
826:       target_names = entry_attribute.all_names
827:       target_names -= ['objectClass', 'objectClass'.underscore]
828:       super + target_names.uniq.collect do |x|
829:         [x, "#{x}=", "#{x}?", "#{x}_before_type_cast"]
830:       end.flatten
831:     end

[Source]

     # File lib/active_ldap/base.rb, line 689
689:     def must
690:       entry_attribute.must
691:     end

new_entry?

Return whether the entry is new entry in LDAP or not

[Source]

     # File lib/active_ldap/base.rb, line 717
717:     def new_entry?
718:       @new_entry
719:     end

[Source]

     # File lib/active_ldap/base.rb, line 924
924:     def reload
925:       clear_association_cache
926:       _, attributes = search(:value => id).find do |_dn, _attributes|
927:         dn == _dn
928:       end
929:       if attributes.nil?
930:         raise EntryNotFound, _("Can't find DN '%s' to reload") % dn
931:       end
932: 
933:       @ldap_data.update(attributes)
934:       classes, attributes = extract_object_class(attributes)
935:       self.classes = classes
936:       self.attributes = attributes
937:       @new_entry = false
938:       self
939:     end

[Source]

     # File lib/active_ldap/base.rb, line 834
834:     def respond_to?(name, include_priv=false)
835:       return true if super
836: 
837:       name = name.to_s
838:       return true if have_attribute?(name)
839:       return false if /(?:=|\?|_before_type_cast)$/ !~ name
840:       have_attribute?($PREMATCH)
841:     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 774
774:     def save
775:       create_or_update
776:     end

[Source]

     # File lib/active_ldap/base.rb, line 778
778:     def save!
779:       unless create_or_update
780:         raise EntryNotSaved, _("entry %s can't be saved") % dn
781:       end
782:     end

[Source]

     # File lib/active_ldap/base.rb, line 995
995:     def schema
996:       @schema ||= super
997:     end

[Source]

      # File lib/active_ldap/base.rb, line 1014
1014:     def scope
1015:       @scope || scope_of_class
1016:     end

[Source]

      # File lib/active_ldap/base.rb, line 1018
1018:     def scope=(scope)
1019:       self.class.validate_scope(scope)
1020:       @scope = scope
1021:     end

[Source]

     # File lib/active_ldap/base.rb, line 894
894:     def to_ldif
895:       Ldif.new([to_ldif_record]).to_s
896:     end

[Source]

     # File lib/active_ldap/base.rb, line 890
890:     def to_ldif_record
891:       super(dn, normalize_data(@data))
892:     end

[Source]

     # File lib/active_ldap/base.rb, line 732
732:     def to_param
733:       id
734:     end

[Source]

     # File lib/active_ldap/base.rb, line 914
914:     def to_s
915:       to_ldif
916:     end

[Source]

     # File lib/active_ldap/base.rb, line 898
898:     def to_xml(options={})
899:       options = options.dup
900:       options[:root] ||= (self.class.name || '').underscore
901:       except = options[:except]
902:       if except
903:         options[:except] = except.collect do |name|
904:           if name.to_s.downcase == "dn"
905:             "dn"
906:           else
907:             to_real_attribute_name(name)
908:           end
909:         end.compact
910:       end
911:       XML.new(dn, normalize_data(@data), schema).to_s(options)
912:     end

Updates a given attribute and saves immediately

[Source]

     # File lib/active_ldap/base.rb, line 844
844:     def update_attribute(name, value)
845:       send("#{name}=", value)
846:       save
847:     end

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

[Source]

     # File lib/active_ldap/base.rb, line 851
851:     def update_attributes(attrs)
852:       self.attributes = attrs
853:       save
854:     end

[Source]

     # File lib/active_ldap/base.rb, line 856
856:     def update_attributes!(attrs)
857:       self.attributes = attrs
858:       save!
859:     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 1344
1344:     def array_of(value, to_a=true)
1345:       case value
1346:       when Array
1347:         if to_a or value.size > 1
1348:           value.collect {|v| array_of(v, false)}.compact
1349:         else
1350:           if value.empty?
1351:             nil
1352:           else
1353:             array_of(value.first, to_a)
1354:           end
1355:         end
1356:       when Hash
1357:         if to_a
1358:           [value]
1359:         else
1360:           result = {}
1361:           value.each {|k, v| result[k] = array_of(v, to_a)}
1362:           result
1363:         end
1364:       else
1365:         to_a ? [value] : value
1366:       end
1367:     end

[Source]

      # File lib/active_ldap/base.rb, line 1065
1065:     def attribute_name_resolvable_without_connection?
1066:       @entry_attribute and @local_entry_attribute
1067:     end

[Source]

      # File lib/active_ldap/base.rb, line 1429
1429:     def collect_all_attributes(data)
1430:       dn_attr = dn_attribute
1431:       dn_value = data[dn_attr]
1432: 
1433:       attributes = []
1434:       attributes.push([dn_attr, dn_value])
1435: 
1436:       oc_value = data['objectClass']
1437:       attributes.push(['objectClass', oc_value])
1438:       data.each do |key, value|
1439:         next if key == 'objectClass' or key == dn_attr
1440:         value = self.class.remove_blank_value(value)
1441:         next if self.class.blank_value?(value)
1442: 
1443:         attributes.push([key, value])
1444:       end
1445: 
1446:       attributes
1447:     end

[Source]

      # File lib/active_ldap/base.rb, line 1384
1384:     def collect_modified_attributes(ldap_data, data)
1385:       attributes = []
1386:       # Now that all the options will be treated as unique attributes
1387:       # we can see what's changed and add anything that is brand-spankin'
1388:       # new.
1389:       ldap_data.each do |k, v|
1390:         value = data[k] || []
1391: 
1392:         next if v == value
1393: 
1394:         x = value
1395:         value = self.class.remove_blank_value(value) || []
1396:         next if v == value
1397: 
1398:         # Create mod entries
1399:         if self.class.blank_value?(value)
1400:           # Since some types do not have equality matching rules,
1401:           # delete doesn't work
1402:           # Replacing with nothing is equivalent.
1403:           if !data.has_key?(k) and schema.attribute(k).binary_required?
1404:             value = [{'binary' => []}]
1405:           end
1406:         else
1407:           # Ditched delete then replace because attribs with no equality
1408:           # match rules will fails
1409:         end
1410:         attributes.push([:replace, k, value])
1411:       end
1412:       data.each do |k, v|
1413:         value = v || []
1414:         next if ldap_data.has_key?(k)
1415: 
1416:         value = self.class.remove_blank_value(value) || []
1417:         next if self.class.blank_value?(value)
1418: 
1419: 
1420:         # Detect subtypes and account for them
1421:         # REPLACE will function like ADD, but doesn't hit EQUALITY problems
1422:         # TODO: Added equality(attr) to Schema
1423:         attributes.push([:replace, k, value])
1424:       end
1425: 
1426:       attributes
1427:     end

[Source]

      # File lib/active_ldap/base.rb, line 1320
1320:     def compute_dn(escape_dn_value=false)
1321:       return base if @dn_is_base
1322: 
1323:       ensure_update_dn
1324:       dn_value = id
1325:       if dn_value.nil?
1326:         format =_("%s's DN attribute (%s) isn't set")
1327:         message = format % [self.inspect, dn_attribute]
1328:         raise DistinguishedNameNotSetError.new, message
1329:       end
1330:       dn_value = DN.escape_value(dn_value.to_s) if escape_dn_value
1331:       _base = base
1332:       _base = nil if _base.blank?
1333:       ["#{dn_attribute}=#{dn_value}", _base].compact.join(",")
1334:     end

[Source]

      # File lib/active_ldap/base.rb, line 1477
1477:     def create
1478:       prepare_data_for_saving do |data, ldap_data|
1479:         attributes = collect_all_attributes(data)
1480:         add_entry(escaped_dn, attributes)
1481:         @new_entry = false
1482:         true
1483:       end
1484:     end

[Source]

      # File lib/active_ldap/base.rb, line 1449
1449:     def create_or_update
1450:       new_entry? ? create : update
1451:     end

[Source]

      # File lib/active_ldap/base.rb, line 1040
1040:     def dn_attribute_with_fallback
1041:       begin
1042:         dn_attribute
1043:       rescue DistinguishedNameInvalid
1044:         _dn_attribute = @dn_attribute || dn_attribute_of_class
1045:         _dn_attribute = to_real_attribute_name(_dn_attribute) || _dn_attribute
1046:         raise if _dn_attribute.nil?
1047:         _dn_attribute
1048:       end
1049:     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 1139
1139:     def enforce_type(key, value)
1140:       # Enforce attribute value formatting
1141:       normalize_attribute(key, value)[1]
1142:     end

[Source]

      # File lib/active_ldap/base.rb, line 1310
1310:     def ensure_update_dn
1311:       return unless need_update_dn?
1312:       @mutex.synchronize do
1313:         if @dn_split_value
1314:           update_dn(*@dn_split_value)
1315:           @dn_split_value = nil
1316:         end
1317:       end
1318:     end

[Source]

      # File lib/active_ldap/base.rb, line 1069
1069:     def entry_attribute
1070:       @entry_attribute ||= connection.entry_attribute(@data["objectClass"] || [])
1071:     end

[Source]

      # File lib/active_ldap/base.rb, line 1336
1336:     def escaped_dn
1337:       compute_dn(true)
1338:     end

[Source]

      # File lib/active_ldap/base.rb, line 1077
1077:     def extract_object_class(attributes)
1078:       classes = []
1079:       attrs = {}
1080:       attributes.each do |key, value|
1081:         key = key.to_s
1082:         if /\Aobject_?class\z/i =~ key
1083:           classes.concat(value.to_a)
1084:         else
1085:           attrs[key] = value
1086:         end
1087:       end
1088:       [classes, attributes]
1089:     end

[Source]

      # File lib/active_ldap/base.rb, line 1205
1205:     def false_value?(value)
1206:       value.nil? or value == false or value == [] or
1207:         value == "false" or value == "FALSE" or value == ""
1208:     end

get_attribute

Return the value of the attribute called by method_missing?

[Source]

      # File lib/active_ldap/base.rb, line 1161
1161:     def get_attribute(name, force_array=false)
1162:       name, value = get_attribute_before_type_cast(name, force_array)
1163:       return value if name.nil?
1164:       attribute = schema.attribute(name)
1165:       type_cast(attribute, value)
1166:     end

[Source]

      # File lib/active_ldap/base.rb, line 1196
1196:     def get_attribute_as_query(name, force_array=false)
1197:       name, value = get_attribute_before_type_cast(name, force_array)
1198:       if force_array
1199:         value.collect {|x| !false_value?(x)}
1200:       else
1201:         !false_value?(value)
1202:       end
1203:     end

[Source]

      # File lib/active_ldap/base.rb, line 1189
1189:     def get_attribute_before_type_cast(name, force_array=false)
1190:       name = to_real_attribute_name(name)
1191: 
1192:       value = @data[name] || []
1193:       [name, array_of(value, force_array)]
1194:     end

[Source]

      # File lib/active_ldap/base.rb, line 1091
1091:     def init_base
1092:       init_instance_variables
1093:     end

[Source]

      # File lib/active_ldap/base.rb, line 1144
1144:     def init_instance_variables
1145:       @mutex = Mutex.new
1146:       @data = {} # where the r/w entry data is stored
1147:       @ldap_data = {} # original ldap entry data
1148:       @dn_attribute = nil
1149:       @base = nil
1150:       @scope = nil
1151:       @dn = nil
1152:       @dn_is_base = false
1153:       @dn_split_value = nil
1154:       @connection ||= nil
1155:       clear_connection_based_cache
1156:     end

[Source]

      # File lib/active_ldap/base.rb, line 1095
1095:     def initialize_by_ldap_data(dn, attributes)
1096:       init_base
1097:       dn = Compatible.convert_to_utf8_encoded_object(dn)
1098:       attributes = Compatible.convert_to_utf8_encoded_object(attributes)
1099:       @dn = dn
1100:       @new_entry = false
1101:       @dn_is_base = false
1102:       @ldap_data = attributes
1103:       classes, attributes = extract_object_class(attributes)
1104:       self.classes = classes
1105:       self.dn = dn
1106:       self.attributes = attributes
1107:       yield self if block_given?
1108:     end

[Source]

      # File lib/active_ldap/base.rb, line 1051
1051:     def inspect_attribute(name)
1052:       values = get_attribute(name, true)
1053:       values.collect do |value|
1054:         if value.is_a?(String) and value.length > 50
1055:           "#{value[0, 50]}...".inspect
1056:         elsif value.is_a?(Date) || value.is_a?(Time)
1057:           "#{value.to_s(:db)}"
1058:         else
1059:           value.inspect
1060:         end
1061:       end
1062:       "#{name}: #{values.inspect}"
1063:     end

[Source]

      # File lib/active_ldap/base.rb, line 1110
1110:     def instantiate(args)
1111:       dn, attributes, options = args
1112:       options ||= {}
1113: 
1114:       obj = self.class.allocate
1115:       obj.connection = options[:connection] || @connection
1116:       obj.instance_eval do
1117:         initialize_by_ldap_data(dn, attributes)
1118:       end
1119:       obj
1120:     end

[Source]

      # File lib/active_ldap/base.rb, line 1073
1073:     def local_entry_attribute
1074:       @local_entry_attribute ||= connection.entry_attribute([])
1075:     end

[Source]

      # File lib/active_ldap/base.rb, line 1306
1306:     def need_update_dn?
1307:       not @dn_split_value.nil?
1308:     end

[Source]

      # File lib/active_ldap/base.rb, line 1369
1369:     def normalize_data(data, except=[])
1370:       _schema = schema
1371:       result = {}
1372:       data.each do |key, values|
1373:         next if except.include?(key)
1374:         real_name = to_real_attribute_name(key)
1375:         next if real_name and except.include?(real_name)
1376:         real_name ||= key
1377:         next if _schema.attribute(real_name).id.nil?
1378:         result[real_name] ||= []
1379:         result[real_name].concat(enforce_type(real_name, values))
1380:       end
1381:       result
1382:     end

[Source]

      # File lib/active_ldap/base.rb, line 1453
1453:     def prepare_data_for_saving
1454:       # Expand subtypes to real ldap_data attributes
1455:       # We can't reuse @ldap_data because an exception would leave
1456:       # an object in an unknown state
1457:       ldap_data = normalize_data(@ldap_data)
1458: 
1459:       # Expand subtypes to real data attributes, but leave @data alone
1460:       bad_attrs = @data.keys - attribute_names
1461:       data = normalize_data(@data, bad_attrs)
1462: 
1463:       success = yield(data, ldap_data)
1464: 
1465:       if success
1466:         @ldap_data = Marshal.load(Marshal.dump(data))
1467:         # Delete items disallowed by objectclasses.
1468:         # They should have been removed from ldap.
1469:         bad_attrs.each do |remove_me|
1470:           @ldap_data.delete(remove_me)
1471:         end
1472:       end
1473: 
1474:       success
1475:     end

[Source]

      # File lib/active_ldap/base.rb, line 1230
1230:     def register_new_dn_attribute(name, value)
1231:       @dn = nil
1232:       @dn_is_base = false
1233:       if value.blank?
1234:         @dn_split_value = nil
1235:         [name, nil]
1236:       else
1237:         new_name, new_value, raw_new_value, new_bases = split_dn_value(value)
1238:         @dn_split_value = [new_name, new_value, new_bases]
1239:         if new_name.nil? and new_value.nil?
1240:           new_name, raw_new_value = new_bases[0].to_a[0]
1241:         end
1242:         [to_real_attribute_name(new_name) || name,
1243:          raw_new_value || value]
1244:       end
1245:     end

set_attribute

Set the value of the attribute called by method_missing?

[Source]

      # File lib/active_ldap/base.rb, line 1213
1213:     def set_attribute(name, value)
1214:       real_name = to_real_attribute_name(name)
1215:       _dn_attribute = nil
1216:       valid_dn_attribute = true
1217:       begin
1218:         _dn_attribute = dn_attribute
1219:       rescue DistinguishedNameInvalid
1220:         valid_dn_attribute = false
1221:       end
1222:       if valid_dn_attribute and real_name == _dn_attribute
1223:         real_name, value = register_new_dn_attribute(real_name, value)
1224:       end
1225:       raise UnknownAttribute.new(name) if real_name.nil?
1226: 
1227:       @data[real_name] = value
1228:     end

[Source]

      # File lib/active_ldap/base.rb, line 1271
1271:     def split_dn_value(value)
1272:       dn_value = relative_dn_value = nil
1273:       begin
1274:         dn_value = value if value.is_a?(DN)
1275:         dn_value ||= DN.parse(value)
1276:       rescue DistinguishedNameInvalid
1277:         begin
1278:           dn_value = DN.parse("#{dn_attribute}=#{value}")
1279:         rescue DistinguishedNameInvalid
1280:           return [nil, value, value, []]
1281:         end
1282:       end
1283: 
1284:       val = bases = nil
1285:       begin
1286:         relative_dn_value = dn_value - self.class.parsed_base
1287:         if relative_dn_value.rdns.empty?
1288:           val = []
1289:           bases = dn_value.rdns
1290:         else
1291:           val, *bases = relative_dn_value.rdns
1292:         end
1293:       rescue ArgumentError
1294:         val, *bases = dn_value.rdns
1295:       end
1296: 
1297:       dn_attribute_name, dn_attribute_value = val.to_a[0]
1298:       escaped_dn_attribute_value = nil
1299:       unless dn_attribute_value.nil?
1300:         escaped_dn_attribute_value = DN.escape_value(dn_attribute_value)
1301:       end
1302:       [dn_attribute_name, escaped_dn_attribute_value,
1303:        dn_attribute_value, bases]
1304:     end

[Source]

      # File lib/active_ldap/base.rb, line 1122
1122:     def to_real_attribute_name(name, allow_normalized_name=true)
1123:       return name if name.nil?
1124:       if allow_normalized_name
1125:         entry_attribute.normalize(name, allow_normalized_name) ||
1126:           local_entry_attribute.normalize(name, allow_normalized_name)
1127:       else
1128:         @real_names[name] ||=
1129:           entry_attribute.normalize(name, false) ||
1130:           local_entry_attribute.normalize(name, false)
1131:       end
1132:     end

[Source]

      # File lib/active_ldap/base.rb, line 1168
1168:     def type_cast(attribute, value)
1169:       case value
1170:       when Hash
1171:         result = {}
1172:         value.each do |option, val|
1173:           result[option] = type_cast(attribute, val)
1174:         end
1175:         if result.size == 1 and result.has_key?("binary")
1176:           result["binary"]
1177:         else
1178:           result
1179:         end
1180:       when Array
1181:         value.collect do |val|
1182:           type_cast(attribute, val)
1183:         end
1184:       else
1185:         attribute.type_cast(value)
1186:       end
1187:     end

[Source]

      # File lib/active_ldap/base.rb, line 1486
1486:     def update
1487:       prepare_data_for_saving do |data, ldap_data|
1488:         attributes = collect_modified_attributes(ldap_data, data)
1489:         modify_entry(escaped_dn, attributes)
1490:         true
1491:       end
1492:     end

[Source]

      # File lib/active_ldap/base.rb, line 1247
1247:     def update_dn(new_name, new_value, bases)
1248:       if new_name.nil? and new_value.nil?
1249:         @dn_is_base = true
1250:         @base = nil
1251:         attr, value = bases[0].to_a[0]
1252:         @dn_attribute = attr
1253:       else
1254:         new_name ||= @dn_attribute || dn_attribute_of_class
1255:         new_name = to_real_attribute_name(new_name)
1256:         if new_name.nil?
1257:           new_name = @dn_attribute || dn_attribute_of_class
1258:           new_name = to_real_attribute_name(new_name)
1259:         end
1260:         new_bases = bases.empty? ? nil : DN.new(*bases).to_s
1261:         dn_components = ["#{new_name}=#{new_value}",
1262:                          new_bases,
1263:                          base_of_class]
1264:         dn_components = dn_components.find_all {|component| !component.blank?}
1265:         DN.parse(dn_components.join(','))
1266:         @base = new_bases
1267:         @dn_attribute = new_name
1268:       end
1269:     end

[Validate]