class Vines::Storage::Ldap

Authenticates usernames and passwords against an LDAP directory. This can provide authentication logic for the other, full-featured Storage implementations while they store and retrieve the rest of the user information.

Public Class Methods

new(host='localhost', port=636, &block) click to toggle source
# File lib/vines/storage/ldap.rb, line 19
def initialize(host='localhost', port=636, &block)
  @config = {host: host, port: port}
  instance_eval(&block)
  @@required.each {|key| raise "Must provide #{key}" if @config[key].nil? }
end

Public Instance Methods

authenticate(username, password) click to toggle source

Validates a username and password by binding to the LDAP instance with those credentials. If the bind succeeds, the user's attributes are retrieved.

# File lib/vines/storage/ldap.rb, line 28
def authenticate(username, password)
  username = JID.new(username).to_s rescue nil
  return if [username, password].any? {|arg| (arg || '').strip.empty? }

  ldap = connect(@config[:dn], @config[:password])
  entries = ldap.search(
    attributes: [@config[:name_attr], 'mail'],
    filter: filter(username))
  return unless entries && entries.size == 1

  user = if connect(entries.first.dn, password).bind
    name = entries.first[@config[:name_attr]].first
    User.new(jid: username, name: name.to_s, roster: [])
  end
  user
end
filter(username) click to toggle source

Return an LDAP search filter for a user optionally belonging to the group defined by the groupdn config attribute.

# File lib/vines/storage/ldap.rb, line 47
def filter(username)
  clas = Net::LDAP::Filter.eq('objectClass', @config[:object_class])
  uid = Net::LDAP::Filter.eq(@config[:user_attr], username)
  filter = clas & uid
  if group = @config[:groupdn]
    memberOf = Net::LDAP::Filter.eq('memberOf', group)
    isMemberOf = Net::LDAP::Filter.eq('isMemberOf', group)
    filter = filter & (memberOf | isMemberOf)
  end
  filter
end

Private Instance Methods

connect(dn, password) click to toggle source
# File lib/vines/storage/ldap.rb, line 61
def connect(dn, password)
  options = [:host, :port, :base].zip(
    @config.values_at(:host, :port, :basedn))
  Net::LDAP.new(Hash[options]).tap do |ldap|
    ldap.encryption(:simple_tls) if @config[:tls]
    ldap.auth(dn, password)
  end
end