Skip to content

Instantly share code, notes, and snippets.

@DanCoughlin
Created July 24, 2012 18:07
Show Gist options
  • Save DanCoughlin/3171559 to your computer and use it in GitHub Desktop.
Save DanCoughlin/3171559 to your computer and use it in GitHub Desktop.
Here is the main ldap library and then the directory controller where these are used and the user model that exposes the ldap functionality
# returns true if the user exists and false otherwise
def user
render :json => User.attributes(params[:uid])
end
def user_attribute
if params[:attribute] == "groups"
res = User.groups(params[:uid])
else
res = User.attributes(params[:uid], params[:attribute])
end
render :json => res
end
def user_groups
render :json => User.groups(params[:uid])
end
require "hydra/ldap/version"
require "net/ldap"
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/hash/indifferent_access'
require 'yaml'
require 'rails'
module Hydra
module LDAP
# Your code goes here...
class NoUsersError < StandardError; end
class MissingOwnerError < StandardError; end
class GroupNotFound < StandardError; end
def self.connection
@ldap_conn ||= Net::LDAP.new(ldap_connection_config)
end
def self.ldap_connection_config
return @ldap_connection_config if @ldap_connection_config
@ldap_connection_config = {}
yml = ldap_config
@ldap_connection_config[:host] = yml[:host]
@ldap_connection_config[:port] = yml[:port]
if yml[:username] && yml[:password]
@ldap_connection_config[:auth]={:method=>:simple}
@ldap_connection_config[:auth][:username] = yml[:username]
@ldap_connection_config[:auth][:password] = yml[:password]
end
@ldap_connection_config
end
def self.ldap_config
root = Rails.root || '.'
env = Rails.env || 'test'
@ldap_config ||= YAML::load(ERB.new(IO.read(File.join(root, 'config', 'hydra-ldap.yml'))).result)[env].with_indifferent_access
end
def self.group_base
ldap_config[:group_base]
end
def self.treebase
ldap_config[:base]
end
def self.dn(code)
dn = "cn=#{code},#{group_base}"
end
#def self.create_group(code, description, owner, users)
def self.create_group(dn, attributes)
raise NoUsersError, "Unable to persist a group without users" unless users.present?
raise MissingOwnerError, "Unable to persist a group without owner" unless owner
#attributes = {
# :cn => code,
# :objectclass => "groupofnames",
# :description => description,
# :member=>users.map {|u| "uid=#{u}"},
# :owner=>"uid=#{owner}"
#}
#connection.add(:dn=>dn(code), :attributes=>attributes)
connection.add(:dn=>dn, :attributes=>attributes)
end
def self.delete_group(dn)
connection.delete(:dn=>dn)
end
# same as
# ldapsearch -h ec2-107-20-53-121.compute-1.amazonaws.com -p 389 -x -b dc=example,dc=com -D "cn=admin,dc=example,dc=com" -W "(&(objectClass=groupofnames)(member=uid=vanessa))" cn
# Northwestern passes attributes=['cn']
def self.groups_for_user(filter, attributes=['psMemberOf'], &block)
#PSU filter=Net::LDAP::Filter.eq('uid', uid)
#NW filter=Net::LDAP::Filter.construct("(&(objectClass=groupofnames)(member=uid=#{uid}))"))
result = connection.search(:base=>group_base, :filter => filter, :attributes => attributes)
block.call(result)
end
#def groups_owned_by_user(uid)
def self.groups_owned_by_user(filter)
#NW - return result.map{|r| r[:cn].first}
result = connection.search(:base=>group_base, :filter=> filter, :attributes=>['cn'])
block.call(result)
end
def self.title_of_group(group_code)
result = find_group(group_code)
#result[:description].first
block.call(result)
end
def self.users_for_group(group_code)
result = find_group(group_code)
#result[:member].map { |v| v.sub(/^uid=/, '') }
block.call(result)
end
def self.owner_for_group(group_code)
result = find_group(group_code)
#result[:owner].first.sub(/^uid=/, '')
block.call(result)
end
def self.add_users_to_group(group_code, users)
invalidate_cache(group_code)
ops = []
users.each do |u|
ops << [:add, :member, "uid=#{u}"]
end
connection.modify(:dn=>dn(group_code), :operations=>ops)
end
def self.remove_users_from_group(group_code, users)
invalidate_cache(group_code)
ops = []
users.each do |u|
ops << [:delete, :member, "uid=#{u}"]
end
connection.modify(:dn=>dn(group_code), :operations=>ops)
end
def self.invalidate_cache(group_code)
@cache ||= {}
@cache[group_code] = nil
end
def self.find_group(group_code, filter, attributes)
@cache ||= {}
return @cache[group_code] if @cache[group_code]
#result = connection.search(:base=>group_base, :filter=> Net::LDAP::Filter.construct("(&(objectClass=groupofnames)(cn=#{group_code}))"), :attributes=>['member', 'owner', 'description'])
result = connection.search(:base=>group_base, :filter=> filter, :attributes=>attributes)
val = {}
raise GroupNotFound, "Can't find group '#{group_code}' in ldap" unless result.first
#result.first.each do |k, v|
# val[k] = v
#end
block.call(result)
#puts "Val is: #{val}"
@cache[group_code] = val
end
def self.get_user(filter, attribute=[])
#result = connection.search(:base=>group_base, :filter => Net::LDAP::Filter.eq('uid', uid), :attributes => attribute)
result = connection.search(:base=>group_base, :filter => filter, :attributes => attribute)
return result
end
def self.does_user_exist?(filter)
#hits = connection.search(:base=>group_base, :filter=>Net::LDAP::Filter.eq('uid', uid))
hits = connection.search(:base=>group_base, :filter=>filter)
return !hits.empty?
end
def self.is_user_unique?(uid)
#hits = connection.search(:base=>group_base, :filter=>Net::LDAP::Filter.eq('uid', uid))
hits = connection.search(:base=>group_base, :filter=>filter)
return hits.count == 1
end
def self.does_group_exist?(filter)
#hits = connection.search(:base=>group_base, :filter=>Net::LDAP::Filter.eq('cn', cn))
hits = connection.search(:base=>group_base, :filter=>filter)
return hits.count == 1
end
end
end
require 'hydra/ldap/engine' if defined?(Rails)
# Groups that user is a member of
def groups
self.class.groups(login)
end
def self.groups(login)
Hydra::LDAP.groups_for_user(Net::LDAP::Filter.eq('uid', login)) { |result| result.first[:psmemberof].select{ |y| y.starts_with? 'cn=umg/' }.map{ |x| x.sub(/^cn=/, '').sub(/,dc=psu,dc=edu/, '') } } rescue []
end
def attributes(attributes=[])
self.class.attributes(login, attributes)
end
def self.attributes(login, attributes=[])
Hydra::LDAP.get_user(Net::LDAP::Filter.eq('uid', login), attributes)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment