Project

General

Profile

« Previous | Next » 

Revision eab0c364

Added by Marc Dequènes about 13 years ago

  • ID eab0c3649292290a4754caa8670edb4d5712a406

[evol] API: implemented hidden nodes and used it to create a '?' node used to search children based on their attributes

View differences:

bin/test_client
ask "MapMaker", :zones, "/DNS/Zones"
#ask "MapMaker", :wanted_failure, "/prout"
ask "MapMaker", :zone_mp, "/DNS/Zones/milkypond.org"
ask "MapMaker", :search, "/DNS/Zones/?"
ask "MapMaker", :search_master, "/DNS/Zones/?", {:master => true}
ask "MapMaker", :search_slave, "/DNS/Zones/?", {:master => false}
know? "MapMaker", :k1, "/DNS/Zones"
know? "MapMaker", :k2, "/prout"
on_error do
lib/cyborghood-mapmaker/interface/dns.rb
node "Zones" do
zone_list = Proc.new{ store.dns.zones }
node zone_list, '_zone'
attr_search_node
node zone_list, :dir => '_zone'
end
end
lib/cyborghood/cyborg/botnet/interface.rb
reveal :nil?
reveal :respond_to?
def initialize(bot, parent_node = nil, ldir = nil, &block)
def initialize(bot, parent_node = nil, options = {}, &block)
@bot = bot
@parent_node = parent_node
@ldir = ldir
@ldir = options[:dir]
@hidden = options[:hidden] || false
# don't call super because we need defered loading
......
cleanup
end
def hidden?
@hidden
end
def add_behavior(&block)
if block_given?
@blocks << block
......
# string, array (useful for aliases), or regex
# TODO: name validation
def node(match, ldir = nil, &block)
child_node = self.class.new(@bot, self, ldir, &block)
def node(match, options = {}, &block)
child_node = self.class.new(@bot, self, options, &block)
if match.is_a? Array
match.each{|n| @nodes[n] = child_node}
else
......
end
end
def attr_search_node
lookup_node = self
node '?', :hidden => true do
on_request do |request|
if request.args.empty?
request.reply.results = lookup_node.__send__(:visible_nodes_names)
else
node_names_list = []
lookup_node.__send__(:visible_nodes).each do |match, node|
if match.is_a? String
match_list = [match]
elsif match.is_a? Proc
match_list = match.call
else
next
end
match_list.each do |child_node_name|
node.__send__(:load, child_node_name)
result = node.__send__(:request, request.session)
if hash_match_criterias(result, request.args.first)
node_names_list << child_node_name
end
end
end
request.reply.results = node_names_list
end
end
end
end
def on_request(&cb)
@request_cb = cb
end
......
class Request
attr_reader :session, :args, :reply
def initialize(session, args)
def initialize(session, args = [])
@session = session
@args = args
......
end
end
def request(session, args)
def request(session, args = [])
if @request_cb
request = Request.new(session, args)
begin
......
raise CyberError.new(:unrecoverable, 'api/cyborghood', "method call failed: " + $!)
end
else
@nodes.keys.collect do |match|
if match.is_a? String
match
elsif match.is_a? Regexp
'/' + match.to_s + '/'
elsif match.is_a? Proc
match.call
end
end.compact.flatten
visible_nodes_names
end
end
def visible_nodes
Hash[@nodes.select{|match, node| not node.hidden? }]
end
def node_match_to_name(match)
if match.is_a? String
match
elsif match.is_a? Regexp
'/' + match.to_s + '/'
elsif match.is_a? Proc
match.call
end
end
def visible_nodes_names
visible_nodes.keys.collect do |match|
node_match_to_name(match)
end.compact.flatten
end
def cleanup
@nodes = {}
@request_cb = nil
......
@store = @parent_node.store
end
end
def hash_match_criterias(hash, crit)
crit.each do |key, wanted_value|
value = hash[key]
if wanted_value.is_a? Array
return false unless wanted_value.include?(value)
elsif wanted_value.is_a? Regexp
return false unless value =~ wanted_value
else
return false unless value == wanted_value
end
end
true
end
end
end
end

Also available in: Unified diff