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,6 +13,8 @@ | ||
13 | - 'posixAccount' | 13 | - 'posixAccount' |
14 | - 'shadowAccount' | 14 | - 'shadowAccount' |
15 | 15 | ||
16 | + :dnPat: "uid=#{:name}" | ||
17 | + | ||
16 | :map: | 18 | :map: |
17 | :uid: :name | 19 | :uid: :name |
18 | :userpassword: :pass | 20 | :userpassword: :pass |
@@ -28,6 +30,8 @@ | @@ -28,6 +30,8 @@ | ||
28 | 30 | ||
29 | :objectClass: 'posixGroup' | 31 | :objectClass: 'posixGroup' |
30 | 32 | ||
33 | + :dnPat: "cn=#{:name}" | ||
34 | + | ||
31 | :map: | 35 | :map: |
32 | :cn: :name | 36 | :cn: :name |
33 | :gidnumber: :gid | 37 | :gidnumber: :gid |
@@ -40,6 +44,8 @@ | @@ -40,6 +44,8 @@ | ||
40 | 44 | ||
41 | :objectClass: 'organization' | 45 | :objectClass: 'organization' |
42 | 46 | ||
47 | + :dnPat: "o=#{:name}" | ||
48 | + | ||
43 | :map: | 49 | :map: |
44 | :o: :name | 50 | :o: :name |
45 | 51 | ||
@@ -52,6 +58,8 @@ | @@ -52,6 +58,8 @@ | ||
52 | - 'organizationalRole' | 58 | - 'organizationalRole' |
53 | - 'MailAlias' | 59 | - 'MailAlias' |
54 | 60 | ||
61 | + :dnPat: "cn=#{:user},o=#{:mail|sub(/.*@/, '')}" | ||
62 | + | ||
55 | :map: | 63 | :map: |
56 | :cn: :user | 64 | :cn: :user |
57 | 65 | ||
@@ -64,6 +72,8 @@ | @@ -64,6 +72,8 @@ | ||
64 | - 'person' | 72 | - 'person' |
65 | - 'MailAlias' | 73 | - 'MailAlias' |
66 | 74 | ||
75 | + :dnPat: "mail=#{:mail},o=#{:mail|sub(/.*@/, '')}" | ||
76 | + | ||
67 | :map: | 77 | :map: |
68 | :sn: :surname | 78 | :sn: :surname |
69 | :cn: :name | 79 | :cn: :name |
@@ -77,6 +87,8 @@ | @@ -77,6 +87,8 @@ | ||
77 | - 'person' | 87 | - 'person' |
78 | - 'MailAccount' | 88 | - 'MailAccount' |
79 | 89 | ||
90 | + :dnPat: "mail=#{:mail},o=#{:mail|sub(/.*@/, '')}" | ||
91 | + | ||
80 | :map: | 92 | :map: |
81 | :homedirectory: :home | 93 | :homedirectory: :home |
82 | 94 |
@@ -50,13 +50,19 @@ module DsAdmin::Model | @@ -50,13 +50,19 @@ module DsAdmin::Model | ||
50 | # always has to be stored back into @id | 50 | # always has to be stored back into @id |
51 | # | 51 | # |
52 | def save | 52 | def save |
53 | - @id = @storage.write(self) | 53 | + @id = @@storage.write(self) |
54 | end | 54 | end |
55 | 55 | ||
56 | def config_key | 56 | def config_key |
57 | self.class.to_s.to_sym | 57 | self.class.to_s.to_sym |
58 | end | 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 | protected | 66 | protected |
61 | def _load(id) | 67 | def _load(id) |
62 | @@storage.config.model = self | 68 | @@storage.config.model = self |
@@ -7,13 +7,19 @@ class DsAdmin::Model::User | @@ -7,13 +7,19 @@ class DsAdmin::Model::User | ||
7 | return if args.empty? | 7 | return if args.empty? |
8 | super(args) | 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 | end | 24 | end |
19 | end | 25 | end |
@@ -16,4 +16,12 @@ class DsAdmin::Storage::Config | @@ -16,4 +16,12 @@ class DsAdmin::Storage::Config | ||
16 | def map(storage) | 16 | def map(storage) |
17 | @config[storage.config_key][@model.config_key][:map] | 17 | @config[storage.config_key][@model.config_key][:map] |
18 | end | 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 | end | 27 | end |
@@ -17,18 +17,97 @@ class DsAdmin::Storage::Ldap | @@ -17,18 +17,97 @@ class DsAdmin::Storage::Ldap | ||
17 | # - map the id's from the ldap search resulte into id's used in | 17 | # - map the id's from the ldap search resulte into id's used in |
18 | # the models. The mapping is read from the config. | 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 | map = { :dn => :id } | 21 | map = { :dn => :id } |
22 | map.merge!(@config.map(self)) | 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 | remapped = Hash.new | 104 | remapped = Hash.new |
25 | data.each do |key,value| | 105 | data.each do |key,value| |
26 | key = map[key] || key | 106 | key = map[key] || key |
27 | value = value.size==1 ? value[0] : value.to_a | 107 | value = value.size==1 ? value[0] : value.to_a |
28 | 108 | ||
29 | remapped.merge!({ key => value }) | 109 | remapped.merge!({ key => value }) |
30 | - end | 110 | + end if data |
31 | remapped | 111 | remapped |
32 | - end | ||
33 | end | 112 | end |
34 | end | 113 | end |
@@ -117,4 +117,36 @@ account.load!('mail=drachenfrau@steffers.org,o=steffers.org,o=hosting,dc=weird-w | @@ -117,4 +117,36 @@ account.load!('mail=drachenfrau@steffers.org,o=steffers.org,o=hosting,dc=weird-w | ||
117 | puts 'base: ' + account.inspect | 117 | puts 'base: ' + account.inspect |
118 | 118 | ||
119 | puts | 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 | puts 'Memory useage: ' + `ps -o rss= -p #{Process.pid}` | 152 | puts 'Memory useage: ' + `ps -o rss= -p #{Process.pid}` |
Please
register
or
login
to post a comment