module Brakeman::ControllerMethods

def add_before_filter exp

def add_before_filter exp
  @options[:before_filters] << exp
end

def before_filter_list processor, method

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 before_filter_to_hash processor, args

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 "Unknown before_filter value: #{option} => #{value}"
      end
    end
  else
    filter[:all] = true
  end
  filter
end

def before_filters

def before_filters
  @options[:before_filters]
end

def filter_includes_method? filter_rule, method_name

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

def get_before_filters processor, method

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 get_skipped_filters processor, method

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 initialize_controller

def initialize_controller
  @options[:before_filters] = []
  @options[:skip_filters] = []
  @layout = nil
  @skip_filter_cache = nil
  @before_filter_cache = nil
end

def prepend_before_filter exp

def prepend_before_filter exp
  @options[:before_filters].unshift exp
end

def protect_from_forgery?

def protect_from_forgery?
  @options[:protect_from_forgery]
end

def remove_skipped_filters processor, filters, method

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 skip_filter exp

def skip_filter exp
  @options[:skip_filters] << exp
end

def skip_filters

def skip_filters
  @options[:skip_filters]
end