parameter_filter 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in activerecord-parameter_filter.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Alex McHale
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,43 @@
1
+ parameter_filter
2
+ ================
3
+
4
+ Summary
5
+ -------
6
+
7
+ ParameterFilter is a module to mix into ActionController subclasses. It inserts
8
+ a before_filter which will automatically remove any fields in params that are
9
+ not explicitly allowed.
10
+
11
+ Installation
12
+ ------------
13
+
14
+ Include the following in your Gemfile:
15
+
16
+ gem "parameter_filter"
17
+
18
+ Usage
19
+ -----
20
+
21
+ For global security, include the following in your ApplicationController:
22
+
23
+ include ParameterFilter
24
+
25
+ Then, inside each of you controllers, specify what fields you want each action
26
+ to receive:
27
+
28
+ # Accept user[email] and user[password] on the create and update actions.
29
+ accepts :fields => { :user => [ :email, :password ] }, :on => [ :create, :update ]
30
+
31
+ # Accept user[email] and user[password] on all actions.
32
+ accepts fields: { user: %w( email password ) }
33
+
34
+ # Accept q on the search action.
35
+ accepts field: "q", on: "search"
36
+
37
+ # Accept q and sort on the search and index actions.
38
+ accepts fields: [ :q, :sort ], on: %w( search index )
39
+
40
+ ParameterFilter should be pretty flexible in what you throw at it.
41
+
42
+ NOTE: All actions are automatically allowed to receive :controller, :action and
43
+ :id.
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << 'lib'
6
+ t.libs << 'test'
7
+ t.pattern = 'test/*_test.rb'
8
+ t.verbose = true
9
+ end
@@ -0,0 +1,98 @@
1
+ require "parameter_filter/version"
2
+
3
+ # When a controller has ParameterFilter included, it will by default remove
4
+ # everything from params. The way to receive parameters is to specifically
5
+ # allow them with accept_fields.
6
+
7
+ module ParameterFilter
8
+
9
+ module ClassMethods
10
+
11
+ def accept_fields_parser fields
12
+ table = {}
13
+
14
+ [fields].flatten.compact.uniq.each do |field|
15
+ case field
16
+
17
+ when Symbol, String
18
+ table[field.to_s] = {}
19
+
20
+ when Hash
21
+ field.each do |key, value|
22
+ table[key.to_s] = accept_fields_parser value
23
+ end
24
+
25
+ end
26
+ end
27
+
28
+ table
29
+ end
30
+
31
+ def accepts options = {}
32
+ @_accepted_fields ||= { nil => { "controller" => {}, "action" => {}, "id" => {} } }
33
+ fields = options[:fields] || options[:field] || {}
34
+
35
+ case options[:on]
36
+ when Array
37
+ options[:on].each do |k|
38
+ @_accepted_fields[k.to_s] = accept_fields_parser fields
39
+ end
40
+
41
+ when Symbol, String
42
+ @_accepted_fields[options[:on].to_s] = accept_fields_parser fields
43
+
44
+ else
45
+ @_accepted_fields[nil] ||= {}
46
+ @_accepted_fields[nil].merge! accept_fields_parser fields
47
+
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ module InstanceMethods
54
+
55
+ def remove_filtered_parameters accepted_fields = nil, parameters = nil
56
+ if !accepted_fields && !parameters
57
+ accepted_fields = self.class.instance_variable_get("@_accepted_fields") || {}
58
+ fields = (accepted_fields[nil] || {}).merge(accepted_fields[self.action_name] || {})
59
+ remove_filtered_parameters fields, self.params
60
+ elsif parameters
61
+ accepted_keys = ParameterFilter.field_keys accepted_fields
62
+ accepted_keys += [ :controller, :action, :id ] if parameters == params
63
+ parameters.slice! *accepted_keys
64
+
65
+ ParameterFilter.each_field accepted_fields do |k, v|
66
+ remove_filtered_parameters v, parameters[k] if parameters[k].kind_of? Hash
67
+ end
68
+ end
69
+ end
70
+
71
+ end
72
+
73
+ def self.each_field fields
74
+ [ fields ].flatten.compact.uniq.each do |f|
75
+ case f
76
+ when Hash then f.each { |k, v| yield k, v }
77
+ when String, Symbol then yield f
78
+ end
79
+ end
80
+ end
81
+
82
+ def self.field_keys fields
83
+ fields.map do |field|
84
+ case field
85
+ when Array then field_keys field
86
+ when Hash then field.keys
87
+ else field
88
+ end
89
+ end.flatten.compact.uniq
90
+ end
91
+
92
+ def self.included base
93
+ base.send :extend, ClassMethods
94
+ base.send :include, InstanceMethods
95
+ base.send :before_filter, :remove_filtered_parameters
96
+ end
97
+
98
+ end
@@ -0,0 +1,5 @@
1
+ module Activerecord
2
+ module ParameterFilter
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "parameter_filter/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "parameter_filter"
7
+ s.version = Activerecord::ParameterFilter::VERSION
8
+ s.authors = ["Alex McHale"]
9
+ s.email = ["alex@anticlever.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{A gem to easily filter out unwanted parameters in ActionController.}
12
+ s.description = %q{A gem to easily filter out unwanted parameters in ActionController.}
13
+
14
+ s.rubyforge_project = "parameter_filter"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
@@ -0,0 +1,57 @@
1
+ require "test_helper"
2
+
3
+ class ParamterFilterTest < MiniTest::Unit::TestCase
4
+
5
+ def test_class_with_parameter_filter
6
+ klass = Class.new
7
+ klass.expects(:before_filter).with(:remove_filtered_parameters).once
8
+ klass.send :include, ParameterFilter
9
+ end
10
+
11
+ def test_allowing_core_parameters
12
+ controller = self.filtered_controller
13
+ controller.params = { controller: "users", action: "index", id: 123 }
14
+ controller.remove_filtered_parameters
15
+ assert_equal [ :controller, :action, :id ], controller.params.keys
16
+ end
17
+
18
+ def test_removing_noncore_parameters
19
+ controller = self.filtered_controller
20
+ controller.params = { foo: 999 }
21
+ assert_equal 999, controller.params[:foo]
22
+ controller.remove_filtered_parameters
23
+ assert_equal nil, controller.params[:foo]
24
+ end
25
+
26
+ def test_allowing_nested_fields
27
+ controller = self.filtered_controller fields: { user: "email" }
28
+ controller.params = { "user" => { "email" => "joe@example.com" } }
29
+ assert_equal "joe@example.com", controller.params["user"]["email"]
30
+ controller.remove_filtered_parameters
31
+ assert_equal "joe@example.com", controller.params["user"]["email"]
32
+ end
33
+
34
+ def test_removing_nested_fields
35
+ controller = self.filtered_controller
36
+ controller.params = { "user" => { "email" => "joe@example.com" } }
37
+ assert_equal "joe@example.com", controller.params["user"]["email"]
38
+ controller.remove_filtered_parameters
39
+ assert_equal nil, controller.params["user"]
40
+ end
41
+
42
+ protected
43
+
44
+ def filtered_controller options = {}
45
+ klass = Class.new
46
+ klass.stubs :before_filter
47
+ klass.send :include, ParameterFilter
48
+ klass.send :accepts, options
49
+
50
+ klass.new.tap do |controller|
51
+ def controller.action_name; "index"; end
52
+ def controller.params; @params ||= {}; end
53
+ def controller.params= p; @params = p; end
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,39 @@
1
+ require "parameter_filter"
2
+ require "minitest/autorun"
3
+ require "minitest/mock"
4
+ require "turn/autorun"
5
+ require "mocha"
6
+
7
+ # Taken from Rails for testing purposes, as they're the what the entire gem leans.
8
+ class Hash
9
+ # Slice a hash to include only the given keys. This is useful for
10
+ # limiting an options hash to valid keys before passing to a method:
11
+ #
12
+ # def search(criteria = {})
13
+ # assert_valid_keys(:mass, :velocity, :time)
14
+ # end
15
+ #
16
+ # search(options.slice(:mass, :velocity, :time))
17
+ #
18
+ # If you have an array of keys you want to limit to, you should splat them:
19
+ #
20
+ # valid_keys = [:mass, :velocity, :time]
21
+ # search(options.slice(*valid_keys))
22
+ def slice(*keys)
23
+ keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
24
+ hash = self.class.new
25
+ keys.each { |k| hash[k] = self[k] if has_key?(k) }
26
+ hash
27
+ end
28
+
29
+ # Replaces the hash with only the given keys.
30
+ # Returns a hash contained the removed key/value pairs
31
+ # {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d => 4}
32
+ def slice!(*keys)
33
+ keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
34
+ omit = slice(*self.keys - keys)
35
+ hash = slice(*keys)
36
+ replace(hash)
37
+ omit
38
+ end
39
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: parameter_filter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alex McHale
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-26 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A gem to easily filter out unwanted parameters in ActionController.
15
+ email:
16
+ - alex@anticlever.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - LICENSE
24
+ - README.markdown
25
+ - Rakefile
26
+ - lib/parameter_filter.rb
27
+ - lib/parameter_filter/version.rb
28
+ - parameter_filter.gemspec
29
+ - test/parameter_filter_test.rb
30
+ - test/test_helper.rb
31
+ homepage: ''
32
+ licenses: []
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project: parameter_filter
51
+ rubygems_version: 1.8.11
52
+ signing_key:
53
+ specification_version: 3
54
+ summary: A gem to easily filter out unwanted parameters in ActionController.
55
+ test_files:
56
+ - test/parameter_filter_test.rb
57
+ - test/test_helper.rb