Project

General

Profile

« Previous | Next » 

Revision 3f984668

Added by Marc Dequènes about 14 years ago

  • ID 3f98466868f60ec29793532960f01c329ab4d412

[evol] implemented vattrs search via post-filters (closes #141)

View differences:

bin/shadowwalker
self.short_desc = "Search items"
self.usages_params = [
"[:objects=<object>[,<object>]...] [:aspects=<aspect>[,<aspect>]...] [<field>=<value>] [:parents|:siblings|:children|:ancestors|:successors=<item-full-handle>[,<item-full-handle>]] ..."
"[:objects=<object>[,<object>]...] [:aspects=<aspect>[,<aspect>]...] [[filter:]<field>=<value>] [:parents|:siblings|:children|:ancestors|:successors=<item-full-handle>[,<item-full-handle>]] ..."
]
self.usage_extra_info = "Criterias are AND-ed, but lists of values for a criteria are OR-ed."
end
......
res = LdapShadows::Manipulation.items_find_from_strings(@shadow, args)
unless res.empty?
display_lines = []
res.each do |raw_item|
display_lines << LdapShadows::Manipulation.raw_item_info(@shadow, raw_item)[:name]
res.each do |item_info|
display_lines << item_info[:name]
end
puts display_lines.join("\n")
end
lib/ldap_shadows/manipulation_helper.rb
modification_done
end
def self.items_find_from_strings(shadow, str_list)
def self.items_find_from_strings(shadow, str_list, full_search = false)
ldap_search_objects = "(objectClass=*)"
ldap_search_aspects = ""
ldap_search_fields = Set.new
ldap_search_where =Set.new
ldap_search_exclude =Set.new
ldap_search_fields_post = Set.new
str_list.each do |str|
unless str =~ /^(#{TEXTUI_KEY_PATTERN})(=|~=)(.*)$/
raise SyntaxError, _("search parameter '%s' is invalid") % str
......
case type
when nil
ldap_search_fields << ldap_search_string_field(field, op, val)
when 'filter'
unless ["=", "~="].include? op
raise SyntaxError, _("Unknown operator '%s'") % op
end
if op == "~="
begin
new_val = Regexp.new(val)
rescue RegexpError
raise SyntaxError, _("Broken regexp '%s'") % val
end
val = new_val
end
ldap_search_fields_post << [field, op, val]
when 'rel'
raise PreProcessingError, _("Searching relations is not implemented yet")
when ''
......
end
ldap_search_string = "(&" + ldap_search_objects + ldap_search_aspects + ldap_search_fields.to_a.join + ")"
# default search location
if ldap_search_where.empty?
ldap_search_where << [ActiveLdap::Base.base, :sub]
end
# all attributes needed for post-search (or if full search requested)
search_attributes = (full_search or not ldap_search_fields_post.empty?) ? nil : ["objectClass"]
# search
res = Set.new
ldap_search_where.each do |where|
res += ActiveLdap::Base.find(:all, :base => where[0], :scope => where[1], :filter => ldap_search_string, :attributes => ["objectClass"])
res += ActiveLdap::Base.find(:all, :base => where[0], :scope => where[1], :filter => ldap_search_string, :attributes => search_attributes)
end
return res.select {|item| not ldap_search_exclude.include?(item.dn) }
# remove excluded entries
res.select {|item| not ldap_search_exclude.include?(item.dn) }
# process result
res.collect! {|item| raw_item_info(shadow, item) }
# post search filters
ldap_filter_results(res, ldap_search_fields_post)
end
def self.find_raw_item_object(shadow, raw_item)
......
obj_hdl = self.find_raw_item_object(shadow, raw_item)
if obj_hdl
obj_klass = shadow.get_object(obj_hdl)
item = obj_klass.new(raw_item.dn)
item = obj_klass.find(raw_item.dn)
name = item.full_handle
name = "root|" + name if is_root
......
"(#{field}=#{esc_val})"
when "~="
raise PreProcessingError, _("Searching with regex is not implemented yet")
raise PreProcessingError, _("Searching with regex is only possible for post-filters")
else
raise SyntaxError, _("Unknown operator '%s'") % op
......
end
"(&" + ldap_search_parts.join + ")"
end
def self.ldap_filter_results(results, ldap_search_fields_post)
results.collect do |item_info|
recognized_item = item_info[:item]
if recognized_item.nil?
nil
else
found = true
ldap_search_fields_post.each do |search_data|
field, op, val = search_data
found_val = false
if recognized_item.has_field?(field)
item_values = recognized_item.send(field.to_sym, true)
item_values.each do |item_val|
found_val = case op
when "="
item_val == val
when "~="
item_val =~ val
end
break if found_val
end
end
unless found_val
found = false
break
end
end
(found) ? item_info : nil
end
end.compact
end
end
end

Also available in: Unified diff