Processes the Sexp from routes.rb. Stores results in tracker.routes.
Note that it is only interested in determining what methods on which controllers are used as routes, not the generated URLs for routes.
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 12 def initialize tracker super @map = Sexp.new(:lvar, :map) @nested = nil #used for identifying nested targets @prefix = [] #Controller name prefix (a module name, usually) @current_controller = nil @with_options = nil #For use inside map.with_options end
Looking for mapping of routes
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 30 def process_call exp target = exp.target if target == map or (not target.nil? and target == nested) process_map exp else process_default exp end exp end
Process collection option
:collection => { :some_action => :http_actions }
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 256 def process_collection exp return unless exp.node_type == :hash routes = @tracker.routes[@current_controller] hash_iterate(exp) do |action, type| routes << action.value end end
Process
map.connect '/something', :controller => 'blah', :action => 'whatever'
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 181 def process_connect exp return if exp.empty? controller = check_for_controller_name exp self.current_controller = controller if controller #Check for default route if string? exp.first if exp.first.value == ":controller/:action/:id" @tracker.routes[:allow_all_actions] = exp.first elsif exp.first.value.include? ":action" @tracker.routes[@current_controller] = [:allow_all_actions, exp.line] return end end #This -seems- redundant, but people might connect actions #to a controller which already allows them all return if @tracker.routes[@current_controller].is_a? Array and @tracker.routes[@current_controller][0] == :allow_all_actions exp.last.each_with_index do |e,i| if symbol? e and e.value == :action action = exp.last[i + 1] if node_type? action, :lit @tracker.routes[@current_controller] << action.value.to_sym end return end end end
Look for map calls that take a block. Otherwise, just do the default processing.
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 63 def process_iter exp target = exp.block_call.target if target == map or target == nested method = exp.block_call.method case method when :namespace process_namespace exp when :resources, :resource process_resources exp.block_call.args process_default exp.block if exp.block when :with_options process_with_options exp end exp else super end end
Process a map.something call based on the method used
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 44 def process_map exp args = exp.args case exp.method when :resource process_resource args when :resources process_resources args when :connect, :root process_connect args else process_named_route args end exp end
map.something_abnormal '/blah', :controller => 'something', :action => 'wohoo'
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 250 def process_named_route exp process_connect exp end
map.namespace :something do |something|
something.resources :blah
end
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 233 def process_namespace exp call = exp.block_call formal_args = exp.block_args block = exp.block @prefix << camelize(call.first_arg.value) if formal_args @nested = Sexp.new(:lvar, formal_args.value) end process block @prefix.pop end
Process route option :except => ...
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 153 def process_option_except exp return unless exp.node_type == :array routes = @tracker.routes[@current_controller] exp[1..-1].each do |e| routes.delete e.value end end
Process route option :only => ...
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 139 def process_option_only exp routes = @tracker.routes[@current_controller] [:index, :new, :create, :show, :edit, :update, :destroy].each do |r| routes.delete r end if exp.node_type == :array exp[1..-1].each do |e| routes << e.value end end end
map.resource :x, ..
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 163 def process_resource exp controller = check_for_controller_name exp if controller self.current_controller = controller process_resource_options exp.last else exp.each do |argument| if node_type? argument, :lit self.current_controller = pluralize(exp.first.value.to_s) add_resource_routes process_resource_options exp.last end end end end
Process all the options that might be in the hash passed to map.resource, et al.
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 104 def process_resource_options exp if exp.nil? and @with_options exp = @with_options elsif @with_options exp = exp.concat @with_options[1..-1] end return unless exp.node_type == :hash hash_iterate(exp) do |option, value| case option[1] when :controller, :requirements, :singular, :path_prefix, :as, :path_names, :shallow, :name_prefix, :member_path, :nested_member_path, :belongs_to, :conditions, :active_scaffold #should be able to skip when :collection, :member, :new process_collection value when :has_one save_controller = current_controller process_resource value[1..-1] #Verify this is proper behavior self.current_controller = save_controller when :has_many save_controller = current_controller process_resources value[1..-1] self.current_controller = save_controller when :only process_option_only value when :except process_option_except value else Brakeman.notify "[Notice] Unhandled resource option, please report: #{option}" end end end
Process
map.resources :x, :controller => :y, :member => ...
etc.
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 86 def process_resources exp controller = check_for_controller_name exp if controller self.current_controller = controller process_resource_options exp[-1] else exp.each do |argument| if node_type? argument, :lit self.current_controller = exp.first.value add_resources_routes process_resource_options exp.last end end end end
Call this with parsed route file information.
This method first calls RouteAliasProcessor#process_safely on the exp, so it does not modify the exp.
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 25 def process_routes exp process Brakeman::RouteAliasProcessor.new.process_safely(exp) end
map.with_options :controller => 'something' do |something|
something.resources :blah
end
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 217 def process_with_options exp @with_options = exp.block_call.last_arg @nested = Sexp.new(:lvar, exp.block_args.value) self.current_controller = check_for_controller_name exp.block_call.args #process block process exp.block @with_options = nil @nested = nil end
Generated with the Darkfish Rdoc Generator 2.