=begin Copyright 2010-2017 Sarosys LLC This file is part of the Arachni Framework project and is subject to redistribution and commercial restrictions. Please see the Arachni Framework web site for more information on licensing and terms of use. =end require 'rack' require 'rack/typhoeus/middleware/params_decoder' require_relative 'base' module Arachni::Element # Represents an auditable JSON element # # @author Tasos "Zapotek" Laskos class JSON < Base # Load and include all JSON-specific capability overrides. lib = "#{File.dirname( __FILE__ )}/#{File.basename(__FILE__, '.rb')}/capabilities/**/*.rb" Dir.glob( lib ).each { |f| require f } # Generic element capabilities. include Arachni::Element::Capabilities::Auditable include Arachni::Element::Capabilities::Auditable::Buffered include Arachni::Element::Capabilities::Auditable::LineBuffered include Arachni::Element::Capabilities::Submittable include Arachni::Element::Capabilities::Analyzable include Arachni::Element::Capabilities::WithSource # JSON-specific overrides. include Capabilities::Inputtable include Capabilities::Mutable # @param [Hash] options # @option options [String] :url # URL of the page which includes the link. # @option options [String] :action # Link URL -- defaults to `:url`. # @option options [Hash] :inputs # Query parameters as `name => value` pairs. If none have been provided # they will automatically be extracted from {#action}. def initialize( options ) self.http_method = options[:method] || :post super( options ) self.inputs = (self.inputs || {}).merge( options[:inputs] || {} ) if @source && self.inputs.empty? self.inputs = ::JSON.load( self.source ) end @default_inputs = self.inputs.dup.freeze end # JSON formatted {#inputs}. def to_json @inputs.to_json end def to_h super.merge( source: @source ) end # @return [Hash] # Simple representation of self in the form of `{ {#action} => {#inputs} }`. def simple { self.action => self.inputs } end # @see .encode def encode( *args ) self.class.encode( *args ) end # @see .decode def decode( *args ) self.class.decode( *args ) end def dup super.tap { |e| e.inputs = @inputs.rpc_clone } end class < 'application/json' } ) opts[:body] = self.to_json opts[:method] = self.http_method http.request( self.action, opts, &block ) end end end Arachni::JSON = Arachni::Element::JSON