Class ActiveLdap::Base
In: lib/active_ldap/base.rb
Parent: Object
Error DeleteError AdapterNotSpecified OperationNotPermitted LdapError RequiredAttributeMissed AttributeAssignmentError RequiredObjectClassMissed DistinguishedNameNotSetError StrongAuthenticationRequired ConnectionError SaveError EntryNotFound AuthenticationError EntryNotSaved UnknownAttribute ConnectionNotEstablished TimeoutError ConfigurationError AdapterNotFound DistinguishedNameInvalid ObjectClassError EntryInvalid EntryAlreadyExist Reloadable::Deprecated Base Reloadable::Subclasses Enumerable Collection StandardError HasMany HasManyWrap BelongsToMany Proxy BelongsTo Base\n[lib/active_ldap/adapter/base.rb\nlib/active_ldap/adapter/ldap.rb\nlib/active_ldap/adapter/net_ldap.rb] Ldap NetLdap ActiveRecord::Callbacks ActiveRecord::Validations Schema DistinguishedName lib/active_ldap/base.rb lib/active_ldap/schema.rb lib/active_ldap/distinguished_name.rb lib/active_ldap/ldap_error.rb ClassMethods Associations lib/active_ldap/association/has_many_wrap.rb lib/active_ldap/association/has_many.rb lib/active_ldap/association/proxy.rb lib/active_ldap/association/collection.rb lib/active_ldap/association/belongs_to_many.rb lib/active_ldap/association/belongs_to.rb Association ClassMethods Configuration Command lib/active_ldap/adapter/net_ldap.rb lib/active_ldap/adapter/ldap.rb lib/active_ldap/adapter/base.rb Adapter ClassMethods Attributes ClassMethods ObjectClass Callbacks ClassMethods Connection Validations Salt UserPassword ActiveLdap dot/m_26_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

==   []   []=   add   apply_object_class   array_of   attribute_names   attribute_present?   attributes   attributes=   base   base   base=   base_class   check_configuration   class_local_attr_accessor   collect_all_entries   collect_modified_entries   create   create   create_or_update   default_dn_attribute   default_prefix   define_attribute_methods   delete   delete_all   destroy   destroy   destroy_all   dn   dn=   dump   each   enforce_type   ensure_apply_object_class   ensure_base   ensure_dn   ensure_dn_attribute   ensure_logger   eql?   escape_filter_value   establish_connection   exists?   exists?   extract_object_class   extract_options_from_args!   false_value?   find   find_every   find_from_dns   find_initial   find_one   find_some   get_attribute   get_attribute_as_query   get_attribute_before_type_cast   has_attribute?   hash   have_attribute?   human_attribute_name   id   id=   init_base   init_instance_variables   initialize_by_ldap_data   instantiate   ldap_mapping   ldap_scope=   load   may   method_missing   methods   modify   must   new   new_entry?   normalize_attribute_names   normalize_data   normalize_sort_order   object_class_filters   prepare_data_for_saving   reload   respond_to?   save   save!   search   set_attribute   split_dn_value   split_search_value   to_ldif   to_ldif   to_param   to_real_attribute_name   to_xml   truncate_base   update   update   update_all   update_attribute   update_attributes   validate_ldap_mapping_options   validate_search_options  

Included Modules

Reloadable::Deprecated Reloadable::Subclasses Enumerable

Constants

VALID_LDAP_MAPPING_OPTIONS = [:dn_attribute, :prefix, :scope, :classes, :recommended_classes]
VALID_SEARCH_OPTIONS = [:attribute, :value, :filter, :prefix, :classes, :scope, :limit, :attributes, :sort_by, :order]

External Aliases

base -> base_inheritable
ldap_scope= -> ldap_scope_without_validation=
respond_to? -> respond_to_without_attributes?
base -> base_of_class

Public Class methods

[Source]

     # File lib/active_ldap/base.rb, line 422
422:       def add(dn, entries, options={})
423:         unnormalized_entries = entries.collect do |type, key, value|
424:           [type, key, unnormalize_attribute(key, value)]
425:         end
426:         connection.add(dn, unnormalized_entries, options)
427:       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 344
344:       def base
345:         _base = base_inheritable
346:         _base = configuration[:base] if _base.nil? and configuration
347:         _base ||= base_inheritable(true)
348:         [prefix, _base].find_all do |component|
349:           component and !component.empty?
350:         end.join(",")
351:       end

[Source]

     # File lib/active_ldap/base.rb, line 511
511:       def base_class
512:         if self == Base or superclass == Base
513:           self
514:         else
515:           superclass.base_class
516:         end
517:       end

[Source]

     # File lib/active_ldap/base.rb, line 179
179:     def self.class_local_attr_accessor(search_ancestors, *syms)
180:       syms.flatten.each do |sym|
181:         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)
182:       end
183:     end

[Source]

     # File lib/active_ldap/base.rb, line 256
256:       def create(attributes=nil, &block)
257:         if attributes.is_a?(Array)
258:           attributes.collect {|attrs| create(attrs, &block)}
259:         else
260:           object = new(attributes, &block)
261:           object.save
262:           object
263:         end
264:       end

[Source]

     # File lib/active_ldap/base.rb, line 402
402:       def delete(targets, options={})
403:         targets = [targets] unless targets.is_a?(Array)
404:         targets = targets.collect do |target|
405:           ensure_dn_attribute(ensure_base(target))
406:         end
407:         connection.delete(targets, options)
408:       end

[Source]

     # File lib/active_ldap/base.rb, line 410
410:       def delete_all(filter=nil, options={})
411:         options = {:base => base, :scope => ldap_scope}.merge(options)
412:         options = options.merge(:filter => filter) if filter
413:         targets = connection.search(options).collect do |dn, attributes|
414:           dn
415:         end.sort_by do |dn|
416:           dn.reverse
417:         end.reverse
418: 
419:         connection.delete(targets)
420:       end

[Source]

     # File lib/active_ldap/base.rb, line 381
381:       def destroy(targets, options={})
382:         targets = [targets] unless targets.is_a?(Array)
383:         targets.each do |target|
384:           find(target, options).destroy
385:         end
386:       end

[Source]

     # File lib/active_ldap/base.rb, line 388
388:       def destroy_all(filter=nil, options={})
389:         targets = []
390:         if filter.is_a?(Hash)
391:           options = options.merge(filter)
392:           filter = nil
393:         end
394:         options = options.merge(:filter => filter) if filter
395:         find(:all, options).sort_by do |target|
396:           target.dn.reverse
397:         end.reverse.each do |target|
398:           target.destroy
399:         end
400:       end

[Source]

     # File lib/active_ldap/base.rb, line 364
364:       def dump(options={})
365:         ldifs = []
366:         options = {:base => base, :scope => ldap_scope}.merge(options)
367:         connection.search(options) do |dn, attributes|
368:           ldifs << to_ldif(dn, attributes)
369:         end
370:         ldifs.join("\n")
371:       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 preconfigured Log4r::Logger to be used for all

  logging

: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 :ldap_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 248
248:       def establish_connection(config=nil)
249:         super
250:         ensure_logger
251:         connection.connect
252:         # Make irb users happy with a 'true'
253:         true
254:       end

[Source]

     # File lib/active_ldap/base.rb, line 455
455:       def exists?(dn, options={})
456:         prefix = /^#{Regexp.escape(truncate_base(ensure_dn_attribute(dn)))}/ #
457:         dn_suffix = nil
458:         not search({:value => dn}.merge(options)).find do |_dn,|
459:           if prefix.match(_dn)
460:             begin
461:               dn_suffix ||= DN.parse(base)
462:               dn_prefix = DN.parse(_dn) - dn_suffix
463:               true
464:             rescue DistinguishedNameInvalid, ArgumentError
465:               false
466:             end
467:           else
468:             false
469:           end
470:         end.nil?
471:       end

find

Finds the first match for value where |value| is the value of some |field|, or the wildcard match. This is only useful for derived classes. usage: Subclass.find(:attribute => "cn", :value => "some*val")

       Subclass.find('some*val')

[Source]

     # File lib/active_ldap/base.rb, line 442
442:       def find(*args)
443:         options = extract_options_from_args!(args)
444:         args = [:first] if args.empty? and !options.empty?
445:         case args.first
446:         when :first
447:           find_initial(options)
448:         when :all
449:           find_every(options)
450:         else
451:           find_from_dns(args, options)
452:         end
453:       end

[Source]

     # File lib/active_ldap/base.rb, line 519
519:       def human_attribute_name(attribute_key_name)
520:         attribute_key_name.humanize
521:       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 316
316:       def ldap_mapping(options={})
317:         validate_ldap_mapping_options(options)
318:         dn_attribute = options[:dn_attribute] || default_dn_attribute
319:         prefix = options[:prefix] || default_prefix
320:         classes = options[:classes]
321:         recommended_classes = options[:recommended_classes]
322:         scope = options[:scope]
323: 
324:         self.dn_attribute = dn_attribute
325:         self.prefix = prefix
326:         self.ldap_scope = scope
327:         self.required_classes = classes
328:         self.recommended_classes = recommended_classes
329: 
330:         public_class_method :new
331:       end

[Source]

     # File lib/active_ldap/base.rb, line 354
354:       def ldap_scope=(scope)
355:         scope = scope.to_sym if scope.is_a?(String)
356:         if scope.nil? or scope.is_a?(Symbol)
357:           self.ldap_scope_without_validation = scope
358:         else
359:           raise ConfigurationError,
360:                   ":ldap_scope '#{scope.inspect}' must be a Symbol"
361:         end
362:       end

[Source]

     # File lib/active_ldap/base.rb, line 377
377:       def load(ldifs)
378:         connection.load(ldifs)
379:       end

[Source]

     # File lib/active_ldap/base.rb, line 429
429:       def modify(dn, entries, options={})
430:         unnormalized_entries = entries.collect do |type, key, value|
431:           [type, key, unnormalize_attribute(key, value)]
432:         end
433:         connection.modify(dn, unnormalized_entries, options)
434:       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 765
765:     def initialize(attributes=nil)
766:       init_base
767:       @new_entry = true
768:       initial_classes = required_classes | recommended_classes
769:       if attributes.nil?
770:         apply_object_class(initial_classes)
771:       elsif attributes.is_a?(String) or attributes.is_a?(Array)
772:         apply_object_class(initial_classes)
773:         self.dn = attributes
774:       elsif attributes.is_a?(Hash)
775:         classes, attributes = extract_object_class(attributes)
776:         apply_object_class(classes | initial_classes)
777:         normalized_attributes = {}
778:         attributes.each do |key, value|
779:           real_key = to_real_attribute_name(key)
780:           normalized_attributes[real_key] = value if real_key
781:         end
782:         self.dn = normalized_attributes[dn_attribute]
783:         self.attributes = normalized_attributes
784:       else
785:         message = "'#{attributes.inspect}' must be either "
786:         message << "nil, DN value as String or Array or attributes as Hash"
787:         raise ArgumentError, message
788:       end
789:       yield self if block_given?
790:     end

[Source]

     # File lib/active_ldap/base.rb, line 266
266:       def search(options={}, &block)
267:         validate_search_options(options)
268:         attr = options[:attribute]
269:         value = options[:value] || '*'
270:         filter = options[:filter]
271:         prefix = options[:prefix]
272:         classes = options[:classes]
273: 
274:         value = value.first if value.is_a?(Array) and value.first.size == 1
275:         if filter.nil? and !value.is_a?(String)
276:           raise ArgumentError, "Search value must be a String"
277:         end
278: 
279:         _attr, value, _prefix = split_search_value(value)
280:         attr ||= _attr || dn_attribute || "objectClass"
281:         prefix ||= _prefix
282:         if filter.nil?
283:           filter = "(#{attr}=#{escape_filter_value(value, true)})"
284:           filter = "(&#{filter}#{object_class_filters(classes)})"
285:         end
286:         _base = [prefix, base].compact.reject{|x| x.empty?}.join(",")
287:         search_options = {
288:           :base => _base,
289:           :scope => options[:scope] || ldap_scope,
290:           :filter => filter,
291:           :limit => options[:limit],
292:           :attributes => options[:attributes],
293:           :sort_by => options[:sort_by],
294:           :order => options[:order],
295:         }
296:         connection.search(search_options) do |dn, attrs|
297:           attributes = {}
298:           attrs.each do |key, value|
299:             normalized_attr, normalized_value = make_subtypes(key, value)
300:             attributes[normalized_attr] ||= []
301:             attributes[normalized_attr].concat(normalized_value)
302:           end
303:           value = [dn, attributes]
304:           value = yield(value) if block_given?
305:           value
306:         end
307:       end

[Source]

     # File lib/active_ldap/base.rb, line 373
373:       def to_ldif(dn, attributes)
374:         connection.to_ldif(dn, unnormalize_attributes(attributes))
375:       end

[Source]

     # File lib/active_ldap/base.rb, line 473
473:       def update(dn, attributes, options={})
474:         if dn.is_a?(Array)
475:           i = -1
476:           dns = dn
477:           dns.collect do |dn|
478:             i += 1
479:             update(dn, attributes[i], options)
480:           end
481:         else
482:           object = find(dn, options)
483:           object.update_attributes(attributes)
484:           object
485:         end
486:       end

[Source]

     # File lib/active_ldap/base.rb, line 488
488:       def update_all(attributes, filter=nil, options={})
489:         search_options = options
490:         if filter
491:           if filter.is_a?(String) and /[=\(\)&\|]/ !~ filter
492:             search_options = search_options.merge(:value => filter)
493:           else
494:             search_options = search_options.merge(:filter => filter)
495:           end
496:         end
497:         targets = search(search_options).collect do |dn, attrs|
498:           dn
499:         end
500: 
501:         entries = attributes.collect do |name, value|
502:           normalized_name, normalized_value = normalize_attribute(name, value)
503:           [:replace, normalized_name,
504:            unnormalize_attribute(normalized_name, normalized_value)]
505:         end
506:         targets.each do |dn|
507:           connection.modify(dn, entries, options)
508:         end
509:       end

Private Class methods

[Source]

     # File lib/active_ldap/base.rb, line 730
730:       def default_dn_attribute
731:         if name.empty?
732:           dn_attribute = nil
733:           parent_class = ancestors[1]
734:           if parent_class.respond_to?(:dn_attribute)
735:             dn_attribute = parent_class.dn_attribute
736:           end
737:           dn_attribute || "cn"
738:         else
739:           Inflector.underscore(Inflector.demodulize(name))
740:         end
741:       end

[Source]

     # File lib/active_ldap/base.rb, line 743
743:       def default_prefix
744:         if name.empty?
745:           nil
746:         else
747:           "ou=#{Inflector.pluralize(Inflector.demodulize(name))}"
748:         end
749:       end

[Source]

     # File lib/active_ldap/base.rb, line 684
684:       def ensure_base(target)
685:         [truncate_base(target),  base].join(',')
686:       end

[Source]

     # File lib/active_ldap/base.rb, line 674
674:       def ensure_dn(target)
675:         attr, value, prefix = split_search_value(target)
676:         "#{attr || dn_attribute}=#{value},#{prefix || base}"
677:       end

[Source]

     # File lib/active_ldap/base.rb, line 679
679:       def ensure_dn_attribute(target)
680:         "#{dn_attribute}=" +
681:           target.gsub(/^\s*#{Regexp.escape(dn_attribute)}\s*=\s*/i, '')
682:       end

[Source]

     # File lib/active_ldap/base.rb, line 700
700:       def ensure_logger
701:         @@logger ||= configuration[:logger]
702:         # Setup default logger to console
703:         if @@logger.nil?
704:           require 'log4r'
705:           @@logger = Log4r::Logger.new('activeldap')
706:           @@logger.level = Log4r::OFF
707:           Log4r::StderrOutputter.new 'console'
708:           @@logger.add('console')
709:         end
710:         configuration[:logger] ||= @@logger
711:       end

[Source]

     # File lib/active_ldap/base.rb, line 664
664:       def escape_filter_value(value, without_asterisk=false)
665:         value.gsub(/[\*\(\)\\\0]/) do |x|
666:           if without_asterisk and x == "*"
667:             x
668:           else
669:             "\\%02x" % x[0]
670:           end
671:         end
672:       end

[Source]

     # File lib/active_ldap/base.rb, line 532
532:       def extract_options_from_args!(args)
533:         args.last.is_a?(Hash) ? args.pop : {}
534:       end

[Source]

     # File lib/active_ldap/base.rb, line 557
557:       def find_every(options)
558:         options = options.dup
559:         sort_by = options.delete(:sort_by)
560:         order = options.delete(:order)
561:         limit = options.delete(:limit) if sort_by or order
562: 
563:         results = search(options).collect do |dn, attrs|
564:           instantiate([dn, attrs])
565:         end
566:         return results if sort_by.nil? and order.nil?
567: 
568:         sort_by ||= "dn"
569:         if sort_by.downcase == "dn"
570:           results = results.sort_by {|result| DN.parse(result.dn)}
571:         else
572:           results = results.sort_by {|result| result.send(sort_by)}
573:         end
574: 
575:         results.reverse! if normalize_sort_order(order || "ascend") == :descend
576:         results = results[0, limit] if limit
577:         results
578:       end

[Source]

     # File lib/active_ldap/base.rb, line 580
580:       def find_from_dns(dns, options)
581:         expects_array = dns.first.is_a?(Array)
582:         return [] if expects_array and dns.first.empty?
583: 
584:         dns = dns.flatten.compact.uniq
585: 
586:         case dns.size
587:         when 0
588:           raise EntryNotFound, "Couldn't find #{name} without a DN"
589:         when 1
590:           result = find_one(dns.first, options)
591:           expects_array ? [result] : result
592:         else
593:           find_some(dns, options)
594:         end
595:       end

[Source]

     # File lib/active_ldap/base.rb, line 542
542:       def find_initial(options)
543:         find_every(options.merge(:limit => 1)).first
544:       end

[Source]

     # File lib/active_ldap/base.rb, line 597
597:       def find_one(dn, options)
598:         attr, value, prefix = split_search_value(dn)
599:         filters = [
600:           "(#{attr || dn_attribute}=#{escape_filter_value(value, true)})",
601:           object_class_filters(options[:classes]),
602:           options[:filter],
603:         ]
604:         filter = "(&#{filters.compact.join('')})"
605:         options = {:prefix => prefix}.merge(options.merge(:filter => filter))
606:         result = find_initial(options)
607:         if result
608:           result
609:         else
610:           message = "Couldn't find #{name} with DN=#{dn}"
611:           message << " #{options[:filter]}" if options[:filter]
612:           raise EntryNotFound, message
613:         end
614:       end

[Source]

     # File lib/active_ldap/base.rb, line 616
616:       def find_some(dns, options)
617:         dn_filters = dns.collect do |dn|
618:           attr, value, prefix = split_search_value(dn)
619:           attr ||= dn_attribute
620:           filter = "(#{attr}=#{escape_filter_value(value, true)})"
621:           if prefix
622:             filter = "(&#{filter}(dn=*,#{escape_filter_value(prefix)},#{base}))"
623:           end
624:           filter
625:         end
626:         filters = [
627:           "(|#{dn_filters.join('')})",
628:           object_class_filters(options[:classes]),
629:           options[:filter],
630:         ]
631:         filter = "(&#{filters.compact.join('')})"
632:         result = find_every(options.merge(:filter => filter))
633:         if result.size == dns.size
634:           result
635:         else
636:           message = "Couldn't find all #{name} with DNs (#{dns.join(', ')})"
637:           message << " #{options[:filter]}"if options[:filter]
638:           raise EntryNotFound, message
639:         end
640:       end

[Source]

     # File lib/active_ldap/base.rb, line 713
713:       def instantiate(entry)
714:         dn, attributes = entry
715:         if self.class == Class
716:           klass = self.ancestors[0].to_s.split(':').last
717:           real_klass = self.ancestors[0]
718:         else
719:           klass = self.class.to_s.split(':').last
720:           real_klass = self.class
721:         end
722: 
723:         obj = real_klass.allocate
724:         obj.instance_eval do
725:           initialize_by_ldap_data(dn, attributes)
726:         end
727:         obj
728:       end

[Source]

     # File lib/active_ldap/base.rb, line 546
546:       def normalize_sort_order(value)
547:         case value.to_s
548:         when /\Aasc(?:end)?\z/i
549:           :ascend
550:         when /\Adesc(?:end)?\z/i
551:           :descend
552:         else
553:           raise ArgumentError, "Invalid order: #{value.inspect}"
554:         end
555:       end

[Source]

     # File lib/active_ldap/base.rb, line 536
536:       def object_class_filters(classes=nil)
537:         (classes || required_classes).collect do |name|
538:           "(objectClass=#{escape_filter_value(name, true)})"
539:         end.join("")
540:       end

[Source]

     # File lib/active_ldap/base.rb, line 642
642:       def split_search_value(value)
643:         attr = prefix = nil
644:         begin
645:           dn = DN.parse(value)
646:           attr, value = dn.rdns.first.to_a.first
647:           rest = dn.rdns[1..-1]
648:           prefix = DN.new(*rest).to_s unless rest.empty?
649:         rescue DistinguishedNameInvalid
650:           begin
651:             dn = DN.parse("DUMMY=#{value}")
652:             _, value = dn.rdns.first.to_a.first
653:             rest = dn.rdns[1..-1]
654:             prefix = DN.new(*rest).to_s unless rest.empty?
655:           rescue DistinguishedNameInvalid
656:           end
657:         end
658: 
659:         prefix = nil if prefix == base
660:         prefix = truncate_base(prefix) if prefix
661:         [attr, value, prefix]
662:       end

[Source]

     # File lib/active_ldap/base.rb, line 688
688:       def truncate_base(target)
689:         if /,/ =~ target
690:           begin
691:             (DN.parse(target) - DN.parse(base)).to_s
692:           rescue DistinguishedNameInvalid, ArgumentError
693:             target
694:           end
695:         else
696:           target
697:         end
698:       end

[Source]

     # File lib/active_ldap/base.rb, line 524
524:       def validate_ldap_mapping_options(options)
525:         options.assert_valid_keys(VALID_LDAP_MAPPING_OPTIONS)
526:       end

[Source]

     # File lib/active_ldap/base.rb, line 528
528:       def validate_search_options(options)
529:         options.assert_valid_keys(VALID_SEARCH_OPTIONS)
530:       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 794
794:     def ==(comparison_object)
795:       comparison_object.equal?(self) or
796:         (comparison_object.instance_of?(self.class) and
797:          comparison_object.dn == dn and
798:          !comparison_object.new_entry?)
799:     end

[Source]

      # File lib/active_ldap/base.rb, line 1054
1054:     def [](name, force_array=false)
1055:       if name == "dn"
1056:         array_of(dn, force_array)
1057:       else
1058:         get_attribute(name, force_array)
1059:       end
1060:     end

[Source]

      # File lib/active_ldap/base.rb, line 1062
1062:     def []=(name, value)
1063:       set_attribute(name, value)
1064:     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 828
828:     def attribute_names
829:       logger.debug {"stub: attribute_names called"}
830:       ensure_apply_object_class
831:       return @attr_methods.keys
832:     end

[Source]

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

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

[Source]

     # File lib/active_ldap/base.rb, line 990
990:     def attributes
991:       Marshal.load(Marshal.dump(@data))
992:     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 1000
1000:     def attributes=(hash_or_assoc)
1001:       targets = remove_attributes_protected_from_mass_assignment(hash_or_assoc)
1002:       targets.each do |key, value|
1003:         set_attribute(key, value) if have_attribute?(key)
1004:       end
1005:     end

destroy

Delete this entry from LDAP

[Source]

     # File lib/active_ldap/base.rb, line 884
884:     def destroy
885:       logger.debug {"stub: delete called"}
886:       begin
887:         self.class.delete(dn)
888:         @new_entry = true
889:       rescue Error
890:         raise DeleteError.new("Failed to delete LDAP entry: '#{dn}'")
891:       end
892:     end

dn

Return the authoritative dn

[Source]

     # File lib/active_ldap/base.rb, line 856
856:     def dn
857:       logger.debug {"stub: dn called"}
858:       dn_value = id
859:       if dn_value.nil?
860:         raise DistinguishedNameNotSetError.new,
861:                 "#{dn_attribute} value of #{self} doesn't set"
862:       end
863:       _base = base
864:       _base = nil if _base.empty?
865:       ["#{dn_attribute}=#{dn_value}", _base].compact.join(",")
866:     end

[Source]

     # File lib/active_ldap/base.rb, line 876
876:     def dn=(value)
877:       set_attribute(dn_attribute, value)
878:     end

[Source]

      # File lib/active_ldap/base.rb, line 1066
1066:     def each
1067:       @data.each do |key, values|
1068:         yield(key.dup, values.dup)
1069:       end
1070:     end

Delegates to ==

[Source]

     # File lib/active_ldap/base.rb, line 802
802:     def eql?(comparison_object)
803:       self == (comparison_object)
804:     end

exists?

Return whether the entry exists in LDAP or not

[Source]

     # File lib/active_ldap/base.rb, line 842
842:     def exists?
843:       self.class.exists?(dn)
844:     end
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 810
810:     def hash
811:       dn.hash
812:     end

[Source]

      # File lib/active_ldap/base.rb, line 1034
1034:     def have_attribute?(name, except=[])
1035:       real_name = to_real_attribute_name(name)
1036:       real_name and !except.include?(real_name)
1037:     end

[Source]

     # File lib/active_ldap/base.rb, line 868
868:     def id
869:       get_attribute(dn_attribute)
870:     end
id=(value)

Alias for dn=

[Source]

     # File lib/active_ldap/base.rb, line 814
814:     def may
815:       ensure_apply_object_class
816:       @may
817:     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 916
916:     def method_missing(name, *args, &block)
917:       logger.debug {"stub: called method_missing" +
918:                       "(#{name.inspect}, #{args.inspect})"}
919:       ensure_apply_object_class
920: 
921:       key = name.to_s
922:       case key
923:       when /=$/
924:         real_key = $PREMATCH
925:         logger.debug {"method_missing: have_attribute? #{real_key}"}
926:         if have_attribute?(real_key, ['objectClass'])
927:           if args.size != 1
928:             raise ArgumentError,
929:                     "wrong number of arguments (#{args.size} for 1)"
930:           end
931:           logger.debug {"method_missing: calling set_attribute" +
932:                           "(#{real_key}, #{args.inspect})"}
933:           return set_attribute(real_key, *args, &block)
934:         end
935:       when /(?:(_before_type_cast)|(\?))?$/
936:         real_key = $PREMATCH
937:         before_type_cast = !$1.nil?
938:         query = !$2.nil?
939:         logger.debug {"method_missing: have_attribute? #{real_key}"}
940:         if have_attribute?(real_key, ['objectClass'])
941:           if args.size > 1
942:             raise ArgumentError,
943:               "wrong number of arguments (#{args.size} for 1)"
944:           end
945:           if before_type_cast
946:             return get_attribute_before_type_cast(real_key, *args)
947:           elsif query
948:             return get_attribute_as_query(real_key, *args)
949:           else
950:             return get_attribute(real_key, *args)
951:           end
952:         end
953:       end
954:       super
955:     end

Add available attributes to the methods

[Source]

     # File lib/active_ldap/base.rb, line 958
958:     def methods(inherited_too=true)
959:       ensure_apply_object_class
960:       target_names = @attr_methods.keys + @attr_aliases.keys
961:       target_names -= ['objectClass', Inflector.underscore('objectClass')]
962:       super + target_names.uniq.collect do |x|
963:         [x, "#{x}=", "#{x}?", "#{x}_before_type_cast"]
964:       end.flatten
965:     end

[Source]

     # File lib/active_ldap/base.rb, line 819
819:     def must
820:       ensure_apply_object_class
821:       @must
822:     end

new_entry?

Return whether the entry is new entry in LDAP or not

[Source]

     # File lib/active_ldap/base.rb, line 849
849:     def new_entry?
850:       @new_entry
851:     end

[Source]

      # File lib/active_ldap/base.rb, line 1040
1040:     def reload
1041:       _, attributes = self.class.search(:value => id).find do |_dn, _attributes|
1042:         dn == _dn
1043:       end
1044:       raise EntryNotFound, "Can't find dn '#{dn}' to reload" if attributes.nil?
1045: 
1046:       @ldap_data.update(attributes)
1047:       classes, attributes = extract_object_class(attributes)
1048:       apply_object_class(classes)
1049:       self.attributes = attributes
1050:       @new_entry = false
1051:       self
1052:     end

[Source]

     # File lib/active_ldap/base.rb, line 968
968:     def respond_to?(name, include_priv=false)
969:       have_attribute?(name.to_s) or
970:         (/(?:=|\?|_before_type_cast)$/ =~ name.to_s and
971:          have_attribute?($PREMATCH)) or
972:         super
973:     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 899
899:     def save
900:       create_or_update
901:     end

[Source]

     # File lib/active_ldap/base.rb, line 903
903:     def save!
904:       unless create_or_update
905:         raise EntryNotSaved, "entry #{dn} can't saved"
906:       end
907:     end

[Source]

      # File lib/active_ldap/base.rb, line 1007
1007:     def to_ldif
1008:       self.class.to_ldif(dn, normalize_data(@data))
1009:     end

[Source]

     # File lib/active_ldap/base.rb, line 872
872:     def to_param
873:       id
874:     end

[Source]

      # File lib/active_ldap/base.rb, line 1011
1011:     def to_xml(options={})
1012:       root = options[:root] || Inflector.underscore(self.class.name)
1013:       result = "<#{root}>\n"
1014:       result << "  <dn>#{dn}</dn>\n"
1015:       normalize_data(@data).sort_by {|key, values| key}.each do |key, values|
1016:         targets = []
1017:         values.each do |value|
1018:           if value.is_a?(Hash)
1019:             value.each do |option, real_value|
1020:               targets << [real_value, " #{option}=\"true\""]
1021:             end
1022:           else
1023:             targets << [value]
1024:           end
1025:         end
1026:         targets.sort_by {|value, attr| value}.each do |value, attr|
1027:           result << "  <#{key}#{attr}>#{value}</#{key}>\n"
1028:         end
1029:       end
1030:       result << "</#{root}>\n"
1031:       result
1032:     end

Updates a given attribute and saves immediately

[Source]

     # File lib/active_ldap/base.rb, line 976
976:     def update_attribute(name, value)
977:       set_attribute(name, value) if have_attribute?(name)
978:       save
979:     end

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

[Source]

     # File lib/active_ldap/base.rb, line 983
983:     def update_attributes(attrs)
984:       self.attributes = attrs
985:       save
986:     end

Private Instance methods

apply_object_class

objectClass= special case for updating appropriately This updates the objectClass entry in @data. It also updating all required and allowed attributes while removing defined attributes that are no longer valid given the new objectclasses.

[Source]

      # File lib/active_ldap/base.rb, line 1157
1157:     def apply_object_class(val)
1158:       logger.debug {"stub: objectClass=(#{val.inspect}) called"}
1159:       new_oc = val
1160:       new_oc = [val] if new_oc.class != Array
1161:       new_oc = new_oc.uniq
1162:       return new_oc if @last_oc == new_oc
1163: 
1164:       # Store for caching purposes
1165:       @last_oc = new_oc.dup
1166: 
1167:       # Set the actual objectClass data
1168:       define_attribute_methods('objectClass')
1169:       replace_class(*new_oc)
1170: 
1171:       # Build |data| from schema
1172:       # clear attr_method mapping first
1173:       @attr_methods = {}
1174:       @normalized_attr_names = {}
1175:       @attr_aliases = {}
1176:       @musts = {}
1177:       @mays = {}
1178:       new_oc.each do |objc|
1179:         # get all attributes for the class
1180:         attributes = schema.class_attributes(objc)
1181:         @musts[objc] = attributes[:must]
1182:         @mays[objc] = attributes[:may]
1183:       end
1184:       @must = normalize_attribute_names(@musts.values)
1185:       @may = normalize_attribute_names(@mays.values)
1186:       (@must + @may).uniq.each do |attr|
1187:         # Update attr_method with appropriate
1188:         define_attribute_methods(attr)
1189:       end
1190:     end

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 1330
1330:     def array_of(value, to_a=true)
1331:       logger.debug {"stub: called array_of" +
1332:                       "(#{value.inspect}, #{to_a.inspect})"}
1333:       case value
1334:       when Array
1335:         if to_a or value.size > 1
1336:           value.collect {|v| array_of(v, to_a)}
1337:         else
1338:           if value.empty?
1339:             nil
1340:           else
1341:             array_of(value.first, to_a)
1342:           end
1343:         end
1344:       when Hash
1345:         if to_a
1346:           [value]
1347:         else
1348:           result = {}
1349:           value.each {|k, v| result[k] = array_of(v, to_a)}
1350:           result
1351:         end
1352:       else
1353:         to_a ? [value.to_s] : value.to_s
1354:       end
1355:     end

[Source]

      # File lib/active_ldap/base.rb, line 1199
1199:     def base
1200:       logger.debug {"stub: called base"}
1201:       [@base, base_of_class].compact.join(",")
1202:     end

[Source]

      # File lib/active_ldap/base.rb, line 1205
1205:     def base=(object_local_base)
1206:       @base = object_local_base
1207:     end

[Source]

      # File lib/active_ldap/base.rb, line 1443
1443:     def check_configuration
1444:       unless dn_attribute
1445:         raise ConfigurationError,
1446:                 "dn_attribute not set for this class: #{self.class}"
1447:       end
1448:     end

[Source]

      # File lib/active_ldap/base.rb, line 1418
1418:     def collect_all_entries(data)
1419:       dn_attr = to_real_attribute_name(dn_attribute)
1420:       dn_value = data[dn_attr]
1421:       logger.debug {'#collect_all_entries: adding all attribute value pairs'}
1422:       logger.debug {"#collect_all_entries: adding " +
1423:                       "#{dn_attr.inspect} = #{dn_value.inspect}"}
1424: 
1425:       entries = []
1426:       entries.push([:add, dn_attr, dn_value])
1427: 
1428:       oc_value = data['objectClass']
1429:       logger.debug {"#collect_all_entries: adding objectClass = " +
1430:                       "#{oc_value.inspect}"}
1431:       entries.push([:add, 'objectClass', oc_value])
1432:       data.each do |key, value|
1433:         next if value.empty? or key == 'objectClass' or key == dn_attr
1434: 
1435:         logger.debug {"#collect_all_entries: adding attribute to new " +
1436:                         "entry: #{key.inspect}: #{value.inspect}"}
1437:         entries.push([:add, key, value])
1438:       end
1439: 
1440:       entries
1441:     end

[Source]

      # File lib/active_ldap/base.rb, line 1370
1370:     def collect_modified_entries(ldap_data, data)
1371:       entries = []
1372:       # Now that all the subtypes will be treated as unique attributes
1373:       # we can see what's changed and add anything that is brand-spankin'
1374:       # new.
1375:       logger.debug {'#collect_modified_entries: traversing ldap_data ' +
1376:                       'determining replaces and deletes'}
1377:       ldap_data.each do |k, v|
1378:         value = data[k] || []
1379: 
1380:         next if v == value
1381: 
1382:         # Create mod entries
1383:         if value.empty?
1384:           # Since some types do not have equality matching rules,
1385:           # delete doesn't work
1386:           # Replacing with nothing is equivalent.
1387:           logger.debug {"#save: removing attribute from existing entry: #{k}"}
1388:           if !data.has_key?(k) and schema.binary_required?(k)
1389:             value = [{'binary' => []}]
1390:           end
1391:         else
1392:           # Ditched delete then replace because attribs with no equality
1393:           # match rules will fails
1394:           logger.debug {"#collect_modified_entries: updating attribute of" +
1395:                           " existing entry: #{k}: #{value.inspect}"}
1396:         end
1397:         entries.push([:replace, k, value])
1398:       end
1399:       logger.debug {'#collect_modified_entries: finished traversing' +
1400:                       ' ldap_data'}
1401:       logger.debug {'#collect_modified_entries: traversing data ' +
1402:                       'determining adds'}
1403:       data.each do |k, v|
1404:         value = v || []
1405:         next if ldap_data.has_key?(k) or value.empty?
1406: 
1407:         # Detect subtypes and account for them
1408:         logger.debug {"#save: adding attribute to existing entry: " +
1409:                         "#{k}: #{value.inspect}"}
1410:         # REPLACE will function like ADD, but doesn't hit EQUALITY problems
1411:         # TODO: Added equality(attr) to Schema
1412:         entries.push([:replace, k, value])
1413:       end
1414: 
1415:       entries
1416:     end

[Source]

      # File lib/active_ldap/base.rb, line 1489
1489:     def create
1490:       prepare_data_for_saving do |data, ldap_data|
1491:         entries = collect_all_entries(data)
1492:         logger.debug {"#create: adding #{dn}"}
1493:         self.class.add(dn, entries)
1494:         logger.debug {"#create: add successful"}
1495:         @new_entry = false
1496:         true
1497:       end
1498:     end

[Source]

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

define_attribute_methods

Make a method entry for every alias of a valid attribute and map it onto the first attribute passed in.

[Source]

      # File lib/active_ldap/base.rb, line 1310
1310:     def define_attribute_methods(attr)
1311:       logger.debug {"stub: called define_attribute_methods(#{attr.inspect})"}
1312:       return if @attr_methods.has_key? attr
1313:       schema.attribute_aliases(attr).each do |ali|
1314:         logger.debug {"associating #{ali} --> #{attr}"}
1315:         @attr_methods[ali] = attr
1316:         logger.debug {"associating #{Inflector.underscore(ali)}" +
1317:                         " --> #{attr}"}
1318:         @attr_aliases[Inflector.underscore(ali)] = attr
1319:         logger.debug {"associating #{normalize_attribute_name(ali)}" +
1320:                         " --> #{attr}"}
1321:         @normalized_attr_names[normalize_attribute_name(ali)] = attr
1322:       end
1323:       logger.debug {"stub: leaving define_attribute_methods(#{attr.inspect})"}
1324:     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 1130
1130:     def enforce_type(key, value)
1131:       logger.debug {"stub: enforce_type called"}
1132:       ensure_apply_object_class
1133:       # Enforce attribute value formatting
1134:       result = self.class.normalize_attribute(key, value)[1]
1135:       logger.debug {"stub: enforce_types done"}
1136:       result
1137:     end

[Source]

      # File lib/active_ldap/base.rb, line 1119
1119:     def ensure_apply_object_class
1120:       current_object_class = @data['objectClass']
1121:       return if current_object_class.nil? or current_object_class == @last_oc
1122:       apply_object_class(current_object_class)
1123:     end

[Source]

      # File lib/active_ldap/base.rb, line 1073
1073:     def extract_object_class(attributes)
1074:       classes = []
1075:       attrs = attributes.reject do |key, value|
1076:         key = key.to_s
1077:         if key == 'objectClass' or
1078:             key.underscore == 'object_class' or
1079:             key.downcase == 'objectclass'
1080:           classes |= [value].flatten
1081:           true
1082:         else
1083:           false
1084:         end
1085:       end
1086:       [classes, attrs]
1087:     end

[Source]

      # File lib/active_ldap/base.rb, line 1229
1229:     def false_value?(value)
1230:       value.nil? or value == false or value == [] or
1231:         value == "false" or value == "FALSE" or value == ""
1232:     end

get_attribute

Return the value of the attribute called by method_missing?

[Source]

      # File lib/active_ldap/base.rb, line 1212
1212:     def get_attribute(name, force_array=false)
1213:       logger.debug {"stub: called get_attribute" +
1214:                       "(#{name.inspect}, #{force_array.inspect}"}
1215:       get_attribute_before_type_cast(name, force_array)
1216:     end

[Source]

      # File lib/active_ldap/base.rb, line 1218
1218:     def get_attribute_as_query(name, force_array=false)
1219:       logger.debug {"stub: called get_attribute_as_query" +
1220:                       "(#{name.inspect}, #{force_array.inspect}"}
1221:       value = get_attribute_before_type_cast(name, force_array)
1222:       if force_array
1223:         value.collect {|x| !false_value?(x)}
1224:       else
1225:         !false_value?(value)
1226:       end
1227:     end

[Source]

      # File lib/active_ldap/base.rb, line 1234
1234:     def get_attribute_before_type_cast(name, force_array=false)
1235:       logger.debug {"stub: called get_attribute_before_type_cast" +
1236:                       "(#{name.inspect}, #{force_array.inspect}"}
1237:       attr = to_real_attribute_name(name)
1238: 
1239:       value = @data[attr] || []
1240:       # Return a copy of the stored data
1241:       if force_array
1242:         value.dup
1243:       else
1244:         array_of(value.dup, false)
1245:       end
1246:     end

[Source]

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

[Source]

      # File lib/active_ldap/base.rb, line 1139
1139:     def init_instance_variables
1140:       @data = {} # where the r/w entry data is stored
1141:       @ldap_data = {} # original ldap entry data
1142:       @attr_methods = {} # list of valid method calls for attributes used for
1143:                          # dereferencing
1144:       @normalized_attr_names = {} # list of normalized attribute name
1145:       @attr_aliases = {} # aliases of @attr_methods
1146:       @last_oc = false # for use in other methods for "caching"
1147:       @base = nil
1148:     end

[Source]

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

[Source]

      # File lib/active_ldap/base.rb, line 1192
1192:     def normalize_attribute_names(names)
1193:       names.flatten.uniq.collect do |may|
1194:         schema.attribute_aliases(may).first
1195:       end
1196:     end

[Source]

      # File lib/active_ldap/base.rb, line 1357
1357:     def normalize_data(data, except=[])
1358:       result = {}
1359:       data.each do |key, values|
1360:         next if except.include?(key)
1361:         real_name = to_real_attribute_name(key)
1362:         next if real_name and except.include?(real_name)
1363:         real_name ||= key
1364:         result[real_name] ||= []
1365:         result[real_name].concat(values)
1366:       end
1367:       result
1368:     end

[Source]

      # File lib/active_ldap/base.rb, line 1454
1454:     def prepare_data_for_saving
1455:       logger.debug {"stub: save called"}
1456: 
1457:       # Expand subtypes to real ldap_data entries
1458:       # We can't reuse @ldap_data because an exception would leave
1459:       # an object in an unknown state
1460:       logger.debug {"#save: expanding subtypes in @ldap_data"}
1461:       ldap_data = normalize_data(@ldap_data)
1462:       logger.debug {'#save: subtypes expanded for @ldap_data'}
1463: 
1464:       # Expand subtypes to real data entries, but leave @data alone
1465:       logger.debug {'#save: expanding subtypes for @data'}
1466:       bad_attrs = @data.keys - attribute_names
1467:       data = normalize_data(@data, bad_attrs)
1468:       logger.debug {'#save: subtypes expanded for @data'}
1469: 
1470:       success = yield(data, ldap_data)
1471: 
1472:       if success
1473:         logger.debug {"#save: resetting @ldap_data to a dup of @data"}
1474:         @ldap_data = Marshal.load(Marshal.dump(data))
1475:         # Delete items disallowed by objectclasses.
1476:         # They should have been removed from ldap.
1477:         logger.debug {'#save: removing attributes from @ldap_data not ' +
1478:                       'sent in data'}
1479:         bad_attrs.each do |remove_me|
1480:           @ldap_data.delete(remove_me)
1481:         end
1482:         logger.debug {'#save: @ldap_data reset complete'}
1483:       end
1484: 
1485:       logger.debug {'stub: save exited'}
1486:       success
1487:     end

set_attribute

Set the value of the attribute called by method_missing?

[Source]

      # File lib/active_ldap/base.rb, line 1251
1251:     def set_attribute(name, value)
1252:       logger.debug {"stub: called set_attribute" +
1253:                       "(#{name.inspect}, #{value.inspect})"}
1254: 
1255:       # Get the attr and clean up the input
1256:       attr = to_real_attribute_name(name)
1257:       raise UnknownAttribute.new(name) if attr.nil?
1258: 
1259:       if attr == dn_attribute and value.is_a?(String)
1260:         value, @base = split_dn_value(value)
1261:       end
1262: 
1263:       logger.debug {"set_attribute(#{name.inspect}, #{value.inspect}): " +
1264:                       "method maps to #{attr}"}
1265: 
1266:       # Enforce LDAP-pleasing values
1267:       logger.debug {"value = #{value.inspect}, value.class = #{value.class}"}
1268:       real_value = value
1269:       # Squash empty values
1270:       if value.class == Array
1271:         real_value = value.collect {|c| (c.nil? or c.empty?) ? [] : c}.flatten
1272:       end
1273:       real_value = [] if real_value.nil?
1274:       real_value = [] if real_value == ''
1275:       real_value = [real_value] if real_value.class == String
1276:       real_value = [real_value.to_s] if real_value.class == Fixnum
1277:       # NOTE: Hashes are allowed for subtyping.
1278: 
1279:       # Assign the value
1280:       @data[attr] = enforce_type(attr, real_value)
1281: 
1282:       # Return the passed in value
1283:       logger.debug {"stub: exiting set_attribute"}
1284:       @data[attr]
1285:     end

[Source]

      # File lib/active_ldap/base.rb, line 1287
1287:     def split_dn_value(value)
1288:       dn_value = relative_dn_value = nil
1289:       begin
1290:         dn_value = DN.parse(value)
1291:       rescue DistinguishedNameInvalid
1292:         dn_value = DN.parse("#{dn_attribute}=#{value}")
1293:       end
1294: 
1295:       begin
1296:         relative_dn_value = dn_value - DN.parse(base_of_class)
1297:         relative_dn_value = dn_value if relative_dn_value.rdns.empty?
1298:       rescue ArgumentError
1299:         relative_dn_value = dn_value
1300:       end
1301: 
1302:       val, *bases = relative_dn_value.rdns
1303:       [val.values[0], bases.empty? ? nil : DN.new(*bases).to_s]
1304:     end

[Source]

      # File lib/active_ldap/base.rb, line 1105
1105:     def to_real_attribute_name(name, allow_normalized_name=false)
1106:       ensure_apply_object_class
1107:       name = name.to_s
1108:       real_name = @attr_methods[name]
1109:       real_name ||= @attr_aliases[Inflector.underscore(name)]
1110:       if real_name
1111:         real_name
1112:       elsif allow_normalized_name
1113:         @attr_methods[@normalized_attr_names[normalize_attribute_name(name)]]
1114:       else
1115:         nil
1116:       end
1117:     end

[Source]

      # File lib/active_ldap/base.rb, line 1500
1500:     def update
1501:       prepare_data_for_saving do |data, ldap_data|
1502:         entries = collect_modified_entries(ldap_data, data)
1503:         logger.debug {'#update: traversing data complete'}
1504:         logger.debug {"#update: modifying #{dn}"}
1505:         self.class.modify(dn, entries)
1506:         logger.debug {'#update: modify successful'}
1507:         true
1508:       end
1509:     end

[Validate]