lib/brakeman/tracker/controller.rb
require 'brakeman/tracker/collection'
module Brakeman
module ControllerMethods
attr_accessor :layout
def initialize_controller
@options[:before_filters] = []
@options[:skip_filters] = []
@layout = nil
@skip_filter_cache = nil
@before_filter_cache = nil
end
def protect_from_forgery?
@options[:protect_from_forgery]
end
def add_before_filter exp
@options[:before_filters] << exp
end
def prepend_before_filter exp
@options[:before_filters].unshift exp
end
def before_filters
@options[:before_filters]
end
def skip_filter exp
@options[:skip_filters] << exp
end
def skip_filters
@options[:skip_filters]
end
def before_filter_list processor, method
controller = self
filters = []
while controller
filters = controller.get_before_filters(processor, method) + filters
controller = tracker.controllers[controller.parent] ||
tracker.libs[controller.parent]
end
remove_skipped_filters processor, filters, method
end
def get_skipped_filters processor, method
filters = []
if @skip_filter_cache.nil?
@skip_filter_cache = skip_filters.map do |filter|
before_filter_to_hash(processor, filter.args)
end
end
@skip_filter_cache.each do |f|
if filter_includes_method? f, method
filters.concat f[:methods]
else
end
end
filters
end
def remove_skipped_filters processor, filters, method
controller = self
while controller
filters = filters - controller.get_skipped_filters(processor, method)
controller = tracker.controllers[controller.parent] ||
tracker.libs[controller.parent]
end
filters
end
def get_before_filters processor, method
filters = []
if @before_filter_cache.nil?
@before_filter_cache = []
before_filters.each do |filter|
@before_filter_cache << before_filter_to_hash(processor, filter.args)
end
end
@before_filter_cache.each do |f|
if filter_includes_method? f, method
filters.concat f[:methods]
end
end
filters
end
def before_filter_to_hash processor, args
filter = {}
#Process args for the uncommon but possible situation
#in which some variables are used in the filter.
args.each do |a|
if sexp? a
a = processor.process_default a
end
end
filter[:methods] = []
args.each do |a|
filter[:methods] << a[1] if a.node_type == :lit
end
options = args.last
if hash? options
# Probably only one option,
# but this also avoids issues with kwsplats
hash_iterate(options) do |option, value|
case value.node_type
when :array
filter[option.value] = value.sexp_body.map {|v| v[1] }
when :lit, :str
filter[option.value] = value[1]
else
Brakeman.debug "[Notice] Unknown before_filter value: #{option} => #{value}"
end
end
else
filter[:all] = true
end
filter
end
private
def filter_includes_method? filter_rule, method_name
filter_rule[:all] or
(filter_rule[:only] == method_name) or
(filter_rule[:only].is_a? Array and filter_rule[:only].include? method_name) or
(filter_rule[:except].is_a? Symbol and filter_rule[:except] != method_name) or
(filter_rule[:except].is_a? Array and not filter_rule[:except].include? method_name)
end
end
class Controller < Brakeman::Collection
include ControllerMethods
def initialize name, parent, file_name, src, tracker
super
initialize_controller
@collection = tracker.controllers
end
end
end