diff --git a/Group.rb b/Group.rb deleted file mode 100644 index e607420..0000000 --- a/Group.rb +++ /dev/null @@ -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 diff --git a/MailAccount.rb b/MailAccount.rb deleted file mode 100644 index a6ec9fd..0000000 --- a/MailAccount.rb +++ /dev/null @@ -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 diff --git a/MailAliasPerson.rb b/MailAliasPerson.rb deleted file mode 100644 index e4308ce..0000000 --- a/MailAliasPerson.rb +++ /dev/null @@ -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 diff --git a/MailAliasRole.rb b/MailAliasRole.rb deleted file mode 100644 index c16b474..0000000 --- a/MailAliasRole.rb +++ /dev/null @@ -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 diff --git a/Site.rb b/Site.rb deleted file mode 100644 index 133ccbe..0000000 --- a/Site.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'SystemData' - -class Site < SystemData - attr_accessor :name - - def initialize(args = {}) - super(args) - - @name = args[:name] - end -end diff --git a/SystemData.rb b/SystemData.rb deleted file mode 100644 index ec1652b..0000000 --- a/SystemData.rb +++ /dev/null @@ -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 diff --git a/SystemDataBackend.rb b/SystemDataBackend.rb deleted file mode 100644 index a53089f..0000000 --- a/SystemDataBackend.rb +++ /dev/null @@ -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 diff --git a/SystemDataBackendLdap.rb b/SystemDataBackendLdap.rb deleted file mode 100644 index a660087..0000000 --- a/SystemDataBackendLdap.rb +++ /dev/null @@ -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 diff --git a/User.rb b/User.rb deleted file mode 100644 index 6f55ccd..0000000 --- a/User.rb +++ /dev/null @@ -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 diff --git a/controllers/system_data.rb b/controllers/system_data.rb deleted file mode 100644 index a53089f..0000000 --- a/controllers/system_data.rb +++ /dev/null @@ -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 diff --git a/database.rb b/database.rb deleted file mode 100644 index 1db079c..0000000 --- a/database.rb +++ /dev/null @@ -1,10 +0,0 @@ -module SdAdmin::Database - class Ldap - require 'database/base.rb' - require 'net/ldap' - - include Enumerable - end - - require 'database/ldap' -end diff --git a/database/base.rb b/database/base.rb deleted file mode 100644 index 81cbc04..0000000 --- a/database/base.rb +++ /dev/null @@ -1,13 +0,0 @@ -class SdAdmin::Database::Base - - def initialize - @data = Hash.new - end - - def _create(data) - end - - def _read(id) - end - -end diff --git a/database/factory.rb b/database/factory.rb deleted file mode 100644 index 96ecacb..0000000 --- a/database/factory.rb +++ /dev/null @@ -1,3 +0,0 @@ -class SdAdmin::Database::Factory - -end diff --git a/database/ldap.rb b/database/ldap.rb deleted file mode 100644 index 2bbde01..0000000 --- a/database/ldap.rb +++ /dev/null @@ -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 diff --git a/docs/development/mystuff.dia b/docs/development/mystuff.dia new file mode 100644 index 0000000..b9cec43 Binary files /dev/null and b/docs/development/mystuff.dia differ diff --git a/docs/development/was.txt b/docs/development/was.txt new file mode 100644 index 0000000..1e3a97e --- /dev/null +++ b/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 + diff --git a/ds_admin.rb b/ds_admin.rb new file mode 100644 index 0000000..b6db539 --- /dev/null +++ b/ds_admin.rb @@ -0,0 +1,4 @@ +module DsAdmin + DsAdmin.autoload(:Model, 'model') + DsAdmin.autoload(:Storage, 'storage') +end diff --git a/loader/user.rb b/loader/user.rb deleted file mode 100644 index e69de29..0000000 diff --git a/mappers/ldap.rb b/mappers/ldap.rb deleted file mode 100644 index a660087..0000000 --- a/mappers/ldap.rb +++ /dev/null @@ -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 diff --git a/model.rb b/model.rb index 37a1e26..607b03e 100644 --- a/model.rb +++ b/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 diff --git a/model/base.rb b/model/base.rb deleted file mode 100644 index 2569a41..0000000 --- a/model/base.rb +++ /dev/null @@ -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 diff --git a/model/group.rb b/model/group.rb index e607420..b5fa3ed 100644 --- a/model/group.rb +++ b/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 diff --git a/model/interface.rb b/model/interface.rb deleted file mode 100644 index 25de225..0000000 --- a/model/interface.rb +++ /dev/null @@ -1,7 +0,0 @@ -module SdAdmin::Model::Interface - - def all - Hash[self.backend.map{|key,entry| [key, entry]}] - end - -end diff --git a/model/mail_account.rb b/model/mail_account.rb index a6ec9fd..6f2113a 100644 --- a/model/mail_account.rb +++ b/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] diff --git a/model/mail_alias_person.rb b/model/mail_alias_person.rb index e4308ce..d71b1f5 100644 --- a/model/mail_alias_person.rb +++ b/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] diff --git a/model/mail_alias_role.rb b/model/mail_alias_role.rb index c16b474..b2e21d3 100644 --- a/model/mail_alias_role.rb +++ b/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] diff --git a/model/site.rb b/model/site.rb index 133ccbe..bea8624 100644 --- a/model/site.rb +++ b/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] diff --git a/model/system_data.rb b/model/system_data.rb deleted file mode 100644 index ec1652b..0000000 --- a/model/system_data.rb +++ /dev/null @@ -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 diff --git a/model/user.rb b/model/user.rb index 6b9f126..0fbb787 100644 --- a/model/user.rb +++ b/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 diff --git a/sd_admin.rb b/sd_admin.rb deleted file mode 100644 index 30de395..0000000 --- a/sd_admin.rb +++ /dev/null @@ -1,10 +0,0 @@ -module SdAdmin - module Model - end - - module Database - end - - require 'model' - require 'database' -end diff --git a/storage.rb b/storage.rb new file mode 100644 index 0000000..dd36bb0 --- /dev/null +++ b/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 diff --git a/storage/config.rb b/storage/config.rb new file mode 100644 index 0000000..dde315f --- /dev/null +++ b/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 diff --git a/storage/ldap.rb b/storage/ldap.rb new file mode 100644 index 0000000..fbbc661 --- /dev/null +++ b/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 diff --git a/storage/mysql.rb b/storage/mysql.rb new file mode 100644 index 0000000..77220a5 --- /dev/null +++ b/storage/mysql.rb @@ -0,0 +1,3 @@ +class DsAdmin::Storage::Mysql + include DsAdmin::Storage +end diff --git a/test_dummy.rb b/test_dummy.rb deleted file mode 100644 index d098635..0000000 --- a/test_dummy.rb +++ /dev/null @@ -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}` diff --git a/test_dummy2.rb b/test_dummy2.rb deleted file mode 100644 index 6fa5b7a..0000000 --- a/test_dummy2.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'sd_admin' - -user = SdAdmin::Model::User.new - -puts user.all.inspect diff --git a/tester.rb b/tester.rb new file mode 100644 index 0000000..9195f0a --- /dev/null +++ b/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