Browse Source

heavy restructuring

implemented new design
master
Georg Hopp 15 years ago
committed by Georg Hopp
parent
commit
666ae5b6fd
  1. 14
      Group.rb
  2. 17
      MailAccount.rb
  3. 18
      MailAliasPerson.rb
  4. 17
      MailAliasRole.rb
  5. 11
      Site.rb
  6. 24
      SystemData.rb
  7. 91
      SystemDataBackend.rb
  8. 197
      SystemDataBackendLdap.rb
  9. 18
      User.rb
  10. 91
      controllers/system_data.rb
  11. 10
      database.rb
  12. 13
      database/base.rb
  13. 3
      database/factory.rb
  14. 53
      database/ldap.rb
  15. BIN
      docs/development/mystuff.dia
  16. 66
      docs/development/was.txt
  17. 4
      ds_admin.rb
  18. 0
      loader/user.rb
  19. 197
      mappers/ldap.rb
  20. 72
      model.rb
  21. 9
      model/base.rb
  22. 12
      model/group.rb
  23. 7
      model/interface.rb
  24. 5
      model/mail_account.rb
  25. 5
      model/mail_alias_person.rb
  26. 5
      model/mail_alias_role.rb
  27. 5
      model/site.rb
  28. 24
      model/system_data.rb
  29. 30
      model/user.rb
  30. 10
      sd_admin.rb
  31. 37
      storage.rb
  32. 21
      storage/config.rb
  33. 34
      storage/ldap.rb
  34. 3
      storage/mysql.rb
  35. 123
      test_dummy.rb
  36. 5
      test_dummy2.rb
  37. 38
      tester.rb

14
Group.rb

@ -1,14 +0,0 @@
require 'SystemData'
class Group < SystemData
attr_accessor :name, :gid, :members
def initialize(args = {})
super(args)
@name = args[:name]
@gid = args[:gid]
@members = args[:members]
@members = Array.new if @members.nil?
end
end

17
MailAccount.rb

@ -1,17 +0,0 @@
require 'SystemData'
class MailAccount < SystemData
attr_accessor :mail, :mailbox
def initialize(args = {})
super(args)
@mail = args[:mail]
@home = args[:home]
@mailbox = args[:mailbox]
end
def site
@mail.sub(/.*@/, '')
end
end

18
MailAliasPerson.rb

@ -1,18 +0,0 @@
require 'SystemData'
class MailAliasPerson < SystemData
attr_accessor :mail, :maildrop, :surname, :name
def initialize(args = {})
super(args)
@mail = args[:mail]
@maildrop = args[:maildrop]
@surname = args[:surname]
@name = args[:name]
end
def site
@mail.sub(/.*@/, '')
end
end

17
MailAliasRole.rb

@ -1,17 +0,0 @@
require 'SystemData'
class MailAliasRole < SystemData
attr_accessor :mail, :maildrop, :user
def initialize(args = {})
super(args)
@mail = args[:mail]
@maildrop = args[:maildrop]
@user = args[:user]
end
def site
@mail.sub(/.*@/, '')
end
end

11
Site.rb

@ -1,11 +0,0 @@
require 'SystemData'
class Site < SystemData
attr_accessor :name
def initialize(args = {})
super(args)
@name = args[:name]
end
end

24
SystemData.rb

@ -1,24 +0,0 @@
class SystemData
attr_reader :id
def initialize(args = {})
@backend = args[:backend]
@id = args[:id]
end
def save
kind = self.class.to_s.to_sym
if @id
@backend.update(kind, to_h)
else
@backend.insert(kind, to_h)
end
end
def to_h
Hash[instance_variables.map do |var|
[var[1...var.size].to_sym, eval(var)] if var != '@backend'
end]
end
end

91
SystemDataBackend.rb

@ -1,91 +0,0 @@
require 'User'
require 'Group'
require 'Site'
require 'MailAliasRole'
require 'MailAliasPerson'
require 'MailAccount'
class SystemDataBackend
def initialize(backend)
@backend = backend
@data = Hash.new
end
def users
load(:User)
end
def groups
load(:Group)
end
def sites
load(:Site)
end
def mailAliasRoles
load(:MailAliasRole)
end
def mailAliasPeople
load(:MailAliasPerson)
end
def mailAccounts
load(:MailAccount)
end
def userByName(name)
users.find{|user| user.name == name}
end
def groupByName(name)
groups.find{|group| group.name == name}
end
def siteByName(name)
sites.find{|site| site.name == name}
end
def usersInGroup(group)
case
when group.members.instance_of?(Array):
Hash[group.members.map{|uid| [uid, userByName(uid)] if userByName(uid)}]
when goup.members.nil?:
{}
else
{group.members => userByName(group.members)} if userByName(group.members)
end
end
def mailAliasRolesBySite(site)
mailAliasRoles.find_all{|mail| mail.site == site.name}
end
def mailAliasPeopleBySite(site)
mailAliasPeople.find_all{|mail| mail.site == site.name}
end
def mailAccountsBySite(site)
mailAccounts.find_all{|mail| mail.site == site.name}
end
private
def load(kind)
load!(kind) if ! @data[kind]
@data[kind]
end
def load!(kind)
@data[kind] = Array.new
@backend.load(kind) do |data|
data[:backend] = @backend
@data[kind].push(
eval(kind.to_s + '.new(data)')
)
end
end
end

197
SystemDataBackendLdap.rb

@ -1,197 +0,0 @@
require 'active_support/secure_random'
require 'net/ldap'
class SystemDataBackendLdap
LDAP_USER_MAP = {
:uid => :name,
:userpassword => :pass,
:uidnumber => :uid,
:gidnumber => :gid,
:loginshell => :shell,
:homedirectory => :home
}
LDAP_GROUP_MAP = {
:cn => :name,
:gidnumber => :gid,
:memberuid => :members
}
LDAP_MAILALIASPERSON_MAP = {
:sn => :surname,
:cn => :name
}
LDAP_MAP = {
:User => LDAP_USER_MAP,
:Group => LDAP_GROUP_MAP,
:Site => { :o => :name },
:MailAliasRole => { :cn => :user },
:MailAliasPerson => LDAP_MAILALIASPERSON_MAP,
:mailAccount => { :homedirectory => :home }
}
LDAP_FILTER = {
:User => '(objectClass=posixAccount)',
:Group => '(objectClass=posixGroup)',
:Site => '(&(objectClass=organization)(!(o=hosting)))',
:MailAliasRole => '(&(objectClass=MailAlias)(objectClass=organizationalrole))',
:MailAliasPerson => '(&(objectClass=MailAlias)(objectClass=person))',
:MailAccount => '(objectClass=mailAccount)'
}
LDAP_OBJECTCLASS = {
:User => [ 'account', 'posixAccount', 'shadowAccount' ],
:Group => 'posixGroup',
:Site => 'organization',
:MailAliasRole => [ 'organizationalRole', 'MailAlias' ],
:MailAliasPerson => [ 'person', 'MailAlias' ],
:MailAccount => [ 'person', 'MailAccount' ]
}
LDAP_LAMBDA_USER = lambda do |entry|
entry[:cn] = entry[:uid]
entry[:shadowlastchange] = (Time::now.to_i/60/60/24).to_s
entry[:replace] += ['shadowreplace'] if entry[:replace]
end
LDAP_LAMBDA = {
:User => LDAP_LAMBDA_USER
}
def initialize(host, port, baseDn, args={})
@baseDn = baseDn
@systemDn = 'o=system,' + @baseDn
@hostingDn = 'o=hosting,' + @baseDn
@systemDn = args[:systemDn] if args[:systemDn]
@hostingDn = args[:hostingDn] if args[:hostingDn]
@ldap = Net::LDAP.new(:host => host, :port => port)
@ldapData = Hash.new
end
def load!(kind)
@ldapData[kind] = Hash.new if ! @ldapData[kind]
@ldapData[kind][:int] = @ldap.search(
:base => ldapBase(kind),
:filter => Net::LDAP::Filter::construct(LDAP_FILTER[kind])
)
end
def load(kind)
load!(kind) if ! @ldapData[kind]
@ldapData[kind][:ext] = @ldapData[kind][:int].map do |data|
map = { :dn => :id }
map.merge!(LDAP_MAP[kind]) if LDAP_MAP[kind]
ydata = {}
data.each do |key,value|
ydata.merge!({ map[key] || key => value.size==1?value[0]:value.to_a })
end
ydata
end if ! @ldapData[kind][:ext] && @ldapData[kind][:int]
@ldapData[kind][:ext].each{|ydata| yield ydata} if @ldapData[kind][:ext]
end
def update(kind, data)
map = {}
map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind]
odata = @ldapData[kind][:ext].find{|edata| edata[:id] == data[:id]}
data.each do |key,value|
pat_key = map[key] ? map[key] : key
if odata[:id] =~ /(^|, *)#{pat_key.to_s}=([^, ]+)/ && $2 != value
return replace(kind, data)
end
end
entry = Net::LDAP::Entry.new(data[:id])
data = data.find_all{|key,value| value != odata[key]}
data.delete(:id)
replace = Array.new
data.each do |key,value|
key = map[key] if map[key]
replace.push(key.to_s)
entry[key] = value
end
if replace.empty?
puts 'INFO: no changes'
else
entry[:changetype] = 'modify'
entry[:replace] = replace
LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind]
puts entry.to_ldif
end
end
def replace(kind, data)
puts 'INFO: do replace'
puts '----------------'
odata = @ldapData[kind][:ext].find{|edata| edata[:id] == data[:id]}
delete(odata)
puts
insert(kind, data)
puts '----------------'
end
def delete(data)
entry = Net::LDAP::Entry.new(data[:id])
entry[:changetype] = 'delete'
puts entry.to_ldif
end
def insert(kind, data)
map = {}
map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind]
data.delete(:id)
entry = Net::LDAP::Entry.new(ldapDn(kind, data))
entry[:changetype] = 'add'
entry[:objectclass] = LDAP_OBJECTCLASS[kind]
data.each do |key,value|
key = map[key] if map[key]
entry[key] = value
end
LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind]
puts entry.to_ldif
end
private
def ldapBase(kind)
case(kind)
when :User, :Group: @systemDn
when :Site, :MailAliasRole, :MailAliasPerson, :MailAccount: @hostingDn
end
end
def ldapDn(kind, data)
case(kind)
when :User
"uid=#{data[:name]},ou=user,#{ldapBase(kind)}"
when :Group
"cn=#{data[:name]},ou=group,#{ldapBase(kind)}"
when :Site
"o=#{data[:name]},#{ldapBase(kind)}"
when :MailAliasRole
"cn=#{data[:user]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
when :MailAliasPerson
"mail=#{data[:mail]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
when :MailAccount
"mail=#{data[:mail]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
end
end
end

18
User.rb

@ -1,18 +0,0 @@
require 'SystemData'
class User < SystemData
attr_accessor :name, :pass, :uid, :gid, :shell, :home
def initialize(args = {})
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]
end
end

91
controllers/system_data.rb

@ -1,91 +0,0 @@
require 'User'
require 'Group'
require 'Site'
require 'MailAliasRole'
require 'MailAliasPerson'
require 'MailAccount'
class SystemDataBackend
def initialize(backend)
@backend = backend
@data = Hash.new
end
def users
load(:User)
end
def groups
load(:Group)
end
def sites
load(:Site)
end
def mailAliasRoles
load(:MailAliasRole)
end
def mailAliasPeople
load(:MailAliasPerson)
end
def mailAccounts
load(:MailAccount)
end
def userByName(name)
users.find{|user| user.name == name}
end
def groupByName(name)
groups.find{|group| group.name == name}
end
def siteByName(name)
sites.find{|site| site.name == name}
end
def usersInGroup(group)
case
when group.members.instance_of?(Array):
Hash[group.members.map{|uid| [uid, userByName(uid)] if userByName(uid)}]
when goup.members.nil?:
{}
else
{group.members => userByName(group.members)} if userByName(group.members)
end
end
def mailAliasRolesBySite(site)
mailAliasRoles.find_all{|mail| mail.site == site.name}
end
def mailAliasPeopleBySite(site)
mailAliasPeople.find_all{|mail| mail.site == site.name}
end
def mailAccountsBySite(site)
mailAccounts.find_all{|mail| mail.site == site.name}
end
private
def load(kind)
load!(kind) if ! @data[kind]
@data[kind]
end
def load!(kind)
@data[kind] = Array.new
@backend.load(kind) do |data|
data[:backend] = @backend
@data[kind].push(
eval(kind.to_s + '.new(data)')
)
end
end
end

10
database.rb

@ -1,10 +0,0 @@
module SdAdmin::Database
class Ldap
require 'database/base.rb'
require 'net/ldap'
include Enumerable
end
require 'database/ldap'
end

13
database/base.rb

@ -1,13 +0,0 @@
class SdAdmin::Database::Base
def initialize
@data = Hash.new
end
def _create(data)
end
def _read(id)
end
end

3
database/factory.rb

@ -1,3 +0,0 @@
class SdAdmin::Database::Factory
end

53
database/ldap.rb

@ -1,53 +0,0 @@
class SdAdmin::Database::Ldap
attr_writer :base_dn, :mapper
def initialize(args = {})
@con = {:host => 'host.one.virtual', :port => 389}
@con[:host] = args[:host] if args[:host]
@con[:port] = args[:port] if args[:port]
@base_dn = args[:base_dn] if args[:base_dn]
@ldap = Net::LDAP.new(@con)
filter = args[:filter] if args[:filter]
end
def filter=(filter)
@filter = Net::LDAP::Filter::construct(filter)
end
def each
_load.each{|key,entry| puts "DEBUG: #{key}"; yield key,entry}
end
def [](id)
_load[id]
end
def []=(id, data)
end
def insert(data)
end
def delete(id)
end
private
def _load!
@data = Hash.new
@ldap.search(:base => @base_dn, :filter => @filter) do |entry|
attributes = Hash.new
entry.each{|attr,value| attributes.merge!({attr => value})}
@data.merge!({attributes[:dn][0] => attributes})
end
end
def _load
_load! if ! @data
@data
end
end

BIN
docs/development/mystuff.dia

66
docs/development/was.txt

@ -0,0 +1,66 @@
was wir haben.
- verschiedene Model (user, group, mailAccount, mailALias, etc.)
- diese koennen in verschiedenen Datenquellen liegen
- die Datenquellen werden mit verschiedenen Abfragesprachen abgefragt.
- das entsprechende Model bestimmt welche Daten abgefragt werden.
- die Datenquelle bestimmt wie diese Daten abgefragt werden.
Konflikt: bei ldap laesst sich das wie nur schwer von dem was abgefragt
werden soll trennen.
Moegliche Loesung: eine Factory, die ueber die Klasse des Models und
die Klasse der Datenbank eine solche konkrete Datenbank initialisiert.
Variation: anstatt eine factory zu bauen koennte man eine generische
Datenbankklasse bauen die eine Klassenmethode bekommt ueber die mit
dem reingegebenen Model dann eine Instanz erzeugt wird.
Problem: Die Datenbankklasse muss dann Initialisierungsinformationen
zu den entsprechenden Models kennen. (Implementierungsdetail)
Um die Datenbankklasse generisch zu halten sollte diese Information
woanders her kommen, allerdings nicht aus dem Model, da dann wiederum
die Model Implementierungsdetails der Datenbankklasse kennen muessen.
Evtl.: laesst sich was ueber Name conventions machen. Sauberer scheint
mir aber zu sein das es zu jeder Datenbankklasse eine Konfigurationsdatei
gibt in der man die Eckdaten fuer die Abfragen der einzelnen Model
konfigurieren kann.
ein yaml koennte evtl. so aussehen: (ldap.yml)
ldap: # => wenn es pro Datenbank ne eigenen datei gibt ist das nicht noetig
host: host.one.virtual
port: 389
queries:
User:
baseDn: ou=user,o=system,dc=weird-web-workers,dc=org
filter: (objectClass=posixAccount)
Group:
baseDn: ou=group,o=system,dc=weird-web-workers,dc=org
filter: (objectClass=posixGroup)
...
alternativ zu einer Datei koennte man eine Mapping Datei zu jeder Kombination
aus Model und Datenbanktyp anlegen...diese waeren schoen klein schnell gelesen
und geschrieben.
Dateistruktur:
- model - user.rb
- group.rb
- site.rb
- mailalias_role.rb
- mailalias_person.rb
- mailaccount.rb
- data - ldap.rb
- data - config - ldap.yml
- adapter - ldap.rb
- config - ldap - user.yml
- group.yml
- site.yml
- mailalias_role.yml
- mailalias_person.yml
- mailaccount.yml

4
ds_admin.rb

@ -0,0 +1,4 @@
module DsAdmin
DsAdmin.autoload(:Model, 'model')
DsAdmin.autoload(:Storage, 'storage')
end

0
loader/user.rb

197
mappers/ldap.rb

@ -1,197 +0,0 @@
require 'active_support/secure_random'
require 'net/ldap'
class SystemDataBackendLdap
LDAP_USER_MAP = {
:uid => :name,
:userpassword => :pass,
:uidnumber => :uid,
:gidnumber => :gid,
:loginshell => :shell,
:homedirectory => :home
}
LDAP_GROUP_MAP = {
:cn => :name,
:gidnumber => :gid,
:memberuid => :members
}
LDAP_MAILALIASPERSON_MAP = {
:sn => :surname,
:cn => :name
}
LDAP_MAP = {
:User => LDAP_USER_MAP,
:Group => LDAP_GROUP_MAP,
:Site => { :o => :name },
:MailAliasRole => { :cn => :user },
:MailAliasPerson => LDAP_MAILALIASPERSON_MAP,
:mailAccount => { :homedirectory => :home }
}
LDAP_FILTER = {
:User => '(objectClass=posixAccount)',
:Group => '(objectClass=posixGroup)',
:Site => '(&(objectClass=organization)(!(o=hosting)))',
:MailAliasRole => '(&(objectClass=MailAlias)(objectClass=organizationalrole))',
:MailAliasPerson => '(&(objectClass=MailAlias)(objectClass=person))',
:MailAccount => '(objectClass=mailAccount)'
}
LDAP_OBJECTCLASS = {
:User => [ 'account', 'posixAccount', 'shadowAccount' ],
:Group => 'posixGroup',
:Site => 'organization',
:MailAliasRole => [ 'organizationalRole', 'MailAlias' ],
:MailAliasPerson => [ 'person', 'MailAlias' ],
:MailAccount => [ 'person', 'MailAccount' ]
}
LDAP_LAMBDA_USER = lambda do |entry|
entry[:cn] = entry[:uid]
entry[:shadowlastchange] = (Time::now.to_i/60/60/24).to_s
entry[:replace] += ['shadowreplace'] if entry[:replace]
end
LDAP_LAMBDA = {
:User => LDAP_LAMBDA_USER
}
def initialize(host, port, baseDn, args={})
@baseDn = baseDn
@systemDn = 'o=system,' + @baseDn
@hostingDn = 'o=hosting,' + @baseDn
@systemDn = args[:systemDn] if args[:systemDn]
@hostingDn = args[:hostingDn] if args[:hostingDn]
@ldap = Net::LDAP.new(:host => host, :port => port)
@ldapData = Hash.new
end
def load!(kind)
@ldapData[kind] = Hash.new if ! @ldapData[kind]
@ldapData[kind][:int] = @ldap.search(
:base => ldapBase(kind),
:filter => Net::LDAP::Filter::construct(LDAP_FILTER[kind])
)
end
def load(kind)
load!(kind) if ! @ldapData[kind]
@ldapData[kind][:ext] = @ldapData[kind][:int].map do |data|
map = { :dn => :id }
map.merge!(LDAP_MAP[kind]) if LDAP_MAP[kind]
ydata = {}
data.each do |key,value|
ydata.merge!({ map[key] || key => value.size==1?value[0]:value.to_a })
end
ydata
end if ! @ldapData[kind][:ext] && @ldapData[kind][:int]
@ldapData[kind][:ext].each{|ydata| yield ydata} if @ldapData[kind][:ext]
end
def update(kind, data)
map = {}
map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind]
odata = @ldapData[kind][:ext].find{|edata| edata[:id] == data[:id]}
data.each do |key,value|
pat_key = map[key] ? map[key] : key
if odata[:id] =~ /(^|, *)#{pat_key.to_s}=([^, ]+)/ && $2 != value
return replace(kind, data)
end
end
entry = Net::LDAP::Entry.new(data[:id])
data = data.find_all{|key,value| value != odata[key]}
data.delete(:id)
replace = Array.new
data.each do |key,value|
key = map[key] if map[key]
replace.push(key.to_s)
entry[key] = value
end
if replace.empty?
puts 'INFO: no changes'
else
entry[:changetype] = 'modify'
entry[:replace] = replace
LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind]
puts entry.to_ldif
end
end
def replace(kind, data)
puts 'INFO: do replace'
puts '----------------'
odata = @ldapData[kind][:ext].find{|edata| edata[:id] == data[:id]}
delete(odata)
puts
insert(kind, data)
puts '----------------'
end
def delete(data)
entry = Net::LDAP::Entry.new(data[:id])
entry[:changetype] = 'delete'
puts entry.to_ldif
end
def insert(kind, data)
map = {}
map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind]
data.delete(:id)
entry = Net::LDAP::Entry.new(ldapDn(kind, data))
entry[:changetype] = 'add'
entry[:objectclass] = LDAP_OBJECTCLASS[kind]
data.each do |key,value|
key = map[key] if map[key]
entry[key] = value
end
LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind]
puts entry.to_ldif
end
private
def ldapBase(kind)
case(kind)
when :User, :Group: @systemDn
when :Site, :MailAliasRole, :MailAliasPerson, :MailAccount: @hostingDn
end
end
def ldapDn(kind, data)
case(kind)
when :User
"uid=#{data[:name]},ou=user,#{ldapBase(kind)}"
when :Group
"cn=#{data[:name]},ou=group,#{ldapBase(kind)}"
when :Site
"o=#{data[:name]},#{ldapBase(kind)}"
when :MailAliasRole
"cn=#{data[:user]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
when :MailAliasPerson
"mail=#{data[:mail]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
when :MailAccount
"mail=#{data[:mail]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
end
end
end

72
model.rb

@ -1,16 +1,64 @@
module SdAdmin::Model
module Interface
end
module DsAdmin::Model
include Enumerable
class Base
require 'model/interface'
require 'database'
include SdAdmin::Model::Interface
end
DsAdmin::Model.autoload(:User, 'model/user')
DsAdmin::Model.autoload(:Group, 'model/group')
DsAdmin::Model.autoload(:Site, 'model/site')
DsAdmin::Model.autoload(:MailAliasRole, 'model/mail_alias_role')
DsAdmin::Model.autoload(:MailAliasPerson, 'model/mail_alias_person')
DsAdmin::Model.autoload(:MailAccount, 'model/mail_account')
class User < Base
end
def (DsAdmin::Model).storage=(storage)
@@storage = storage
end
require 'model/base'
require 'model/user'
def (DsAdmin::Model).storage
@@storage
end
attr_accessor :id
def initialize(args = {})
@id = args[:id] if args[:id]
end
def all
@@storage.config.model = self
@@storage.map do |data|
self.class.new(data)
end
end
def each(&block)
all.each(&block)
end
def load(id)
self.class.new(_load(id))
end
def load!(id)
initialize(_load(id))
end
def save
@id = @storage.create_id(self) unless @id
@storage.write(self)
end
def update
@storage.write(self)
end
def to_sym
self.class.to_s.to_sym
end
protected
def _load(id)
data = @@storage.find {|data| data[:id] == id}
throw "unknown id (#{id})" unless data
data
end
end

9
model/base.rb

@ -1,9 +0,0 @@
class SdAdmin::Model::Base
attr_reader :backend
def initialize(backend)
@backend = SdAdmin::Database::Ldap.new
@backend = backend if backend
end
end

12
model/group.rb

@ -1,14 +1,14 @@
require 'SystemData'
class DsAdmin::Model::Group
include DsAdmin::Model
class Group < SystemData
attr_accessor :name, :gid, :members
def initialize(args = {})
super(args)
return if args.empty?
super(args)
@name = args[:name]
@gid = args[:gid]
@members = args[:members]
@members = Array.new if @members.nil?
@members = args[:members] ? args[:members] : Array.new
end
end

7
model/interface.rb

@ -1,7 +0,0 @@
module SdAdmin::Model::Interface
def all
Hash[self.backend.map{|key,entry| [key, entry]}]
end
end

5
model/mail_account.rb

@ -1,9 +1,10 @@
require 'SystemData'
class DsAdmin::Model::MailAccount
include DsAdmin::Model
class MailAccount < SystemData
attr_accessor :mail, :mailbox
def initialize(args = {})
return if args.empty?
super(args)
@mail = args[:mail]

5
model/mail_alias_person.rb

@ -1,9 +1,10 @@
require 'SystemData'
class DsAdmin::Model::MailAliasPerson
include DsAdmin::Model
class MailAliasPerson < SystemData
attr_accessor :mail, :maildrop, :surname, :name
def initialize(args = {})
return if args.empty?
super(args)
@mail = args[:mail]

5
model/mail_alias_role.rb

@ -1,9 +1,10 @@
require 'SystemData'
class DsAdmin::Model::MailAliasRole
include DsAdmin::Model
class MailAliasRole < SystemData
attr_accessor :mail, :maildrop, :user
def initialize(args = {})
return if args.empty?
super(args)
@mail = args[:mail]

5
model/site.rb

@ -1,9 +1,10 @@
require 'SystemData'
class DsAdmin::Model::Site
include DsAdmin::Model
class Site < SystemData
attr_accessor :name
def initialize(args = {})
return if args.empty?
super(args)
@name = args[:name]

24
model/system_data.rb

@ -1,24 +0,0 @@
class SystemData
attr_reader :id
def initialize(args = {})
@backend = args[:backend]
@id = args[:id]
end
def save
kind = self.class.to_s.to_sym
if @id
@backend.update(kind, to_h)
else
@backend.insert(kind, to_h)
end
end
def to_h
Hash[instance_variables.map do |var|
[var[1...var.size].to_sym, eval(var)] if var != '@backend'
end]
end
end

30
model/user.rb

@ -1,19 +1,19 @@
class SdAdmin::Model::User
attr_accessor :name, :pass, :uid, :gid, :shell, :home
class DsAdmin::Model::User
include DsAdmin::Model
def initialize(args={}, backend=nil)
super(backend)
attr_accessor :name, :pass, :uid, :gid, :shell, :home
@backend.base_dn = 'ou=user,o=system,dc=weird-web-workers,dc=org'
@backend.filter = '(objectClass=posixAccount)'
def initialize(args = {})
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]
end
@name = args[:name]
@pass = args[:pass]
@uid = args[:uid]
@gid = args[:gid]
@shell = args[:shell]
@home = args[:home]
@shadowmax = args[:shadowmax]
@shadowwarning = args[:shadowwarning]
end
end

10
sd_admin.rb

@ -1,10 +0,0 @@
module SdAdmin
module Model
end
module Database
end
require 'model'
require 'database'
end

37
storage.rb

@ -0,0 +1,37 @@
module DsAdmin::Storage
include Enumerable
DsAdmin::Storage.autoload(:Ldap, 'storage/ldap')
DsAdmin::Storage.autoload(:Mysql, 'storage/mysql')
DsAdmin::Storage.autoload(:Config, 'storage/config')
attr_accessor :config
def initialize(config)
@config = config
end
def each(&block)
read.each(&block)
end
##
# We don't need this....the 'id' is a storage id and as
# thus returned after successfully writing a new entry.
#
def create_id(model)
return "dummy id for #{model.inspect}"
end
def read
throw "#{self.class}: read not implemented"
end
def write(model)
throw "#{self.class}: write not implemented"
end
def to_sym
self.class.to_s.to_sym
end
end

21
storage/config.rb

@ -0,0 +1,21 @@
require 'yaml'
class Test::Storage::Config
attr_accessor :model
def initialize(yml_file)
@config = YAML.load_file(yml_file)
end
def con(storage)
@config[storage.to_sym][:con]
end
def query(storage)
@config[storage.to_sym][@model.to_sym][:query]
end
def map(storage)
@config[storage.to_sym][@model.to_sym][:map]
end
end

34
storage/ldap.rb

@ -0,0 +1,34 @@
require 'net/ldap'
class DsAdmin::Storage::Ldap
include DsAdmin::Storage
def initialize(config)
super(config)
@ldap = Net::LDAP.new(@config.con(self))
end
def read
query = @config.query(self)
##
# two things.
# - create a hash from the ldap search result
# - 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|
map = { :dn => :id }
map.merge!(@config.map(self))
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
remapped
end
end
end

3
storage/mysql.rb

@ -0,0 +1,3 @@
class DsAdmin::Storage::Mysql
include DsAdmin::Storage
end

123
test_dummy.rb

@ -1,123 +0,0 @@
require 'SystemDataBackend'
require 'SystemDataBackendLdap'
ldap = SystemDataBackendLdap.new(
'host.one.virtual',
389,
'dc=weird-web-workers,dc=org'
)
backend = SystemDataBackend.new(ldap)
backend.users.each do |user|
puts 'user: '+user.name+','+user.uid+','+user.gid+','+user.home
end
puts
backend.groups.each do |group|
members = backend.usersInGroup(group)
puts 'group: '+group.name+','+group.gid
puts ' members:'
group.members.each do |name|
print ' ' + name + ': '
print members[name].uid + ', ' + members[name].home if members[name]
puts
end
puts
end
backend.sites.each do |site|
puts 'site: ' + site.name
puts ' MailAliasRoles:'
backend.mailAliasRolesBySite(site).each{|account| puts ' ' + account.mail}
puts
puts ' MailAliasPeople:'
backend.mailAliasPeopleBySite(site).each{|account| puts ' ' + account.mail}
puts
puts ' MailAccounts:'
backend.mailAccountsBySite(site).each{|account| puts ' ' + account.mail}
puts
end
backend.mailAliasRoles.each do |mailAlias|
puts 'mailAliasRole: '+mailAlias.mail.inspect+','+mailAlias.maildrop.inspect
end
puts
backend.mailAliasPeople.each do |mailAlias|
puts 'mailAliasPerson: '+mailAlias.mail.inspect+','+mailAlias.maildrop.inspect
end
puts
backend.mailAccounts.each do |mailAccount|
puts 'mailAccount: '+mailAccount.mail.inspect+','+mailAccount.mailbox.inspect
end
puts
georg = backend.userByName('georg')
georg.save
puts
georg.uid = 1001
georg.save
puts
wheel = backend.groupByName('wheel')
wheel.save
puts
wheel.gid = 100
wheel.save
puts
site = backend.siteByName('kommandozeilenchef.de')
site.save
puts
site.name = 'wumbaba.de'
site.save
puts
mail = MailAliasRole.new({
:backend => ldap,
:mail => 'newrole@kommandozeilenchef.de',
:maildrop => 'newrole',
:user => 'newrole'
})
mail.save
puts
mail = MailAliasPerson.new({
:backend => ldap,
:mail => 'ohotte@kommandozeilenchef.de',
:maildrop => 'ohotte',
:name => 'Onkel Hotte',
:surname => 'Hotte'
})
mail.save
puts
mail = MailAccount.new({
:backend => ldap,
:mail => 'foobar@kommandozeilenchef.de',
:mailbox => 'kommandozeilenchef.de/foobar',
:home => '/var/spool/vmail/domains'
})
mail.save
puts
puts '====================================='
# -o vsz/vsize
puts 'Memory useage: ' + `ps -o rss= -p #{Process.pid}`

5
test_dummy2.rb

@ -1,5 +0,0 @@
require 'sd_admin'
user = SdAdmin::Model::User.new
puts user.all.inspect

38
tester.rb

@ -0,0 +1,38 @@
require 'ds_admin'
config = DsAdmin::Storage::Config.new(File.dirname(__FILE__) + '/config/storage.yml')
DsAdmin::Model.storage = DsAdmin::Storage::Ldap.new(config)
user = DsAdmin::Model::User.new
group = DsAdmin::Model::Group.new
site = DsAdmin::Model::Site.new
alias_role = DsAdmin::Model::MailAliasRole.new
alias_person = DsAdmin::Model::MailAliasPerson.new
account = DsAdmin::Model::MailAccount.new
puts '=== DsAdmin each ==='
user.each {|user| puts user.inspect}
puts '---'
group.each {|group| puts group.inspect}
puts '---'
site.each {|site| puts site.inspect}
puts '---'
alias_role.each {|ma_role| puts ma_role.inspect}
puts '---'
alias_person.each {|ma_person| puts ma_person.inspect}
puts '---'
account.each {|macc| puts macc.inspect}
puts
puts '=== DsAdmin Enumerable ==='
puts user.find {|user| user.uid == '1000'}.inspect
puts '---'
puts group.find {|group| group.gid == '10'}.inspect
puts '---'
puts site.find {|site| site.name == 'steffers.org'}.inspect
puts '---'
puts alias_role.find_all {|mar| mar.maildrop == 'abuse'}.inspect
puts '---'
puts alias_person.find {|map| map.mail == 'georg@steffers.org'}.inspect
puts '---'
puts account.find {|acc| acc.mail == 'drachenfrau@steffers.org'}.inspect
Loading…
Cancel
Save