#
# Encapsulate access to LDAP, caching results for performance.  For best
# performance in applications that access large number of objects, make use
# of the preload methods to pre-fetch multiple objects in a single LDAP
# call, and rely on the cache to find the objects later.
#
# The cache makes heavy use of Weak References internally to enable garbage
# collection to reclaim objects; among other things, this ensures that
# LDAP results don't become too stale.
#
# Until garbage collection reclaims an object, calls to find methods for the
# same name is guaranteed to return the same object.  Holding on to the
# results of find or preload calls (by assigning it to a variable) is
# sufficient to prevent reclaiming of objects.
#
# To illustrate, the following is likely to return the same id twice, followed
# by a new id:
#   puts ASF::Person.find('rubys').__id__
#   puts ASF::Person.find('rubys').__id__
#   GC.start
#   puts ASF::Person.find('rubys').__id__
#
# By contrast, the following is guaranteed to produce the same id three times:
#   rubys1 = ASF::Person.find('rubys')
#   rubys2 = ASF::Person.find('rubys')
#   GC.start
#   rubys3 = ASF::Person.find('rubys')
#   puts [rubys1.__id__, rubys2.__id__, rubys3.__id__]
#

# Note: custom ASF LDAP attributes are defined in the file:
# https://github.com/apache/infrastructure-puppet/blob/deployment/modules/ldapserver/files/asf-custom.schema

require 'wunderbar'
require 'ldap'
require 'weakref'
require 'net/http'
require 'base64'
require 'thread'
require 'securerandom'
require 'set'

module ASF
  @@weakrefs = Set.new

  module LDAP
     # see https://s.apache.org/IWu8
     # Previously derived from the following sources:
     # * https://github.com/apache/infrastructure-puppet/blob/deployment/data/common.yaml (ldapserver::slapd_peers)
     # Updated 2018-02-24
    RO_HOSTS = %w(
      ldaps://ldap-us-ro.apache.org:636
      ldaps://ldap-eu-ro.apache.org:636
    )

    RW_HOSTS = %w(
      ldaps://ldap-master.apache.org:636
    )

    # Mutex preventing simultaneous connections to LDAP from a single process
    CONNECT_LOCK = Mutex.new

    # fetch configuration from apache/infrastructure-puppet
    def self.puppet_config
      return @puppet if @puppet
      # the enclosing method is optional, so we only require the gem here
      require 'yaml'
      require_relative 'git' # just in case
      @puppet = YAML.load(ASF::Git.infra_puppet('data/common.yaml'))
    end

    # extract the ldapcert from the puppet configuration
    def self.puppet_cert
      puppet_config['ldapclient::ldapcert']
    end

    # connect to LDAP
    def self.connect(test = true, hosts = nil)
      # If the host list is specified, use that as is
      # otherwise ensure we start with the next in the default list
      hosts ||= self.hosts.rotate!

      # Try each host at most once
      hosts.each do |host|

        Wunderbar.info "[#{host}] - Connecting to LDAP server"

        begin
          # request connection
          uri = URI.parse(host)
          if uri.scheme == 'ldaps'
            ldap = ::LDAP::SSLConn.new(uri.host, uri.port)
          else
            ldap = ::LDAP::Conn.new(uri.host, uri.port)
          end

          # test the connection
          ldap.bind if test

          # save the host
          @host = host

          return ldap
        rescue ::LDAP::ResultError => re
          Wunderbar.warn "[#{host}] - Error connecting to LDAP server: " +
            re.message + " (continuing)"
        end

      end

      Wunderbar.error "Failed to connect to any LDAP host"
      return nil
    end

    # connect to LDAP with a user and password; generally required for
    # update operations.  If a block is passed, the connection will be
    # closed after the block executes.
    #
    # when run interactively, will default user and prompt for password
    def self.bind(user=nil, password=nil, &block)
      if not user or not password
        raise ArgumentError.new('Need user name and password') unless STDIN.isatty

        require 'etc'
        require 'io/console'
        user ||= Etc.getlogin
        password = STDIN.getpass("Password for #{user}:")
      end

      dn = ASF::Person.new(user).dn
      raise ::LDAP::ResultError.new('Unknown user') unless dn

      ASF.ldap.unbind if ASF.ldap.bound? rescue nil
      ldap = ASF.init_ldap(true, RW_HOSTS)
      if block
        ASF.flush_weakrefs
        ldap.bind(dn, password, &block)
        ASF.init_ldap(true)
      else
        ldap.bind(dn, password)
      end
    ensure
      ASF.flush_weakrefs
    end

    # validate HTTP authorization, and optionally invoke a block bound to
    # that user.
    def self.http_auth(string, &block)
      auth = Base64.decode64(string.to_s[/Basic (.*)/, 1] || '')
      user, password = auth.split(':', 2)
      return unless password

      if block
        self.bind(user, password, &block)
      else
        begin
          ASF::LDAP.bind(user, password) {}
          return ASF::Person.new(user)
        rescue ::LDAP::ResultError
          return nil
        end
      end
    end

    # Return the last chosen host (if any)
    def self.host
      @host
    end

    # determine what LDAP hosts are available
    def self.hosts(use_config = true)
      return @hosts if @hosts # cache the hosts list
      # try whimsy config
      hosts = Array(ASF::Config.get(:ldap))

      # check system configuration
      if use_config and hosts.empty?
        conf = "#{ETCLDAP}/ldap.conf"
        if File.exist? conf
          uris = File.read(conf)[/^uri\s+(.*)/i, 1].to_s
          hosts = uris.scan(/ldaps?:\/\/\S+?:\d+/)
          Wunderbar.debug "Using hosts from LDAP config"
        end
      else
        Wunderbar.debug "Using hosts from Whimsy config"
      end

      # if all else fails, use default list
      Wunderbar.debug "Using default host list" if hosts.empty?
      hosts = ASF::LDAP::RO_HOSTS if hosts.empty?

      hosts.shuffle!
      #Wunderbar.debug "Hosts:\n#{hosts.join(' ')}"
      @hosts = hosts
    end

    # query and extract cert from openssl output
    def self.extract_cert
      host = hosts.sample[%r{//(.*?)(/|$)}, 1]
      puts ['openssl', 's_client', '-connect', host, '-showcerts'].join(' ')
      out, _, _ = Open3.capture3 'openssl', 's_client',
        '-connect', host, '-showcerts'
      out[/^-+BEGIN.*?\n-+END[^\n]+\n/m]
    end

    # update /etc/ldap.conf. Usage:
    #
    #   sudo ruby -I /srv/whimsy/lib -r whimsy/asf -e "ASF::LDAP.configure"
    #
    def self.configure
      cert = Dir["#{ETCLDAP}/asf*-ldap-client.pem"].first

      # verify/obtain/write the cert
      if not cert
        cert = "#{ETCLDAP}/asf-ldap-client.pem"
        File.write cert, ASF::LDAP.puppet_cert || self.extract_cert
      end

      # read the current configuration file
      ldap_conf = "#{ETCLDAP}/ldap.conf"
      content = File.read(ldap_conf)

      # ensure that the right cert is used
      unless content =~ /asf.*-ldap-client\.pem/
        content.gsub!(/^TLS_CACERT/i, '# TLS_CACERT')
        content += "TLS_CACERT #{ETCLDAP}/asf-ldap-client.pem\n"
      end

      # provide the URIs of the ldap hosts
      content.gsub!(/^URI/, '# URI')
      content += "uri \n" unless content =~ /^uri /
      content[/uri (.*)\n/, 1] = hosts(false).join(' ')

      # verify/set the base
      unless content.include? 'base dc=apache'
        content.gsub!(/^BASE/i, '# BASE')
        content += "base dc=apache,dc=org\n"
      end

      # ensure TLS_REQCERT is allow (Mac OS/X only)
      if ETCLDAP.include? 'openldap' and not content.include? 'REQCERT allow'
        content.gsub!(/^TLS_REQCERT/i, '# TLS_REQCERT')
        content += "TLS_REQCERT allow\n"
      end

      # write the configuration if there were any changes
      File.write(ldap_conf, content) unless content == File.read(ldap_conf)
    end

    # determine if ldap has been configured atleast once
    def self.configured?
      return File.read("#{ETCLDAP}/ldap.conf").include? "asf-ldap-client.pem"
    end

    # modify an entry in LDAP; dump information on LDAP errors
    def self.modify(dn, list)
      ASF.ldap.modify(dn, list)
    rescue ::LDAP::ResultError
      Wunderbar.warn(list.inspect)
      Wunderbar.warn(dn.to_s)
      raise
    end

    # add an entry to LDAP; dump information on LDAP errors
    def self.add(dn, list)
      ASF.ldap.add(dn, list)
    rescue ::LDAP::ResultError
      Wunderbar.warn(list.inspect)
      Wunderbar.warn(dn.to_s)
      raise
    end

    # delete an entry from LDAP; dump information on LDAP errors
    def self.delete(dn)
      ASF.ldap.delete(dn)
    rescue ::LDAP::ResultError
      Wunderbar.warn(dn.to_s)
      raise
    end
  end

  # public entry point for establishing a connection safely
  def self.init_ldap(reset = false, hosts = nil)
    ASF::LDAP::CONNECT_LOCK.synchronize do
      @ldap = nil if reset
      @ldap ||= ASF::LDAP.connect(!reset, hosts)
    end
  end

  # Directory where ldap.conf resides.  Differs based on operating system.
  ETCLDAP = case
    when Dir.exist?('/etc/openldap') then '/etc/openldap'
    when Dir.exist?('/usr/local/etc/openldap') then '/user/local//etc/openldap'
    else '/etc/ldap'
  end

  # Returns existing LDAP connection, creating one if necessary.
  def self.ldap
    @ldap || self.init_ldap
  end

  # search with a scope of one, with automatic retry/failover
  def self.search_one(base, filter, attrs=nil)
    self.search_scope(::LDAP::LDAP_SCOPE_ONELEVEL, base, filter, attrs)
  end

  # search with a scope of subtree, with automatic retry/failover
  def self.search_subtree(base, filter, attrs=nil)
    self.search_scope(::LDAP::LDAP_SCOPE_SUBTREE, base, filter, attrs)
  end

  # search with a specified scope, with automatic retry/failover
  def self.search_scope(scope, base, filter, attrs=nil)

    # Dummy command, used for logging purposes only
    sname = %w(base one sub children)[scope] rescue scope
    cmd = "ldapsearch -x -LLL -b #{base} -s #{sname} #{filter} " +
      "#{[attrs].flatten.join(' ')}"

    # try once per host, with a minimum of two tries
    attempts_left = [ASF::LDAP.hosts.length, 2].max
    begin
      attempts_left -= 1
      init_ldap unless @ldap
      return [] unless @ldap

      target = @ldap.get_option(::LDAP::LDAP_OPT_HOST_NAME) rescue '?'
      Wunderbar.info "[#{target}] #{cmd}"

      result = @ldap.search2(base, scope, filter, attrs)
    rescue Exception => re
      if attempts_left <= 0
        Wunderbar.error "[#{target}] => #{re.inspect} for #{cmd}"
        raise
      else
        Wunderbar.warn "[#{target}] => #{re.inspect} for #{cmd}, retrying ..."
        @ldap.unbind if @ldap.bound? rescue nil
        @ldap = nil # force new connection
        sleep 1
        retry
      end
    end

    result.map! {|hash| hash[attrs]} if String === attrs

    result.compact
  end

  # safely dereference a weakref array attribute.  Block provided is
  # used when reference is not set or has been reclaimed.
  # N.B. dereference_weakref(object, :XYZ, block) stores the reference in @XYZ
  def self.dereference_weakref(object, attr, &block)
    attr = "@#{attr}"
    value = object.instance_variable_get(attr) || block.call
    value[0..-1]
  rescue WeakRef::RefError
    value = block.call
  ensure
    if not value or RUBY_VERSION.start_with? '1'
      object.instance_variable_set(attr, value)
    elsif value and not value.instance_of? WeakRef
      object.instance_variable_set(attr, WeakRef.new(value))
    end

    # keep track of which weak references are saved
    @@weakrefs << attr if object == self
  end

  def self.flush_weakrefs
    @@weakrefs.each do |attr|
      self.remove_instance_variable(attr)
    end

    @@weakrefs.clear

    # run garbage collection
    GC.start
  end

  # shortcut for dereference weakref
  # N.B. weakref(:XYZ) stores the reference in @XYZ
  def self.weakref(attr, &block)
    self.dereference_weakref(self, attr, &block)
  end

  # Obtain a list of PMC chairs from LDAP 
  # <tt>cn=pmc-chairs,ou=groups,ou=services,dc=apache,dc=org</tt>
  # Note: this list may include non-PMC VPs.
  def self.pmc_chairs
    weakref(:pmc_chairs) {Service.find('pmc-chairs').members}
  end

  # Obtain a list of committers from LDAP
  # <tt>cn=committers,ou=role,ou=groups,dc=apache,dc=org</tt>
  def self.committers
    weakref(:committers) {RoleGroup.find('committers').members}
  end

  # Obtain a list of committerids from LDAP
  # <tt>cn=committers,ou=role,ou=groups,dc=apache,dc=org</tt>
  def self.committerids
    weakref(:committerids) {RoleGroup.find('committers').memberids}
  end
  
  # Obtain a list of members from LDAP 
  # <tt>cn=member,ou=groups,dc=apache,dc=org</tt>
  # Note: includes some non-ASF member infrastructure contractors
  # TODO: convert to RoleGroup at some point?
  def self.members
    weakref(:members) {Group.find('member').members}
  end

  # Obtain a list of memberids from LDAP 
  # <tt>cn=member,ou=groups,dc=apache,dc=org</tt>
  # Note: includes some non-ASF member infrastructure contractors
  # TODO: convert to RoleGroup at some point?
  def self.memberids
    weakref(:memberids) {Group.find('member').memberids}
  end

  # Superclass for all classes which are backed by LDAP data.  Encapsulates
  # the management of collections to weak references to instance data, for
  # both performance and funcational reasons.  Sequentially finding the same
  # same object will return the same instance unless the prior instance has
  # been reclaimed by garbage collection.  This often prevents large numbers
  # of requests to fetch the same data from LDAP.
  #
  # This class also contains a number of helper classes that will construct
  # various LDAP <tt>mod</tt> objects.
  class Base
    # Simple name for the LDAP object, generally the value of <tt>uid</tt>
    # for people, and the value of <tt>cn</tt> for all of the rest.
    attr_reader :name

    # define default sort key (make Base objects sortable)
    def <=>(other)
      @name <=> other.name
    end

    # return the LDAP base for this object: identifies the subtree where
    # this object can be found.
    def self.base
      @base
    end

    # return the LDAP base for this object: identifies the subtree where
    # this object can be found.
    def base
      self.class.base
    end

    # return the collection of instances of this class, as a hash.  Note the
    # values are weak references, so may have already been reclaimed.
    def self.collection
      @collection ||= Hash.new
    end

    # Find an instance of this class, given a name
    def self.[] name
      new(name)
    end

    # Find an instance of this class, given a name
    def self.find name
      new(name)
    end

    # Create an instance of this class, given a name.  Note: if an instance
    # already exists, it will return a handle to the existing object.
    def self.new name
      begin
        object = collection[name]
        return object.reference if object and object.weakref_alive?
      rescue
      end

      super
    end

    # create an instance of this class, returning a weak reference to the
    # object for reuse.  Note: self.new will check for such a reference and
    # return it in favor of allocating a new object.
    def initialize name
      self.class.collection[name] = WeakRef.new(self)
      @name = name
    end

    # returns a reference to the underlying object.  Useful for converting
    # weak references to strong references.
    def reference
      self
    end

    # construct a weak reference to this object
    # N.B. weakref(:XYZ) stores the reference in @XYZ
    def weakref(attr, &block)
      ASF.dereference_weakref(self, attr, &block)
    end

    # Return the simple name for this LDAP object.  This is the value of
    # <tt>uid</tt> for people objects, and the value of <tt>cn</tt> for all
    # other objects.
    def id
      @name
    end

    # helper method to construct LDAP_MOD_ADD objects
    def self.mod_add(attr, vals)
      ::LDAP::Mod.new(::LDAP::LDAP_MOD_ADD, attr.to_s, Array(vals))
    end

    # helper method to construct LDAP_MOD_REPLACE objects
    def self.mod_replace(attr, vals)
      vals = Array(vals) unless Hash === vals
      ::LDAP::Mod.new(::LDAP::LDAP_MOD_REPLACE, attr.to_s, vals)
    end

    # helper method to construct LDAP_MOD_DELETE objects
    def self.mod_delete(attr, vals)
      ::LDAP::Mod.new(::LDAP::LDAP_MOD_DELETE, attr.to_s, Array(vals))
    end

    def hasLDAP?
      ASF.search_one(base, "cn=#{name}", 'cn').any?
    end

  end

  # a hash of attributes which is not populated until the first attempt
  # to reference a value
  class LazyHash < Hash
    # capture an initializer to be called only if necessary.
    def initialize(&initializer)
      @initializer = initializer
    end

    # if referencing a key that is not in the hash, and the initializer has
    # not yet been called, call the initializer, merge the results, and
    # try again.
    def [](key)
      result = super
      if not result and not keys.include? key and @initializer
        merge! @initializer.call || {}
        @initializer = nil
        result = super
      end
      result
    end
  end

  # Manage committers: list, add, and remove people not only from the list
  # of people, but from the list of committers.
  class Committer < Base
    @base = 'ou=role,ou=groups,dc=apache,dc=org'

    # get a list of committers
    def self.list()
      ASF.search_one(base, 'cn=committers', 'member').flatten.
        map {|uid| Person.find uid[/uid=(.*?),/,1]}
    end

    # get a list of committers (ids only)
    def self.listids()
      ASF.search_one(base, 'cn=committers', 'member').flatten.
        map {|uid| uid[/uid=(.*?),/,1]}
    end

    # create a new person and add as a new committer to LDAP.
    # Attrs must include uid, cn, and mail
    def self.create(attrs)
      # add person to LDAP
      person = ASF::Person.add(attrs)

      # add person to 'new' committers list
      ASF::LDAP.modify("cn=committers,#@base", 
        [ASF::Base.mod_add('member', [person.dn])])

      # add person to 'legacy' committers list
      ASF::Group['committers'].add(person)

      # return new person
      person
    end

    # rename a person
    def rename(newid, attrs={})
      # ensure person exists in LDAP
      raise ArgumentError(self.id) unless self.dn

      # create a new person
      new_person = ASF::Person.create(self.attrs.merge(attrs).merge(uid: newid))

      # determine what groups the individual is a member of
      uid_groups = ASF.search_subtree('dc=apache,dc=org', 
        'memberUid=#{self.id}', 'dn').flatten
      dn_groups = ASF.search_subtree('dc=apache,dc=org', 
        'member=#{self.dn}', 'dn').flatten

      # add new user to all groups
      uid_groups.each do |dn|
        ASF::LDAP.modify(dn, [ASF::Base.mod_add('memberUid', new_person.id)])
      end
      dn_groups.each do |dn|
        ASF::LDAP.modify(dn, [ASF::Base.mod_add('member', new_person.dn)])
      end

      # remove original user from all groups
      uid_groups.each do |dn|
        ASF::LDAP.modify(dn, [ASF::Base.mod_delete('memberUid', self.id)])
      end
      dn_groups.each do |dn|
        ASF::LDAP.modify(dn, [ASF::Base.mod_delete('member', self.dn)])
      end

      # remove original user
      ASF::Person.remove(person.id)

      # return new user
      new_person
    end

    # completely remove a committer from LDAP
    # ** DO NOT USE **
    # In almost all cases, use deregister instead
    def self.destroy(person)
      # if person is a string, find the person object
      person = ASF::Person.find(person) if person.instance_of? String

      # remove person from 'legacy' committers list, ignoring exceptions
      ASF::Group['committers'].remove(person) rescue nil

      # remove person from 'new' committers list, ignoring exceptions
      ASF::LDAP.modify("cn=committers,#@base", 
        [ASF::Base.mod_delete('member', [person.dn])]) rescue nil

      # remove person from LDAP (should almost never be done)
      ASF::Person.remove(person.id)
    end

    # register an existing person as a committer
    # updates both committer LDAP groups
    def self.register(person)
      if person.instance_of? String
        id = person # save for use in error message
        person = ASF::Person[person] or raise ArgumentError.new("Cannot find person: '#{id}'") 
      end

      # add person to 'new' committers list
      ASF::LDAP.modify("cn=committers,#@base", 
        [ASF::Base.mod_add('member', [person.dn])])

      # add person to 'legacy' committers list
      ASF::Group['committers'].add(person)
    end

    # deregister an existing person as a committer
    # updates both committer LDAP groups
    def self.deregister(person)
      if person.instance_of? String
        id = person # save for use in error message
        person = ASF::Person[person] or raise ArgumentError.new("Cannot find person: '#{id}'") 
      end

      # remove person from 'legacy' committers list
      ASF::Group['committers'].remove(person)

      # remove person from 'new' committers list
      ASF::LDAP.modify("cn=committers,#@base", 
        [ASF::Base.mod_delete('member', [person.dn])])
    end

  end

  class Person < Base
    @base = 'ou=people,dc=apache,dc=org'

    def self.group_base
      'ou=people,' + ASF::Group.base
    end

    # Obtain a list of people known to LDAP.  LDAP filters may be used
    # to retrieve only a subset.
    def self.list(filter='uid=*')
      ASF.search_one(base, filter, 'uid').flatten.map {|uid| find(uid)}
    end

    # Obtain a list of people (ids) known to LDAP.  LDAP filters may be used
    # to retrieve only a subset. Result is returned as a list of ids only.
    def self.listids(filter='uid=*')
      ASF.search_one(base, filter, 'uid').flatten
    end

    # pre-fetch a given set of attributes, for a given list of people
    def self.preload(attributes, people=[])
      list = Hash.new {|hash, name| hash[name] = find(name)}

      attributes = [attributes].flatten

      if people.empty? or people.length > 1000
        filter = "(|#{attributes.map {|attribute| "(#{attribute}=*)"}.join})"
      else
        filter = "(|#{people.map {|person| "(uid=#{person.name})"}.join})"
      end
      
      zero = Hash[attributes.map {|attribute| [attribute,nil]}]

      data = ASF.search_one(base, filter, attributes + ['uid'])
      data = Hash[data.map! {|hash| [list[hash['uid'].first], hash]}]
      data.each {|person, hash| person.attrs.merge!(zero.merge(hash))}

      if people.empty?
        (list.values - data.keys).each do |person|
          person.attrs.merge! zero
        end
      end

      list.values
    end

    # return person only if it actually exits
    def self.[] id
      person = super
      person.attrs['dn'] ? person : nil
    end

    # list of LDAP attributes for this person, populated lazily upon
    # first reference.
    def attrs
      @attrs ||= LazyHash.new {ASF.search_one(base, "uid=#{name}").first}
    end

    # reload all attributes from LDAP
    def reload!
      @attrs = nil
      attrs
    end

    # Is this person listed in the committers LDAP group?
    def asf_committer?
       ASF::Group.new('committers').include? self
    end

    # determine if the person is banned.  If scanning a large list, consider
    # preloading the <tt>loginShell</tt> attributes for these people.
    def banned?
      # FreeBSD uses /usr/bin/false; Ubuntu uses /bin/false
      not attrs['loginShell'] or %w(/bin/false bin/nologin bin/no-cla).any? {|a| attrs['loginShell'].first.include? a}
    end

    # determine if the person has no login.  If scanning a large list, consider
    # preloading the <tt>loginShell</tt> attributes for these people.
    def nologin?
      # FreeBSD uses /usr/bin/false; Ubuntu uses /bin/false
      not attrs['loginShell'] or %w(/bin/false bin/nologin bin/no-cla).any? {|a| attrs['loginShell'].first.include? a}
    end

    # determine if the person has asf-banned: yes.  If scanning a large list, consider
    # preloading the <tt>asf-banned</tt> attributes for these people.
    def asf_banned?
      # No idea what this means (yet)
      attrs['asf-banned'] == 'yes'
    end

    # is the login marked as inactive?
    def inactive?
      nologin? || asf_banned?
    end

    # primary mail addresses
    def mail
      attrs['mail'] || []
    end

    # list all of the alternative emails for this person
    def alt_email
      attrs['asf-altEmail'] || []
    end

    # list all of the PGP key fingerprints
    def pgp_key_fingerprints
      attrs['asf-pgpKeyFingerprint'] || []
    end

    # list all of the ssh public keys
    def ssh_public_keys
      attrs['sshPublicKey'] || []
    end

    # list all of the personal URLs
    def urls
      attrs['asf-personalURL'] || []
    end

    # list of LDAP committees that this individual is a member of
    # TODO should this be deleted? 
    # It seems to be used partly as LDAP membership and partly as PMC membership (which were originally generally the same)
    # If the former, then it disappears.
    # If the latter, then it needs to be derived from project_owners filtered to keep only PMCs
    def committees
      # legacy LDAP entries
      committees = []
#      committees = weakref(:committees) do
#        Committee.list("member=uid=#{name},#{base}")
#      end

      # add in projects
      # Get list of project names where the person is an owner
      projects = self.projects.select{|prj| prj.owners.include? self}.map(&:name)
      committees += ASF::Committee.pmcs.select do |pmc| 
        projects.include? pmc.name
      end

      # dedup
      committees.uniq
    end

    # list of LDAP projects that this individual is a member of
    def projects
      weakref(:projects) do
        Project.list("member=uid=#{name},#{base}")
      end
    end

    # list of LDAP projects that this individual is an owner of - i.e. on (P)PMC
    def project_owners
      weakref(:project_owners) do
        Project.list("owner=uid=#{name},#{base}")
      end
    end

    # list of Podlings that this individual is a member (owner) of
    def podlings
      ASF::Podling.current.select{|pod| project_owners.map(&:name).include? pod.name}
    end

    # list of LDAP groups that this individual is a member of
    def groups
      weakref(:groups) do
        Group.list("memberUid=#{name}")
      end
    end

    # list of LDAP services that this individual is a member of
    def services
      weakref(:services) do
        Service.listcns("member=#{dn}")
      end
    end

    # Designated Name from LDAP
    def dn
      "uid=#{name},#{ASF::Person.base}"
    end

    # Allow arbitrary LDAP attibutes to be referenced as object properties.
    # Example: <tt>ASF::Person.find('rubys').cn</tt>.  Can also be used
    # to modify an LDAP attribute.
    def method_missing(name, *args)
      if name.to_s.end_with? '=' and args.length == 1
        return modify(name.to_s[0..-2], args)
      end

      return super unless args.empty?
      result = self.attrs[name.to_s]
      return super unless result

      if result.empty?
        return nil
      else
        result.map! do |value|
          value = value.dup.force_encoding('utf-8') if String === value
          value
        end

        if result.length == 1
          result.first
        else
          result
        end
      end
    end

    # update an LDAP attribute for this person.  This needs to be run
    # either inside or after ASF::LDAP.bind.
    def modify(attr, value)
      ASF::LDAP.modify(self.dn, [ASF::Base.mod_replace(attr.to_s, value)])
      attrs[attr.to_s] = value
    end

    # add a new person to LDAP.  Attrs must include uid, cn, and mail
    def self.add(attrs)
      # convert keys to strings
      attrs = attrs.map {|key, value| [key.to_s, value]}.to_h

      # verify required arguments are present
      %w(uid cn mail).each do |required|
        unless attrs.include? required
          raise ArgumentError.new("missing attribute #{required}")
        end
      end

      availid = attrs['uid']

      # determine next uid and group, unless provided
      nextuid = attrs['uidNumber'] || 
        ASF::search_one(ASF::Person.base, 'uid=*', 'uidNumber').
          flatten.map(&:to_i).max + 1

      nextgid = attrs['gidNumber']
      unless nextgid
        nextgid = ASF::search_one(group_base, 'cn=*', 'gidNumber').
          flatten.map(&:to_i).max + 1

        # create new LDAP group
        entry = [
          mod_add('objectClass', ['posixGroup', 'top']),
          mod_add('cn', availid),
          mod_add('userPassword', '{crypt}*'),
          mod_add('gidNumber', nextgid.to_s),
        ]
      end
 
      # fixed attributes
      attrs.merge!({
        'uidNumber' => nextuid.to_s,
        'gidNumber' => nextuid.to_s,
        'asf-committer-email' => "#{availid}@apache.org",
        'objectClass' => %w(person top posixAccount organizationalPerson
           inetOrgPerson asf-committer hostObject ldapPublicKey)
      })

      # defaults
      attrs['loginShell'] ||= '/usr/local/bin/bash'
      attrs['homeDirectory'] ||= "/home/#{availid}"
      attrs['host'] ||= "home.apache.org"
      attrs['asf-sascore'] ||= "10"

      # parse name
      attrs = ASF::Person.ldap_name(attrs['cn']).merge(attrs)

      # generate a password that is between 8 and 16 alphanumeric characters
      if not attrs['userPassword']
        while attrs['userPassword'].to_s.length < 8
          attrs['userPassword'] = SecureRandom.base64(12).gsub(/\W+/, '')
        end
      end

      ASF::LDAP.add("cn=#{availid},#{group_base}", entry)

      # create new LDAP person
      begin
        entry = attrs.map {|key, value| mod_add(key, value)}
        ASF::LDAP.add("uid=#{availid},#{base}", entry)
      rescue
        # don't leave an orphan group behind
        ASF::LDAP.delete("cn=#{availid},#{group_base}") rescue nil
        raise
      end

      # return person object with password filled in
      person = ASF::Person.find(availid)
      person.attrs['userPassword'] = [attrs['userPassword']]
      person
    end

    # remove a person from LDAP
    def self.remove(availid)
      ASF::LDAP.delete("cn=#{availid},#{group_base}")
      ASF::LDAP.delete("uid=#{availid},#{base}")
    end
  end

  #
  # Access to LDAP groups; where committer lists for PMCs have traditionally
  # been stored.  The intent is to move this data to member attributes on
  # Project lists.
  #
  class Group < Base
    @base = 'ou=groups,dc=apache,dc=org'

    # obtain a list of groups from LDAP
    def self.list(filter='cn=*')
      ASF.search_one(base, filter, 'cn').flatten.map {|cn| find(cn)}
    end

    # determine if a given ASF::Person is a member of this group
    def include?(person)
      filter = "(&(cn=#{name})(memberUid=#{person.name}))"
      if ASF.search_one(base, filter, 'cn').empty?
        return false
      else
        return true
      end
    end

    # fetch <tt>dn</tt>, <tt>member</tt>, <tt>modifyTimestamp</tt>, and
    # <tt>createTimestamp</tt> for all groups in LDAP.
    def self.preload
      Hash[ASF.search_one(base, "cn=*", %w(dn memberUid modifyTimestamp createTimestamp)).map do |results|
        cn = results['dn'].first[/^cn=(.*?),/, 1]
        group = ASF::Group.find(cn)
        group.modifyTimestamp = results['modifyTimestamp'].first # it is returned as an array of 1 entry
        group.createTimestamp = results['createTimestamp'].first # it is returned as an array of 1 entry
        members = results['memberUid']  || []
        group.members = members
        [group, members]
      end]
    end

    # Date this committee was last modified in LDAP.
    attr_accessor :modifyTimestamp

    # Date this committee was initially created in LDAP.
    attr_accessor :createTimestamp

    # return group only if it actually exits
    def self.[] name
      group = super
      group.dn ? group : nil
    end

    # setter for members, should only be used by #preload
    # N.B. Do not dereference @members directly; use weakref(:members) instead
    def members=(members)
      @members = WeakRef.new(members)
    end

    # return a list of ASF::People who are members of this group
    def members
      memberids.map {|uid| Person.find(uid)}
    end

    # return a list of ids who are members of this group
    def memberids
      weakref(:members) do # initialises @members if necessary
        ASF.search_one(base, "cn=#{name}", 'memberUid').flatten
      end
    end

    # Designated Name from LDAP
    def dn
      @dn ||= ASF.search_one(base, "cn=#{name}", 'dn').first.first rescue nil
    end

    # remove people from an existing group in LDAP
    def remove(people)
      @members = nil  # force fresh LDAP search
      people = (Array(people) & members).map(&:id)
      return if people.empty?
      ASF::LDAP.modify(self.dn, [ASF::Base.mod_delete('memberUid', people)])
    ensure
      @members = nil
    end

    # add people to an existing group in LDAP
    def add(people)
      @members = nil  # force fresh LDAP search
      people = (Array(people) - members).map(&:id)
      return if people.empty?
      ASF::LDAP.modify(self.dn, [ASF::Base.mod_add('memberUid', people)])
    ensure
      @members = nil
    end

    # add a new group to LDAP
    def self.add(name, people)
      nextgid = ASF::search_one(ASF::Group.base, 'cn=*', 'gidNumber').
        flatten.map(&:to_i).max + 1

      entry = [
        mod_add('objectClass', ['posixGroup', 'top']),
        mod_add('cn', name),
        mod_add('userPassword', '{crypt}*'),
        mod_add('gidNumber', nextgid.to_s),
        mod_add('memberUid', people.map(&:id))
      ]

      ASF::LDAP.add("cn=#{name},#{base}", entry)
    end

    # remove a group from LDAP
    def self.remove(name)
      ASF::LDAP.delete("cn=#{name},#{base}")
    end
  end

  # Ultimately, this will include both PMCs and PPMCs, and enable separate
  # updating of owners and members.  For now this is only used for PPMCs
  # and owners and members are kept in sync.
  class Project < Base
    @base = 'ou=project,ou=groups,dc=apache,dc=org'

    # obtain a list of projects from LDAP
    def self.list(filter='cn=*')
      ASF.search_one(base, filter, 'cn').flatten.map {|cn| Project.find(cn)}
    end

    # obtain a list of projectids from LDAP
    def self.listids(filter='cn=*')
      ASF.search_one(base, filter, 'cn').flatten
    end

    # return project only if it actually exits
    def self.[] name
      project = super
      project.dn ? project : nil
    end

    # fetch <tt>dn</tt>, <tt>member</tt>, <tt>modifyTimestamp</tt>, and
    # <tt>createTimestamp</tt> for all projects in LDAP.
    def self.preload
      Hash[ASF.search_one(base, "cn=*", %w(dn member owner modifyTimestamp createTimestamp)).map do |results|
        cn = results['dn'].first[/^cn=(.*?),/, 1]
        project = self.find(cn)
        project.modifyTimestamp = results['modifyTimestamp'].first # it is returned as an array of 1 entry
        project.createTimestamp = results['createTimestamp'].first # it is returned as an array of 1 entry
        members = results['member'] || []
        owners = results['owner'] || []
        # TODO members and owners are duplicated in the project object and the returned hash
        project.members = members
        project.owners = owners
        [project, [members, owners]] # TODO is this correct? it seems to work...
      end]
    end

    # Date this committee was last modified in LDAP.
    attr_accessor :modifyTimestamp

    # Date this committee was initially created in LDAP.
    attr_accessor :createTimestamp

    # Designated Name from LDAP
    def dn
      @dn ||= ASF.search_one(base, "cn=#{name}", 'dn').first.first rescue nil
    end

    # create an LDAP group for this project
    def create(owners, committers=nil)
      committers = Array(committers || owners).map(&:dn)
      owners = Array(owners).map(&:dn)

      entry = [
        ASF::Base.mod_add('objectClass', ['groupOfNames', 'top']),
        ASF::Base.mod_add('cn', name), 
        ASF::Base.mod_add('owner', owners),
        ASF::Base.mod_add('member', committers),
      ]

      ASF::LDAP.add("cn=#{name},#{base}", entry)

      self.owners = owners
      self.members = committers
    end

    # setter for members, should only be called by #preload.
    # N.B. Do not dereference @members directly; use weakref(:members) instead
    def members=(members)
      @members = WeakRef.new(members)
    end

    # setter for owners, should only be called by #preload.
    # N.B. Do not dereference @owners directly; use weakref(:owners) instead
    def owners=(owners)
      @owners = WeakRef.new(owners)
    end

    # list of committers on this project.  Stored in LDAP as a <tt>member</tt>
    # attribute.
    def members
      memberids.map {|id| Person.find id}
    end

    # list of member ids in the project
    def memberids
      members = weakref(:members) do
        ASF.search_one(base, "cn=#{name}", 'member').flatten
      end    
      members.map {|uid| uid[/uid=(.*?),/,1]}
    end

    # list of owners on this project.  Stored in LDAP as a <tt>owners</tt>
    # attribute.
    def owners
      ownerids.map {|id| Person.find id}
    end

    # list of owner ids in the project
    def ownerids
      owners = weakref(:owners) do
        ASF.search_one(base, "cn=#{name}", 'owner').flatten
      end
      owners.map {|uid| uid[/uid=(.*?),/,1]}
    end

    
    # remove people from a project as owners and members in LDAP
    def remove(people)
      remove_owners(people)
      remove_members(people)
    end

    # remove people as owners of a project in LDAP
    def remove_owners(people)
      @owners = nil  # force fresh LDAP search
      removals = (Array(people) & owners).map(&:dn)
      unless removals.empty?
        ASF::LDAP.modify(self.dn, [ASF::Base.mod_delete('owner', removals)])
      end
    ensure
      @owners = nil
    end

    # remove people as members of a project in LDAP
    def remove_members(people)
      @members = nil  # force fresh LDAP search
      removals = (Array(people) & members).map(&:dn)
      unless removals.empty?
        ASF::LDAP.modify(self.dn, [ASF::Base.mod_delete('member', removals)])
      end
    ensure
      @members = nil
    end

    # add people to a project as members and owners in LDAP
    def add(people)
      add_owners(people)
      add_members(people)
    end

    # add people as owners of a project in LDAP
    def add_owners(people)
      @owners = nil  # force fresh LDAP search
      additions = (Array(people) - owners).map(&:dn)
      unless additions.empty?
        ASF::LDAP.modify(self.dn, [ASF::Base.mod_add('owner', additions)])
      end
    ensure
      @owners = nil
    end

    # add people as members of a project in LDAP
    def add_members(people)
      @members = nil  # force fresh LDAP search
      additions = (Array(people) - members).map(&:dn)
      unless additions.empty?
        ASF::LDAP.modify(self.dn, [ASF::Base.mod_add('member', additions)])
      end
    ensure
      @members = nil
    end
  end

  # representation of Committee, i.e. entry in committee-info.txt
  # includes PMCs and other committees, but does not include podlings
  class Committee < Base
    @base = nil # not sure it makes sense to define base here

    # return committee only if it actually exists
    def self.[] name
      committee = super
      # Cannot rely on presence/absence of LDAP record as projects includes podlings
      (ASF::Committee.pmcs+ASF::Committee.nonpmcs).map(&:name).include?(name) ? committee : nil
    end

    # Date this committee was last modified in LDAP.
    # defer to Project; must have called project.preload
    def modifyTimestamp
      ASF::Project[name].modifyTimestamp
    end

    # Date this committee was initially created in LDAP.
    # defer to Project; must have called project.preload
    def createTimestamp
      ASF::Project[name].createTimestamp
    end

    # List of owners for this committee, i.e. people who are members of the
    # committee and have update access.  Data is obtained from LDAP.
    # Takes info from Project
    def owners
      ASF::Project.find(name).owners
    end

    # List of owner ids for this committee
    # Takes info from Project
    def ownerids
      ASF::Project.find(name).ownerids
    end

    # List of committers for this committee.  Data is obtained from LDAP.  This
    # data is generally stored in an attribute named <tt>member</tt>.
    # Takes info from Project
    def committers
      ASF::Project.find(name).members
    end

    # List of committer ids for this committee
    # Takes info from Project
    def committerids
      ASF::Project.find(name).memberids
    end

    # remove people as owners of a project in LDAP
    def remove_owners(people)
      ASF::Project.find(name).remove_owners(people)
    end

    # remove people as members of a project in LDAP
    def remove_committers(people)
      ASF::Project.find(name).remove_members(people)
    end

    # add people as owners of a project in LDAP
    def add_owners(people)
      ASF::Project.find(name).add_owners(people)
    end

    # add people as committers of a project.  This information is stored
    # in LDAP using a <tt>members</tt> attribute.
    def add_committers(people)
      ASF::Project.find(name).add_members(people)
    end

    # Designated Name from LDAP
    def dn
      @dn ||= ASF::Project.find(name).dn
    end

  end

  #
  # Access to LDAP services (<tt>ou=groups,ou=services,dc=apache,dc=org</tt>)
  #
  class Service < Base
    @base = 'ou=groups,ou=services,dc=apache,dc=org'

    # return a list of services (cns only), from LDAP.
    def self.listcns(filter='cn=*')
      ASF.search_one(base, filter, 'cn').flatten
    end

    # Designated Name from LDAP
    def dn
      return @dn if @dn
      dns = ASF.search_subtree(self.class.base, "cn=#{name}", 'dn')
      @dn = dns.first.first unless dns.empty?
      @dn
    end

    # base subtree for this service
    def base
      if dn
        dn.sub(/^cn=.*?,/, '')
      else
        super
      end
    end

    # fetch <tt>dn</tt>, <tt>member</tt>, <tt>modifyTimestamp</tt>, and
    # <tt>createTimestamp</tt> for all services in LDAP.
    def self.preload
      Hash[ASF.search_one(base, "cn=*", %w(dn member modifyTimestamp createTimestamp)).map do |results|
        cn = results['dn'].first[/^cn=(.*?),/, 1]
        service = self.find(cn)
        service.modifyTimestamp = results['modifyTimestamp'].first # it is returned as an array of 1 entry
        service.createTimestamp = results['createTimestamp'].first # it is returned as an array of 1 entry
        members = results['member'] || []
        service.members = members
        [service, members]
      end]
    end

    # Date this committee was last modified in LDAP.
    attr_accessor :modifyTimestamp

    # Date this committee was initially created in LDAP.
    attr_accessor :createTimestamp

    # setters for members.  Should only be called by #preload
    # N.B. Do not dereference @members directly; use weakref(:members) instead
    def members=(members)
      @members = WeakRef.new(members)
    end

    # list of members for this service in LDAP
    def members
      members = weakref(:members) do
        ASF.search_one(base, "cn=#{name}", 'member').flatten
      end

      members.map {|uid| Person.find uid[/uid=(.*?),/,1]}
    end

    # list of memberids for this service in LDAP
    def memberids
      members = weakref(:members) do
        ASF.search_one(base, "cn=#{name}", 'member').flatten
      end
    
      members.map {|uid| uid[/uid=(.*?),/,1]}
    end

    # remove people from this service in LDAP
    def remove(people)
      @members = nil # force fresh LDAP search
      people = (Array(people) & members).map(&:dn)
      return if people.empty?
      ASF::LDAP.modify(self.dn, [ASF::Base.mod_delete('member', people)])
    ensure
      @members = nil
    end

    # add people to this service in LDAP
    def add(people)
      @members = nil # force fresh LDAP search
      people = (Array(people) - members).map(&:dn)
      return if people.empty?
      ASF::LDAP.modify(self.dn, [ASF::Base.mod_add('member', people)])
    ensure
      @members = nil
    end
  end

  # <tt>ou=apps</tt> subtree of <tt>ou=groups,dc=apache,dc=org</tt>, currently
  # only used for <tt>hudson-jobadmin</tt>
  class AppGroup < Service
    @base = 'ou=apps,ou=groups,dc=apache,dc=org'

    # return a list of App groups (cns only), from LDAP.
    def self.listcns(filter='cn=*')
      # Note that hudson-job-admin is under ou=hudson hence need 
      # to override Service.listcns and use subtree search
      ASF.search_subtree(base, filter, 'cn').flatten
    end

    # remove people from an application group.
    def remove(people)
      @members = nil
      people = (Array(people) & members).map(&:dn)
      ASF::LDAP.modify(self.dn, [ASF::Base.mod_delete('member', people)])
    ensure
      @members = nil
    end

    # add people to an application group.
    def add(people)
      @members = nil
      people = (Array(people) - members).map(&:dn)
      ASF::LDAP.modify(self.dn, [ASF::Base.mod_add('member', people)])
    ensure
      @members = nil
    end
  end

  # <tt>ou=auth</tt> subtree of <tt>ou=groups,dc=apache,dc=org</tt>, used for
  # subprojects and a variety of organizational constructs (accounting,
  # exec-officers, fundraising, trademarks, ...)
  class AuthGroup < Service
    @base = 'ou=auth,ou=groups,dc=apache,dc=org'
  end

  # <tt>ou=role</tt> subtree of <tt>ou=groups,dc=apache,dc=org</tt>, used for
  # committers (new) group only currently
  class RoleGroup < Service
    @base = 'ou=role,ou=groups,dc=apache,dc=org'
  end
end

if __FILE__ == $0
  $LOAD_PATH.unshift '/srv/whimsy/lib'
  require 'whimsy/asf/config'
  mem=ASF.members()
  puts mem.length
  puts mem.first.inspect
  memids=ASF.memberids()
  puts memids.length
  puts memids.first
  new=ASF.committers()
  puts new.length
  puts new.first.inspect
  newids=ASF.committerids()
  puts newids.length
  puts newids.first
  ASF::RoleGroup.listcns.map {|g| puts ASF::RoleGroup.find(g).dn}
  ASF::AppGroup.listcns.map {|g| puts ASF::AppGroup.find(g).dn}
end
