Commit 77f3f376544384b8ac52a1bc7b84c34183129f7c
Committed by
Georg Hopp
1 parent
a4818bf1
add functionality for create, update, delete
Showing
6 changed files
with
155 additions
and
12 deletions
... | ... | @@ -13,6 +13,8 @@ |
13 | 13 | - 'posixAccount' |
14 | 14 | - 'shadowAccount' |
15 | 15 | |
16 | + :dnPat: "uid=#{:name}" | |
17 | + | |
16 | 18 | :map: |
17 | 19 | :uid: :name |
18 | 20 | :userpassword: :pass |
... | ... | @@ -28,6 +30,8 @@ |
28 | 30 | |
29 | 31 | :objectClass: 'posixGroup' |
30 | 32 | |
33 | + :dnPat: "cn=#{:name}" | |
34 | + | |
31 | 35 | :map: |
32 | 36 | :cn: :name |
33 | 37 | :gidnumber: :gid |
... | ... | @@ -40,6 +44,8 @@ |
40 | 44 | |
41 | 45 | :objectClass: 'organization' |
42 | 46 | |
47 | + :dnPat: "o=#{:name}" | |
48 | + | |
43 | 49 | :map: |
44 | 50 | :o: :name |
45 | 51 | |
... | ... | @@ -52,6 +58,8 @@ |
52 | 58 | - 'organizationalRole' |
53 | 59 | - 'MailAlias' |
54 | 60 | |
61 | + :dnPat: "cn=#{:user},o=#{:mail|sub(/.*@/, '')}" | |
62 | + | |
55 | 63 | :map: |
56 | 64 | :cn: :user |
57 | 65 | |
... | ... | @@ -64,6 +72,8 @@ |
64 | 72 | - 'person' |
65 | 73 | - 'MailAlias' |
66 | 74 | |
75 | + :dnPat: "mail=#{:mail},o=#{:mail|sub(/.*@/, '')}" | |
76 | + | |
67 | 77 | :map: |
68 | 78 | :sn: :surname |
69 | 79 | :cn: :name |
... | ... | @@ -77,6 +87,8 @@ |
77 | 87 | - 'person' |
78 | 88 | - 'MailAccount' |
79 | 89 | |
90 | + :dnPat: "mail=#{:mail},o=#{:mail|sub(/.*@/, '')}" | |
91 | + | |
80 | 92 | :map: |
81 | 93 | :homedirectory: :home |
82 | 94 | ... | ... |
... | ... | @@ -50,13 +50,19 @@ module DsAdmin::Model |
50 | 50 | # always has to be stored back into @id |
51 | 51 | # |
52 | 52 | def save |
53 | - @id = @storage.write(self) | |
53 | + @id = @@storage.write(self) | |
54 | 54 | end |
55 | 55 | |
56 | 56 | def config_key |
57 | 57 | self.class.to_s.to_sym |
58 | 58 | end |
59 | 59 | |
60 | + def to_h | |
61 | + Hash[instance_variables.map do |var| | |
62 | + [var[1...var.size].to_sym, instance_variable_get(var)] | |
63 | + end] | |
64 | + end | |
65 | + | |
60 | 66 | protected |
61 | 67 | def _load(id) |
62 | 68 | @@storage.config.model = self | ... | ... |
... | ... | @@ -7,13 +7,19 @@ class DsAdmin::Model::User |
7 | 7 | return if args.empty? |
8 | 8 | super(args) |
9 | 9 | |
10 | - @name = args[:name] | |
11 | - @pass = args[:pass] | |
12 | - @uid = args[:uid] | |
13 | - @gid = args[:gid] | |
14 | - @shell = args[:shell] | |
15 | - @home = args[:home] | |
16 | - @shadowmax = args[:shadowmax] | |
17 | - @shadowwarning = args[:shadowwarning] | |
10 | + @name = args[:name] | |
11 | + @pass = args[:pass] | |
12 | + @uid = args[:uid] | |
13 | + @gid = args[:gid] | |
14 | + @shell = args[:shell] | |
15 | + @home = args[:home] | |
16 | + @shadowmax = args[:shadowmax] | |
17 | + @shadowwarning = args[:shadowwarning] | |
18 | + @shadowlastchange = args[:shadowlastchange] | |
19 | + end | |
20 | + | |
21 | + def save | |
22 | + @shadowlastchange = (Time::now.to_i/60/60/24).to_s | |
23 | + super | |
18 | 24 | end |
19 | 25 | end | ... | ... |
... | ... | @@ -16,4 +16,12 @@ class DsAdmin::Storage::Config |
16 | 16 | def map(storage) |
17 | 17 | @config[storage.config_key][@model.config_key][:map] |
18 | 18 | end |
19 | + | |
20 | + def object_class(storage) | |
21 | + @config[storage.config_key][@model.config_key][:objectClass] | |
22 | + end | |
23 | + | |
24 | + def dn_pat(storage) | |
25 | + @config[storage.config_key][@model.config_key][:dnPat] | |
26 | + end | |
19 | 27 | end | ... | ... |
... | ... | @@ -17,18 +17,97 @@ class DsAdmin::Storage::Ldap |
17 | 17 | # - map the id's from the ldap search resulte into id's used in |
18 | 18 | # the models. The mapping is read from the config. |
19 | 19 | # |
20 | - foo = @ldap.search(query).map do |data| | |
20 | + @ldap.search(query).map do |data| | |
21 | 21 | map = { :dn => :id } |
22 | 22 | map.merge!(@config.map(self)) |
23 | 23 | |
24 | + remap(data, map) | |
25 | + end | |
26 | + end | |
27 | + | |
28 | + def write(model) | |
29 | + @config.model = model | |
30 | + | |
31 | + data = model.to_h | |
32 | + odata = read.find{|od| od[:id] == data[:id]} | |
33 | + | |
34 | + return create(data) unless odata | |
35 | + | |
36 | + update(odata, data) | |
37 | + end | |
38 | + | |
39 | + protected | |
40 | + def create(data) | |
41 | + map = @config.map(self).invert | |
42 | + scan_exp = /(^|, *)([^=]*=)(([^#][^,]*)|#\{([^|}]*)(\|([^}]*))?\})/ | |
43 | + | |
44 | + dn = String.new | |
45 | + @config.dn_pat(self).scan(scan_exp) do |m| | |
46 | + val = m[3] if m[3] | |
47 | + val = data[m[4][1..m[4].length].to_sym] if m[4] | |
48 | + val = eval('"' + val + '".send ' + m[6]) if data && m[6] | |
49 | + | |
50 | + dn += m[0] + m[1] + val | |
51 | + end | |
52 | + dn += ',' + @config.query(self)[:base] | |
53 | + | |
54 | + data.delete(:id) | |
55 | + | |
56 | + entry = Net::LDAP::Entry.new(dn) | |
57 | + entry[:changetype] = 'add' | |
58 | + entry[:objectclass] = @config.object_class(self) | |
59 | + remap(data, @config.map(self).invert).each {|key,value| entry[key] = value} | |
60 | + | |
61 | + puts entry.to_ldif # TODO: make real writes | |
62 | + return dn | |
63 | + end | |
64 | + | |
65 | + def update(old, new) | |
66 | + new.delete(:id) | |
67 | + replace = remap( | |
68 | + new.find_all{|key,value| value != old[key]}, | |
69 | + @config.map(self).invert | |
70 | + ) | |
71 | + | |
72 | + ## | |
73 | + # if the given model already has an id; | |
74 | + # | |
75 | + # check if ldap dn has to be changed in order to | |
76 | + # reflect the attributes. | |
77 | + # if so, remove old entry | |
78 | + # | |
79 | + replace.each do |key,value| | |
80 | + if old[:id] =~ /(^|, *)#{key.to_s}=([^, ]+)/ && $2 != value | |
81 | + delete(old[:id]) | |
82 | + return create(new) | |
83 | + end | |
84 | + end | |
85 | + | |
86 | + entry = Net::LDAP::Entry.new(old[:id]) | |
87 | + entry[:changetype] = 'modify' | |
88 | + entry[:replace] = replace.keys | |
89 | + replace.each {|key,value| entry[key] = value } | |
90 | + | |
91 | + puts entry.to_ldif # TODO: make real writes | |
92 | + return old[:id] | |
93 | + end | |
94 | + | |
95 | + def delete(id) | |
96 | + entry = Net::LDAP::Entry.new(id) | |
97 | + entry[:changetype] = 'delete' | |
98 | + | |
99 | + puts entry.to_ldif # TODO: make real writes | |
100 | + return true | |
101 | + end | |
102 | + | |
103 | + def remap(data, map) | |
24 | 104 | remapped = Hash.new |
25 | 105 | data.each do |key,value| |
26 | 106 | key = map[key] || key |
27 | 107 | value = value.size==1 ? value[0] : value.to_a |
28 | 108 | |
29 | 109 | remapped.merge!({ key => value }) |
30 | - end | |
110 | + end if data | |
31 | 111 | remapped |
32 | - end | |
33 | 112 | end |
34 | 113 | end | ... | ... |
... | ... | @@ -117,4 +117,36 @@ account.load!('mail=drachenfrau@steffers.org,o=steffers.org,o=hosting,dc=weird-w |
117 | 117 | puts 'base: ' + account.inspect |
118 | 118 | |
119 | 119 | puts |
120 | +puts '=== Model#to_h ===' | |
121 | +puts user.to_h.inspect | |
122 | +puts 'base: ' + user.inspect | |
123 | +puts '---' | |
124 | +puts group.to_h.inspect | |
125 | +puts 'base: ' + group.inspect | |
126 | +puts '---' | |
127 | +puts site.to_h.inspect | |
128 | +puts 'base: ' + site.inspect | |
129 | +puts '---' | |
130 | +puts alias_role.to_h.inspect | |
131 | +puts 'base: ' + alias_role.inspect | |
132 | +puts '---' | |
133 | +puts alias_person.to_h.inspect | |
134 | +puts 'base: ' + alias_person.inspect | |
135 | +puts '---' | |
136 | +puts account.to_h.inspect | |
137 | +puts 'base: ' + account.inspect | |
138 | + | |
139 | +puts | |
140 | +puts '=== Storage#update ===' | |
141 | +user.home = '/home/user/foo' | |
142 | +puts 'returns: ' + user.save | |
143 | +puts 'base: ' + user.inspect | |
144 | + | |
145 | +puts | |
146 | +puts '=== Storage#update(replace[delete,create]) ===' | |
147 | +user.name = 'brad' | |
148 | +puts 'returns: ' + user.save | |
149 | +puts 'base: ' + user.inspect | |
150 | + | |
151 | +puts | |
120 | 152 | puts 'Memory useage: ' + `ps -o rss= -p #{Process.pid}` | ... | ... |
Please
register
or
login
to post a comment