Commit 666ae5b6fd8823340081c236abe54007fb7540fd

Authored by Georg GH. Hopp
Committed by Georg Hopp
1 parent 4790392a

heavy restructuring

implemented new design
1   -require 'SystemData'
2   -
3   -class Group < SystemData
4   - attr_accessor :name, :gid, :members
5   -
6   - def initialize(args = {})
7   - super(args)
8   -
9   - @name = args[:name]
10   - @gid = args[:gid]
11   - @members = args[:members]
12   - @members = Array.new if @members.nil?
13   - end
14   -end
1   -require 'SystemData'
2   -
3   -class MailAccount < SystemData
4   - attr_accessor :mail, :mailbox
5   -
6   - def initialize(args = {})
7   - super(args)
8   -
9   - @mail = args[:mail]
10   - @home = args[:home]
11   - @mailbox = args[:mailbox]
12   - end
13   -
14   - def site
15   - @mail.sub(/.*@/, '')
16   - end
17   -end
1   -require 'SystemData'
2   -
3   -class MailAliasPerson < SystemData
4   - attr_accessor :mail, :maildrop, :surname, :name
5   -
6   - def initialize(args = {})
7   - super(args)
8   -
9   - @mail = args[:mail]
10   - @maildrop = args[:maildrop]
11   - @surname = args[:surname]
12   - @name = args[:name]
13   - end
14   -
15   - def site
16   - @mail.sub(/.*@/, '')
17   - end
18   -end
1   -require 'SystemData'
2   -
3   -class MailAliasRole < SystemData
4   - attr_accessor :mail, :maildrop, :user
5   -
6   - def initialize(args = {})
7   - super(args)
8   -
9   - @mail = args[:mail]
10   - @maildrop = args[:maildrop]
11   - @user = args[:user]
12   - end
13   -
14   - def site
15   - @mail.sub(/.*@/, '')
16   - end
17   -end
1   -require 'SystemData'
2   -
3   -class Site < SystemData
4   - attr_accessor :name
5   -
6   - def initialize(args = {})
7   - super(args)
8   -
9   - @name = args[:name]
10   - end
11   -end
1   -class SystemData
2   - attr_reader :id
3   -
4   - def initialize(args = {})
5   - @backend = args[:backend]
6   - @id = args[:id]
7   - end
8   -
9   - def save
10   - kind = self.class.to_s.to_sym
11   -
12   - if @id
13   - @backend.update(kind, to_h)
14   - else
15   - @backend.insert(kind, to_h)
16   - end
17   - end
18   -
19   - def to_h
20   - Hash[instance_variables.map do |var|
21   - [var[1...var.size].to_sym, eval(var)] if var != '@backend'
22   - end]
23   - end
24   -end
1   -require 'User'
2   -require 'Group'
3   -require 'Site'
4   -require 'MailAliasRole'
5   -require 'MailAliasPerson'
6   -require 'MailAccount'
7   -
8   -class SystemDataBackend
9   -
10   - def initialize(backend)
11   - @backend = backend
12   - @data = Hash.new
13   - end
14   -
15   - def users
16   - load(:User)
17   - end
18   -
19   - def groups
20   - load(:Group)
21   - end
22   -
23   - def sites
24   - load(:Site)
25   - end
26   -
27   - def mailAliasRoles
28   - load(:MailAliasRole)
29   - end
30   -
31   - def mailAliasPeople
32   - load(:MailAliasPerson)
33   - end
34   -
35   - def mailAccounts
36   - load(:MailAccount)
37   - end
38   -
39   - def userByName(name)
40   - users.find{|user| user.name == name}
41   - end
42   -
43   - def groupByName(name)
44   - groups.find{|group| group.name == name}
45   - end
46   -
47   - def siteByName(name)
48   - sites.find{|site| site.name == name}
49   - end
50   -
51   - def usersInGroup(group)
52   - case
53   - when group.members.instance_of?(Array):
54   - Hash[group.members.map{|uid| [uid, userByName(uid)] if userByName(uid)}]
55   - when goup.members.nil?:
56   - {}
57   - else
58   - {group.members => userByName(group.members)} if userByName(group.members)
59   - end
60   - end
61   -
62   - def mailAliasRolesBySite(site)
63   - mailAliasRoles.find_all{|mail| mail.site == site.name}
64   - end
65   -
66   - def mailAliasPeopleBySite(site)
67   - mailAliasPeople.find_all{|mail| mail.site == site.name}
68   - end
69   -
70   - def mailAccountsBySite(site)
71   - mailAccounts.find_all{|mail| mail.site == site.name}
72   - end
73   -
74   - private
75   -
76   - def load(kind)
77   - load!(kind) if ! @data[kind]
78   - @data[kind]
79   - end
80   -
81   - def load!(kind)
82   - @data[kind] = Array.new
83   - @backend.load(kind) do |data|
84   - data[:backend] = @backend
85   - @data[kind].push(
86   - eval(kind.to_s + '.new(data)')
87   - )
88   - end
89   - end
90   -
91   -end
1   - require 'active_support/secure_random'
2   - require 'net/ldap'
3   -
4   - class SystemDataBackendLdap
5   -
6   - LDAP_USER_MAP = {
7   - :uid => :name,
8   - :userpassword => :pass,
9   - :uidnumber => :uid,
10   - :gidnumber => :gid,
11   - :loginshell => :shell,
12   - :homedirectory => :home
13   - }
14   -
15   - LDAP_GROUP_MAP = {
16   - :cn => :name,
17   - :gidnumber => :gid,
18   - :memberuid => :members
19   - }
20   -
21   - LDAP_MAILALIASPERSON_MAP = {
22   - :sn => :surname,
23   - :cn => :name
24   - }
25   -
26   - LDAP_MAP = {
27   - :User => LDAP_USER_MAP,
28   - :Group => LDAP_GROUP_MAP,
29   - :Site => { :o => :name },
30   - :MailAliasRole => { :cn => :user },
31   - :MailAliasPerson => LDAP_MAILALIASPERSON_MAP,
32   - :mailAccount => { :homedirectory => :home }
33   - }
34   -
35   - LDAP_FILTER = {
36   - :User => '(objectClass=posixAccount)',
37   - :Group => '(objectClass=posixGroup)',
38   - :Site => '(&(objectClass=organization)(!(o=hosting)))',
39   - :MailAliasRole => '(&(objectClass=MailAlias)(objectClass=organizationalrole))',
40   - :MailAliasPerson => '(&(objectClass=MailAlias)(objectClass=person))',
41   - :MailAccount => '(objectClass=mailAccount)'
42   - }
43   -
44   - LDAP_OBJECTCLASS = {
45   - :User => [ 'account', 'posixAccount', 'shadowAccount' ],
46   - :Group => 'posixGroup',
47   - :Site => 'organization',
48   - :MailAliasRole => [ 'organizationalRole', 'MailAlias' ],
49   - :MailAliasPerson => [ 'person', 'MailAlias' ],
50   - :MailAccount => [ 'person', 'MailAccount' ]
51   - }
52   -
53   - LDAP_LAMBDA_USER = lambda do |entry|
54   - entry[:cn] = entry[:uid]
55   - entry[:shadowlastchange] = (Time::now.to_i/60/60/24).to_s
56   - entry[:replace] += ['shadowreplace'] if entry[:replace]
57   - end
58   -
59   - LDAP_LAMBDA = {
60   - :User => LDAP_LAMBDA_USER
61   - }
62   -
63   - def initialize(host, port, baseDn, args={})
64   - @baseDn = baseDn
65   - @systemDn = 'o=system,' + @baseDn
66   - @hostingDn = 'o=hosting,' + @baseDn
67   -
68   - @systemDn = args[:systemDn] if args[:systemDn]
69   - @hostingDn = args[:hostingDn] if args[:hostingDn]
70   -
71   - @ldap = Net::LDAP.new(:host => host, :port => port)
72   - @ldapData = Hash.new
73   - end
74   -
75   - def load!(kind)
76   - @ldapData[kind] = Hash.new if ! @ldapData[kind]
77   -
78   - @ldapData[kind][:int] = @ldap.search(
79   - :base => ldapBase(kind),
80   - :filter => Net::LDAP::Filter::construct(LDAP_FILTER[kind])
81   - )
82   - end
83   -
84   - def load(kind)
85   - load!(kind) if ! @ldapData[kind]
86   -
87   - @ldapData[kind][:ext] = @ldapData[kind][:int].map do |data|
88   - map = { :dn => :id }
89   - map.merge!(LDAP_MAP[kind]) if LDAP_MAP[kind]
90   -
91   - ydata = {}
92   - data.each do |key,value|
93   - ydata.merge!({ map[key] || key => value.size==1?value[0]:value.to_a })
94   - end
95   - ydata
96   - end if ! @ldapData[kind][:ext] && @ldapData[kind][:int]
97   -
98   - @ldapData[kind][:ext].each{|ydata| yield ydata} if @ldapData[kind][:ext]
99   - end
100   -
101   - def update(kind, data)
102   - map = {}
103   - map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind]
104   -
105   - odata = @ldapData[kind][:ext].find{|edata| edata[:id] == data[:id]}
106   -
107   - data.each do |key,value|
108   - pat_key = map[key] ? map[key] : key
109   - if odata[:id] =~ /(^|, *)#{pat_key.to_s}=([^, ]+)/ && $2 != value
110   - return replace(kind, data)
111   - end
112   - end
113   -
114   - entry = Net::LDAP::Entry.new(data[:id])
115   - data = data.find_all{|key,value| value != odata[key]}
116   - data.delete(:id)
117   -
118   - replace = Array.new
119   - data.each do |key,value|
120   - key = map[key] if map[key]
121   - replace.push(key.to_s)
122   - entry[key] = value
123   - end
124   -
125   - if replace.empty?
126   - puts 'INFO: no changes'
127   - else
128   - entry[:changetype] = 'modify'
129   - entry[:replace] = replace
130   - LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind]
131   -
132   - puts entry.to_ldif
133   - end
134   - end
135   -
136   - def replace(kind, data)
137   - puts 'INFO: do replace'
138   - puts '----------------'
139   - odata = @ldapData[kind][:ext].find{|edata| edata[:id] == data[:id]}
140   - delete(odata)
141   - puts
142   - insert(kind, data)
143   - puts '----------------'
144   - end
145   -
146   - def delete(data)
147   - entry = Net::LDAP::Entry.new(data[:id])
148   - entry[:changetype] = 'delete'
149   -
150   - puts entry.to_ldif
151   - end
152   -
153   - def insert(kind, data)
154   - map = {}
155   - map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind]
156   -
157   - data.delete(:id)
158   - entry = Net::LDAP::Entry.new(ldapDn(kind, data))
159   - entry[:changetype] = 'add'
160   - entry[:objectclass] = LDAP_OBJECTCLASS[kind]
161   -
162   - data.each do |key,value|
163   - key = map[key] if map[key]
164   - entry[key] = value
165   - end
166   - LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind]
167   -
168   - puts entry.to_ldif
169   - end
170   -
171   - private
172   -
173   - def ldapBase(kind)
174   - case(kind)
175   - when :User, :Group: @systemDn
176   - when :Site, :MailAliasRole, :MailAliasPerson, :MailAccount: @hostingDn
177   - end
178   - end
179   -
180   - def ldapDn(kind, data)
181   - case(kind)
182   - when :User
183   - "uid=#{data[:name]},ou=user,#{ldapBase(kind)}"
184   - when :Group
185   - "cn=#{data[:name]},ou=group,#{ldapBase(kind)}"
186   - when :Site
187   - "o=#{data[:name]},#{ldapBase(kind)}"
188   - when :MailAliasRole
189   - "cn=#{data[:user]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
190   - when :MailAliasPerson
191   - "mail=#{data[:mail]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
192   - when :MailAccount
193   - "mail=#{data[:mail]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
194   - end
195   - end
196   -
197   -end
1   -require 'SystemData'
2   -
3   -class User < SystemData
4   - attr_accessor :name, :pass, :uid, :gid, :shell, :home
5   -
6   - def initialize(args = {})
7   - super(args)
8   -
9   - @name = args[:name]
10   - @pass = args[:pass]
11   - @uid = args[:uid]
12   - @gid = args[:gid]
13   - @shell = args[:shell]
14   - @home = args[:home]
15   - @shadowmax = args[:shadowmax]
16   - @shadowwarning = args[:shadowwarning]
17   - end
18   -end
1   -require 'User'
2   -require 'Group'
3   -require 'Site'
4   -require 'MailAliasRole'
5   -require 'MailAliasPerson'
6   -require 'MailAccount'
7   -
8   -class SystemDataBackend
9   -
10   - def initialize(backend)
11   - @backend = backend
12   - @data = Hash.new
13   - end
14   -
15   - def users
16   - load(:User)
17   - end
18   -
19   - def groups
20   - load(:Group)
21   - end
22   -
23   - def sites
24   - load(:Site)
25   - end
26   -
27   - def mailAliasRoles
28   - load(:MailAliasRole)
29   - end
30   -
31   - def mailAliasPeople
32   - load(:MailAliasPerson)
33   - end
34   -
35   - def mailAccounts
36   - load(:MailAccount)
37   - end
38   -
39   - def userByName(name)
40   - users.find{|user| user.name == name}
41   - end
42   -
43   - def groupByName(name)
44   - groups.find{|group| group.name == name}
45   - end
46   -
47   - def siteByName(name)
48   - sites.find{|site| site.name == name}
49   - end
50   -
51   - def usersInGroup(group)
52   - case
53   - when group.members.instance_of?(Array):
54   - Hash[group.members.map{|uid| [uid, userByName(uid)] if userByName(uid)}]
55   - when goup.members.nil?:
56   - {}
57   - else
58   - {group.members => userByName(group.members)} if userByName(group.members)
59   - end
60   - end
61   -
62   - def mailAliasRolesBySite(site)
63   - mailAliasRoles.find_all{|mail| mail.site == site.name}
64   - end
65   -
66   - def mailAliasPeopleBySite(site)
67   - mailAliasPeople.find_all{|mail| mail.site == site.name}
68   - end
69   -
70   - def mailAccountsBySite(site)
71   - mailAccounts.find_all{|mail| mail.site == site.name}
72   - end
73   -
74   - private
75   -
76   - def load(kind)
77   - load!(kind) if ! @data[kind]
78   - @data[kind]
79   - end
80   -
81   - def load!(kind)
82   - @data[kind] = Array.new
83   - @backend.load(kind) do |data|
84   - data[:backend] = @backend
85   - @data[kind].push(
86   - eval(kind.to_s + '.new(data)')
87   - )
88   - end
89   - end
90   -
91   -end
1   -module SdAdmin::Database
2   - class Ldap
3   - require 'database/base.rb'
4   - require 'net/ldap'
5   -
6   - include Enumerable
7   - end
8   -
9   - require 'database/ldap'
10   -end
1   -class SdAdmin::Database::Base
2   -
3   - def initialize
4   - @data = Hash.new
5   - end
6   -
7   - def _create(data)
8   - end
9   -
10   - def _read(id)
11   - end
12   -
13   -end
1   -class SdAdmin::Database::Factory
2   -
3   -end
1   -class SdAdmin::Database::Ldap
2   - attr_writer :base_dn, :mapper
3   -
4   - def initialize(args = {})
5   - @con = {:host => 'host.one.virtual', :port => 389}
6   -
7   - @con[:host] = args[:host] if args[:host]
8   - @con[:port] = args[:port] if args[:port]
9   -
10   - @base_dn = args[:base_dn] if args[:base_dn]
11   -
12   - @ldap = Net::LDAP.new(@con)
13   - filter = args[:filter] if args[:filter]
14   - end
15   -
16   - def filter=(filter)
17   - @filter = Net::LDAP::Filter::construct(filter)
18   - end
19   -
20   - def each
21   - _load.each{|key,entry| puts "DEBUG: #{key}"; yield key,entry}
22   - end
23   -
24   - def [](id)
25   - _load[id]
26   - end
27   -
28   - def []=(id, data)
29   - end
30   -
31   - def insert(data)
32   - end
33   -
34   - def delete(id)
35   - end
36   -
37   - private
38   -
39   - def _load!
40   - @data = Hash.new
41   - @ldap.search(:base => @base_dn, :filter => @filter) do |entry|
42   - attributes = Hash.new
43   - entry.each{|attr,value| attributes.merge!({attr => value})}
44   - @data.merge!({attributes[:dn][0] => attributes})
45   - end
46   - end
47   -
48   - def _load
49   - _load! if ! @data
50   - @data
51   - end
52   -
53   -end
No preview for this file type
  1 +was wir haben.
  2 +
  3 +- verschiedene Model (user, group, mailAccount, mailALias, etc.)
  4 +- diese koennen in verschiedenen Datenquellen liegen
  5 +- die Datenquellen werden mit verschiedenen Abfragesprachen abgefragt.
  6 +- das entsprechende Model bestimmt welche Daten abgefragt werden.
  7 +- die Datenquelle bestimmt wie diese Daten abgefragt werden.
  8 +
  9 + Konflikt: bei ldap laesst sich das wie nur schwer von dem was abgefragt
  10 +werden soll trennen.
  11 +
  12 + Moegliche Loesung: eine Factory, die ueber die Klasse des Models und
  13 +die Klasse der Datenbank eine solche konkrete Datenbank initialisiert.
  14 +
  15 + Variation: anstatt eine factory zu bauen koennte man eine generische
  16 + Datenbankklasse bauen die eine Klassenmethode bekommt ueber die mit
  17 + dem reingegebenen Model dann eine Instanz erzeugt wird.
  18 +
  19 + Problem: Die Datenbankklasse muss dann Initialisierungsinformationen
  20 +zu den entsprechenden Models kennen. (Implementierungsdetail)
  21 +Um die Datenbankklasse generisch zu halten sollte diese Information
  22 +woanders her kommen, allerdings nicht aus dem Model, da dann wiederum
  23 +die Model Implementierungsdetails der Datenbankklasse kennen muessen.
  24 +
  25 + Evtl.: laesst sich was ueber Name conventions machen. Sauberer scheint
  26 +mir aber zu sein das es zu jeder Datenbankklasse eine Konfigurationsdatei
  27 +gibt in der man die Eckdaten fuer die Abfragen der einzelnen Model
  28 +konfigurieren kann.
  29 +
  30 + ein yaml koennte evtl. so aussehen: (ldap.yml)
  31 +
  32 + ldap: # => wenn es pro Datenbank ne eigenen datei gibt ist das nicht noetig
  33 + host: host.one.virtual
  34 + port: 389
  35 + queries:
  36 + User:
  37 + baseDn: ou=user,o=system,dc=weird-web-workers,dc=org
  38 + filter: (objectClass=posixAccount)
  39 + Group:
  40 + baseDn: ou=group,o=system,dc=weird-web-workers,dc=org
  41 + filter: (objectClass=posixGroup)
  42 +
  43 + ...
  44 +
  45 + alternativ zu einer Datei koennte man eine Mapping Datei zu jeder Kombination
  46 +aus Model und Datenbanktyp anlegen...diese waeren schoen klein schnell gelesen
  47 +und geschrieben.
  48 +
  49 + Dateistruktur:
  50 +
  51 + - model - user.rb
  52 + - group.rb
  53 + - site.rb
  54 + - mailalias_role.rb
  55 + - mailalias_person.rb
  56 + - mailaccount.rb
  57 + - data - ldap.rb
  58 + - data - config - ldap.yml
  59 + - adapter - ldap.rb
  60 + - config - ldap - user.yml
  61 + - group.yml
  62 + - site.yml
  63 + - mailalias_role.yml
  64 + - mailalias_person.yml
  65 + - mailaccount.yml
  66 +
... ...
  1 +module DsAdmin
  2 + DsAdmin.autoload(:Model, 'model')
  3 + DsAdmin.autoload(:Storage, 'storage')
  4 +end
... ...
1   - require 'active_support/secure_random'
2   - require 'net/ldap'
3   -
4   - class SystemDataBackendLdap
5   -
6   - LDAP_USER_MAP = {
7   - :uid => :name,
8   - :userpassword => :pass,
9   - :uidnumber => :uid,
10   - :gidnumber => :gid,
11   - :loginshell => :shell,
12   - :homedirectory => :home
13   - }
14   -
15   - LDAP_GROUP_MAP = {
16   - :cn => :name,
17   - :gidnumber => :gid,
18   - :memberuid => :members
19   - }
20   -
21   - LDAP_MAILALIASPERSON_MAP = {
22   - :sn => :surname,
23   - :cn => :name
24   - }
25   -
26   - LDAP_MAP = {
27   - :User => LDAP_USER_MAP,
28   - :Group => LDAP_GROUP_MAP,
29   - :Site => { :o => :name },
30   - :MailAliasRole => { :cn => :user },
31   - :MailAliasPerson => LDAP_MAILALIASPERSON_MAP,
32   - :mailAccount => { :homedirectory => :home }
33   - }
34   -
35   - LDAP_FILTER = {
36   - :User => '(objectClass=posixAccount)',
37   - :Group => '(objectClass=posixGroup)',
38   - :Site => '(&(objectClass=organization)(!(o=hosting)))',
39   - :MailAliasRole => '(&(objectClass=MailAlias)(objectClass=organizationalrole))',
40   - :MailAliasPerson => '(&(objectClass=MailAlias)(objectClass=person))',
41   - :MailAccount => '(objectClass=mailAccount)'
42   - }
43   -
44   - LDAP_OBJECTCLASS = {
45   - :User => [ 'account', 'posixAccount', 'shadowAccount' ],
46   - :Group => 'posixGroup',
47   - :Site => 'organization',
48   - :MailAliasRole => [ 'organizationalRole', 'MailAlias' ],
49   - :MailAliasPerson => [ 'person', 'MailAlias' ],
50   - :MailAccount => [ 'person', 'MailAccount' ]
51   - }
52   -
53   - LDAP_LAMBDA_USER = lambda do |entry|
54   - entry[:cn] = entry[:uid]
55   - entry[:shadowlastchange] = (Time::now.to_i/60/60/24).to_s
56   - entry[:replace] += ['shadowreplace'] if entry[:replace]
57   - end
58   -
59   - LDAP_LAMBDA = {
60   - :User => LDAP_LAMBDA_USER
61   - }
62   -
63   - def initialize(host, port, baseDn, args={})
64   - @baseDn = baseDn
65   - @systemDn = 'o=system,' + @baseDn
66   - @hostingDn = 'o=hosting,' + @baseDn
67   -
68   - @systemDn = args[:systemDn] if args[:systemDn]
69   - @hostingDn = args[:hostingDn] if args[:hostingDn]
70   -
71   - @ldap = Net::LDAP.new(:host => host, :port => port)
72   - @ldapData = Hash.new
73   - end
74   -
75   - def load!(kind)
76   - @ldapData[kind] = Hash.new if ! @ldapData[kind]
77   -
78   - @ldapData[kind][:int] = @ldap.search(
79   - :base => ldapBase(kind),
80   - :filter => Net::LDAP::Filter::construct(LDAP_FILTER[kind])
81   - )
82   - end
83   -
84   - def load(kind)
85   - load!(kind) if ! @ldapData[kind]
86   -
87   - @ldapData[kind][:ext] = @ldapData[kind][:int].map do |data|
88   - map = { :dn => :id }
89   - map.merge!(LDAP_MAP[kind]) if LDAP_MAP[kind]
90   -
91   - ydata = {}
92   - data.each do |key,value|
93   - ydata.merge!({ map[key] || key => value.size==1?value[0]:value.to_a })
94   - end
95   - ydata
96   - end if ! @ldapData[kind][:ext] && @ldapData[kind][:int]
97   -
98   - @ldapData[kind][:ext].each{|ydata| yield ydata} if @ldapData[kind][:ext]
99   - end
100   -
101   - def update(kind, data)
102   - map = {}
103   - map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind]
104   -
105   - odata = @ldapData[kind][:ext].find{|edata| edata[:id] == data[:id]}
106   -
107   - data.each do |key,value|
108   - pat_key = map[key] ? map[key] : key
109   - if odata[:id] =~ /(^|, *)#{pat_key.to_s}=([^, ]+)/ && $2 != value
110   - return replace(kind, data)
111   - end
112   - end
113   -
114   - entry = Net::LDAP::Entry.new(data[:id])
115   - data = data.find_all{|key,value| value != odata[key]}
116   - data.delete(:id)
117   -
118   - replace = Array.new
119   - data.each do |key,value|
120   - key = map[key] if map[key]
121   - replace.push(key.to_s)
122   - entry[key] = value
123   - end
124   -
125   - if replace.empty?
126   - puts 'INFO: no changes'
127   - else
128   - entry[:changetype] = 'modify'
129   - entry[:replace] = replace
130   - LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind]
131   -
132   - puts entry.to_ldif
133   - end
134   - end
135   -
136   - def replace(kind, data)
137   - puts 'INFO: do replace'
138   - puts '----------------'
139   - odata = @ldapData[kind][:ext].find{|edata| edata[:id] == data[:id]}
140   - delete(odata)
141   - puts
142   - insert(kind, data)
143   - puts '----------------'
144   - end
145   -
146   - def delete(data)
147   - entry = Net::LDAP::Entry.new(data[:id])
148   - entry[:changetype] = 'delete'
149   -
150   - puts entry.to_ldif
151   - end
152   -
153   - def insert(kind, data)
154   - map = {}
155   - map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind]
156   -
157   - data.delete(:id)
158   - entry = Net::LDAP::Entry.new(ldapDn(kind, data))
159   - entry[:changetype] = 'add'
160   - entry[:objectclass] = LDAP_OBJECTCLASS[kind]
161   -
162   - data.each do |key,value|
163   - key = map[key] if map[key]
164   - entry[key] = value
165   - end
166   - LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind]
167   -
168   - puts entry.to_ldif
169   - end
170   -
171   - private
172   -
173   - def ldapBase(kind)
174   - case(kind)
175   - when :User, :Group: @systemDn
176   - when :Site, :MailAliasRole, :MailAliasPerson, :MailAccount: @hostingDn
177   - end
178   - end
179   -
180   - def ldapDn(kind, data)
181   - case(kind)
182   - when :User
183   - "uid=#{data[:name]},ou=user,#{ldapBase(kind)}"
184   - when :Group
185   - "cn=#{data[:name]},ou=group,#{ldapBase(kind)}"
186   - when :Site
187   - "o=#{data[:name]},#{ldapBase(kind)}"
188   - when :MailAliasRole
189   - "cn=#{data[:user]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
190   - when :MailAliasPerson
191   - "mail=#{data[:mail]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
192   - when :MailAccount
193   - "mail=#{data[:mail]},o=#{data[:mail].sub(/.*@/, '')},#{ldapBase(kind)}"
194   - end
195   - end
196   -
197   -end
1   -module SdAdmin::Model
2   - module Interface
3   - end
  1 +module DsAdmin::Model
  2 + include Enumerable
4 3
5   - class Base
6   - require 'model/interface'
7   - require 'database'
8   - include SdAdmin::Model::Interface
9   - end
  4 + DsAdmin::Model.autoload(:User, 'model/user')
  5 + DsAdmin::Model.autoload(:Group, 'model/group')
  6 + DsAdmin::Model.autoload(:Site, 'model/site')
  7 + DsAdmin::Model.autoload(:MailAliasRole, 'model/mail_alias_role')
  8 + DsAdmin::Model.autoload(:MailAliasPerson, 'model/mail_alias_person')
  9 + DsAdmin::Model.autoload(:MailAccount, 'model/mail_account')
10 10
11   - class User < Base
12   - end
  11 + def (DsAdmin::Model).storage=(storage)
  12 + @@storage = storage
  13 + end
13 14
14   - require 'model/base'
15   - require 'model/user'
  15 + def (DsAdmin::Model).storage
  16 + @@storage
  17 + end
  18 +
  19 + attr_accessor :id
  20 +
  21 + def initialize(args = {})
  22 + @id = args[:id] if args[:id]
  23 + end
  24 +
  25 + def all
  26 + @@storage.config.model = self
  27 +
  28 + @@storage.map do |data|
  29 + self.class.new(data)
  30 + end
  31 + end
  32 +
  33 + def each(&block)
  34 + all.each(&block)
  35 + end
  36 +
  37 + def load(id)
  38 + self.class.new(_load(id))
  39 + end
  40 +
  41 + def load!(id)
  42 + initialize(_load(id))
  43 + end
  44 +
  45 + def save
  46 + @id = @storage.create_id(self) unless @id
  47 + @storage.write(self)
  48 + end
  49 +
  50 + def update
  51 + @storage.write(self)
  52 + end
  53 +
  54 + def to_sym
  55 + self.class.to_s.to_sym
  56 + end
  57 +
  58 + protected
  59 + def _load(id)
  60 + data = @@storage.find {|data| data[:id] == id}
  61 + throw "unknown id (#{id})" unless data
  62 + data
  63 + end
16 64 end
... ...
1   -class SdAdmin::Model::Base
2   - attr_reader :backend
3   -
4   - def initialize(backend)
5   - @backend = SdAdmin::Database::Ldap.new
6   - @backend = backend if backend
7   - end
8   -
9   -end
1   -require 'SystemData'
  1 +class DsAdmin::Model::Group
  2 + include DsAdmin::Model
2 3
3   -class Group < SystemData
4 4 attr_accessor :name, :gid, :members
5   -
  5 +
6 6 def initialize(args = {})
7   - super(args)
  7 + return if args.empty?
  8 + super(args)
8 9
9 10 @name = args[:name]
10 11 @gid = args[:gid]
11   - @members = args[:members]
12   - @members = Array.new if @members.nil?
  12 + @members = args[:members] ? args[:members] : Array.new
13 13 end
14 14 end
... ...
1   -module SdAdmin::Model::Interface
2   -
3   - def all
4   - Hash[self.backend.map{|key,entry| [key, entry]}]
5   - end
6   -
7   -end
1   -require 'SystemData'
  1 +class DsAdmin::Model::MailAccount
  2 + include DsAdmin::Model
2 3
3   -class MailAccount < SystemData
4 4 attr_accessor :mail, :mailbox
5 5
6 6 def initialize(args = {})
  7 + return if args.empty?
7 8 super(args)
8 9
9 10 @mail = args[:mail]
... ...
1   -require 'SystemData'
  1 +class DsAdmin::Model::MailAliasPerson
  2 + include DsAdmin::Model
2 3
3   -class MailAliasPerson < SystemData
4 4 attr_accessor :mail, :maildrop, :surname, :name
5 5
6 6 def initialize(args = {})
  7 + return if args.empty?
7 8 super(args)
8 9
9 10 @mail = args[:mail]
... ...
1   -require 'SystemData'
  1 +class DsAdmin::Model::MailAliasRole
  2 + include DsAdmin::Model
2 3
3   -class MailAliasRole < SystemData
4 4 attr_accessor :mail, :maildrop, :user
5 5
6 6 def initialize(args = {})
  7 + return if args.empty?
7 8 super(args)
8 9
9 10 @mail = args[:mail]
... ...
1   -require 'SystemData'
  1 +class DsAdmin::Model::Site
  2 + include DsAdmin::Model
2 3
3   -class Site < SystemData
4 4 attr_accessor :name
5 5
6 6 def initialize(args = {})
  7 + return if args.empty?
7 8 super(args)
8 9
9 10 @name = args[:name]
... ...
1   -class SystemData
2   - attr_reader :id
3   -
4   - def initialize(args = {})
5   - @backend = args[:backend]
6   - @id = args[:id]
7   - end
8   -
9   - def save
10   - kind = self.class.to_s.to_sym
11   -
12   - if @id
13   - @backend.update(kind, to_h)
14   - else
15   - @backend.insert(kind, to_h)
16   - end
17   - end
18   -
19   - def to_h
20   - Hash[instance_variables.map do |var|
21   - [var[1...var.size].to_sym, eval(var)] if var != '@backend'
22   - end]
23   - end
24   -end
1   -class SdAdmin::Model::User
2   - attr_accessor :name, :pass, :uid, :gid, :shell, :home
  1 +class DsAdmin::Model::User
  2 + include DsAdmin::Model
3 3
4   - def initialize(args={}, backend=nil)
5   - super(backend)
  4 + attr_accessor :name, :pass, :uid, :gid, :shell, :home
6 5
7   - @backend.base_dn = 'ou=user,o=system,dc=weird-web-workers,dc=org'
8   - @backend.filter = '(objectClass=posixAccount)'
  6 + def initialize(args = {})
  7 + return if args.empty?
  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]
18   - end
  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 + end
19 19 end
... ...
1   -module SdAdmin
2   - module Model
3   - end
4   -
5   - module Database
6   - end
7   -
8   - require 'model'
9   - require 'database'
10   -end
  1 +module DsAdmin::Storage
  2 + include Enumerable
  3 +
  4 + DsAdmin::Storage.autoload(:Ldap, 'storage/ldap')
  5 + DsAdmin::Storage.autoload(:Mysql, 'storage/mysql')
  6 + DsAdmin::Storage.autoload(:Config, 'storage/config')
  7 +
  8 + attr_accessor :config
  9 +
  10 + def initialize(config)
  11 + @config = config
  12 + end
  13 +
  14 + def each(&block)
  15 + read.each(&block)
  16 + end
  17 +
  18 + ##
  19 + # We don't need this....the 'id' is a storage id and as
  20 + # thus returned after successfully writing a new entry.
  21 + #
  22 + def create_id(model)
  23 + return "dummy id for #{model.inspect}"
  24 + end
  25 +
  26 + def read
  27 + throw "#{self.class}: read not implemented"
  28 + end
  29 +
  30 + def write(model)
  31 + throw "#{self.class}: write not implemented"
  32 + end
  33 +
  34 + def to_sym
  35 + self.class.to_s.to_sym
  36 + end
  37 +end
... ...
  1 +require 'yaml'
  2 +
  3 +class Test::Storage::Config
  4 + attr_accessor :model
  5 +
  6 + def initialize(yml_file)
  7 + @config = YAML.load_file(yml_file)
  8 + end
  9 +
  10 + def con(storage)
  11 + @config[storage.to_sym][:con]
  12 + end
  13 +
  14 + def query(storage)
  15 + @config[storage.to_sym][@model.to_sym][:query]
  16 + end
  17 +
  18 + def map(storage)
  19 + @config[storage.to_sym][@model.to_sym][:map]
  20 + end
  21 +end
... ...
  1 +require 'net/ldap'
  2 +
  3 +class DsAdmin::Storage::Ldap
  4 + include DsAdmin::Storage
  5 +
  6 + def initialize(config)
  7 + super(config)
  8 + @ldap = Net::LDAP.new(@config.con(self))
  9 + end
  10 +
  11 + def read
  12 + query = @config.query(self)
  13 +
  14 + ##
  15 + # two things.
  16 + # - create a hash from the ldap search result
  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.
  19 + #
  20 + foo = @ldap.search(query).map do |data|
  21 + map = { :dn => :id }
  22 + map.merge!(@config.map(self))
  23 +
  24 + remapped = Hash.new
  25 + data.each do |key,value|
  26 + key = map[key] || key
  27 + value = value.size==1 ? value[0] : value.to_a
  28 +
  29 + remapped.merge!({ key => value })
  30 + end
  31 + remapped
  32 + end
  33 + end
  34 +end
... ...
  1 +class DsAdmin::Storage::Mysql
  2 + include DsAdmin::Storage
  3 +end
... ...
1   -require 'SystemDataBackend'
2   -require 'SystemDataBackendLdap'
3   -
4   -ldap = SystemDataBackendLdap.new(
5   - 'host.one.virtual',
6   - 389,
7   - 'dc=weird-web-workers,dc=org'
8   -)
9   -backend = SystemDataBackend.new(ldap)
10   -
11   -backend.users.each do |user|
12   - puts 'user: '+user.name+','+user.uid+','+user.gid+','+user.home
13   -end
14   -
15   -puts
16   -
17   -backend.groups.each do |group|
18   - members = backend.usersInGroup(group)
19   -
20   - puts 'group: '+group.name+','+group.gid
21   - puts ' members:'
22   - group.members.each do |name|
23   - print ' ' + name + ': '
24   - print members[name].uid + ', ' + members[name].home if members[name]
25   - puts
26   - end
27   - puts
28   -end
29   -
30   -backend.sites.each do |site|
31   - puts 'site: ' + site.name
32   - puts ' MailAliasRoles:'
33   - backend.mailAliasRolesBySite(site).each{|account| puts ' ' + account.mail}
34   - puts
35   - puts ' MailAliasPeople:'
36   - backend.mailAliasPeopleBySite(site).each{|account| puts ' ' + account.mail}
37   - puts
38   - puts ' MailAccounts:'
39   - backend.mailAccountsBySite(site).each{|account| puts ' ' + account.mail}
40   - puts
41   -end
42   -
43   -backend.mailAliasRoles.each do |mailAlias|
44   - puts 'mailAliasRole: '+mailAlias.mail.inspect+','+mailAlias.maildrop.inspect
45   -end
46   -
47   -puts
48   -
49   -backend.mailAliasPeople.each do |mailAlias|
50   - puts 'mailAliasPerson: '+mailAlias.mail.inspect+','+mailAlias.maildrop.inspect
51   -end
52   -
53   -puts
54   -
55   -backend.mailAccounts.each do |mailAccount|
56   - puts 'mailAccount: '+mailAccount.mail.inspect+','+mailAccount.mailbox.inspect
57   -end
58   -
59   -puts
60   -
61   -georg = backend.userByName('georg')
62   -georg.save
63   -
64   -puts
65   -
66   -georg.uid = 1001
67   -georg.save
68   -
69   -puts
70   -
71   -wheel = backend.groupByName('wheel')
72   -wheel.save
73   -
74   -puts
75   -
76   -wheel.gid = 100
77   -wheel.save
78   -
79   -puts
80   -
81   -site = backend.siteByName('kommandozeilenchef.de')
82   -site.save
83   -
84   -puts
85   -
86   -site.name = 'wumbaba.de'
87   -site.save
88   -
89   -puts
90   -
91   -mail = MailAliasRole.new({
92   - :backend => ldap,
93   - :mail => 'newrole@kommandozeilenchef.de',
94   - :maildrop => 'newrole',
95   - :user => 'newrole'
96   -})
97   -mail.save
98   -
99   -puts
100   -
101   -mail = MailAliasPerson.new({
102   - :backend => ldap,
103   - :mail => 'ohotte@kommandozeilenchef.de',
104   - :maildrop => 'ohotte',
105   - :name => 'Onkel Hotte',
106   - :surname => 'Hotte'
107   -})
108   -mail.save
109   -
110   -puts
111   -
112   -mail = MailAccount.new({
113   - :backend => ldap,
114   - :mail => 'foobar@kommandozeilenchef.de',
115   - :mailbox => 'kommandozeilenchef.de/foobar',
116   - :home => '/var/spool/vmail/domains'
117   -})
118   -mail.save
119   -
120   -puts
121   -puts '====================================='
122   -# -o vsz/vsize
123   -puts 'Memory useage: ' + `ps -o rss= -p #{Process.pid}`
1   -require 'sd_admin'
2   -
3   -user = SdAdmin::Model::User.new
4   -
5   -puts user.all.inspect
  1 +require 'ds_admin'
  2 +
  3 +config = DsAdmin::Storage::Config.new(File.dirname(__FILE__) + '/config/storage.yml')
  4 +DsAdmin::Model.storage = DsAdmin::Storage::Ldap.new(config)
  5 +
  6 +user = DsAdmin::Model::User.new
  7 +group = DsAdmin::Model::Group.new
  8 +site = DsAdmin::Model::Site.new
  9 +alias_role = DsAdmin::Model::MailAliasRole.new
  10 +alias_person = DsAdmin::Model::MailAliasPerson.new
  11 +account = DsAdmin::Model::MailAccount.new
  12 +
  13 +puts '=== DsAdmin each ==='
  14 +user.each {|user| puts user.inspect}
  15 +puts '---'
  16 +group.each {|group| puts group.inspect}
  17 +puts '---'
  18 +site.each {|site| puts site.inspect}
  19 +puts '---'
  20 +alias_role.each {|ma_role| puts ma_role.inspect}
  21 +puts '---'
  22 +alias_person.each {|ma_person| puts ma_person.inspect}
  23 +puts '---'
  24 +account.each {|macc| puts macc.inspect}
  25 +
  26 +puts
  27 +puts '=== DsAdmin Enumerable ==='
  28 +puts user.find {|user| user.uid == '1000'}.inspect
  29 +puts '---'
  30 +puts group.find {|group| group.gid == '10'}.inspect
  31 +puts '---'
  32 +puts site.find {|site| site.name == 'steffers.org'}.inspect
  33 +puts '---'
  34 +puts alias_role.find_all {|mar| mar.maildrop == 'abuse'}.inspect
  35 +puts '---'
  36 +puts alias_person.find {|map| map.mail == 'georg@steffers.org'}.inspect
  37 +puts '---'
  38 +puts account.find {|acc| acc.mail == 'drachenfrau@steffers.org'}.inspect
... ...
Please register or login to post a comment