param_protected 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +25 -11
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/param_protected/controller_modifications.rb +11 -0
- data/lib/param_protected/protector.rb +40 -4
- data/param_protected.gemspec +14 -6
- data/test/app_root/app/controllers/inherited_users_controller.rb +4 -0
- data/test/app_root/app/controllers/merge_controller.rb +11 -0
- data/test/inherited_users_controller_test.rb +24 -0
- data/test/merge_controller_test.rb +15 -0
- metadata +10 -2
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
|
1
|
+
=== Summary
|
2
2
|
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>.
|
3
3
|
|
4
|
-
|
4
|
+
=== Installation
|
5
5
|
|
6
6
|
Put in your <tt>environment.rb</tt> file...
|
7
7
|
|
@@ -9,7 +9,7 @@ Put in your <tt>environment.rb</tt> file...
|
|
9
9
|
|
10
10
|
Alternatively, just install the gem from the command line and <tt>require "param_protected"</tt> somewhere in your project.
|
11
11
|
|
12
|
-
|
12
|
+
=== Usage
|
13
13
|
class YourController < ActiveController::Base
|
14
14
|
param_protected <param_name> <options>
|
15
15
|
param_accessible <param_name> <options>
|
@@ -20,30 +20,44 @@ Alternatively, just install the gem from the command line and <tt>require "param
|
|
20
20
|
|
21
21
|
<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.
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
== Blacklisting
|
23
|
+
=== Blacklisting
|
26
24
|
Any of these combinations should work.
|
27
25
|
param_protected :client_id
|
28
26
|
param_protected [:client_id, :user_id]
|
29
27
|
param_protected :client_id, :only => 'my_action'
|
30
28
|
param_protected :client_id, :except => [:your_action, :my_action]
|
31
29
|
|
32
|
-
|
30
|
+
=== Whitelisting
|
33
31
|
Any of these combinations should work.
|
34
32
|
param_accessible :client_id
|
35
33
|
param_accessible :[:client_id, :user_id]
|
36
34
|
param_accessible :client_id, :only => 'my_action'
|
37
35
|
param_accessible :client_id, :except => [:your_action, :my_action]
|
38
36
|
|
39
|
-
|
37
|
+
=== Nested Params
|
40
38
|
You can use combinations of arrays and hashes to specify nested params, much the same way <tt>ActiveRecord::Base#find</tt>'s
|
41
39
|
<tt>:include</tt> argument works.
|
42
40
|
param_accessible [:account_name, { :user => [:first_name, :last_name, :address => [:street, :city, :state]] }]
|
43
41
|
param_protected [:id, :password, { :user => [:id, :password] }]
|
44
42
|
|
45
|
-
|
43
|
+
=== Merging
|
44
|
+
If you call <tt>param_protected</tt> or <tt>param_accessible</tt> multiple times for an action or actions, then the protections will be merged. For example...
|
45
|
+
param_protected [:id, :user], :only => :some_action
|
46
|
+
param_protected [{ :user => [:first, :last] }, :password], :only => :some_action
|
47
|
+
Is equivalent to saying...
|
48
|
+
param_protected [:id, { :user => [:first, :last] }, :password], :only => :some_action
|
49
|
+
Credit: Moritz Heidkamp
|
50
|
+
|
51
|
+
=== Inheritance
|
52
|
+
Param protections will be inherited to derived controllers.
|
53
|
+
|
54
|
+
Credit: Moritz Heidkamp
|
55
|
+
|
56
|
+
=== How does it work?
|
46
57
|
It does an <tt>alias_method_chain</tt> on <tt>ActionController::Base#params</tt> that filters (and caches) the params. You can get the unfiltered, pristine params by calling <tt>ActionController::Base#params_without_protection</tt>.
|
47
58
|
|
48
|
-
|
49
|
-
Christopher J. Bottaro
|
59
|
+
=== Author
|
60
|
+
Christopher J. Bottaro - {cjbottaro}[http://github.com/cjbottaro]
|
61
|
+
|
62
|
+
=== Contributors
|
63
|
+
Moritz Heidkamp - {DerGuteMoritz}[http://github.com/DerGuteMoritz]
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
@@ -4,6 +4,7 @@ module ParamProtected
|
|
4
4
|
def self.extended(action_controller)
|
5
5
|
action_controller.class_eval do
|
6
6
|
extend ClassMethods
|
7
|
+
metaclass.alias_method_chain :inherited, :protector
|
7
8
|
include InstanceMethods
|
8
9
|
alias_method_chain :params, :protection
|
9
10
|
end
|
@@ -18,6 +19,16 @@ module ParamProtected
|
|
18
19
|
def param_accessible(params, actions = nil)
|
19
20
|
Protector.instance(self).declare_protection(params, actions, WHITELIST)
|
20
21
|
end
|
22
|
+
|
23
|
+
def inherited_with_protector(controller)
|
24
|
+
inherited_without_protector(controller)
|
25
|
+
|
26
|
+
if defined? @pp_protector
|
27
|
+
controller.instance_variable_set :@pp_protector, @pp_protector.dup
|
28
|
+
controller.class_eval { attr_reader :pp_protector }
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
21
32
|
|
22
33
|
end
|
23
34
|
|
@@ -12,6 +12,10 @@ module ParamProtected
|
|
12
12
|
def initialize
|
13
13
|
@protections = []
|
14
14
|
end
|
15
|
+
|
16
|
+
def initialize_copy(copy)
|
17
|
+
copy.instance_variable_set(:@protections, deep_copy(@protections))
|
18
|
+
end
|
15
19
|
|
16
20
|
def declare_protection(params, actions, exclusivity)
|
17
21
|
params = normalize_params(params)
|
@@ -21,15 +25,47 @@ module ParamProtected
|
|
21
25
|
|
22
26
|
def protect(controller_params, action_name)
|
23
27
|
returning(deep_copy(controller_params)) do |params|
|
24
|
-
|
25
|
-
|
26
|
-
next unless action_matches?(scope, actions, action_name)
|
27
|
-
filter_params(protected_params, params, exclusivity)
|
28
|
+
protections_for_action(action_name).each do |exclusivity, protected_params|
|
29
|
+
filter_params(protected_params, params, exclusivity) unless protected_params.empty?
|
28
30
|
end
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
34
|
private
|
35
|
+
|
36
|
+
def protections_for_action(action_name)
|
37
|
+
@protections_for_action ||= { }
|
38
|
+
|
39
|
+
@protections_for_action[action_name] ||= @protections.select do |protected_params, actions, exclusivity|
|
40
|
+
action_matches?(actions[0], actions[1..-1], action_name)
|
41
|
+
end.inject({ WHITELIST => { }, BLACKLIST => { } }) do |result, (protected_params, action_name, exclusivity)|
|
42
|
+
merge_protections(result[exclusivity], protected_params)
|
43
|
+
result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Merge protections for the same params into one so as to allow extension of them
|
48
|
+
# in inheriting controllers.
|
49
|
+
#
|
50
|
+
# Mutating the first argument is okay since this method is used within inject only.
|
51
|
+
#
|
52
|
+
# Example:
|
53
|
+
# merge_protections({ :foo => { :qux => nil }, :bar => { :baz => nil, :qux => nil } },
|
54
|
+
# { :foo => { :baz => nil, :qux => { :foo => nil } } })
|
55
|
+
# =>
|
56
|
+
#
|
57
|
+
# { :foo => { :baz => nil, :qux => { :foo => nil } }, :bar => { :baz =>nil, :qux => nil } }
|
58
|
+
def merge_protections(protections, protected_params)
|
59
|
+
protected_params.each do |k,v|
|
60
|
+
if protections[k].is_a?(Hash)
|
61
|
+
merge_protections(protections[k], v) if v
|
62
|
+
else
|
63
|
+
protections[k] = v
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
protections
|
68
|
+
end
|
33
69
|
|
34
70
|
# When specifying params to protect, we allow a combination of arrays and hashes much like how
|
35
71
|
# ActiveRecord::Base#find's :include options works. This method normalizes that into just nested hashes,
|
data/param_protected.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{param_protected}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Christopher J. Bottaro"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-02-18}
|
13
13
|
s.description = %q{Provides two class methods on ActiveController::Base that filter the params hash for that controller's actions. You can think of them as the controller analog of attr_protected and attr_accessible.}
|
14
14
|
s.email = %q{cjbottaro@alumni.cs.utexas.edu}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -34,6 +34,8 @@ Gem::Specification.new do |s|
|
|
34
34
|
"test/app_root/app/controllers/accessible_except_controller.rb",
|
35
35
|
"test/app_root/app/controllers/accessible_only_controller.rb",
|
36
36
|
"test/app_root/app/controllers/application_controller.rb",
|
37
|
+
"test/app_root/app/controllers/inherited_users_controller.rb",
|
38
|
+
"test/app_root/app/controllers/merge_controller.rb",
|
37
39
|
"test/app_root/app/controllers/protected_controller.rb",
|
38
40
|
"test/app_root/app/controllers/users_controller.rb",
|
39
41
|
"test/app_root/config/boot.rb",
|
@@ -46,17 +48,18 @@ Gem::Specification.new do |s|
|
|
46
48
|
"test/app_root/config/environments/sqlite3.rb",
|
47
49
|
"test/app_root/config/routes.rb",
|
48
50
|
"test/app_root/lib/console_with_fixtures.rb",
|
51
|
+
"test/inherited_users_controller_test.rb",
|
52
|
+
"test/merge_controller_test.rb",
|
49
53
|
"test/protected_controller_test.rb",
|
50
54
|
"test/protector_test.rb",
|
51
55
|
"test/test_helper.rb",
|
52
56
|
"test/users_controller_test.rb",
|
53
57
|
"uninstall.rb"
|
54
58
|
]
|
55
|
-
s.has_rdoc = true
|
56
59
|
s.homepage = %q{http://github.com/cjbottaro/param_protected}
|
57
60
|
s.rdoc_options = ["--charset=UTF-8"]
|
58
61
|
s.require_paths = ["lib"]
|
59
|
-
s.rubygems_version = %q{1.3.
|
62
|
+
s.rubygems_version = %q{1.3.5}
|
60
63
|
s.summary = %q{Filter unwanted parameters in your controllers and actions.}
|
61
64
|
s.test_files = [
|
62
65
|
"test/accessible_except_test.rb",
|
@@ -64,6 +67,8 @@ Gem::Specification.new do |s|
|
|
64
67
|
"test/app_root/app/controllers/accessible_except_controller.rb",
|
65
68
|
"test/app_root/app/controllers/accessible_only_controller.rb",
|
66
69
|
"test/app_root/app/controllers/application_controller.rb",
|
70
|
+
"test/app_root/app/controllers/inherited_users_controller.rb",
|
71
|
+
"test/app_root/app/controllers/merge_controller.rb",
|
67
72
|
"test/app_root/app/controllers/protected_controller.rb",
|
68
73
|
"test/app_root/app/controllers/users_controller.rb",
|
69
74
|
"test/app_root/config/boot.rb",
|
@@ -75,6 +80,8 @@ Gem::Specification.new do |s|
|
|
75
80
|
"test/app_root/config/environments/sqlite3.rb",
|
76
81
|
"test/app_root/config/routes.rb",
|
77
82
|
"test/app_root/lib/console_with_fixtures.rb",
|
83
|
+
"test/inherited_users_controller_test.rb",
|
84
|
+
"test/merge_controller_test.rb",
|
78
85
|
"test/protected_controller_test.rb",
|
79
86
|
"test/protector_test.rb",
|
80
87
|
"test/test_helper.rb",
|
@@ -91,3 +98,4 @@ Gem::Specification.new do |s|
|
|
91
98
|
else
|
92
99
|
end
|
93
100
|
end
|
101
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class InheritedUsersControllerTest < ActionController::TestCase
|
4
|
+
|
5
|
+
PARAMS = { :user => { :id => 123,
|
6
|
+
:name => { :first => "chris", :middle => "james", :last => "bottaro"},
|
7
|
+
:email => "cjbottaro@blah.com",
|
8
|
+
:password => "SEcReT" },
|
9
|
+
:something => "something" }
|
10
|
+
|
11
|
+
EXPECTED_PARAMS = { "user" => { "email" => "cjbottaro@blah.com",
|
12
|
+
"password" => "SEcReT" } }
|
13
|
+
|
14
|
+
def test_create
|
15
|
+
get :create, PARAMS
|
16
|
+
assert_equal EXPECTED_PARAMS, params
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_update
|
20
|
+
get :update, PARAMS
|
21
|
+
assert_equal EXPECTED_PARAMS, params
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class MergeControllerTest < ActionController::TestCase
|
4
|
+
|
5
|
+
test_action :first do
|
6
|
+
assert_params %w[a b h]
|
7
|
+
assert_equal({"b" => "b"}, params["h"])
|
8
|
+
end
|
9
|
+
|
10
|
+
test_action :second do
|
11
|
+
assert_params %w[b h]
|
12
|
+
assert_equal({"b" => "b", "c" => "c"}, params["h"])
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: param_protected
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher J. Bottaro
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-02-18 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -40,6 +40,8 @@ files:
|
|
40
40
|
- test/app_root/app/controllers/accessible_except_controller.rb
|
41
41
|
- test/app_root/app/controllers/accessible_only_controller.rb
|
42
42
|
- test/app_root/app/controllers/application_controller.rb
|
43
|
+
- test/app_root/app/controllers/inherited_users_controller.rb
|
44
|
+
- test/app_root/app/controllers/merge_controller.rb
|
43
45
|
- test/app_root/app/controllers/protected_controller.rb
|
44
46
|
- test/app_root/app/controllers/users_controller.rb
|
45
47
|
- test/app_root/config/boot.rb
|
@@ -52,6 +54,8 @@ files:
|
|
52
54
|
- test/app_root/config/environments/sqlite3.rb
|
53
55
|
- test/app_root/config/routes.rb
|
54
56
|
- test/app_root/lib/console_with_fixtures.rb
|
57
|
+
- test/inherited_users_controller_test.rb
|
58
|
+
- test/merge_controller_test.rb
|
55
59
|
- test/protected_controller_test.rb
|
56
60
|
- test/protector_test.rb
|
57
61
|
- test/test_helper.rb
|
@@ -91,6 +95,8 @@ test_files:
|
|
91
95
|
- test/app_root/app/controllers/accessible_except_controller.rb
|
92
96
|
- test/app_root/app/controllers/accessible_only_controller.rb
|
93
97
|
- test/app_root/app/controllers/application_controller.rb
|
98
|
+
- test/app_root/app/controllers/inherited_users_controller.rb
|
99
|
+
- test/app_root/app/controllers/merge_controller.rb
|
94
100
|
- test/app_root/app/controllers/protected_controller.rb
|
95
101
|
- test/app_root/app/controllers/users_controller.rb
|
96
102
|
- test/app_root/config/boot.rb
|
@@ -102,6 +108,8 @@ test_files:
|
|
102
108
|
- test/app_root/config/environments/sqlite3.rb
|
103
109
|
- test/app_root/config/routes.rb
|
104
110
|
- test/app_root/lib/console_with_fixtures.rb
|
111
|
+
- test/inherited_users_controller_test.rb
|
112
|
+
- test/merge_controller_test.rb
|
105
113
|
- test/protected_controller_test.rb
|
106
114
|
- test/protector_test.rb
|
107
115
|
- test/test_helper.rb
|