|
#!/usr/bin/ruby -Ku
|
|
|
|
#--
|
|
# 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/>.
|
|
#++
|
|
|
|
# to allow in-place run for test
|
|
$: << File.join(File.dirname(__FILE__), "..", "lib")
|
|
|
|
require 'ldap_shadows'
|
|
require 'yaml'
|
|
require 'cmdparse2'
|
|
|
|
config_str = IO.read(File.join(LdapShadows::Config::CFG_DIR, "test.conf"))
|
|
config = YAML.load(config_str)
|
|
config_str_prv_filelist = [
|
|
File.join(ENV['HOME'], ".shadowwalker"),
|
|
File.join(LdapShadows::Config::CFG_DIR, "private.conf")
|
|
]
|
|
config_str_prv_filelist.each do |file|
|
|
if File.exists?(file)
|
|
config_str_prv = IO.read(file)
|
|
config.merge!(YAML.load(config_str_prv))
|
|
break
|
|
end
|
|
end
|
|
config.recursive_symbolize_keys!
|
|
ActiveLdap::Base.setup_connection(config[:ldap])
|
|
|
|
cmdparser = CmdParse::CommandParser.new(true)
|
|
cmdparser.banner = LdapShadows::PRODUCT
|
|
cmdparser.program_name = File.basename(__FILE__)
|
|
cmdparser.program_version = LdapShadows::VERSION.split(".")
|
|
|
|
cmdparser.options = CmdParse::OptionParserWrapper.new do |opt|
|
|
opt.separator "Global options:"
|
|
opt.on("--debug", "Output debug info without being formated") {|t| $debug_opt = true }
|
|
opt.on("--expert", "Output extra info for expert users") {|t| $expert_opt = true }
|
|
opt.on("--handles", "Output with handles (objects/field/... keys used for manipulations)") {|t| $handles_opt = true }
|
|
end
|
|
|
|
cmdparser.add_command(CmdParse::HelpCommand.new)
|
|
cmdparser.add_command(CmdParse::VersionCommand.new)
|
|
|
|
I18n.load_path += Dir[File.join(LdapShadows::Config::DATA_DIR, "*.yml")]
|
|
I18n.default_locale = :en
|
|
|
|
ldapctl = LdapShadows::Controller.new
|
|
ldapctl.set_global_config(config[:presentation])
|
|
config[:aspects].each_pair do |aspect_name, aspect_data|
|
|
ldapctl.set_aspect(aspect_name, aspect_data)
|
|
end
|
|
config[:objects].each_pair do |obj_name, obj_data|
|
|
ldapctl.load_object(obj_name, obj_data)
|
|
end
|
|
ldapctl.load_relations
|
|
|
|
cmd = CmdParse::Command.new('list', false)
|
|
cmd.short_desc = "list objects"
|
|
cmd.set_execution_block do |args|
|
|
if args.size != 1
|
|
STDERR.puts "syntax error: no object name given"
|
|
exit 1
|
|
end
|
|
|
|
obj_hdl = args[0]
|
|
obj_klass = ldapctl.find_klass(obj_hdl)
|
|
if obj_klass.nil?
|
|
STDERR.puts "No such object '#{obj_hdl}'."
|
|
exit 2
|
|
end
|
|
|
|
obj_human_name = I18n.t(obj_hdl, :scope => 'objects', :default => "Object '#{obj_hdl}'")
|
|
puts "=== List of #{obj_human_name.pluralize} ==="
|
|
obj_klass.find(:all).each do |obj|
|
|
str = obj.human_name
|
|
str += " [#{obj.name}]" if $handles_opt
|
|
str += ": #{obj.description}" unless obj.description.empty?
|
|
puts str
|
|
end
|
|
end
|
|
cmdparser.add_command(cmd)
|
|
|
|
def translate_data_key(name)
|
|
if name.index(":")
|
|
type, key = name.split(":")
|
|
case type
|
|
when 'rel'
|
|
I18n.t(key, :scope => 'relations', :default => name)
|
|
else
|
|
raise "Cannot translate unknown data key type"
|
|
end
|
|
else
|
|
att = ActiveLdap::Base.schema.attribute(name)
|
|
I18n.t(att.human_attribute_name, :scope => 'attribute_types', :default => att.human_attribute_description)
|
|
end
|
|
end
|
|
|
|
def display_data(attr_data)
|
|
attr_data.each_pair do |key, val|
|
|
field_name = translate_data_key(key)
|
|
field_name += " [#{key}]" if $handles_opt
|
|
puts field_name + ": " + (val.is_a?(Array) ? val.sort.collect{|v| v.to_s }.join(", ") : val.to_s)
|
|
end
|
|
end
|
|
|
|
cmd = CmdParse::Command.new('show', false)
|
|
cmd.short_desc = "show object information"
|
|
cmd.set_execution_block do |args|
|
|
if args.size < 1
|
|
STDERR.puts "syntax error: no object name given"
|
|
exit 1
|
|
end
|
|
if args.size < 2
|
|
STDERR.puts "syntax error: no item name given"
|
|
exit 1
|
|
end
|
|
|
|
obj_hdl = args[0]
|
|
obj_klass = ldapctl.find_klass(obj_hdl)
|
|
if obj_klass.nil?
|
|
STDERR.puts "No such object '#{obj_hdl}'."
|
|
exit 2
|
|
end
|
|
|
|
item_hdl = args[1]
|
|
begin
|
|
item = obj_klass.find(item_hdl)
|
|
rescue ActiveLdap::EntryNotFound
|
|
STDERR.puts "No such item '#{obj_hdl}/#{item_hdl}'"
|
|
exit 2
|
|
end
|
|
|
|
obj_human_name = I18n.t(obj_hdl, :scope => 'objects', :default => "Object '#{obj_hdl}'")
|
|
name = item.human_name
|
|
name += " [#{item.name}]" if $handles_opt
|
|
puts "=== #{obj_human_name}: #{name} ==="
|
|
|
|
if $debug_opt
|
|
puts item.to_s
|
|
puts "--- Detected Info ---"
|
|
puts "aspects: " + item.aspects.sort.join(", ")
|
|
|
|
puts "--- Family ---"
|
|
puts "parent: " + item.family_parent_dn.to_s
|
|
puts "siblings: " + item.family_siblings_dn.join(", ")
|
|
puts "children: " + item.family_children_dn.join(", ")
|
|
|
|
puts "--- Relations ---"
|
|
item.relations.each do |rel|
|
|
puts "#{rel}: " + item.send(rel).collect{|g| g.name }.join(", ")
|
|
end
|
|
else
|
|
obj_info, obj_aspects = item.organized_data(:expert => $expert_opt, :skip_binary => true)
|
|
|
|
display_data(obj_info)
|
|
|
|
obj_aspects.each_pair do |aspect_name, aspect_data|
|
|
aspect_display_name = I18n.t(aspect_name, :scope => 'aspects', :default => "Aspect '#{aspect_name}'")
|
|
puts "--- #{aspect_display_name} ---"
|
|
display_data(aspect_data)
|
|
end
|
|
end
|
|
end
|
|
cmdparser.add_command(cmd)
|
|
|
|
cmdparser.parse
|
|
|