Browse Source

add functionality for create, update, delete

master
Georg Hopp 15 years ago
committed by Georg Hopp
parent
commit
77f3f37654
  1. 12
      config/storage.yml
  2. 8
      model.rb
  3. 22
      model/user.rb
  4. 8
      storage/config.rb
  5. 85
      storage/ldap.rb
  6. 32
      tester.rb

12
config/storage.yml

@ -13,6 +13,8 @@
- 'posixAccount'
- 'shadowAccount'
:dnPat: "uid=#{:name}"
:map:
:uid: :name
:userpassword: :pass
@ -28,6 +30,8 @@
:objectClass: 'posixGroup'
:dnPat: "cn=#{:name}"
:map:
:cn: :name
:gidnumber: :gid
@ -40,6 +44,8 @@
:objectClass: 'organization'
:dnPat: "o=#{:name}"
:map:
:o: :name
@ -52,6 +58,8 @@
- 'organizationalRole'
- 'MailAlias'
:dnPat: "cn=#{:user},o=#{:mail|sub(/.*@/, '')}"
:map:
:cn: :user
@ -64,6 +72,8 @@
- 'person'
- 'MailAlias'
:dnPat: "mail=#{:mail},o=#{:mail|sub(/.*@/, '')}"
:map:
:sn: :surname
:cn: :name
@ -77,6 +87,8 @@
- 'person'
- 'MailAccount'
:dnPat: "mail=#{:mail},o=#{:mail|sub(/.*@/, '')}"
:map:
:homedirectory: :home

8
model.rb

@ -50,13 +50,19 @@ module DsAdmin::Model
# always has to be stored back into @id
#
def save
@id = @storage.write(self)
@id = @@storage.write(self)
end
def config_key
self.class.to_s.to_sym
end
def to_h
Hash[instance_variables.map do |var|
[var[1...var.size].to_sym, instance_variable_get(var)]
end]
end
protected
def _load(id)
@@storage.config.model = self

22
model/user.rb

@ -7,13 +7,19 @@ class DsAdmin::Model::User
return if args.empty?
super(args)
@name = args[:name]
@pass = args[:pass]
@uid = args[:uid]
@gid = args[:gid]
@shell = args[:shell]
@home = args[:home]
@shadowmax = args[:shadowmax]
@shadowwarning = args[:shadowwarning]
@name = args[:name]
@pass = args[:pass]
@uid = args[:uid]
@gid = args[:gid]
@shell = args[:shell]
@home = args[:home]
@shadowmax = args[:shadowmax]
@shadowwarning = args[:shadowwarning]
@shadowlastchange = args[:shadowlastchange]
end
def save
@shadowlastchange = (Time::now.to_i/60/60/24).to_s
super
end
end

8
storage/config.rb

@ -16,4 +16,12 @@ class DsAdmin::Storage::Config
def map(storage)
@config[storage.config_key][@model.config_key][:map]
end
def object_class(storage)
@config[storage.config_key][@model.config_key][:objectClass]
end
def dn_pat(storage)
@config[storage.config_key][@model.config_key][:dnPat]
end
end

85
storage/ldap.rb

@ -17,18 +17,97 @@ class DsAdmin::Storage::Ldap
# - map the id's from the ldap search resulte into id's used in
# the models. The mapping is read from the config.
#
foo = @ldap.search(query).map do |data|
@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)
map = @config.map(self).invert
scan_exp = /(^|, *)([^=]*=)(([^#][^,]*)|#\{([^|}]*)(\|([^}]*))?\})/
dn = String.new
@config.dn_pat(self).scan(scan_exp) do |m|
val = m[3] if m[3]
val = data[m[4][1..m[4].length].to_sym] if m[4]
val = eval('"' + val + '".send ' + m[6]) if data && m[6]
dn += m[0] + m[1] + val
end
dn += ',' + @config.query(self)[:base]
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])
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
end if data
remapped
end
end
end

32
tester.rb

@ -116,5 +116,37 @@ puts '---'
account.load!('mail=drachenfrau@steffers.org,o=steffers.org,o=hosting,dc=weird-web-workers,dc=org')
puts 'base: ' + account.inspect
puts
puts '=== Model#to_h ==='
puts user.to_h.inspect
puts 'base: ' + user.inspect
puts '---'
puts group.to_h.inspect
puts 'base: ' + group.inspect
puts '---'
puts site.to_h.inspect
puts 'base: ' + site.inspect
puts '---'
puts alias_role.to_h.inspect
puts 'base: ' + alias_role.inspect
puts '---'
puts alias_person.to_h.inspect
puts 'base: ' + alias_person.inspect
puts '---'
puts account.to_h.inspect
puts 'base: ' + account.inspect
puts
puts '=== Storage#update ==='
user.home = '/home/user/foo'
puts 'returns: ' + user.save
puts 'base: ' + user.inspect
puts
puts '=== Storage#update(replace[delete,create]) ==='
user.name = 'brad'
puts 'returns: ' + user.save
puts 'base: ' + user.inspect
puts
puts 'Memory useage: ' + `ps -o rss= -p #{Process.pid}`
Loading…
Cancel
Save