Commit 77f3f376544384b8ac52a1bc7b84c34183129f7c

Authored by Georg GH. Hopp
Committed by Georg Hopp
1 parent a4818bf1

add functionality for create, update, delete

... ... @@ -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