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::COOKIES_SEXP, Util::PARAMETERS, Util::PARAMS_SEXP, Util::PATH_PARAMETERS, Util::QUERY_PARAMETERS, Util::REQUEST_ENV, Util::REQUEST_PARAMETERS, Util::REQUEST_PARAMS, Util::SESSION, Util::SESSION_SEXP
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.
- #get_skipped_filters(method, controller) ⇒ Object
-
#initialize(app_tree, 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
Skip it, must be an inner class.
- #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.
- #remove_skipped_filters(filters, method, klass) ⇒ Object
-
#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
#assign_args, #collapse_send_call, #duplicate?, #find_push_target, #get_call_value, #join_arrays, #join_strings, #merge_if_branch, #meth_env, #only_ivars, #only_request_vars, #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_helper_method, #process_iasgn, #process_if, #process_if_branch, #process_lasgn, #process_masgn, #process_op_asgn1, #process_op_asgn2, #process_or_simple_operation, #process_or_target, #process_safely, #process_scope, #process_selfdef, #process_svalue, #same_value?, #self_assign?, #self_assign_target?, #self_assign_var?, #set_value, #too_deep?, #top_target, #value_from_if
Methods included from Util
#array?, #block?, #call?, #camelize, #contains_class?, #context_for, #cookies?, #false?, #file_by_name, #file_for, #github_url, #hash?, #hash_access, #hash_insert, #hash_iterate, #integer?, #make_call, #node_type?, #number?, #params?, #pluralize, #regexp?, #relative_path, #request_env?, #request_value?, #result?, #set_env_defaults, #sexp?, #string?, #symbol?, #table_to_csv, #template_path_to_name, #true?, #truncate_table, #underscore
Methods included from ProcessorHelper
#class_name, #process_all, #process_all!, #process_call_args, #process_module
Methods inherited from SexpProcessor
#error_handler, #in_context, #process, #process_dummy, #scope
Constructor Details
#initialize(app_tree, 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.
13 14 15 16 17 18 19 20 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 13 def initialize app_tree, tracker, only_method = nil super tracker @app_tree = app_tree @only_method = only_method @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
214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 214 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]] || @tracker.libs[controller[:parent]] end remove_skipped_filters filters, method, klass end |
#before_filter_to_hash(args) ⇒ Object
Returns a before filter as a hash table
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 326 327 328 329 330 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 297 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.
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 337 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[:src] } end else nil end end |
#get_before_filters(method, controller) ⇒ Object
Returns an array of filter names
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 267 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.args) 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 |
#get_skipped_filters(method, controller) ⇒ Object
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 241 def get_skipped_filters method, controller return [] unless controller[:options] and controller[:options][:skip_filters] filters = [] if controller[:skip_filter_cache].nil? controller[:skip_filter_cache] = controller[:options][:skip_filters].map do |filter| before_filter_to_hash(filter.args) end end controller[:skip_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
190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 190 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?
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 162 163 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 137 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_list, only_ivars(:include_request_vars)) 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()
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 106 def process_call exp exp = super return exp unless call? exp method = exp.method if method == :head @rendered = true elsif @tracker.[:interprocedural] and @current_method and (exp.target.nil? or exp.target.node_type == :self) exp = get_call_value(exp) end exp end |
#process_call_with_block(exp) ⇒ Object
Check for respond_to
124 125 126 127 128 129 130 131 132 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 124 def process_call_with_block exp super if call? exp.block_call and exp.block_call.method == :respond_to @rendered = true end exp end |
#process_class(exp) ⇒ Object
Skip it, must be an inner class
67 68 69 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 67 def process_class exp exp end |
#process_controller(name, src) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 22 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
166 167 168 169 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 166 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.
73 74 75 76 77 78 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 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 73 def process_methdef exp meth_name = exp.method_name Brakeman.debug "Processing #{@current_class}##{meth_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 meth_env do if is_route before_filter_list(@current_method, @current_class).each do |f| process_before_filter f end end process_all 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.
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 64 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 36 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(@app_tree, @tracker) method = mixin[:public][name][:src].deep_clone 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
172 173 174 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 172 def process_template name, args super name, args, ["#@current_class##@current_method"] end |
#remove_skipped_filters(filters, method, klass) ⇒ Object
228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 228 def remove_skipped_filters filters, method, klass controller = @tracker.controllers[klass] while controller filters = filters - get_skipped_filters(method, controller) controller = @tracker.controllers[controller[:parent]] || @tracker.libs[controller[:parent]] end filters end |
#route?(method) ⇒ Boolean
Returns true if the given method name is also a route
204 205 206 207 208 209 210 211 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 204 def route? method if @tracker.routes[:allow_all_actions] or @tracker.[:assume_all_routes] true else routes = @tracker.routes[@current_class] routes and (routes.include? :allow_all_actions or routes.include? method) end end |
#template_name(name = nil) ⇒ Object
Turns a method name into a template name
177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/brakeman/processors/controller_alias_processor.rb', line 177 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 |