20 changed files with 540 additions and 6 deletions
-
12SystemDataBackendLdap.rb
-
91controllers/system_data.rb
-
10database.rb
-
13database/base.rb
-
3database/factory.rb
-
53database/ldap.rb
-
0loader/user.rb
-
197mappers/ldap.rb
-
16model.rb
-
9model/base.rb
-
14model/group.rb
-
7model/interface.rb
-
17model/mail_account.rb
-
18model/mail_alias_person.rb
-
17model/mail_alias_role.rb
-
11model/site.rb
-
24model/system_data.rb
-
19model/user.rb
-
10sd_admin.rb
-
5test_dummy2.rb
@ -0,0 +1,91 @@ |
|||||
|
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 |
||||
@ -0,0 +1,10 @@ |
|||||
|
module SdAdmin::Database |
||||
|
class Ldap |
||||
|
require 'database/base.rb' |
||||
|
require 'net/ldap' |
||||
|
|
||||
|
include Enumerable |
||||
|
end |
||||
|
|
||||
|
require 'database/ldap' |
||||
|
end |
||||
@ -0,0 +1,13 @@ |
|||||
|
class SdAdmin::Database::Base |
||||
|
|
||||
|
def initialize |
||||
|
@data = Hash.new |
||||
|
end |
||||
|
|
||||
|
def _create(data) |
||||
|
end |
||||
|
|
||||
|
def _read(id) |
||||
|
end |
||||
|
|
||||
|
end |
||||
@ -0,0 +1,3 @@ |
|||||
|
class SdAdmin::Database::Factory |
||||
|
|
||||
|
end |
||||
@ -0,0 +1,53 @@ |
|||||
|
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 |
||||
@ -0,0 +1,197 @@ |
|||||
|
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 |
||||
@ -0,0 +1,16 @@ |
|||||
|
module SdAdmin::Model |
||||
|
module Interface |
||||
|
end |
||||
|
|
||||
|
class Base |
||||
|
require 'model/interface' |
||||
|
require 'database' |
||||
|
include SdAdmin::Model::Interface |
||||
|
end |
||||
|
|
||||
|
class User < Base |
||||
|
end |
||||
|
|
||||
|
require 'model/base' |
||||
|
require 'model/user' |
||||
|
end |
||||
@ -0,0 +1,9 @@ |
|||||
|
class SdAdmin::Model::Base |
||||
|
attr_reader :backend |
||||
|
|
||||
|
def initialize(backend) |
||||
|
@backend = SdAdmin::Database::Ldap.new |
||||
|
@backend = backend if backend |
||||
|
end |
||||
|
|
||||
|
end |
||||
@ -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 |
||||
@ -0,0 +1,7 @@ |
|||||
|
module SdAdmin::Model::Interface |
||||
|
|
||||
|
def all |
||||
|
Hash[self.backend.map{|key,entry| [key, entry]}] |
||||
|
end |
||||
|
|
||||
|
end |
||||
@ -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 |
||||
@ -0,0 +1,18 @@ |
|||||
|
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 |
||||
@ -0,0 +1,17 @@ |
|||||
|
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 |
||||
@ -0,0 +1,11 @@ |
|||||
|
require 'SystemData' |
||||
|
|
||||
|
class Site < SystemData |
||||
|
attr_accessor :name |
||||
|
|
||||
|
def initialize(args = {}) |
||||
|
super(args) |
||||
|
|
||||
|
@name = args[:name] |
||||
|
end |
||||
|
end |
||||
@ -0,0 +1,24 @@ |
|||||
|
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 |
||||
@ -0,0 +1,19 @@ |
|||||
|
class SdAdmin::Model::User |
||||
|
attr_accessor :name, :pass, :uid, :gid, :shell, :home |
||||
|
|
||||
|
def initialize(args={}, backend=nil) |
||||
|
super(backend) |
||||
|
|
||||
|
@backend.base_dn = 'ou=user,o=system,dc=weird-web-workers,dc=org' |
||||
|
@backend.filter = '(objectClass=posixAccount)' |
||||
|
|
||||
|
@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 |
||||
@ -0,0 +1,10 @@ |
|||||
|
module SdAdmin |
||||
|
module Model |
||||
|
end |
||||
|
|
||||
|
module Database |
||||
|
end |
||||
|
|
||||
|
require 'model' |
||||
|
require 'database' |
||||
|
end |
||||
@ -0,0 +1,5 @@ |
|||||
|
require 'sd_admin' |
||||
|
|
||||
|
user = SdAdmin::Model::User.new |
||||
|
|
||||
|
puts user.all.inspect |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue