Revision 953a2b4d
Added by Marc Dequènes about 15 years ago
- ID 953a2b4d0942a3ca69d941dc031485db21de1106
conf/ldap_shadows/shadows/MilkyPond/aspects/fs.conf | ||
---|---|---|
object: group
|
||
many: uniqueMember
|
||
foreign_key: dn
|
||
plugin:
|
||
min_uid: 10000
|
||
max_uid: 65535
|
||
step_uid: 100
|
||
default_group: dc-users
|
||
default_home_base: '/home'
|
conf/ldap_shadows/shadows/MilkyPond/hooks/aspects/fs.rb | ||
---|---|---|
|
||
# TODO: should be in the configuration file, so find a way to get these parameters
|
||
MIN_UID = 10000
|
||
MAX_UID = 65535
|
||
STEP_UID = 100
|
||
DEFAULT_GROUP = 'dc-users'
|
||
|
||
def self.hook_before_create(shadow, item)
|
||
hook_common(shadow, item)
|
||
end
|
||
|
||
def self.hook_before_modify(shadow, item)
|
||
hook_common(shadow, item)
|
||
end
|
||
|
||
def self.hook_common(shadow, item)
|
||
unless item.attribute_present?('gidNumber')
|
||
item.primaryGroup = shadow.get_object(:group).find(:first, DEFAULT_GROUP)
|
||
end
|
||
|
||
if item.attribute_present?('uidNumber')
|
||
user = ActiveLdap::Base.find(:first, :scope => :sub, :filter => "(&(objectClass=posixAccount)(uidNumber=#{item.uidNumber}))", :attributes => ['uidNumber'])
|
||
unless user.nil? or user.dn == item.dn
|
||
raise_error "UID already used by another item"
|
||
end
|
||
else
|
||
users = ActiveLdap::Base.find(:all, :scope => :sub, :filter => "(&(objectClass=posixAccount)(uidNumber=*))", :attributes => ['uidNumber'])
|
||
uidnumbers = users.collect {|user| user.uidNumber }
|
||
|
||
avail_uidnumber = nil
|
||
min_uidn = MIN_UID
|
||
max_uidn = [min_uidn + STEP_UID, MAX_UID].min
|
||
while avail_uidnumber.nil?
|
||
avail = (min_uidn..max_uidn).to_a - uidnumbers
|
||
unless avail.empty?
|
||
avail_uidnumber = avail.first
|
||
break
|
||
end
|
||
min_uidn = max_uidn
|
||
max_uidn = [min_uidn + STEP_UID, MAX_UID].min
|
||
end
|
||
|
||
if avail_uidnumber.nil?
|
||
raise_error "Available UID range is depleted."
|
||
else
|
||
item.uidNumber = avail_uidnumber
|
||
end
|
||
end
|
||
|
||
unless item.attribute_present?('homeDirectory')
|
||
item.homeDirectory = "/home/" + item.uid
|
||
end
|
||
end
|
conf/ldap_shadows/shadows/MilkyPond/hooks/objects/individual.rb | ||
---|---|---|
|
||
def self.hook_before_create(shadow, item)
|
||
unless item.attribute_present?('cn')
|
||
cn = item.surname || ""
|
||
cn = item.givenName + " " + cn if item.givenName
|
||
item.cn = cn
|
||
end
|
||
end
|
||
|
conf/ldap_shadows/shadows/MilkyPond/plugins/aspects/fs.rb | ||
---|---|---|
|
||
def self.hook_before_create(item)
|
||
hook_common(item)
|
||
end
|
||
|
||
def self.hook_before_modify(item)
|
||
hook_common(item)
|
||
end
|
||
|
||
def self.hook_common(item)
|
||
pconfig_default = {
|
||
:default_group => 'users',
|
||
:min_uid => 1000,
|
||
:max_uid => 65535,
|
||
:step_uid => 100,
|
||
:default_home_base => "/home"
|
||
}
|
||
pconfig = pconfig_default.merge(self.parameters[:plugin])
|
||
|
||
unless item.attribute_present?('gidNumber')
|
||
item.primaryGroup = item.class.shadow.get_object(:group).find(:first, pconfig[:default_group])
|
||
end
|
||
|
||
if item.attribute_present?('uidNumber')
|
||
user = ActiveLdap::Base.find(:first, :scope => :sub, :filter => "(&(objectClass=posixAccount)(uidNumber=#{item.uidNumber}))", :attributes => ['uidNumber'])
|
||
unless user.nil? or user.dn == item.dn
|
||
raise_error "UID already used by another item"
|
||
end
|
||
else
|
||
users = ActiveLdap::Base.find(:all, :scope => :sub, :filter => "(&(objectClass=posixAccount)(uidNumber=*))", :attributes => ['uidNumber'])
|
||
uidnumbers = users.collect {|user| user.uidNumber }
|
||
|
||
avail_uidnumber = nil
|
||
min_uidn = pconfig[:min_uid]
|
||
max_uidn = [min_uidn + pconfig[:step_uid], pconfig[:max_uid]].min
|
||
while avail_uidnumber.nil?
|
||
avail = (min_uidn..max_uidn).to_a - uidnumbers
|
||
unless avail.empty?
|
||
avail_uidnumber = avail.first
|
||
break
|
||
end
|
||
min_uidn = max_uidn
|
||
max_uidn = [min_uidn + pconfig[:step_uid], pconfig[:max_uid]].min
|
||
end
|
||
|
||
if avail_uidnumber.nil?
|
||
raise_error "Available UID range is depleted."
|
||
else
|
||
item.uidNumber = avail_uidnumber
|
||
end
|
||
end
|
||
|
||
unless item.attribute_present?('homeDirectory')
|
||
item.homeDirectory = File.join(pconfig[:default_home_base], item.uid)
|
||
end
|
||
end
|
conf/ldap_shadows/shadows/MilkyPond/plugins/objects/individual.rb | ||
---|---|---|
|
||
def self.hook_before_create(item)
|
||
unless item.attribute_present?('cn')
|
||
cn = item.surname || ""
|
||
cn = item.givenName + " " + cn if item.givenName
|
||
item.cn = cn
|
||
end
|
||
end
|
||
|
data/ldap_shadows/schema/aspect.yaml | ||
---|---|---|
"foreign_key": {type: str, required: true}
|
||
"many": {type: str}
|
||
"primary_key": {type: str}
|
||
"plugin":
|
||
type: map
|
||
mapping:
|
||
=: {type: any}
|
||
|
data/ldap_shadows/schema/object.yaml | ||
---|---|---|
required: true
|
||
name: ObjectMapping
|
||
mapping:
|
||
=:
|
||
type: any
|
||
=: {type: any}
|
||
"presentation":
|
||
type: map
|
||
mapping:
|
||
... | ... | |
"foreign_key": {type: str, required: true}
|
||
"many": {type: str}
|
||
"primary_key": {type: str}
|
||
"plugin":
|
||
type: map
|
||
mapping:
|
||
=: {type: any}
|
||
|
lib/ldap_shadows/config.rb | ||
---|---|---|
config = File.read(config_file)
|
||
|
||
shadow = Shadow.new(shadow_name)
|
||
# register early (needed to load hooks)
|
||
# register early (needed to load plugins)
|
||
@shadows[shadow_name] = {
|
||
:config_path => shadow_config_path,
|
||
:shadow => shadow
|
||
... | ... | |
s_info = get_shadow_info(shadow_name)
|
||
return nil if s_info.nil?
|
||
|
||
filename = File.join(s_info[:config_path], "hooks", type.pluralize, hook_name.to_s.downcase + ".rb")
|
||
filename = File.join(s_info[:config_path], "plugins", type.pluralize, hook_name.to_s.downcase + ".rb")
|
||
return nil unless File.exists?(filename)
|
||
|
||
File.read(filename)
|
lib/ldap_shadows/elements.rb | ||
---|---|---|
def cast_relations; end
|
||
|
||
# default empty hooks
|
||
def hook_before_create(shadow, item); end
|
||
def hook_before_modify(shadow, item); end
|
||
def hook_before_delete(shadow, item); end
|
||
def hook_after_create(shadow, item); end
|
||
def hook_after_modify(shadow, item); end
|
||
def hook_after_delete(shadow, item); end
|
||
def hook_before_create(item); end
|
||
def hook_before_modify(item); end
|
||
def hook_before_delete(item); end
|
||
def hook_after_create(item); end
|
||
def hook_after_modify(item); end
|
||
def hook_after_delete(item); end
|
||
|
||
protected
|
||
|
lib/ldap_shadows/elements/object.rb | ||
---|---|---|
after_delete_jobs
|
||
end
|
||
|
||
protected
|
||
# cannot override create_or_update() because of alias chaining
|
||
def save
|
||
before_save_jobs
|
||
r = super
|
||
after_save_jobs
|
||
r
|
||
end
|
||
|
||
def create_or_update
|
||
def save!
|
||
before_save_jobs
|
||
r = super
|
||
after_save_jobs
|
||
r
|
||
end
|
||
|
||
protected
|
||
|
||
def before_save_jobs
|
||
check_hooks_before(:save)
|
||
check_missing_attributes
|
||
... | ... | |
case action
|
||
when :save
|
||
if self.new_entry?
|
||
self.class.hook_before_create(self.class.shadow, self)
|
||
self.class.hook_before_create(self)
|
||
else
|
||
self.class.hook_before_modify(self.class.shadow, self)
|
||
self.class.hook_before_modify(self)
|
||
end
|
||
when :delete
|
||
self.class.hook_before_delete(self.class.shadow, self)
|
||
self.class.hook_before_delete(self)
|
||
end
|
||
|
||
# TODO: move this in the LdapAspect class
|
||
self.aspects.each do |aspect|
|
||
aklass = self.class.shadow.get_aspect(aspect)
|
||
next if aklass.nil?
|
||
... | ... | |
case action
|
||
when :save
|
||
if self.new_entry?
|
||
aklass.hook_before_create(self.class.shadow, self)
|
||
aklass.hook_before_create(self)
|
||
else
|
||
aklass.hook_before_modify(self.class.shadow, self)
|
||
aklass.hook_before_modify(self)
|
||
end
|
||
when :delete
|
||
aklass.hook_before_delete(self.class.shadow, self)
|
||
aklass.hook_before_delete(self)
|
||
end
|
||
end
|
||
end
|
||
... | ... | |
case action
|
||
when :save
|
||
if self.new_entry?
|
||
aklass.hook_after_create(self.class.shadow, self)
|
||
aklass.hook_after_create(self)
|
||
else
|
||
aklass.hook_after_modify(self.class.shadow, self)
|
||
aklass.hook_after_modify(self)
|
||
end
|
||
when :delete
|
||
aklass.hook_after_delete(self.class.shadow, self)
|
||
aklass.hook_after_delete(self)
|
||
end
|
||
end
|
||
|
||
# TODO: move this in the LdapAspect class
|
||
case action
|
||
when :save
|
||
if self.new_entry?
|
||
self.class.hook_after_create(self.class.shadow, self)
|
||
self.class.hook_after_create(self)
|
||
else
|
||
self.class.hook_after_modify(self.class.shadow, self)
|
||
self.class.hook_after_modify(self)
|
||
end
|
||
when :delete
|
||
self.class.hook_after_delete(self.class.shadow, self)
|
||
self.class.hook_after_delete(self)
|
||
end
|
||
end
|
||
|
Also available in: Unified diff
[evol/fix] fixed creation hooks call, hooks->plugins with hooks and simplified hooks, added plugin parameters in config and updated aspect/fs