Class: Brakeman::ControllerAliasProcessor
- Inherits:
-
AliasProcessor
- Object
- SexpProcessor
- AliasProcessor
- Brakeman::ControllerAliasProcessor
- Includes:
- RenderHelper
- Defined in:
- lib/brakeman/processors/controller_alias_processor.rb
Overview
Processes aliasing in controllers, but includes following renders in routes and putting variables into templates
Constant Summary
Constants included from Util
Util::ALL_PARAMETERS, Util::COOKIES, Util::PARAMETERS, Util::PATH_PARAMETERS, Util::QUERY_PARAMETERS, Util::REQUEST_ENV, Util::REQUEST_PARAMETERS, Util::REQUEST_PARAMS, Util::SESSION
Constants inherited from SexpProcessor
Instance Attribute Summary
Attributes inherited from AliasProcessor
Attributes inherited from SexpProcessor
Instance Method Summary collapse
-
#before_filter_list(method, klass) ⇒ Object
Get list of filters, including those that are inherited.
-
#before_filter_to_hash(args) ⇒ Object
Returns a before filter as a hash table.
-
#find_method(method_name, klass) ⇒ Object
Finds a method in the given class or a parent class.
-
#get_before_filters(method, controller) ⇒ Object
Returns an array of filter names.
-
#initialize(tracker, only_method = nil) ⇒ ControllerAliasProcessor
constructor
If only_method is specified, only that method will be processed, other methods will be skipped.
-
#layout_name ⇒ Object
Determines default layout name.
-
#process_before_filter(name) ⇒ Object
Processes a call to a before filter.
-
#process_call(exp) ⇒ Object
Look for calls to head().
-
#process_call_with_block(exp) ⇒ Object
Check for
respond_to
. -
#process_class(exp) ⇒ Object
Processes a class which is probably a controller.
- #process_controller(name, src) ⇒ Object
-
#process_default_render(exp) ⇒ Object
Processes the default template for the current action.
-
#process_methdef(exp) ⇒ Object
Processes a method definition, which may include processing any rendered templates.
-
#process_mixins ⇒ Object
Process modules mixed into the controller, in case they contain actions.
-
#process_template(name, args) ⇒ Object
Process template and add the current class and method name as called_from info.
-
#route?(method) ⇒ Boolean
Returns true if the given method name is also a route.
-
#template_name(name = nil) ⇒ Object
Turns a method name into a template name.
Methods included from RenderHelper
#get_class_target, #get_options, #process_action, #process_layout, #process_partial, #process_render
Methods inherited from AliasProcessor
#duplicate?, #find_push_target, #join_arrays, #join_strings, #only_ivars, #process_array_access, #process_attrasgn, #process_block, #process_cdecl, #process_cvdecl, #process_default, #process_gasgn, #process_hash_access, #process_hash_merge, #process_hash_merge!, #process_iasgn, #process_if, #process_lasgn, #process_op_asgn1, #process_op_asgn2, #process_safely, #process_scope, #process_selfdef, #process_svalue, #set_line
Methods included from Util
#array?, #call?, #camelize, #contains_class?, #context_for, #cookies?, #false?, #file_by_name, #file_for, #hash?, #hash_access, #hash_insert, #hash_iterate, #integer?, #node_type?, #number?, #params?, #pluralize, #regexp?, #request_env?, #request_value?, #result?, #set_env_defaults, #sexp?, #string?, #symbol?, #table_to_csv, #true?, #truncate_table, #underscore
Methods included from ProcessorHelper
#class_name, #process_all, #process_module
Methods inherited from SexpProcessor
#error_handler, #in_context, #process, #process_dummy, #scope
Constructor Details
#initialize(tracker, only_method = nil) ⇒ ControllerAliasProcessor
If only_method is specified, only that method will be processed, other methods will be skipped. This is for rescanning just a single action.
12 13 14 15 16 17 18 19 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 12 def initialize tracker, only_method = nil super() @only_method = only_method @tracker = tracker @rendered = false @current_class = @current_module = @current_method = nil @method_cache = {} #Cache method lookups end |
Instance Method Details
#before_filter_list(method, klass) ⇒ Object
Get list of filters, including those that are inherited
209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 209 def before_filter_list method, klass controller = @tracker.controllers[klass] filters = [] while controller filters = get_before_filters(method, controller) + filters controller = @tracker.controllers[controller[:parent]] end filters end |
#before_filter_to_hash(args) ⇒ Object
Returns a before filter as a hash table
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 253 def before_filter_to_hash 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 = process_default a end end filter[:methods] = [args[0][1]] args[1..-1].each do |a| filter[:methods] << a[1] if a.node_type == :lit end if args[-1].node_type == :hash option = args[-1][1][1] value = args[-1][2] case value.node_type when :array filter[option] = value[1..-1].map {|v| v[1] } when :lit, :str filter[option] = value[1] else Brakeman.debug "[Notice] Unknown before_filter value: #{option} => #{value}" end else filter[:all] = true end filter end |
#find_method(method_name, klass) ⇒ Object
Finds a method in the given class or a parent class
Returns nil if the method could not be found.
If found, returns hash table with controller name and method sexp.
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 293 def find_method method_name, klass return nil if sexp? method_name method_name = method_name.to_sym if method = @method_cache[method_name] return method end controller = @tracker.controllers[klass] controller ||= @tracker.libs[klass] if klass and controller method = controller[:public][method_name] method ||= controller[:private][method_name] method ||= controller[:protected][method_name] if method.nil? controller[:includes].each do |included| method = find_method method_name, included if method @method_cache[method_name] = method return method end end @method_cache[method_name] = find_method method_name, controller[:parent] else @method_cache[method_name] = { :controller => controller[:name], :method => method } end else nil end end |
#get_before_filters(method, controller) ⇒ Object
Returns an array of filter names
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 223 def get_before_filters method, controller return [] unless controller[:options] and controller[:options][:before_filters] filters = [] if controller[:before_filter_cache].nil? filter_cache = [] controller[:options][:before_filters].each do |filter| filter_cache << before_filter_to_hash(filter) end controller[:before_filter_cache] = filter_cache end controller[:before_filter_cache].each do |f| if f[:all] or (f[:only] == method) or (f[:only].is_a? Array and f[:only].include? method) or (f[:except].is_a? Symbol and f[:except] != method) or (f[:except].is_a? Array and not f[:except].include? method) filters.concat f[:methods] end end filters end |
#layout_name ⇒ Object
Determines default layout name
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 188 def layout_name controller = @tracker.controllers[@current_class] return controller[:layout] if controller[:layout] return false if controller[:layout] == false app_controller = @tracker.controllers[:ApplicationController] return app_controller[:layout] if app_controller and app_controller[:layout] nil end |
#process_before_filter(name) ⇒ Object
Processes a call to a before filter. Basically, adds any instance variable assignments to the environment. TODO: method arguments?
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 135 def process_before_filter name filter = find_method name, @current_class if filter.nil? Brakeman.debug "[Notice] Could not find filter #{name}" return end method = filter[:method] if ivars = @tracker.filter_cache[[filter[:controller], name]] ivars.each do |variable, value| env[variable] = value end else processor = Brakeman::AliasProcessor.new @tracker processor.process_safely(method.body) ivars = processor.only_ivars(:include_request_vars).all @tracker.filter_cache[[filter[:controller], name]] = ivars ivars.each do |variable, value| env[variable] = value end end end |
#process_call(exp) ⇒ Object
Look for calls to head()
112 113 114 115 116 117 118 119 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 112 def process_call exp exp = super if call? exp and exp.method == :head @rendered = true end exp end |
#process_call_with_block(exp) ⇒ Object
Check for respond_to
122 123 124 125 126 127 128 129 130 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 122 def process_call_with_block exp process_default exp if call? exp.block_call and exp.block_call.method == :respond_to @rendered = true end exp end |
#process_class(exp) ⇒ Object
Processes a class which is probably a controller. (This method should be retired - only classes should ever be processed and @current_module will never be set, leading to inaccurate class names)
68 69 70 71 72 73 74 75 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 68 def process_class exp @current_class = class_name(exp.class_name) if @current_module @current_class = ("#@current_module::#@current_class").to_sym end process_default exp end |
#process_controller(name, src) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 21 def process_controller name, src if not node_type? src, :class Brakeman.debug "#{name} is not a class, it's a #{src.node_type}" return else @current_class = name process_default src process_mixins end end |
#process_default_render(exp) ⇒ Object
Processes the default template for the current action
164 165 166 167 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 164 def process_default_render exp process_layout process_template template_name, nil end |
#process_methdef(exp) ⇒ Object
Processes a method definition, which may include processing any rendered templates.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 79 def process_methdef exp meth_name = exp.method_name #Skip if instructed to only process a specific method #(but don't skip if this method was called from elsewhere) return exp if @current_method.nil? and @only_method and @only_method != meth_name is_route = route? meth_name other_method = @current_method @current_method = meth_name @rendered = false if is_route env.scope do set_env_defaults if is_route before_filter_list(@current_method, @current_class).each do |f| process_before_filter f end end process exp.body if is_route and not @rendered process_default_render exp end end @current_method = other_method exp end |
#process_mixins ⇒ Object
Process modules mixed into the controller, in case they contain actions.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 35 def process_mixins controller = @tracker.controllers[@current_class] controller[:includes].each do |i| mixin = @tracker.libs[i] next unless mixin #Process methods in alphabetical order for consistency methods = mixin[:public].keys.map { |n| n.to_s }.sort.map { |n| n.to_sym } methods.each do |name| #Need to process the method like it was in a controller in order #to get the renders set processor = Brakeman::ControllerProcessor.new(@tracker) method = mixin[:public][name] if node_type? method, :methdef method = processor.process_defn method else #Should be a methdef, but this will catch other cases method = processor.process method end #Then process it like any other method in the controller process method end end end |
#process_template(name, args) ⇒ Object
Process template and add the current class and method name as called_from info
170 171 172 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 170 def process_template name, args super name, args, ["#@current_class##@current_method"] end |
#route?(method) ⇒ Boolean
Returns true if the given method name is also a route
202 203 204 205 206 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 202 def route? method return true if @tracker.routes[:allow_all_actions] or @tracker.[:assume_all_routes] routes = @tracker.routes[@current_class] routes and (routes == :allow_all_actions or routes.include? method) end |
#template_name(name = nil) ⇒ Object
Turns a method name into a template name
175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 175 def template_name name = nil name ||= @current_method name = name.to_s if name.include? "/" name else controller = @current_class.to_s.gsub("Controller", "") controller.gsub!("::", "/") underscore(controller + "/" + name.to_s) end end |