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 ConnectionNotEstablished TimeoutError AuthenticationError AttributeValueInvalid EntryNotSaved DistinguishedNameInputInvalid EntryAlreadyExist ObjectClassError UnknownAttribute EntryInvalid DeleteError ConfigurationError DistinguishedNameInvalid 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 Schema\n[lib/active_ldap/schema.rb\nlib/active_ldap/schema/syntaxes.rb] JndiConnection lib/active_ldap/distinguished_name.rb lib/active_ldap/base.rb lib/active_ldap/schema.rb lib/active_ldap/entry_attribute.rb lib/active_ldap/ldif.rb lib/active_ldap/ldap_error.rb 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_44_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

==   []   []=   array_of   assert_dn_attribute   attribute_name_resolvable_without_connection?   attribute_names   attribute_present?   attributes   attributes=   base   base   base=   base=   base_class   bind   class_local_attr_accessor   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   each   enforce_type   ensure_logger   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?   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   new   new_entry?   normalize_data   parsed_base   prepare_data_for_saving   reload   respond_to?   save   save!   schema   scope   scope=   scope=   set_attribute   split_dn_value   to_ldif   to_ldif_record   to_param   to_real_attribute_name   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

Public Class methods

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 395
395:       def base
396:         _base = base_inheritable
397:         _base = configuration[:base] if _base.nil? and configuration
398:         _base ||= base_inheritable(true)
399:         [prefix, _base].find_all do |component|
400:           !component.blank?
401:         end.join(",")
402:       end

[Source]

     # File lib/active_ldap/base.rb, line 405
405:       def base=(value)
406:         self.base_without_parsed_cache_clear = value
407:         @parsed_base = nil
408:       end

[Source]

     # File lib/active_ldap/base.rb, line 427
427:       def base_class
428:         if self == Base or superclass == Base
429:           self
430:         else
431:           superclass.base_class
432:         end
433:       end

[Source]

     # File lib/active_ldap/base.rb, line 268
268:     def self.class_local_attr_accessor(search_ancestors, *syms)
269:       syms.flatten.each do |sym|
270:         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\ndef \#{sym}=(value); self.class.\#{sym} = value; end\n", __FILE__, __LINE__ + 1)
271:       end
272:     end

[Source]

     # File lib/active_ldap/base.rb, line 350
350:       def create(attributes=nil, &block)
351:         if attributes.is_a?(Array)
352:           attributes.collect {|attrs| create(attrs, &block)}
353:         else
354:           object = new(attributes, &block)
355:           object.save
356:           object
357:         end
358:       end

[Source]

     # File lib/active_ldap/base.rb, line 435
435:       def default_search_attribute
436:         dn_attribute
437:       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/configuration.rb for defaults for each option

[Source]

     # File lib/active_ldap/base.rb, line 344
344:       def establish_connection(config=nil)
345:         super
346:         ensure_logger
347:         nil
348:       end

Hide new in Base

[Source]

     # File lib/active_ldap/base.rb, line 305
305:       def inherited(sub_class)
306:         super
307:         sub_class.module_eval do
308:           include GetTextSupport
309:         end
310:       end

[Source]

     # File lib/active_ldap/base.rb, line 439
439:       def inspect
440:         if self == Base
441:           super
442:         else
443:           class_names = []
444:           must = []
445:           may = []
446:           class_names = classes.collect do |object_class|
447:             must.concat(object_class.must)
448:             may.concat(object_class.may)
449:             object_class.name
450:           end
451:           detail = ["objectClass:<#{class_names.join(', ')}>",
452:                     "must:<#{inspect_attributes(must)}>",
453:                     "may:<#{inspect_attributes(may)}>"].join(", ")
454:           "#{super}(#{detail})"
455:         end
456:       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 367
367:       def ldap_mapping(options={})
368:         options = options.symbolize_keys
369:         validate_ldap_mapping_options(options)
370: 
371:         self.dn_attribute = options[:dn_attribute] || default_dn_attribute
372:         self.dn_attribute = dn_attribute.to_s if dn_attribute.is_a?(Symbol)
373:         self.prefix = options[:prefix] || default_prefix
374:         self.scope = options[:scope]
375:         self.required_classes = options[:classes]
376:         self.recommended_classes = options[:recommended_classes]
377:         self.excluded_classes = options[:excluded_classes]
378:         self.sort_by = options[:sort_by]
379:         self.order = options[:order]
380: 
381:         public_class_method :new
382:       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 557
557:     def initialize(attributes=nil)
558:       init_base
559:       @new_entry = true
560:       initial_classes = required_classes | recommended_classes
561:       case attributes
562:       when nil
563:         self.classes = initial_classes
564:       when String, Array, DN
565:         self.classes = initial_classes
566:         self.dn = attributes
567:       when Hash
568:         classes, attributes = extract_object_class(attributes)
569:         self.classes = classes | initial_classes
570:         normalized_attributes = {}
571:         attributes.each do |key, value|
572:           real_key = to_real_attribute_name(key) || key
573:           normalized_attributes[real_key] = value
574:         end
575:         self.dn = normalized_attributes.delete(dn_attribute)
576:         self.attributes = normalized_attributes
577:       else
578:         format = _("'%s' must be either nil, DN value as ActiveLdap::DN, " \
579:                    "String or Array or attributes as Hash")
580:         raise ArgumentError, format % attributes.inspect
581:       end
582:       yield self if block_given?
583:       assert_dn_attribute
584:     end

[Source]

     # File lib/active_ldap/base.rb, line 410
410:       def parsed_base
411:         @parsed_base ||= DN.parse(base)
412:       end

[Source]

     # File lib/active_ldap/base.rb, line 415
415:       def scope=(scope)
416:         validate_scope(scope)
417:         self.scope_without_validation = scope
418:       end

[Source]

     # File lib/active_ldap/base.rb, line 420
420:       def validate_scope(scope)
421:         scope = scope.to_sym if scope.is_a?(String)
422:         return if scope.nil? or scope.is_a?(Symbol)
423:         raise ConfigurationError,
424:                 _("scope '%s' must be a Symbol") % scope.inspect
425:       end

Private Class methods

[Source]

     # File lib/active_ldap/base.rb, line 521
521:       def default_dn_attribute
522:         if name.empty?
523:           dn_attribute = nil
524:           parent_class = ancestors[1]
525:           if parent_class.respond_to?(:dn_attribute)
526:             dn_attribute = parent_class.dn_attribute
527:           end
528:           dn_attribute || "cn"
529:         else
530:           name.demodulize.underscore
531:         end
532:       end

[Source]

     # File lib/active_ldap/base.rb, line 534
534:       def default_prefix
535:         if name.empty?
536:           nil
537:         else
538:           "ou=#{name.demodulize.pluralize}"
539:         end
540:       end

[Source]

     # File lib/active_ldap/base.rb, line 489
489:       def ensure_logger
490:         @@logger ||= configuration[:logger]
491:         # Setup default logger to console
492:         if @@logger.nil?
493:           require 'logger'
494:           @@logger = Logger.new(STDERR)
495:           @@logger.progname = 'ActiveLdap'
496:           @@logger.level = Logger::UNKNOWN
497:         end
498:         configuration[:logger] ||= @@logger
499:       end

[Source]

     # File lib/active_ldap/base.rb, line 471
471:       def inspect_attribute(attribute)
472:         syntax = attribute.syntax
473:         result = "#{attribute.name}"
474:         if syntax and !syntax.description.blank?
475:           result << ": #{syntax.description}"
476:         end
477:         properties = []
478:         properties << "read-only" if attribute.read_only?
479:         properties << "binary" if attribute.binary?
480:         properties << "binary-required" if attribute.binary_required?
481:         result << "(#{properties.join(', ')})" unless properties.empty?
482:         result
483:       end

[Source]

     # File lib/active_ldap/base.rb, line 459
459:       def inspect_attributes(attributes)
460:         inspected_attribute_names = {}
461:         attributes.collect do |attribute|
462:           if inspected_attribute_names.has_key?(attribute.name)
463:             nil
464:           else
465:             inspected_attribute_names[attribute.name] = true
466:             inspect_attribute(attribute)
467:           end
468:         end.compact.join(', ')
469:       end

[Source]

     # File lib/active_ldap/base.rb, line 501
501:       def instantiate(args)
502:         dn, attributes, options = args
503:         options ||= {}
504:         if self.class == Class
505:           klass = self.ancestors[0].to_s.split(':').last
506:           real_klass = self.ancestors[0]
507:         else
508:           klass = self.class.to_s.split(':').last
509:           real_klass = self.class
510:         end
511: 
512:         obj = real_klass.allocate
513:         conn = options[:connection] || connection
514:         obj.connection = conn if conn != connection
515:         obj.instance_eval do
516:           initialize_by_ldap_data(dn, attributes)
517:         end
518:         obj
519:       end

[Source]

     # File lib/active_ldap/base.rb, line 485
485:       def validate_ldap_mapping_options(options)
486:         options.assert_valid_keys(VALID_LDAP_MAPPING_OPTIONS)
487:       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 588
588:     def ==(comparison_object)
589:       comparison_object.equal?(self) or
590:         (comparison_object.instance_of?(self.class) and
591:          comparison_object.dn == dn and
592:          !comparison_object.new_entry?)
593:     end

[Source]

     # File lib/active_ldap/base.rb, line 866
866:     def [](name, force_array=false)
867:       if name == "dn"
868:         array_of(dn, force_array)
869:       else
870:         get_attribute(name, force_array)
871:       end
872:     end

[Source]

     # File lib/active_ldap/base.rb, line 874
874:     def []=(name, value)
875:       set_attribute(name, value)
876:     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 620
620:     def attribute_names(normalize=false)
621:       entry_attribute.names(normalize)
622:     end

[Source]

     # File lib/active_ldap/base.rb, line 624
624:     def attribute_present?(name)
625:       values = get_attribute(name, true)
626:       !values.empty? or values.any? {|x| not (x and x.empty?)}
627:     end

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

[Source]

     # File lib/active_ldap/base.rb, line 785
785:     def attributes
786:       Marshal.load(Marshal.dump(@data))
787:     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 795
795:     def attributes=(new_attributes)
796:       return if new_attributes.nil?
797:       _schema = _local_entry_attribute = nil
798:       targets = remove_attributes_protected_from_mass_assignment(new_attributes)
799:       targets.each do |key, value|
800:         setter = "#{key}="
801:         unless respond_to?(setter)
802:           _schema ||= schema
803:           attribute = _schema.attribute(key)
804:           next if attribute.id.nil?
805:           _local_entry_attribute ||= local_entry_attribute
806:           _local_entry_attribute.register(attribute)
807:         end
808:         send(setter, value)
809:       end
810:     end

[Source]

     # File lib/active_ldap/base.rb, line 925
925:     def base
926:       [@base, base_of_class].compact.join(",")
927:     end

[Source]

     # File lib/active_ldap/base.rb, line 930
930:     def base=(object_local_base)
931:       @dn = nil
932:       @base = object_local_base
933:     end

[Source]

     # File lib/active_ldap/base.rb, line 884
884:     def bind(config_or_password={}, config_or_ignore=nil, &block)
885:       if config_or_password.is_a?(String)
886:         config = (config_or_ignore || {}).merge(:password => config_or_password)
887:       else
888:         config = config_or_password
889:       end
890:       config = {:bind_dn => dn, :allow_anonymous => false}.merge(config)
891:       config[:password_block] ||= block if block_given?
892:       establish_connection(config)
893: 
894:       before_connection = @connection
895:       begin
896:         @connection = nil
897:         connection.connect
898:         @connection = connection
899:         clear_connection_based_cache
900:         clear_association_cache
901:       rescue ActiveLdap::Error
902:         remove_connection
903:         @connection = before_connection
904:         raise
905:       end
906:       true
907:     end

[Source]

     # File lib/active_ldap/base.rb, line 909
909:     def clear_connection_based_cache
910:       @schema = nil
911:       @local_entry_attribute = nil
912:       clear_object_class_based_cache
913:     end

[Source]

     # File lib/active_ldap/base.rb, line 915
915:     def clear_object_class_based_cache
916:       @entry_attribute = nil
917:       @real_names = {}
918:     end

[Source]

     # File lib/active_ldap/base.rb, line 671
671:     def default_search_attribute
672:       self.class.default_search_attribute
673:     end

[Source]

     # File lib/active_ldap/base.rb, line 687
687:     def delete(options={})
688:       super(dn, options)
689:     end

destroy

Delete this entry from LDAP

[Source]

     # File lib/active_ldap/base.rb, line 678
678:     def destroy
679:       begin
680:         self.class.delete(dn)
681:         @new_entry = true
682:       rescue Error
683:         raise DeleteError.new(_("Failed to delete LDAP entry: %s") % dn)
684:       end
685:     end

dn

Return the authoritative dn

[Source]

     # File lib/active_ldap/base.rb, line 647
647:     def dn
648:       @dn ||= compute_dn
649:     end

[Source]

     # File lib/active_ldap/base.rb, line 659
659:     def dn=(value)
660:       set_attribute(dn_attribute, value)
661:       @dn = nil
662:     end

[Source]

     # File lib/active_ldap/base.rb, line 666
666:     def dn_attribute
667:       _dn_attribute = @dn_attribute || dn_attribute_of_class
668:       to_real_attribute_name(_dn_attribute) || _dn_attribute
669:     end

[Source]

     # File lib/active_ldap/base.rb, line 878
878:     def each
879:       @data.each do |key, values|
880:         yield(key.dup, values.dup)
881:       end
882:     end

Delegates to ==

[Source]

     # File lib/active_ldap/base.rb, line 596
596:     def eql?(comparison_object)
597:       self == (comparison_object)
598:     end

exist?

Return whether the entry exists in LDAP or not

[Source]

     # File lib/active_ldap/base.rb, line 632
632:     def exist?
633:       self.class.exists?(dn)
634:     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 604
604:     def hash
605:       dn.hash
606:     end

[Source]

     # File lib/active_ldap/base.rb, line 843
843:     def have_attribute?(name, except=[])
844:       real_name = to_real_attribute_name(name)
845:       real_name and !except.include?(real_name)
846:     end

[Source]

     # File lib/active_ldap/base.rb, line 651
651:     def id
652:       get_attribute(dn_attribute)
653:     end
id=(value)

Alias for dn=

[Source]

     # File lib/active_ldap/base.rb, line 946
946:     def inspect
947:       object_classes = entry_attribute.object_classes
948:       inspected_object_classes = object_classes.collect do |object_class|
949:         object_class.name
950:       end.join(', ')
951:       must_attributes = must.collect(&:name).sort.join(', ')
952:       may_attributes = may.collect(&:name).sort.join(', ')
953:       inspected_attributes = attribute_names.sort.collect do |name|
954:         inspect_attribute(name)
955:       end.join(', ')
956:       result = "\#<#{self.class} objectClass:<#{inspected_object_classes}>, "
957:       result << "must:<#{must_attributes}>, may:<#{may_attributes}>, "
958:       result << "#{inspected_attributes}>"
959:       result
960:     end

[Source]

     # File lib/active_ldap/base.rb, line 608
608:     def may
609:       entry_attribute.may
610:     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 713
713:     def method_missing(name, *args, &block)
714:       key = name.to_s
715:       case key
716:       when /=$/
717:         real_key = $PREMATCH
718:         if have_attribute?(real_key, ['objectClass'])
719:           if args.size != 1
720:             raise ArgumentError,
721:                     _("wrong number of arguments (%d for 1)") % args.size
722:           end
723:           return set_attribute(real_key, *args, &block)
724:         end
725:       when /(?:(_before_type_cast)|(\?))?$/
726:         real_key = $PREMATCH
727:         before_type_cast = !$1.nil?
728:         query = !$2.nil?
729:         if have_attribute?(real_key, ['objectClass'])
730:           if args.size > 1
731:             raise ArgumentError,
732:               _("wrong number of arguments (%d for 1)") % args.size
733:           end
734:           if before_type_cast
735:             return get_attribute_before_type_cast(real_key, *args)[1]
736:           elsif query
737:             return get_attribute_as_query(real_key, *args)
738:           else
739:             return get_attribute(real_key, *args)
740:           end
741:         end
742:       end
743:       super
744:     end

Add available attributes to the methods

[Source]

     # File lib/active_ldap/base.rb, line 747
747:     def methods(inherited_too=true)
748:       target_names = entry_attribute.all_names
749:       target_names -= ['objectClass', 'objectClass'.underscore]
750:       super + target_names.uniq.collect do |x|
751:         [x, "#{x}=", "#{x}?", "#{x}_before_type_cast"]
752:       end.flatten
753:     end

[Source]

     # File lib/active_ldap/base.rb, line 612
612:     def must
613:       entry_attribute.must
614:     end

new_entry?

Return whether the entry is new entry in LDAP or not

[Source]

     # File lib/active_ldap/base.rb, line 640
640:     def new_entry?
641:       @new_entry
642:     end

[Source]

     # File lib/active_ldap/base.rb, line 849
849:     def reload
850:       clear_association_cache
851:       _, attributes = search(:value => id).find do |_dn, _attributes|
852:         dn == _dn
853:       end
854:       if attributes.nil?
855:         raise EntryNotFound, _("Can't find DN '%s' to reload") % dn
856:       end
857: 
858:       @ldap_data.update(attributes)
859:       classes, attributes = extract_object_class(attributes)
860:       self.classes = classes
861:       self.attributes = attributes
862:       @new_entry = false
863:       self
864:     end

[Source]

     # File lib/active_ldap/base.rb, line 756
756:     def respond_to?(name, include_priv=false)
757:       return true if super
758: 
759:       name = name.to_s
760:       return true if have_attribute?(name)
761:       return false if /(?:=|\?|_before_type_cast)$/ !~ name
762:       have_attribute?($PREMATCH)
763:     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 696
696:     def save
697:       create_or_update
698:     end

[Source]

     # File lib/active_ldap/base.rb, line 700
700:     def save!
701:       unless create_or_update
702:         raise EntryNotSaved, _("entry %s can't be saved") % dn
703:       end
704:     end

[Source]

     # File lib/active_ldap/base.rb, line 920
920:     def schema
921:       @schema ||= super
922:     end

[Source]

     # File lib/active_ldap/base.rb, line 936
936:     def scope
937:       @scope || scope_of_class
938:     end

[Source]

     # File lib/active_ldap/base.rb, line 941
941:     def scope=(scope)
942:       self.class.validate_scope(scope)
943:       @scope = scope
944:     end

[Source]

     # File lib/active_ldap/base.rb, line 816
816:     def to_ldif
817:       Ldif.new([to_ldif_record]).to_s
818:     end

[Source]

     # File lib/active_ldap/base.rb, line 812
812:     def to_ldif_record
813:       super(dn, normalize_data(@data))
814:     end

[Source]

     # File lib/active_ldap/base.rb, line 655
655:     def to_param
656:       id
657:     end

[Source]

     # File lib/active_ldap/base.rb, line 820
820:     def to_xml(options={})
821:       root = options[:root] || self.class.name.underscore
822:       result = "<#{root}>\n"
823:       result << "  <dn>#{dn}</dn>\n"
824:       normalize_data(@data).sort_by {|key, values| key}.each do |key, values|
825:         targets = []
826:         values.each do |value|
827:           if value.is_a?(Hash)
828:             value.each do |option, real_value|
829:               targets << [real_value, " #{option}=\"true\""]
830:             end
831:           else
832:             targets << [value]
833:           end
834:         end
835:         targets.sort_by {|value, attr| value}.each do |value, attr|
836:           result << "  <#{key}#{attr}>#{value}</#{key}>\n"
837:         end
838:       end
839:       result << "</#{root}>\n"
840:       result
841:     end

Updates a given attribute and saves immediately

[Source]

     # File lib/active_ldap/base.rb, line 766
766:     def update_attribute(name, value)
767:       send("#{name}=", value)
768:       save
769:     end

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

[Source]

     # File lib/active_ldap/base.rb, line 773
773:     def update_attributes(attrs)
774:       self.attributes = attrs
775:       save
776:     end

[Source]

     # File lib/active_ldap/base.rb, line 778
778:     def update_attributes!(attrs)
779:       self.attributes = attrs
780:       save!
781:     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 1201
1201:     def array_of(value, to_a=true)
1202:       case value
1203:       when Array
1204:         if to_a or value.size > 1
1205:           value.collect {|v| array_of(v, false)}.compact
1206:         else
1207:           if value.empty?
1208:             nil
1209:           else
1210:             array_of(value.first, to_a)
1211:           end
1212:         end
1213:       when Hash
1214:         if to_a
1215:           [value]
1216:         else
1217:           result = {}
1218:           value.each {|k, v| result[k] = array_of(v, to_a)}
1219:           result
1220:         end
1221:       else
1222:         to_a ? [value] : value
1223:       end
1224:     end

[Source]

      # File lib/active_ldap/base.rb, line 1296
1296:     def assert_dn_attribute
1297:       unless dn_attribute
1298:         raise ConfigurationError,
1299:                 _("dn_attribute isn't set for this class: %s") % self.class
1300:       end
1301:     end

[Source]

     # File lib/active_ldap/base.rb, line 977
977:     def attribute_name_resolvable_without_connection?
978:       @entry_attribute and @local_entry_attribute
979:     end

[Source]

      # File lib/active_ldap/base.rb, line 1278
1278:     def collect_all_attributes(data)
1279:       dn_attr = dn_attribute
1280:       dn_value = data[dn_attr]
1281: 
1282:       attributes = []
1283:       attributes.push([dn_attr, dn_value])
1284: 
1285:       oc_value = data['objectClass']
1286:       attributes.push(['objectClass', oc_value])
1287:       data.each do |key, value|
1288:         next if value.empty? or key == 'objectClass' or key == dn_attr
1289: 
1290:         attributes.push([key, value])
1291:       end
1292: 
1293:       attributes
1294:     end

[Source]

      # File lib/active_ldap/base.rb, line 1241
1241:     def collect_modified_attributes(ldap_data, data)
1242:       attributes = []
1243:       # Now that all the options will be treated as unique attributes
1244:       # we can see what's changed and add anything that is brand-spankin'
1245:       # new.
1246:       ldap_data.each do |k, v|
1247:         value = data[k] || []
1248: 
1249:         next if v == value
1250: 
1251:         # Create mod entries
1252:         if value.empty?
1253:           # Since some types do not have equality matching rules,
1254:           # delete doesn't work
1255:           # Replacing with nothing is equivalent.
1256:           if !data.has_key?(k) and schema.attribute(k).binary_required?
1257:             value = [{'binary' => []}]
1258:           end
1259:         else
1260:           # Ditched delete then replace because attribs with no equality
1261:           # match rules will fails
1262:         end
1263:         attributes.push([:replace, k, value])
1264:       end
1265:       data.each do |k, v|
1266:         value = v || []
1267:         next if ldap_data.has_key?(k) or value.empty?
1268: 
1269:         # Detect subtypes and account for them
1270:         # REPLACE will function like ADD, but doesn't hit EQUALITY problems
1271:         # TODO: Added equality(attr) to Schema
1272:         attributes.push([:replace, k, value])
1273:       end
1274: 
1275:       attributes
1276:     end

[Source]

      # File lib/active_ldap/base.rb, line 1179
1179:     def compute_dn(escape_dn_value=false)
1180:       return base if @dn_is_base
1181: 
1182:       dn_value = id
1183:       if dn_value.nil?
1184:         raise DistinguishedNameNotSetError.new,
1185:                 _("%s's DN attribute (%s) isn't set") % [self, dn_attribute]
1186:       end
1187:       dn_value = DN.escape_value(dn_value) if escape_dn_value
1188:       _base = base
1189:       _base = nil if _base.empty?
1190:       ["#{dn_attribute}=#{dn_value}", _base].compact.join(",")
1191:     end

[Source]

      # File lib/active_ldap/base.rb, line 1331
1331:     def create
1332:       prepare_data_for_saving do |data, ldap_data|
1333:         attributes = collect_all_attributes(data)
1334:         add_entry(escaped_dn, attributes)
1335:         @new_entry = false
1336:         true
1337:       end
1338:     end

[Source]

      # File lib/active_ldap/base.rb, line 1303
1303:     def create_or_update
1304:       new_entry? ? create : update
1305:     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 1050
1050:     def enforce_type(key, value)
1051:       # Enforce attribute value formatting
1052:       normalize_attribute(key, value)[1]
1053:     end

[Source]

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

[Source]

      # File lib/active_ldap/base.rb, line 1193
1193:     def escaped_dn
1194:       compute_dn(true)
1195:     end

[Source]

      # File lib/active_ldap/base.rb, line 989
 989:     def extract_object_class(attributes)
 990:       classes = []
 991:       attrs = {}
 992:       attributes.each do |key, value|
 993:         key = key.to_s
 994:         if /\Aobject_?class\z/i =~ key
 995:           classes.concat(value.to_a)
 996:         else
 997:           attrs[key] = value
 998:         end
 999:       end
1000:       [classes, attributes]
1001:     end

[Source]

      # File lib/active_ldap/base.rb, line 1114
1114:     def false_value?(value)
1115:       value.nil? or value == false or value == [] or
1116:         value == "false" or value == "FALSE" or value == ""
1117:     end

get_attribute

Return the value of the attribute called by method_missing?

[Source]

      # File lib/active_ldap/base.rb, line 1070
1070:     def get_attribute(name, force_array=false)
1071:       name, value = get_attribute_before_type_cast(name, force_array)
1072:       return value if name.nil?
1073:       attribute = schema.attribute(name)
1074:       type_cast(attribute, value)
1075:     end

[Source]

      # File lib/active_ldap/base.rb, line 1105
1105:     def get_attribute_as_query(name, force_array=false)
1106:       name, value = get_attribute_before_type_cast(name, force_array)
1107:       if force_array
1108:         value.collect {|x| !false_value?(x)}
1109:       else
1110:         !false_value?(value)
1111:       end
1112:     end

[Source]

      # File lib/active_ldap/base.rb, line 1098
1098:     def get_attribute_before_type_cast(name, force_array=false)
1099:       name = to_real_attribute_name(name)
1100: 
1101:       value = @data[name] || []
1102:       [name, array_of(value, force_array)]
1103:     end

[Source]

      # File lib/active_ldap/base.rb, line 1003
1003:     def init_base
1004:       init_instance_variables
1005:     end

[Source]

      # File lib/active_ldap/base.rb, line 1055
1055:     def init_instance_variables
1056:       @mutex = Mutex.new
1057:       @data = {} # where the r/w entry data is stored
1058:       @ldap_data = {} # original ldap entry data
1059:       @dn_attribute = nil
1060:       @base = nil
1061:       @scope = nil
1062:       @dn = nil
1063:       @connection ||= nil
1064:       clear_connection_based_cache
1065:     end

[Source]

      # File lib/active_ldap/base.rb, line 1007
1007:     def initialize_by_ldap_data(dn, attributes)
1008:       init_base
1009:       @dn = dn
1010:       @new_entry = false
1011:       @dn_is_base = false
1012:       @ldap_data = attributes
1013:       classes, attributes = extract_object_class(attributes)
1014:       self.classes = classes
1015:       self.dn = dn
1016:       self.attributes = attributes
1017:       yield self if block_given?
1018:       assert_dn_attribute
1019:     end

[Source]

     # File lib/active_ldap/base.rb, line 963
963:     def inspect_attribute(name)
964:       values = get_attribute(name, true)
965:       values.collect do |value|
966:         if value.is_a?(String) and value.length > 50
967:           "#{value[0, 50]}...".inspect
968:         elsif value.is_a?(Date) || value.is_a?(Time)
969:           "#{value.to_s(:db)}"
970:         else
971:           value.inspect
972:         end
973:       end
974:       "#{name}: #{values.inspect}"
975:     end

[Source]

      # File lib/active_ldap/base.rb, line 1021
1021:     def instantiate(args)
1022:       dn, attributes, options = args
1023:       options ||= {}
1024: 
1025:       obj = self.class.allocate
1026:       obj.connection = options[:connection] || @connection
1027:       obj.instance_eval do
1028:         initialize_by_ldap_data(dn, attributes)
1029:       end
1030:       obj
1031:     end

[Source]

     # File lib/active_ldap/base.rb, line 985
985:     def local_entry_attribute
986:       @local_entry_attribute ||= connection.entry_attribute([])
987:     end

[Source]

      # File lib/active_ldap/base.rb, line 1226
1226:     def normalize_data(data, except=[])
1227:       _schema = schema
1228:       result = {}
1229:       data.each do |key, values|
1230:         next if except.include?(key)
1231:         real_name = to_real_attribute_name(key)
1232:         next if real_name and except.include?(real_name)
1233:         real_name ||= key
1234:         next if _schema.attribute(real_name).id.nil?
1235:         result[real_name] ||= []
1236:         result[real_name].concat(enforce_type(real_name, values))
1237:       end
1238:       result
1239:     end

[Source]

      # File lib/active_ldap/base.rb, line 1307
1307:     def prepare_data_for_saving
1308:       # Expand subtypes to real ldap_data attributes
1309:       # We can't reuse @ldap_data because an exception would leave
1310:       # an object in an unknown state
1311:       ldap_data = normalize_data(@ldap_data)
1312: 
1313:       # Expand subtypes to real data attributes, but leave @data alone
1314:       bad_attrs = @data.keys - attribute_names
1315:       data = normalize_data(@data, bad_attrs)
1316: 
1317:       success = yield(data, ldap_data)
1318: 
1319:       if success
1320:         @ldap_data = Marshal.load(Marshal.dump(data))
1321:         # Delete items disallowed by objectclasses.
1322:         # They should have been removed from ldap.
1323:         bad_attrs.each do |remove_me|
1324:           @ldap_data.delete(remove_me)
1325:         end
1326:       end
1327: 
1328:       success
1329:     end

set_attribute

Set the value of the attribute called by method_missing?

[Source]

      # File lib/active_ldap/base.rb, line 1122
1122:     def set_attribute(name, value)
1123:       attr = to_real_attribute_name(name)
1124:       attr, value = update_dn(attr, value) if attr == dn_attribute
1125:       raise UnknownAttribute.new(name) if attr.nil?
1126: 
1127:       @data[attr] = value
1128:     end

[Source]

      # File lib/active_ldap/base.rb, line 1154
1154:     def split_dn_value(value)
1155:       dn_value = relative_dn_value = nil
1156:       begin
1157:         dn_value = value if value.is_a?(DN)
1158:         dn_value ||= DN.parse(value)
1159:       rescue DistinguishedNameInvalid
1160:         dn_value = DN.parse("#{dn_attribute}=#{value}")
1161:       end
1162: 
1163:       begin
1164:         relative_dn_value = dn_value - self.class.parsed_base
1165:         if relative_dn_value.rdns.empty?
1166:           val = []
1167:           bases = dn_value.rdns
1168:         else
1169:           val, *bases = relative_dn_value.rdns
1170:         end
1171:       rescue ArgumentError
1172:         val, *bases = dn_value.rdns
1173:       end
1174: 
1175:       dn_attribute_name, dn_attribute_value = val.to_a[0]
1176:       [dn_attribute_name, dn_attribute_value, bases]
1177:     end

[Source]

      # File lib/active_ldap/base.rb, line 1033
1033:     def to_real_attribute_name(name, allow_normalized_name=false)
1034:       return name if name.nil?
1035:       if allow_normalized_name
1036:         entry_attribute.normalize(name, allow_normalized_name) ||
1037:           local_entry_attribute.normalize(name, allow_normalized_name)
1038:       else
1039:         @real_names[name] ||=
1040:           entry_attribute.normalize(name, false) ||
1041:           local_entry_attribute.normalize(name, false)
1042:       end
1043:     end

[Source]

      # File lib/active_ldap/base.rb, line 1077
1077:     def type_cast(attribute, value)
1078:       case value
1079:       when Hash
1080:         result = {}
1081:         value.each do |option, val|
1082:           result[option] = type_cast(attribute, val)
1083:         end
1084:         if result.size == 1 and result.has_key?("binary")
1085:           result["binary"]
1086:         else
1087:           result
1088:         end
1089:       when Array
1090:         value.collect do |val|
1091:           type_cast(attribute, val)
1092:         end
1093:       else
1094:         attribute.type_cast(value)
1095:       end
1096:     end

[Source]

      # File lib/active_ldap/base.rb, line 1340
1340:     def update
1341:       prepare_data_for_saving do |data, ldap_data|
1342:         attributes = collect_modified_attributes(ldap_data, data)
1343:         modify_entry(escaped_dn, attributes)
1344:         true
1345:       end
1346:     end

[Source]

      # File lib/active_ldap/base.rb, line 1130
1130:     def update_dn(attr, value)
1131:       @dn = nil
1132:       @dn_is_base = false
1133:       return [attr, nil] if value.blank?
1134: 
1135:       new_dn_attribute, new_value, bases = split_dn_value(value)
1136:       if new_dn_attribute.nil? and new_value.nil?
1137:         @dn_is_base = true
1138:         @base = nil
1139:         attr, value = bases[0].to_a[0]
1140:         @dn_attribute = attr
1141:       else
1142:         new_dn_attribute = to_real_attribute_name(new_dn_attribute)
1143:         if new_dn_attribute
1144:           value = new_value
1145:           @base = bases.empty? ? nil : DN.new(*bases).to_s
1146:           if dn_attribute != new_dn_attribute
1147:             @dn_attribute = attr = new_dn_attribute
1148:           end
1149:         end
1150:       end
1151:       [attr, value]
1152:     end

[Validate]