diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a01ee28 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.*.swp diff --git a/Group.rb b/Group.rb new file mode 100644 index 0000000..e607420 --- /dev/null +++ b/Group.rb @@ -0,0 +1,14 @@ +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 new file mode 100644 index 0000000..a6ec9fd --- /dev/null +++ b/MailAccount.rb @@ -0,0 +1,17 @@ +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/MailAlias.rb b/MailAlias.rb new file mode 100644 index 0000000..b7f4c9c --- /dev/null +++ b/MailAlias.rb @@ -0,0 +1,17 @@ +require 'SystemData' + +class MailAlias < 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 new file mode 100644 index 0000000..313166a --- /dev/null +++ b/Site.rb @@ -0,0 +1,9 @@ +require 'SystemData' + +class Site < SystemData + attr_accessor :name, :mailAccounts, :mailAliases + + def initialize(args = {}) + @name = args[:name] + end +end diff --git a/SystemData.rb b/SystemData.rb new file mode 100644 index 0000000..79fe4a4 --- /dev/null +++ b/SystemData.rb @@ -0,0 +1,16 @@ +class SystemData + attr_reader :id + + def initialize(args = {}) + @backend = args[:backend] + @id = args[:id] + end + + def save + if @id + @backend.update(self) + else + @backend.insert(self) + end + end +end diff --git a/SystemDataBackend.rb b/SystemDataBackend.rb new file mode 100644 index 0000000..75df516 --- /dev/null +++ b/SystemDataBackend.rb @@ -0,0 +1,84 @@ +require 'User' +require 'Group' +require 'Site' +require 'MailAlias' +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 mailAliases + load(:mailAlias) + 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 mailAliasesBySite(site) + mailAliases.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 + class_str = kind.to_s + class_str[0] = class_str[0..0].capitalize + + @backend.load(kind) do |data| + @data[kind].push( + eval(class_str + '.new(data)') + ) + end + end + +end diff --git a/SystemDataBackendLdap.rb b/SystemDataBackendLdap.rb new file mode 100644 index 0000000..5b28818 --- /dev/null +++ b/SystemDataBackendLdap.rb @@ -0,0 +1,84 @@ +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_SITE_MAP = {:o => :name} + + LDAP_MAP = { + :user => LDAP_USER_MAP, + :group => LDAP_GROUP_MAP, + :site => LDAP_SITE_MAP + } + + LDAP_FILTER = { + :user => Net::LDAP::Filter::eq('objectClass', 'posixAccount'), + :group => Net::LDAP::Filter::eq('objectClass', 'posixGroup'), + :site => Net::LDAP::Filter::eq('objectClass', 'organization') & + (~Net::LDAP::Filter::eq('o', 'hosting')), + :mailAlias => Net::LDAP::Filter::eq('objectClass', 'mailAlias'), + :mailAccount => Net::LDAP::Filter::eq('objectClass', 'mailAccount') + } + + + 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] = @ldap.search( + :base => ldapBase(kind), + :filter => LDAP_FILTER[kind] + ) + end + + def load(kind) + load!(kind) if ! @ldapData[kind] + + @ldapData[kind].each do |data| + map = { :dn => :id } + map.merge!(LDAP_MAP[kind]) if LDAP_MAP[kind] + + ydata = { :backend => self } + + data.each do |key,value| + ydata.merge!({ map[key] || key => value.size==1?value[0]:value.to_a }) + end + + yield ydata + end + end + + private + + def ldapBase(kind) + case(kind) + when :user, :group: @systemDn + when :site, :mailAlias, :mailAccount: @hostingDn + end + end + +end diff --git a/User.rb b/User.rb new file mode 100644 index 0000000..68bb781 --- /dev/null +++ b/User.rb @@ -0,0 +1,16 @@ +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] + end +end diff --git a/test_dummy.rb b/test_dummy.rb new file mode 100644 index 0000000..963fa28 --- /dev/null +++ b/test_dummy.rb @@ -0,0 +1,46 @@ +require 'SystemDataBackend' +require 'SystemDataBackendLdap' + +backend = SystemDataBackend.new( + SystemDataBackendLdap.new('host.one.virtual', 389, 'dc=weird-web-workers,dc=org') +) + +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 ' MailAliases:' + backend.mailAliasesBySite(site).each{|account| puts ' ' + account.mail} + puts + puts ' MailAccounts:' + backend.mailAccountsBySite(site).each{|account| puts ' ' + account.mail} + puts +end + +backend.mailAliases.each do |mailAlias| + puts 'mailAlias: '+mailAlias.mail.inspect+','+mailAlias.maildrop.inspect +end + +puts + +backend.mailAccounts.each do |mailAccount| + puts 'mailAccount: '+mailAccount.mail.inspect+','+mailAccount.mailbox.inspect +end +