Last Updated: February 25, 2016
·
4.499K
· ejstembler

Authenticates a Ruby on Rails User model via LDAP and saves their LDAP photo if they have one

https://gist.github.com/4156208

ldap.yml

# config/ldap.yml
# LDAP server configuration settings
# Host is a Windows Domain Controller

development:
 host: examplehost
 port: 389
 default_domain: EXAMPLEDOMAIN
 base: examplebase # OU=US-Tampa Bay,OU=North America,OU=Accounts,DC=ourdomain,DC=org

test:
 host: examplehost
 port: 389
 default_domain: EXAMPLEDOMAIN
 base: examplebase # OU=US-Tampa Bay,OU=North America,OU=Accounts,DC=ourdomain,DC=org

production:
 host: examplehost
 port: 389
 default_domain: EXAMPLEDOMAIN
 base: examplebase # OU=US-Tampa Bay,OU=North America,OU=Accounts,DC=ourdomain,DC=org

load_ldap_config.rb

# config/initializers/load_ldap_config.rb
LDAP_CONFIG = YAML.load_file("#{Rails.root}/config/ldap.yml")[Rails.env]

user.rb

# app/models/user.rb
require 'net/ldap'

class User < ActiveRecord::Base

 # Authenticates the User via LDAP and saves their LDAP photo if they have one
 def authenticate_ldap(domain, password)
 raise ArgumentError, 'domain is nil' if domain.nil? or domain.blank?
 raise ArgumentError, 'password is nil' if password.nil? or password.blank?

 ldap = Net::LDAP.new
 ldap.host = LDAP_CONFIG['host']
 ldap.port = LDAP_CONFIG['port']
 ldap.auth "#{domain}\\#{login}", password
 bound = ldap.bind

 if bound
 photo_path = "#{Rails.public_path}/images/avatars/#{id}.jpg"
 unless File.exists?(photo_path)
 base = LDAP_CONFIG['base']
 filter = Net::LDAP::Filter.eq('sAMAccountName', login)
 ldap.search(:base => base, :filter => filter, :return_result => true) do |entry|
 [:thumbnailphoto, :jpegphoto, :photo].each do |photo_key|
 if entry.attribute_names.include?(photo_key)
 @ldap_photo = entry[photo_key][0]
 File.open(photo_path, 'wb') { |f| f.write(@ldap_photo) }
 break
 end
 end
 end
 end
 end
 bound
 end

end