Revision 90809ae4
Added by Marc Dequènes about 15 years ago
- ID 90809ae4611daed224702e4f6083c42f9277a4a4
bin/shadowwalker | ||
---|---|---|
raise SyntaxError, _("no object name given") if args.empty?
|
||
|
||
obj_hdl = args.shift.downcase.singularize
|
||
obj_klass = $shadow.find_klass(obj_hdl)
|
||
obj_klass = $shadow.get_object(obj_hdl)
|
||
raise PreProcessingError, _("No such object '%s'") % obj_hdl if obj_klass.nil?
|
||
obj_klass
|
||
end
|
||
... | ... | |
sconfig = $shadow.get_config()
|
||
|
||
(sconfig[:presentation][:tree_objects] || []).each do |obj_hdl|
|
||
obj_klass = $shadow.find_klass(obj_hdl.downcase)
|
||
obj_klass = $shadow.get_object(obj_hdl.downcase)
|
||
unless obj_klass
|
||
raise PreProcessingError, _("Location object '%s' not defined") % obj_hdl
|
||
end
|
conf/ldap_shadows/shadows/MilkyPond/hooks/aspects/fs.rb | ||
---|---|---|
|
||
def self.hook_common(shadow, item)
|
||
unless item.attribute_present?('gidNumber')
|
||
item.primaryGroup = shadow.find_klass(:group).find(:first, DEFAULT_GROUP)
|
||
item.primaryGroup = shadow.get_object(:group).find(:first, DEFAULT_GROUP)
|
||
end
|
||
|
||
if item.attribute_present?('uidNumber')
|
lib/ldap_shadows/config.rb | ||
---|---|---|
shadow.add_object(c_name, c_config)
|
||
end
|
||
|
||
shadow.load_relations
|
||
shadow.cast
|
||
|
||
# TODO: find a way to handle translations per-shadow
|
||
translation_path = File.join(shadow_config_path, "translations")
|
||
if File.exists? translation_path
|
||
# load interface translation
|
lib/ldap_shadows/elements.rb | ||
---|---|---|
#--
|
||
# LdapShadows, a Medium-level LDAP Access Library and Tool.
|
||
# Copyright (c) 2009 Marc Dequènes (Duck) <Duck@DuckCorp.org>
|
||
#
|
||
# This program is free software: you can redistribute it and/or modify
|
||
# it under the terms of the GNU General Public License as published by
|
||
# the Free Software Foundation, either version 3 of the License, or
|
||
# (at your option) any later version.
|
||
#
|
||
# This program is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
# GNU General Public License for more details.
|
||
#
|
||
# You should have received a copy of the GNU General Public License
|
||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
#++
|
||
|
||
|
||
module LdapShadows
|
||
module Elements
|
||
module LdapElement
|
||
def self.included(base)
|
||
base.extend(ClassMethods)
|
||
end
|
||
|
||
module ClassMethods
|
||
# initializers
|
||
def cast; end
|
||
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
|
||
|
||
protected
|
||
|
||
def self.raise_error(msg)
|
||
raise ProcessingError, msg
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
require 'ldap_shadows/elements/object'
|
||
require 'ldap_shadows/elements/aspect'
|
lib/ldap_shadows/elements/aspect.rb | ||
---|---|---|
#++
|
||
|
||
|
||
require 'ldap_shadows/hooks'
|
||
|
||
|
||
module LdapShadows
|
||
module Elements
|
||
class LdapAspect
|
||
include Hooks
|
||
include LdapElement
|
||
end
|
||
end
|
||
end
|
lib/ldap_shadows/elements/object.rb | ||
---|---|---|
#++
|
||
|
||
|
||
require 'ldap_shadows/hooks'
|
||
|
||
|
||
module LdapShadows
|
||
module Elements
|
||
class LdapObject < ActiveLdap::Base
|
||
include Hooks
|
||
include LdapElement
|
||
|
||
class_inheritable_accessor :presentation, :relations_info
|
||
class_inheritable_accessor :presentation
|
||
@relations_info = {}
|
||
|
||
class << self
|
||
attr_accessor :relations_info
|
||
protected :relations_info
|
||
end
|
||
|
||
# default
|
||
ldap_mapping :prefix => '', :classes => ['top'], :scope => :sub
|
||
|
||
def self.cast
|
||
ldap_mapping self.parameters[:mapping]
|
||
end
|
||
|
||
def self.cast_relations
|
||
object_rel = {}
|
||
object_rel.merge!(self.parameters[:relations]) if self.parameters.include?(:relations)
|
||
if self.parameters[:presentation].has_key?(:allowed_aspects)
|
||
self.parameters[:presentation][:allowed_aspects].each do |aspect|
|
||
aspect_data = self.shadow.get_aspect(aspect)
|
||
if aspect_data.nil?
|
||
raise PreProcessingError, _("Aspect '%s' is missing for object '%s'") % [aspect, self.handle]
|
||
end
|
||
object_rel.merge!(aspect_data[:relations]) if aspect_data.has_key?(:relations) and aspect_data[:relations]
|
||
end
|
||
end
|
||
return if object_rel.empty?
|
||
|
||
object_relations_info = {}
|
||
object_rel.each_pair do |field_name, rel|
|
||
foreign_klass = self.shadow.get_object(rel[:object])
|
||
if foreign_klass.nil?
|
||
raise PreProcessingError, _("Relation '%s' for object '%s' is impossible: foreign object '%s' is missing") % [field_name, self.handle, rel[:object]]
|
||
end
|
||
rel[:class_name] = foreign_klass.to_s
|
||
|
||
case rel[:type]
|
||
when 'belongs_to'
|
||
belongs_to field_name, rel.reject {|key, val| not ActiveLdap::Associations::ClassMethods::VALID_BELONGS_TO_OPTIONS.include?(key) }
|
||
when 'has_many'
|
||
has_many field_name, rel.reject {|key, val| not ActiveLdap::Associations::ClassMethods::VALID_HAS_MANY_OPTIONS.include?(key) }
|
||
else
|
||
raise "bug in '#{self.handle}' object relations (wrong type)"
|
||
end
|
||
|
||
object_relations_info[field_name] = {
|
||
:foreign_klass => foreign_klass,
|
||
:single_value => ActiveLdap::Base.schema.attribute(rel[:foreign_key]).single_value?,
|
||
:read_only => rel[:read_only] || false
|
||
}
|
||
end
|
||
self.relations_info = object_relations_info
|
||
end
|
||
|
||
# temporary method until active_ldap is fixed: return a DN object (see activeldap#23932)
|
||
def dn_obj
|
||
ActiveLdap::DistinguishedName.parse(self.dn)
|
||
... | ... | |
def self.ldap_search_string_objects(shadow, field, op, val_list)
|
||
ldap_search_parts = val_list.split(",").collect do |val|
|
||
obj_hdl = val.downcase.singularize
|
||
obj_klass = shadow.find_klass(obj_hdl)
|
||
obj_klass = shadow.get_object(obj_hdl)
|
||
raise PreProcessingError, _("No such object '%s'") % val if obj_klass.nil?
|
||
|
||
ldap_classes = obj_klass.required_classes
|
||
... | ... | |
|
||
def self.find_raw_item_object(shadow, raw_item)
|
||
shadow.objects.each do |obj_hdl|
|
||
obj_klass = shadow.find_klass(obj_hdl)
|
||
obj_klass = shadow.get_object(obj_hdl)
|
||
ldap_classes = obj_klass.required_classes
|
||
return obj_hdl if raw_item.classes & ldap_classes == ldap_classes
|
||
end
|
||
... | ... | |
def self.raw_item_info(shadow, raw_item)
|
||
obj_hdl = self.find_raw_item_object(shadow, raw_item)
|
||
if obj_hdl
|
||
obj_klass = shadow.find_klass(obj_hdl)
|
||
obj_klass = shadow.get_object(obj_hdl)
|
||
item = obj_klass.new(raw_item.dn)
|
||
{:name => "#{obj_hdl}/#{item.name}", :item => item, :object => obj_klass}
|
||
else
|
lib/ldap_shadows/hooks.rb | ||
---|---|---|
#--
|
||
# LdapShadows, a Medium-level LDAP Access Library and Tool.
|
||
# Copyright (c) 2009 Marc Dequènes (Duck) <Duck@DuckCorp.org>
|
||
#
|
||
# This program is free software: you can redistribute it and/or modify
|
||
# it under the terms of the GNU General Public License as published by
|
||
# the Free Software Foundation, either version 3 of the License, or
|
||
# (at your option) any later version.
|
||
#
|
||
# This program is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
# GNU General Public License for more details.
|
||
#
|
||
# You should have received a copy of the GNU General Public License
|
||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
#++
|
||
|
||
|
||
module LdapShadows
|
||
module Hooks
|
||
def self.included(base)
|
||
base.extend(ClassMethods)
|
||
end
|
||
|
||
module ClassMethods
|
||
# 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
|
||
|
||
protected
|
||
|
||
def self.raise_error(msg)
|
||
raise ProcessingError, msg
|
||
end
|
||
end
|
||
end
|
||
end
|
lib/ldap_shadows/shadow.rb | ||
---|---|---|
require 'active_ldap'
|
||
require 'ldap_shadows/activeldap_fixes'
|
||
require 'facets/metaid'
|
||
require 'ldap_shadows/elements/object'
|
||
require 'ldap_shadows/elements/aspect'
|
||
require 'lib/ldap_shadows/elements'
|
||
|
||
|
||
module LdapShadows
|
||
... | ... | |
@config = Config.instance
|
||
|
||
# cannot use anonymous modules/classes, as active_ldap needs named classes for relations
|
||
module_name = "Shadow" + name.classify
|
||
module_name = "Shadow" + name.camelize
|
||
@container = LdapShadows::Shadows.module_eval(<<-EOS)
|
||
module #{module_name}; self; end
|
||
EOS
|
||
|
||
@container_elements = {}
|
||
@object_definitions = {}
|
||
@aspects = {}
|
||
end
|
||
|
||
... | ... | |
# TODO: remove this crap
|
||
object_def = @config.parse_and_validate(object_name, e_type, object_def_raw)
|
||
klass.presentation = object_def[:presentation]
|
||
klass.ldap_mapping object_def[:mapping]
|
||
@object_definitions[object_name.to_sym] = object_def
|
||
end
|
||
|
||
def find_klass(object_name)
|
||
def get_object(object_name)
|
||
@container_elements['object'][object_name.to_s]
|
||
end
|
||
|
||
# run it _once_ when all objects are loaded
|
||
def load_relations
|
||
@object_definitions.each_pair do |object_name, object_def|
|
||
object_rel = {}
|
||
object_rel.merge!(object_def[:relations]) if object_def.include?(:relations)
|
||
if object_def[:presentation].has_key?(:allowed_aspects)
|
||
object_def[:presentation][:allowed_aspects].each do |aspect|
|
||
aspect_data = get_aspect(aspect)
|
||
if aspect_data.nil?
|
||
raise PreProcessingError, _("Aspect '%s' is missing") % aspect
|
||
end
|
||
object_rel.merge!(aspect_data[:relations]) if aspect_data.has_key?(:relations) and aspect_data[:relations]
|
||
end
|
||
def cast
|
||
@container_elements.each_value do |e_models|
|
||
e_models.each_value do |e_klass|
|
||
e_klass.cast
|
||
end
|
||
next if object_rel.empty?
|
||
|
||
klass = find_klass(object_name)
|
||
|
||
object_relations_info = {}
|
||
object_rel.each_pair do |field_name, rel|
|
||
foreign_klass = find_klass(rel[:object])
|
||
if foreign_klass.nil?
|
||
raise PreProcessingError, _("Relation '%s' for object '%s' is impossible: foreign object '%s' is missing") % [field_name, object_name, rel[:object]]
|
||
end
|
||
rel[:class_name] = foreign_klass.to_s
|
||
|
||
case rel[:type]
|
||
when 'belongs_to'
|
||
klass.belongs_to field_name, rel.reject {|key, val| not ActiveLdap::Associations::ClassMethods::VALID_BELONGS_TO_OPTIONS.include?(key) }
|
||
when 'has_many'
|
||
klass.has_many field_name, rel.reject {|key, val| not ActiveLdap::Associations::ClassMethods::VALID_HAS_MANY_OPTIONS.include?(key) }
|
||
else
|
||
raise "bug in '#{object_name}' object relations (wrong type)"
|
||
end
|
||
|
||
object_relations_info[field_name] = {
|
||
:foreign_klass => foreign_klass,
|
||
:single_value => ActiveLdap::Base.schema.attribute(rel[:foreign_key]).single_value?,
|
||
:read_only => rel[:read_only] || false
|
||
}
|
||
end
|
||
|
||
@container_elements.each_value do |e_models|
|
||
e_models.each_value do |e_klass|
|
||
e_klass.cast_relations
|
||
end
|
||
klass.relations_info = object_relations_info
|
||
end
|
||
end
|
||
|
||
... | ... | |
|
||
def add_container_element(e_type, e_name, e_def_raw)
|
||
superklass_location = LdapShadows::Elements
|
||
superklass_name = 'Ldap' + e_type.classify
|
||
superklass_name = 'Ldap' + e_type.camelize
|
||
unless superklass_location.const_defined?(superklass_name)
|
||
raise PreProcessingError, _("Element model '%s' does not exist") % e_type
|
||
end
|
||
|
||
klass_name = superklass_name + e_name.to_s.classify
|
||
klass_name = superklass_name + e_name.to_s.camelize
|
||
if @container.const_defined?(klass_name)
|
||
raise PreProcessingError, _("Element '%s' for model '%s' as already been defined") % [e_name, e_type]
|
||
end
|
||
|
||
e_def = @config.parse_and_validate(e_name, e_type, e_def_raw)
|
||
|
||
klass = @container.module_eval(<<-EOS)
|
||
class #{klass_name} < #{superklass_location}::#{superklass_name}; self; end
|
||
EOS
|
||
klass.instance_variable_set(:@handle, e_name)
|
||
klass.instance_variable_set(:@shadow, self)
|
||
klass.instance_variable_set(:@parameters, e_def)
|
||
klass.meta_eval do
|
||
attr_reader :handle, :shadow
|
||
attr_reader :handle, :shadow, :parameters
|
||
protected :parameters
|
||
end
|
||
|
||
e_def = @config.parse_and_validate(e_name, e_type, e_def_raw)
|
||
klass.instance_variable_set(:@parameters, e_def)
|
||
|
||
begin
|
||
klass_content = @config.load_hook_content(@name, e_type, e_name)
|
||
klass.class_eval(klass_content) unless klass_content.nil?
|
Also available in: Unified diff
[cleanup] internal rework #2