Some ruby code written to manage an ldap directory.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.6 KiB

require 'net/ldap'
##
# some additional ldap specific config handlings.
#
class DsAdmin::Storage::Config
def object_class(storage)
@config[storage.config_key][@model.config_key][:objectClass]
end
def dn(storage, data)
eval_pattern(
@config[storage.config_key][@model.config_key][:dnPat],
data) + ',' + query(storage)[:base]
end
end
class DsAdmin::Storage::Ldap
include DsAdmin::Storage
def initialize(config)
super(config)
@ldap = Net::LDAP.new(@config.con(self))
end
def read
query = @config.query(self)
##
# two things.
# - create a hash from the ldap search result
# - map the id's from the ldap search resulte into id's used in
# the models. The mapping is read from the config.
#
@ldap.search(query).map do |data|
map = { :dn => :id }
map.merge!(@config.map(self))
remap(data, map)
end
end
def write(model)
@config.model = model
data = model.to_h
odata = read.find{|od| od[:id] == data[:id]}
return create(data) unless odata
update(odata, data)
end
protected
def create(data)
dn = @config.dn(self, data)
data.delete(:id)
entry = Net::LDAP::Entry.new(dn)
entry[:changetype] = 'add'
entry[:objectclass] = @config.object_class(self)
remap(data, @config.map(self).invert).each {|key,value| entry[key] = value}
puts entry.to_ldif # TODO: make real writes
return dn
end
def update(old, new)
new.delete(:id)
replace = remap(
new.find_all{|key,value| value != old[key]},
@config.map(self).invert
)
##
# if the given model already has an id;
#
# check if ldap dn has to be changed in order to
# reflect the attributes.
# if so, remove old entry
#
replace.each do |key,value|
if old[:id] =~ /(^|, *)#{key.to_s}=([^, ]+)/ && $2 != value
delete(old[:id])
puts
return create(new)
end
end
entry = Net::LDAP::Entry.new(old[:id])
entry[:changetype] = 'modify'
entry[:replace] = replace.keys
replace.each {|key,value| entry[key] = value }
puts entry.to_ldif # TODO: make real writes
return old[:id]
end
def delete(id)
entry = Net::LDAP::Entry.new(id)
entry[:changetype] = 'delete'
puts entry.to_ldif # TODO: make real writes
return true
end
def remap(data, map)
remapped = Hash.new
data.each do |key,value|
key = map[key] || key
value = value.size==1 ? value[0] : value.to_a
remapped.merge!({ key => value })
end if data
remapped
end
end