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