Skip to content
Browse files

moving over from svn

  • Loading branch information...
0 parents commit 00bd18f7b1cac83bcf708f0850bb6e276e958fa8 Christopher J. Bottaro committed May 18, 2008
Showing with 812 additions and 0 deletions.
  1. +68 −0 README
  2. +22 −0 Rakefile
  3. +4 −0 init.rb
  4. +1 −0 install.rb
  5. +183 −0 lib/param_protected.rb
  6. +4 −0 tasks/param_protected_tasks.rake
  7. +100 −0 test/helpers_test.rb
  8. +229 −0 test/param_accessible_test.rb
  9. +200 −0 test/param_protected_test.rb
  10. +1 −0 uninstall.rb
68 README
@@ -0,0 +1,68 @@
+ParamProtected
+==============
+
+= Summary
+This plugin provides two class methods on <tt>ActiveController::Base</tt> that filter the <tt>params</tt> hash for that controller's actions. You can think of them as the controller analog of <tt>attr_protected</tt> and <tt>attr_accessible</tt>.
+
+= Author
+Christopher J. Bottaro
+
+= Usage
+ class YourController < ActiveController::Base
+ param_protected <param_name> <options>
+ param_accessible <param_name> <options>
+
+ ...
+ end
+<tt>param_name</tt> can be a String, Symbol, or Array of Strings and/or Symbols.
+
+<tt>options</tt> is a Hash that has <em>one</em> of two keys: <tt>:only</tt> or <tt>:except</tt>. The value for these keys is a String, Symbol, or Array of Strings and/or Symbols which denotes to the action(s) for which params to protect.
+
+= Examples
+
+== Blacklisting
+Any of these combinations should work.
+ param_protected :client_id
+ param_protected [:client_id, :user_id]
+ param_protected :client_id, :only => 'my_action'
+ param_protected :client_id, :exclude => [:your_action, :my_action]
+
+== Whitelisting
+Any of these combinations should work.
+ param_accessible :client_id
+ param_accessible :[:client_id, :user_id]
+ param_accessible :client_id, :only => 'my_action'
+ param_accessible :client_id, :exclude => [:your_action, :my_action]
+
+== Nested Params
+There is a language to protect nested params, but it has some caveats.
+
+ param_protected 'user/fname'
+<tt>params[:user][:fname]</tt> will be removed, but <tt>params[:user][:client_id]</tt> won't (or anything else for that matter.)
+
+ param_protected 'user'
+This works as expected... it removes <tt>params[:user]</tt>, even if it is a Hash.
+
+ param_accessible 'user/fname'
+This will filter <tt>params[:user][:lname]</tt> and anything that is not <tt>params[:user][:fname]</tt>.
+
+ param_accessible 'user'
+This has no effect if <tt>params[:user]</tt> is a Hash.
+
+== Array Params
+If you have an array of params like
+ params[:person][:nicknames][0]
+ params[:person][:nicknames][1]
+ ...
+ params[:person][:nicknames][n]
+
+You can remove all of them by saying
+ param_protected 'person/nicknames'
+
+<tt>param_accessible</tt> also works with array params.
+
+== Caveats
+Both <tt>param_protected</tt> and <tt>param_accessible</tt> are really just calls to <tt>prepend_before_filter</tt>. Thus any methods in your filter chain that run before either of these methods will have full access to the <em>unprotected</em> <tt>params</tt> Hash.
+
+== Notes
+You should be able to see all the parameters that have been filtered out in your log (log level info). They get printed out directly after the 'Parameters:' line.
22 Rakefile
@@ -0,0 +1,22 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the param_protected plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the param_protected plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'ParamProtected'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
4 init.rb
@@ -0,0 +1,4 @@
+# Include hook code here
+require 'param_protected'
+
+ActionController::Base.send(:include, Cjbottaro::ParamProtected)
1 install.rb
@@ -0,0 +1 @@
+# Install hook code here
183 lib/param_protected.rb
@@ -0,0 +1,183 @@
+# paramProtected
+
+module Cjbottaro
+
+ module ParamProtected
+
+ def self.included(base)
+ base.extend BaseClassMethods
+ end
+
+ module BaseClassMethods
+
+ attr_accessor :_pp_protected_map, :_pp_accessible_map
+
+ def param_accessible(param_list, actions = nil)
+ self._pp_add_to_map(param_list, actions, :accessible)
+ end
+
+ def param_protected(param_list, actions = nil)
+ self._pp_add_to_map(param_list, actions, :protected)
+ end
+
+ protected
+
+ # Build the protected/accessible maps for the controller (self).
+ # Ex:
+ # param_protected [:user_id, :client_id], :only => :some_action
+ # param_protected :account_id, :only => :another_action
+ # would result in a _pp_protected_map of
+ # { :some_action => [:user_id, :client_id],
+ # :another_action => [:account_id] }
+ def _pp_add_to_map(params, actions, which_map)
+ PrivateMethods.sanity_check_arguments(params, actions)
+ include Cjbottaro::ParamProtected::InstanceMethods
+ self._pp_init_maps
+ map = which_map == :accessible ? self._pp_accessible_map : self._pp_protected_map
+ params = PrivateMethods.normalize_to_array(params)
+ actions = self._pp_get_actions(actions)
+ actions.each do |action|
+ map[action] ||= []
+ map[action] += params
+ end
+
+ # add the actual protection method as a before filter
+ self.skip_before_filter :_pp_do_param_filter # this is for the people who call protect_param more than once for a single controller
+ self.prepend_before_filter :_pp_do_param_filter
+ end
+
+ # Initialize the protected/accessible maps to {} if they don't exist yet.
+ def _pp_init_maps
+ self._pp_protected_map = {} if self._pp_protected_map.blank?
+ self._pp_accessible_map = {} if self._pp_accessible_map.blank?
+ end
+
+ # Given an action hash (second argument to param_protected), figure out which actions we mean.
+ # So if we have a controller (self) with three actions, :action1, :action2, :action3 ...
+ # _pp_get_actions :only => :action1 # returns [:action1]
+ # _pp_get_actions :except => :action1 # returns [:action2, :action3]
+ # _pp_get_actions :except => [:action2, :action3] # returns [:action1]
+ def _pp_get_actions(actions)
+ action_methods = PrivateMethods.normalize_to_array(Set.new(public_instance_methods - hidden_actions))
+
+ if actions.blank?
+ actions = action_methods
+ elsif actions.has_key?(:only)
+ actions = PrivateMethods.normalize_to_array(actions[:only])
+ actions = action_methods.to_set & actions.to_set
+ elsif actions.has_key?(:except)
+ actions = PrivateMethods.normalize_to_array(actions[:except])
+ actions = action_methods.to_set - actions.to_set
+ else
+ raise RuntimeError, "second argument to param_protected or param_accessible should be hash with single key - :only or :except"
+ end
+
+ return actions
+ end
+
+ end
+
+ module ClassMethods
+ end
+
+ module InstanceMethods
+
+ protected
+
+ # This is the method that gets registered to the controller via prepend_before_filter when you call
+ # either param_protected or param_accessible. It will eventually call methods (see below) that will
+ # filter an action's params.
+ def _pp_do_param_filter
+ killed_params1, killed_params2 = {}, {}
+ action_name = self.action_name.to_s
+ param_map = PrivateMethods.params_by_xpathy(params)
+ killed_params1 = self._pp_do_accessible_filter(action_name, param_map) if self.class._pp_accessible_map.has_key?(action_name)
+ killed_params2 = self._pp_do_protected_filter(action_name, param_map) if self.class._pp_protected_map.has_key?(action_name)
+ logger.info " Parameters protected: " + killed_params1.merge(killed_params2).inspect
+ end
+
+ # Filter an action's params by looking at the accessible map (which was made by calls to param_accessible).
+ def _pp_do_accessible_filter(action_name, params_by_xpathy)
+ killed_params = {}
+ params_to_access = self.class._pp_accessible_map[action_name]
+ params_by_xpathy.each do |param_path, delete_list|
+ next if params_to_access.include?(param_path)
+ # Consider param_accessible 'user/fname'. params[:user][:fname] will be deleted because params[:user] will be
+ # deleted because 'user' is not on the accessible list. That's why we have the 'unless h[k].kind_of?(Hash).
+ delete_list.each { |h, k| killed_params[k] = h.delete(k) unless h[k].kind_of?(Hash) }
+ end
+ return killed_params
+ end
+
+ # Filter an action's params by looking at the protected map (which was made by calls to param_protected).
+ def _pp_do_protected_filter(action_name, params_by_xpathy)
+ killed_params = {}
+ params_to_protect = self.class._pp_protected_map[action_name]
+ params_by_xpathy.each do |param_path, delete_list|
+ next unless params_to_protect.include?(param_path)
+ delete_list.each { |h, k| killed_params[k] = h.delete(k) }
+ end
+ return killed_params
+ end
+
+ end
+
+ module PrivateMethods
+
+ # Takes a scalar or collection of scalars and normalizes it an array of Strings.
+ def self.normalize_to_array(x)
+ if x.respond_to?(:collect)
+ return x.collect{ |y| y.to_s }
+ else
+ return [ x.to_s ]
+ end
+ end
+
+ # Checks that the arguments to param_protected/param_accessible make sense.
+ def self.sanity_check_arguments(params, actions)
+ errmsg = "second argument must be nil or a hash containing a single key: :only or :except."
+ if actions.blank?
+ nil # noop
+ elsif !actions.instance_of?(Hash)
+ raise RuntimeError.new(errmsg)
+ elsif !actions.has_key?(:only) && !actions.has_key?(:except)
+ raise RuntimeError.new(errmsg)
+ elsif actions.has_key?(:only) && actions.has_key?(:except)
+ raise RuntimeError.new(errmsg)
+ end
+ end
+
+ # Takes a params hash and returns a hash where the keys are an xpath like string and the values are the
+ # information needed to remove the entry from the inputted params hash.
+ # Examples:
+ # params = { :user => {:first => 'calia', :last => 'rose' } }
+ # params_by_xpathy(params) => { 'user' => [[params, :user]],
+ # 'user/first' => [[params[:user], :first]],
+ # 'user/last' => [[params[:user], :last]] }
+ # Notice the values are arrays of doubles. That's so we can properly filter on params that are arrays, like so:
+ # params = { :users => [ {:first => 'calia', :last => 'rose'},
+ # {:first => 'coco', :last => 'rae' } ] }
+ # params_by_xpathy(params) => { 'users' => [[params, :user]],
+ # 'users/first' => [[params[:user][0], :first], [params[:user][1], :first]],
+ # 'users/last' => [[params[:user][0], :last ], [params[:user][0], :last ]] }
+ # Now if we want to protect parameter 'users/first', we can simply do...
+ # params_by_xpathy(params)['users/first'].each { |h, v| h.delete(v) }
+ def self.params_by_xpathy(node, path_so_far = '', result = {})
+ node.each do |k, v|
+ path = path_so_far.blank? ? k.to_s : path_so_far + "/#{k}"
+ result[path] ||= []
+ result[path] << [node, k]
+ if v.is_a?(Hash)
+ params_by_xpathy(v, path, result)
+ elsif v.is_a?(Array)
+ v.each{ |e| params_by_xpathy(e, path, result) }
+ end
+ end
+ return result
+ end
+
+ end
+
+ end
+
+end
4 tasks/param_protected_tasks.rake
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :param_protected do
+# # Task goes here
+# end
100 test/helpers_test.rb
@@ -0,0 +1,100 @@
+require File.dirname(__FILE__) + '/../../../../test/test_helper'
+require File.dirname(__FILE__) + '/../init.rb'
+
+class FakeController < ActionController::Base
+
+ def fake_action1
+ render :text => ''
+ end
+
+ def fake_action2
+ render :text => ''
+ end
+
+ def fake_action3
+ render :text => ''
+ end
+
+ protected
+
+ def rescue_action(e)
+ raise e
+ end
+
+end
+
+class HelpersTest < Test::Unit::TestCase
+
+ def setup
+ FakeController._pp_accessible_map = nil
+ FakeController._pp_protected_map = nil
+ @controller = FakeController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_the_xpathy_thing
+ params = {
+ :scalar => 'test',
+ :user => { :name => { :fname => 'chris', :lname => 'bottaro'},
+ :id => 1 },
+ :pets => [ {:fname => 'calia', :mname => 'rose'},
+ {:fname => 'coco', :mname => 'rae' } ]
+ }
+ expected_xpathy_thing = {
+ 'scalar' => [[params, :scalar]],
+ 'user' => [[params, :user]],
+ 'user/name' => [[params[:user], :name]],
+ 'user/name/fname' => [[params[:user][:name], :fname]],
+ 'user/name/lname' => [[params[:user][:name], :lname]],
+ 'user/id' => [[params[:user], :id]],
+ 'pets' => [[params, :pets]],
+ 'pets/fname' => [[params[:pets][0], :fname], [params[:pets][1], :fname]],
+ 'pets/mname' => [[params[:pets][0], :mname], [params[:pets][1], :mname]]
+ }
+ xpathy_thing = Cjbottaro::ParamProtected::PrivateMethods.params_by_xpathy(params)
+ assert_equal expected_xpathy_thing, xpathy_thing
+ end
+
+ def test_accessible_map
+
+ FakeController.param_accessible :user_id
+ expected_map = { 'fake_action1' => ['user_id'],
+ 'fake_action2' => ['user_id'],
+ 'fake_action3' => ['user_id'] }
+ assert_equal expected_map, FakeController._pp_accessible_map
+
+ FakeController.param_accessible :client_id
+ expected_map = { 'fake_action1' => ['user_id', 'client_id'],
+ 'fake_action2' => ['user_id', 'client_id'],
+ 'fake_action3' => ['user_id', 'client_id'] }
+ assert_equal expected_map, FakeController._pp_accessible_map
+
+ FakeController.param_accessible :account_id, :only => :fake_action1
+ expected_map = { 'fake_action1' => ['user_id', 'client_id', 'account_id'],
+ 'fake_action2' => ['user_id', 'client_id'],
+ 'fake_action3' => ['user_id', 'client_id'] }
+ assert_equal expected_map, FakeController._pp_accessible_map
+
+ FakeController.param_accessible :account_id, :except => :fake_action1
+ expected_map = { 'fake_action1' => ['user_id', 'client_id', 'account_id'],
+ 'fake_action2' => ['user_id', 'client_id', 'account_id'],
+ 'fake_action3' => ['user_id', 'client_id', 'account_id'] }
+ assert_equal expected_map, FakeController._pp_accessible_map
+ end
+
+ def test_accessible_map_with_arrays
+
+ FakeController.param_accessible [:user_id, :client_id], :only => [:fake_action1, :fake_action2]
+ expected_map = { 'fake_action1' => ['user_id', 'client_id'],
+ 'fake_action2' => ['user_id', 'client_id'] }
+ assert_equal expected_map, FakeController._pp_accessible_map
+
+ FakeController.param_accessible [:user_id, :client_id], :except => [:fake_action1, :fake_action2]
+ expected_map = { 'fake_action1' => ['user_id', 'client_id'],
+ 'fake_action2' => ['user_id', 'client_id'],
+ 'fake_action3' => ['user_id', 'client_id'] }
+ assert_equal expected_map, FakeController._pp_accessible_map
+ end
+
+end
229 test/param_accessible_test.rb
@@ -0,0 +1,229 @@
+require File.dirname(__FILE__) + '/../../../../test/test_helper'
+require File.dirname(__FILE__) + '/../init.rb'
+
+require 'ruby-debug'
+Debugger.start
+
+class FakeController < ActionController::Base
+
+ def fake_action1
+ render :text => ''
+ end
+
+ def fake_action2
+ render :text => ''
+ end
+
+ def fake_action3
+ render :text => ''
+ end
+
+ protected
+
+ def rescue_action(e)
+ raise e
+ end
+
+end
+
+class ParamAccessibleTest < Test::Unit::TestCase
+
+ def setup
+ FakeController._pp_accessible_map = nil
+ FakeController._pp_protected_map = nil
+ @controller = FakeController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_simple
+ @controller.class.param_accessible :user_id
+
+ get :fake_action1, :user_id => true, :client_id => true, :account_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == false
+ assert @controller.params.has_key?(:account_id) == false
+ end
+
+ def test_only
+ @controller.class.param_accessible :user_id, :only => :fake_action1
+
+ get :fake_action1, :user_id => true, :client_id => true, :account_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == false
+ assert @controller.params.has_key?(:account_id) == false
+
+ get :fake_action2, :user_id => true, :client_id => true, :account_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == true
+ assert @controller.params.has_key?(:account_id) == true
+
+ get :fake_action3, :user_id => true, :client_id => true, :account_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == true
+ assert @controller.params.has_key?(:account_id) == true
+ end
+
+ def text_except
+ @controller.class.param_accessible :user_id, :except => :fake_action1
+
+ get :fake_action1, :user_id => true, :client_id => true, :account_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == true
+ assert @controller.params.has_key?(:account_id) == true
+
+ get :fake_action2, :user_id => true, :client_id => true, :account_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == false
+ assert @controller.params.has_key?(:account_id) == false
+
+ get :fake_action3, :user_id => true, :client_id => true, :account_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == false
+ assert @controller.params.has_key?(:account_id) == false
+ end
+
+ def test_param_array
+ @controller.class.param_accessible [:user_id, :other_id]
+
+ get :fake_action1, :user_id => true, :other_id => true, :good_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == false
+
+ get :fake_action2, :user_id => true, :other_id => true, :good_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == false
+ end
+
+ def test_only_array
+ @controller.class.param_accessible [:user_id, :other_id], :only => [:fake_action1, :fake_action2]
+
+ get :fake_action1, :user_id => true, :other_id => true, :good_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == false
+
+ get :fake_action2, :user_id => true, :other_id => true, :good_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == false
+
+ get :fake_action3, :user_id => true, :other_id => true, :good_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+ end
+
+ def test_except_array
+ @controller.class.param_accessible [:user_id, :other_id], :except => [:fake_action1, :fake_action2]
+
+ get :fake_action1, :user_id => true, :other_id => true, :good_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action2, :user_id => 123, :other_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action3, :user_id => 123, :other_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == false
+ end
+
+ def test_param_string
+ @controller.class.param_accessible 'user_id'
+
+ get :fake_action1, :user_id => true
+ assert @controller.params.has_key?(:user_id) == true
+
+ get :fake_action2, :user_id => true
+ assert @controller.params.has_key?(:user_id) == true
+
+ get :fake_action3, :user_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ end
+
+ def test_only_string
+ @controller.class.param_accessible 'user_id', :only => 'fake_action1'
+
+ get :fake_action1, :user_id => true, :client_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == false
+
+ get :fake_action2, :user_id => true, :client_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == true
+
+ get :fake_action3, :user_id => true, :client_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == true
+ end
+
+ def test_exclude_string
+ @controller.class.param_accessible 'user_id', :except => 'fake_action1'
+
+ get :fake_action1, :user_id => 123, :client_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == true
+
+ get :fake_action2, :user_id => 123, :client_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == false
+
+ get :fake_action3, :user_id => 123, :client_id => true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:client_id) == false
+ end
+
+ def test_nested
+ @controller.class.param_accessible 'user/user_id', :only => :fake_action1
+
+ get :fake_action1, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params[:user].has_key?(:user_id) == true
+ assert @controller.params[:user].has_key?(:good_id) == false
+ assert @controller.params.has_key?(:user_id) == false
+ assert @controller.params.has_key?(:good_id) == false
+
+ get :fake_action2, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params[:user].has_key?(:user_id) == true
+ assert @controller.params[:user].has_key?(:good_id) == true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action3, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params[:user].has_key?(:user_id) == true
+ assert @controller.params[:user].has_key?(:good_id) == true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+ end
+
+ # Adding a hash to the accessible list really don't have any effect.
+ def test_nested_deep
+ @controller.class.param_accessible 'user', :only => :fake_action1
+
+ get :fake_action1, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user) == true
+ assert @controller.params[:user].has_key?(:user_id) == false
+ assert @controller.params[:user].has_key?(:good_id) == false
+ assert @controller.params.has_key?(:user_id) == false
+ assert @controller.params.has_key?(:good_id) == false
+
+ get :fake_action2, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params[:user].has_key?(:user_id) == true
+ assert @controller.params[:user].has_key?(:good_id) == true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action3, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params[:user].has_key?(:user_id) == true
+ assert @controller.params[:user].has_key?(:good_id) == true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+ end
+
+end
200 test/param_protected_test.rb
@@ -0,0 +1,200 @@
+require File.dirname(__FILE__) + '/../../../../test/test_helper'
+require File.dirname(__FILE__) + '/../init.rb'
+
+require 'ruby-debug'
+Debugger.start
+
+class FakeController < ActionController::Base
+
+ def fake_action1
+ render :text => ''
+ end
+
+ def fake_action2
+ render :text => ''
+ end
+
+ def fake_action3
+ render :text => ''
+ end
+
+ protected
+
+ def rescue_action(e)
+ raise e
+ end
+
+end
+
+class ParamProtectedTest < Test::Unit::TestCase
+
+ def setup
+ FakeController._pp_accessible_map = nil
+ FakeController._pp_protected_map = nil
+ @controller = FakeController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_simple
+ @controller.class.param_protected :user_id
+
+ get :fake_action1, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == false
+ end
+
+ def test_only
+ @controller.class.param_protected :user_id, :only => :fake_action1
+
+ get :fake_action1, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == false
+
+ get :fake_action2, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == true
+ end
+
+ def text_except
+ @controller.class.param_protected :user_id, :except => :fake_action1
+
+ get :fake_action1, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == true
+
+ get :fake_action2, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == false
+ end
+
+ def test_param_array
+ @controller.class.param_protected [:user_id, :other_id]
+
+ get :fake_action1, :user_id => 123, :other_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user_id) == false
+ assert @controller.params.has_key?(:other_id) == false
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action2, :user_id => 123, :other_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user_id) == false
+ assert @controller.params.has_key?(:other_id) == false
+ assert @controller.params.has_key?(:good_id) == true
+ end
+
+ def test_only_array
+ @controller.class.param_protected [:user_id, :other_id], :only => [:fake_action1, :fake_action2]
+
+ get :fake_action1, :user_id => 123, :other_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user_id) == false
+ assert @controller.params.has_key?(:other_id) == false
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action2, :user_id => 123, :other_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user_id) == false
+ assert @controller.params.has_key?(:other_id) == false
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action3, :user_id => 123, :other_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+ end
+
+ def test_except_array
+ @controller.class.param_protected [:user_id, :other_id], :except => [:fake_action1, :fake_action2]
+
+ get :fake_action1, :user_id => 123, :other_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action2, :user_id => 123, :other_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:other_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action3, :user_id => 123, :other_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user_id) == false
+ assert @controller.params.has_key?(:other_id) == false
+ assert @controller.params.has_key?(:good_id) == true
+ end
+
+ def test_param_string
+ @controller.class.param_protected 'user_id'
+
+ get :fake_action1, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == false
+
+ get :fake_action2, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == false
+
+ get :fake_action3, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == false
+ end
+
+ def test_only_string
+ @controller.class.param_protected 'user_id', :only => 'fake_action1'
+
+ get :fake_action1, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == false
+
+ get :fake_action2, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == true
+
+ get :fake_action3, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == true
+ end
+
+ def test_exclude_string
+ @controller.class.param_protected 'user_id', :except => 'fake_action1'
+
+ get :fake_action1, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == true
+
+ get :fake_action2, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == false
+
+ get :fake_action3, :user_id => 123
+ assert @controller.params.has_key?(:user_id) == false
+ end
+
+ def test_nested
+ @controller.class.param_protected 'user/user_id', :only => :fake_action1
+
+ get :fake_action1, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params[:user].has_key?(:user_id) == false
+ assert @controller.params[:user].has_key?(:good_id) == true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action2, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params[:user].has_key?(:user_id) == true
+ assert @controller.params[:user].has_key?(:good_id) == true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action3, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params[:user].has_key?(:user_id) == true
+ assert @controller.params[:user].has_key?(:good_id) == true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+ end
+
+ def test_nested_deep
+ @controller.class.param_protected 'user', :only => :fake_action1
+
+ get :fake_action1, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params.has_key?(:user) == false
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action2, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params[:user].has_key?(:user_id) == true
+ assert @controller.params[:user].has_key?(:good_id) == true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+
+ get :fake_action3, :user => { :user_id => 123, :good_id => 321 }, :user_id => 456, :good_id => 789
+ assert @controller.params[:user].has_key?(:user_id) == true
+ assert @controller.params[:user].has_key?(:good_id) == true
+ assert @controller.params.has_key?(:user_id) == true
+ assert @controller.params.has_key?(:good_id) == true
+ end
+
+end
1 uninstall.rb
@@ -0,0 +1 @@
+# Uninstall hook code here

0 comments on commit 00bd18f

Please sign in to comment.
Something went wrong with that request. Please try again.