ldap.rb
2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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