<commit_before>require 'net/ldap'

module LdapClient
  LdapNotEnabled = Class.new(StandardError)
  LdapNotCorrectlyConfigured = Class.new(StandardError)
  extend self

  def enabled?
    config.fetch('enable', false)
  end

  # used to prefill a user create form
  def search(username)
    filter = Net::LDAP::Filter.eq(config['attribute']['uid'], username)
    results = client.search :filter => filter

    unless results
      error = client.get_operation_result
      Rails.logger.error "LDAP Error: Code: #{error.code} Message: #{error.message}"
      raise LdapNotCorrectlyConfigured.new(error.message)
    end

    results.map do |result|
      {
        :username =>   result[config['attribute']['uid']].first,
        :dept =>       result[config['attribute']['ou']].first,
        :first_name => result[config['attribute']['gn']].first,
        :last_name =>  result[config['attribute']['sn']].first,
        :email =>      result[config['attribute']['mail']].first,
        :title =>      result[config['attribute']['title']].first
      }
    end
  end

  # used to login to Chorus as an LDAP user. Ugly if-structure for backwards-compatibility
  def authenticate(username, password)
    ldap = client

    if config['user_search_base'].nil? #old way...TODO: ask prakash the best way to check this

      ldap = client
      ldap.auth make_dn(username), password
      return ldap.bind

    else

      user_entries = ldap.bind_as(
        :base => config['user_search_base'],
        :filter => config['user_search_filter'].gsub('{0}', username),
        :password => password
      )

      if user_entries && user_dn_in_user_group?(user_entries.first.dn)
        return user_entries.first
      else
        return nil
      end
    end
  end

  def user_dn_in_user_group?(user_dn)
    ldap = client

    group_search_base = config['group_search_base']
    group_search_filter = config['group_search_filter']

    user_groups = config['user_groups'].split(',').map(&:strip)

    if ldap.bind

      user_groups.each do |group_cn| # search for each group name in the LDAP tree

        filter = Net::LDAP::Filter.eq 'cn', group_cn
        results = ldap.search :base => group_search_base, :filter => filter

        results.each do |group| # if we find a group, see if our user_dn is a member of that group

          return true if group[:member].any?{|dn| dn.include?(user_dn)}
        end
      end

    else
      Rails.logger.error "LDAP Error: Code: #{error.code} Message: #{error.message}"
      raise LdapNotCorrectlyConfigured.new(error.message)
      # throw error: Could not bind with LDAP server with the credentials supplied in the chorus.properties file
    end
  end

  def create_users
    ldap = client
    ldap.search(:base => "ou=" + config["attribute"]["ou"] + "," + config["base"]) do |entry| # add a config option for this
      create_user_from_entry entry
    end
  end

  def create_user_from_entry(entry)
    User.create! ( {<commit_msg>added ruby errors to LDAP client around new functionality<commit_after>require 'net/ldap'

module LdapClient
  LdapNotEnabled = Class.new(StandardError)
  LdapNotCorrectlyConfigured = Class.new(StandardError)
  LdapCouldNotBindWithUser = Class.new(StandardError)
  LdapCouldNotFindMember = Class.new(StandardError)
  extend self

  def enabled?
    config.fetch('enable', false)
  end

  # used to prefill a user create form
  def search(username)
    filter = Net::LDAP::Filter.eq(config['attribute']['uid'], username)
    results = client.search :filter => filter

    unless results
      error = client.get_operation_result
      Rails.logger.error "LDAP Error: Code: #{error.code} Message: #{error.message}"
      raise LdapNotCorrectlyConfigured.new(error.message)
    end

    results.map do |result|
      {
        :username =>   result[config['attribute']['uid']].first,
        :dept =>       result[config['attribute']['ou']].first,
        :first_name => result[config['attribute']['gn']].first,
        :last_name =>  result[config['attribute']['sn']].first,
        :email =>      result[config['attribute']['mail']].first,
        :title =>      result[config['attribute']['title']].first
      }
    end
  end

  # used to login to Chorus as an LDAP user. First if-block is for backwards-compatibility
  def authenticate(username, password)
    ldap = client

    if config['user_search_base'].nil? #old way...TODO: ask prakash the best way to check this

      ldap = client
      ldap.auth make_dn(username), password
      return ldap.bind

    else

      user_entries = ldap.bind_as(
        :base => config['user_search_base'],
        :filter => config['user_search_filter'].gsub('{0}', username),
        :password => password
      )

      if !user_entries
        raise LdapCouldNotBindWithUser.new(
                  "Could not authenticate with user #{username} in #{config['user_search_base']} using filter #{config['user_search_filter']}"
              )
      end

      if config['group_search_base'].present? && !user_dn_in_user_group?(user_entries.first.dn)
        raise LdapCouldNotFindMember.new(
                  "Could not find membership for #{user_entries.first.dn} "\
                  "in group base #{config['group_search_base']} with filter #{config['group_search_filter']}"
              )
      end

      user_entries.first
    end
  end

  def user_dn_in_user_group?(user_dn)
    ldap = client

    group_search_base = config['group_search_base']
    group_search_filter = config['group_search_filter'] # TODO: try to use group_search_filter, revert to

    user_groups = config['user_groups'].split(',').map(&:strip)

    if ldap.bind

      user_groups.each do |group_cn| # search for each group name in the LDAP tree
        filter = Net::LDAP::Filter.eq 'cn', group_cn
        results = ldap.search :base => group_search_base, :filter => filter

        results.each do |group| # if we find a group, see if our user_dn is a member of that group
          return true if group[:member].any?{|dn| dn.include?(user_dn)}
        end
      end

      return false
    else
      error = ldap.get_operation_result
      Rails.logger.error "LDAP Error: Code: #{error.code} Message: #{error.message}"
      raise LdapNotCorrectlyConfigured.new(error.message)
    end
  end

  def create_users
    ldap = client
    ldap.search(:base => "ou=" + config["attribute"]["ou"] + "," + config["base"]) do |entry| # add a config option for this
      create_user_from_entry entry
    end
  end

  def create_user_from_entry(entry)
    User.create! ( {
{'fraction_non_alphanumeric': 0.11831886706258565, 'fraction_numerical': 0.00030455306837216383, 'mean_word_length': 3.0693928128872368, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4523981', 'n_tokens_mistral': 1995, 'n_tokens_neox': 1961, 'n_words': 495}