param_accessible 0.0.1
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/.gitignore +19 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +93 -0
- data/Rakefile +7 -0
- data/lib/param_accessible/controller_ext.rb +41 -0
- data/lib/param_accessible/error.rb +19 -0
- data/lib/param_accessible/not_acceptable_helper.rb +23 -0
- data/lib/param_accessible/rule.rb +93 -0
- data/lib/param_accessible/rules.rb +58 -0
- data/lib/param_accessible/version.rb +3 -0
- data/lib/param_accessible.rb +8 -0
- data/param_accessible.gemspec +23 -0
- data/spec/app_root/app/controllers/application_controller.rb +34 -0
- data/spec/app_root/app/controllers/except_controller.rb +6 -0
- data/spec/app_root/app/controllers/if_false_controller.rb +12 -0
- data/spec/app_root/app/controllers/if_true_controller.rb +12 -0
- data/spec/app_root/app/controllers/merge_controller.rb +6 -0
- data/spec/app_root/app/controllers/not_acceptable_controller.rb +6 -0
- data/spec/app_root/app/controllers/only_controller.rb +6 -0
- data/spec/app_root/app/controllers/simple_controller.rb +4 -0
- data/spec/app_root/app/controllers/unless_false_controller.rb +12 -0
- data/spec/app_root/app/controllers/unless_true_controller.rb +12 -0
- data/spec/app_root/config/application.rb +12 -0
- data/spec/app_root/config/environment.rb +5 -0
- data/spec/app_root/config/routes.rb +3 -0
- data/spec/lib/except_spec.rb +34 -0
- data/spec/lib/if_false_spec.rb +24 -0
- data/spec/lib/if_true_spec.rb +34 -0
- data/spec/lib/merge_spec.rb +20 -0
- data/spec/lib/not_acceptable_helper_spec.rb +30 -0
- data/spec/lib/only_spec.rb +34 -0
- data/spec/lib/simple_spec.rb +57 -0
- data/spec/lib/unless_false_spec.rb +34 -0
- data/spec/lib/unless_true_spec.rb +24 -0
- data/spec/spec_helper.rb +15 -0
- metadata +160 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Dan Cunning
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# ParamAccessible
|
2
|
+
|
3
|
+
[](https://secure.travis-ci.org/topdan/param_accessible.png)
|
4
|
+
|
5
|
+
Provides a method to help protect your Ruby on Rails controllers from malicious or accidentally destructive user parameters. It is independent, but heavily influenced by param_protected.
|
6
|
+
|
7
|
+
Make all your controllers secure by default as well as provide readable messages to users when a security breach was prevented.
|
8
|
+
|
9
|
+
For more information on the design considerations please visit: https://www.topdan.com/ruby-on-rails/params-accessible.html
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'param_accessible'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install param_accessible
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
class ApplicationController < ActionController::Base
|
28
|
+
|
29
|
+
# make all your controllers secure by default
|
30
|
+
before_filter :ensure_params_are_accessible, :only => [:create, :update]
|
31
|
+
|
32
|
+
# expose the common rails parameters
|
33
|
+
param_accessible :controller, :action, :format, :id
|
34
|
+
|
35
|
+
# this error is thrown when the user tries to access an inaccessible param
|
36
|
+
rescue_from ParamAccessible::Error, :with => :handle_param_not_accessible
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def handle_param_not_accessible e
|
41
|
+
flash[:error] = "You gave me some invalid parameters: #{e.inaccessible_params.join(', )}"
|
42
|
+
redirect_to :back
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
class UserController < ApplicationController
|
48
|
+
|
49
|
+
# these attributes are available for everyone
|
50
|
+
param_accessible :user => {:name, :email, :password, :password_confirmation}
|
51
|
+
|
52
|
+
# these attributes are only available if the controller instance method is_admin? is true
|
53
|
+
param_accessible :user => {:is_admin, :is_locked_out}, :if => :is_admin?
|
54
|
+
|
55
|
+
def update
|
56
|
+
@user = User.find(params[:id])
|
57
|
+
|
58
|
+
# this is now safe!
|
59
|
+
if @user.update_attributes(params[:user])
|
60
|
+
...
|
61
|
+
else
|
62
|
+
...
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class DemoController < ApplicationController
|
68
|
+
|
69
|
+
# rescue_from ParamAccessible::Error and respond with a 406 Not Acceptable status
|
70
|
+
# with an HTML, JSON, XML, or JS explanation of which parameters were invalid
|
71
|
+
include ParamAccessible::NotAcceptableHelper
|
72
|
+
|
73
|
+
param_accessible :foo, :if => :is_admin
|
74
|
+
param_accessible :bar, :unless => :logged_in?
|
75
|
+
param_accessible :baz, :only => :show
|
76
|
+
param_accessible :nut, :except => :index
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
class InsecureController < ApplicationController
|
81
|
+
|
82
|
+
# skip the filter ApplicationController set up to avoid the accessible parameter checks
|
83
|
+
skip_before_filter :ensure_params_are_accessible
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
## Contributing
|
88
|
+
|
89
|
+
1. Fork it
|
90
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
91
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
92
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
93
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module ParamAccessible
|
2
|
+
|
3
|
+
module ControllerExt
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
protected
|
7
|
+
|
8
|
+
def ensure_params_are_accessible
|
9
|
+
inaccessible_params = param_accessible_rules.detect_inaccessible_params self
|
10
|
+
|
11
|
+
unless inaccessible_params.nil? || inaccessible_params.blank?
|
12
|
+
raise ParamAccessible::Error.new(inaccessible_params)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def param_accessible_rules
|
17
|
+
self.class.param_accessible_rules
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
|
22
|
+
def param_accessible *args
|
23
|
+
param_accessible_rules.push *args
|
24
|
+
end
|
25
|
+
|
26
|
+
def param_accessible_rules
|
27
|
+
return @param_accessible_rules if defined? @param_accessible_rules
|
28
|
+
|
29
|
+
# inheritance
|
30
|
+
if superclass.respond_to?(:param_accessible_rules)
|
31
|
+
@param_accessible_rules = Rules.new superclass.param_accessible_rules
|
32
|
+
else
|
33
|
+
@param_accessible_rules = Rules.new
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ParamAccessible
|
2
|
+
|
3
|
+
class Error < Exception
|
4
|
+
|
5
|
+
attr_reader :inaccessible_params
|
6
|
+
|
7
|
+
def initialize inaccessible_params
|
8
|
+
if inaccessible_params.length == 1
|
9
|
+
super "#{inaccessible_params.join(', ')} is an invalid parameter"
|
10
|
+
else
|
11
|
+
super "#{inaccessible_params.join(', ')} are invalid parameters"
|
12
|
+
end
|
13
|
+
|
14
|
+
@inaccessible_params = inaccessible_params
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ParamAccessible
|
2
|
+
|
3
|
+
module NotAcceptableHelper
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
rescue_from ParamAccessible::Error, :with => :handle_param_not_accessible
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def handle_param_not_accessible error
|
13
|
+
respond_to do |format|
|
14
|
+
format.html { render :status => 406, :text => error.message }
|
15
|
+
format.json { render :status => 406, :json => {:error => {:message => "You supplied invalid parameters: #{error.inaccessible_params.join(', ')}"}} }
|
16
|
+
format.xml { render :status => 406, :xml => {:message => "You supplied invalid parameters: #{error.inaccessible_params.join(', ')}"}.to_xml('error') }
|
17
|
+
format.js { render :status => 406, :text => %(// invalid parameters: #{error.inaccessible_params.join(', ')}\n) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module ParamAccessible
|
2
|
+
|
3
|
+
class Rule
|
4
|
+
|
5
|
+
attr_reader :attributes
|
6
|
+
attr_reader :if_option, :unless_option
|
7
|
+
attr_reader :only_options, :except_options
|
8
|
+
|
9
|
+
def initialize *args
|
10
|
+
if args.length > 1 && args.last.is_a?(Hash)
|
11
|
+
options = args.last
|
12
|
+
attributes = args[0..-2]
|
13
|
+
|
14
|
+
options.assert_valid_keys :if, :unless, :only, :except
|
15
|
+
# options = normalize_options options
|
16
|
+
else
|
17
|
+
options = {}
|
18
|
+
attributes = args
|
19
|
+
end
|
20
|
+
|
21
|
+
@if_option = options[:if]
|
22
|
+
@unless_option = options[:unless]
|
23
|
+
|
24
|
+
@only_options = clean_action_option options[:only]
|
25
|
+
@except_options = clean_action_option options[:except]
|
26
|
+
|
27
|
+
@attributes = normalize_params attributes
|
28
|
+
end
|
29
|
+
|
30
|
+
def clean_action_option value
|
31
|
+
return if value == nil
|
32
|
+
value = [value] unless value.is_a?(Array)
|
33
|
+
value.collect {|v| v.to_s }
|
34
|
+
end
|
35
|
+
|
36
|
+
def accessible_params_for controller, dest
|
37
|
+
return if @if_option != nil && !controller.send(@if_option)
|
38
|
+
return if @unless_option != nil && controller.send(@unless_option)
|
39
|
+
|
40
|
+
return if @only_options != nil && !@only_options.include?(controller.action_name)
|
41
|
+
return if @except_options != nil && @except_options.include?(controller.action_name)
|
42
|
+
|
43
|
+
accessible_hash_for controller, @attributes, dest
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def accessible_hash_for controller, attributes, dest
|
49
|
+
attributes.each do |key, value|
|
50
|
+
if value.is_a?(Hash)
|
51
|
+
attrs = dest[key]
|
52
|
+
if attrs.nil?
|
53
|
+
attrs = {}
|
54
|
+
dest[key] = attrs
|
55
|
+
end
|
56
|
+
|
57
|
+
accessible_hash_for controller, value, attrs
|
58
|
+
else
|
59
|
+
dest[key] = value
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# When specifying params to protect, we allow a combination of arrays and hashes much like how
|
65
|
+
# ActiveRecord::Base#find's :include options works. This method normalizes that into just nested hashes,
|
66
|
+
# stringifying the keys and setting all values to nil. This format is easier/faster to work with when
|
67
|
+
# filtering the controller params.
|
68
|
+
# Example...
|
69
|
+
# [:a, {:b => [:c, :d]}]
|
70
|
+
# to
|
71
|
+
# {"a"=>nil, "b"=>{"c"=>nil, "d"=>nil}}
|
72
|
+
def normalize_params(params, params_out = {})
|
73
|
+
if params.instance_of?(Array)
|
74
|
+
params.each{ |param| normalize_params(param, params_out) }
|
75
|
+
elsif params.instance_of?(Hash)
|
76
|
+
params.each do |k, v|
|
77
|
+
k = normalize_key(k)
|
78
|
+
params_out[k] = {}
|
79
|
+
normalize_params(v, params_out[k])
|
80
|
+
end
|
81
|
+
else
|
82
|
+
params_out[normalize_key(params)] = nil
|
83
|
+
end
|
84
|
+
params_out
|
85
|
+
end
|
86
|
+
|
87
|
+
def normalize_key(k)
|
88
|
+
k.to_s
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module ParamAccessible
|
2
|
+
|
3
|
+
class Rules < Array
|
4
|
+
|
5
|
+
def initialize parent = nil
|
6
|
+
content = (parent.to_a if parent) || []
|
7
|
+
super content
|
8
|
+
end
|
9
|
+
|
10
|
+
def detect_inaccessible_params controller
|
11
|
+
accessible_params = {}
|
12
|
+
|
13
|
+
each do |rule|
|
14
|
+
rule.accessible_params_for controller, accessible_params
|
15
|
+
end
|
16
|
+
|
17
|
+
detect_inaccessible_hash controller.params, accessible_params, []
|
18
|
+
end
|
19
|
+
|
20
|
+
def push *args
|
21
|
+
super Rule.new(*args)
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def detect_inaccessible_hash hash, accessible, errors, prefix = nil
|
27
|
+
hash.each do |key, value|
|
28
|
+
if !accessible.has_key?(key)
|
29
|
+
errors.push prefix_for(prefix, key)
|
30
|
+
|
31
|
+
elsif value.is_a?(Hash)
|
32
|
+
nested = accessible[key] || {}
|
33
|
+
detect_inaccessible_hash value, nested, errors, prefix_for(prefix, key)
|
34
|
+
|
35
|
+
elsif value.is_a?(Array)
|
36
|
+
nested = accessible[key] || {}
|
37
|
+
value.each do |v|
|
38
|
+
if v.is_a?(Hash)
|
39
|
+
detect_inaccessible_hash v, nested, errors, prefix_for(prefix, key)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
errors
|
46
|
+
end
|
47
|
+
|
48
|
+
def prefix_for prefix, key
|
49
|
+
if prefix
|
50
|
+
"#{prefix}[#{key}]"
|
51
|
+
else
|
52
|
+
key
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require "param_accessible/version"
|
2
|
+
require "param_accessible/error"
|
3
|
+
require "param_accessible/rule"
|
4
|
+
require "param_accessible/rules"
|
5
|
+
require "param_accessible/not_acceptable_helper"
|
6
|
+
require "param_accessible/controller_ext"
|
7
|
+
|
8
|
+
ActionController::Base.send(:include, ParamAccessible::ControllerExt)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/param_accessible/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Dan Cunning"]
|
6
|
+
gem.email = ["dan@topdan.com"]
|
7
|
+
gem.description = %q{Help secure your controllers from malicious parameters}
|
8
|
+
gem.summary = %q{Help secure your controllers from malicious parameters}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "param_accessible"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = ParamAccessible::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'activesupport', '>= 3.0.0'
|
19
|
+
gem.add_dependency 'actionpack', '>= 3.0.0'
|
20
|
+
gem.add_development_dependency 'rails', '>= 3.0.0'
|
21
|
+
gem.add_development_dependency 'rspec-rails'
|
22
|
+
gem.add_development_dependency "simplecov"
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class ApplicationController < ActionController::Base
|
2
|
+
before_filter :ensure_params_are_accessible, :only => [:create, :update]
|
3
|
+
before_filter :render_nothing
|
4
|
+
|
5
|
+
param_accessible :action, :controller, :format
|
6
|
+
|
7
|
+
def index
|
8
|
+
end
|
9
|
+
|
10
|
+
def show
|
11
|
+
end
|
12
|
+
|
13
|
+
def new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
end
|
18
|
+
|
19
|
+
def edit
|
20
|
+
end
|
21
|
+
|
22
|
+
def update
|
23
|
+
end
|
24
|
+
|
25
|
+
def destroy
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def render_nothing
|
31
|
+
render :nothing => true
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "action_controller/railtie"
|
2
|
+
|
3
|
+
module TestApp
|
4
|
+
class Application < Rails::Application
|
5
|
+
config.root = File.join(File.expand_path('.'), 'spec', 'app_root')
|
6
|
+
config.cache_classes = false
|
7
|
+
config.whiny_nils = true
|
8
|
+
config.secret_token = 'd229e4d22437432705ab3985d4d246'
|
9
|
+
config.session_store :cookie_store, :key => 'rails_session'
|
10
|
+
config.active_support.deprecation = :stderr
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe ExceptController do
|
4
|
+
include RSpec::Rails::ControllerExampleGroup
|
5
|
+
|
6
|
+
it "should limit those attribute to ONLY those actions" do
|
7
|
+
post :update, :foo => "hi"
|
8
|
+
response.code.should == "200"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should disallow unknown attributes from those actions" do
|
12
|
+
begin
|
13
|
+
post :update, :bar => "hi"
|
14
|
+
raise "should fail"
|
15
|
+
rescue ParamAccessible::Error => e
|
16
|
+
e.inaccessible_params.should == %w(bar)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should obey nested attributes" do
|
21
|
+
post :create, :bar => {:baz => 'hi'}
|
22
|
+
response.code.should == "200"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should catch invalid nested attributes for those actions" do
|
26
|
+
begin
|
27
|
+
post :create, :bar => {:foo => 'hi'}
|
28
|
+
raise "should fail"
|
29
|
+
rescue ParamAccessible::Error => e
|
30
|
+
e.inaccessible_params.should == %w(bar[foo])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe IfFalseController do
|
4
|
+
include RSpec::Rails::ControllerExampleGroup
|
5
|
+
|
6
|
+
it "should not allow the attribute" do
|
7
|
+
begin
|
8
|
+
post :create, :foo => "hi"
|
9
|
+
raise "should fail"
|
10
|
+
rescue ParamAccessible::Error => e
|
11
|
+
e.inaccessible_params.should == %w(foo)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should not allow the nested attribute" do
|
16
|
+
begin
|
17
|
+
post :create, :bar => {:baz => "hi"}
|
18
|
+
raise "should fail"
|
19
|
+
rescue ParamAccessible::Error => e
|
20
|
+
e.inaccessible_params.should == %w(bar)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe IfTrueController do
|
4
|
+
include RSpec::Rails::ControllerExampleGroup
|
5
|
+
|
6
|
+
it "should allow valid attributes" do
|
7
|
+
post :create, :foo => "hi"
|
8
|
+
response.code.should == "200"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should disallow invalid attributes" do
|
12
|
+
begin
|
13
|
+
post :create, :nuts => "hi"
|
14
|
+
raise "should fail"
|
15
|
+
rescue ParamAccessible::Error => e
|
16
|
+
e.inaccessible_params.should == %w(nuts)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should allow valid nested attributes" do
|
21
|
+
post :update, :bar => {:baz => 'hi'}
|
22
|
+
response.code.should == "200"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should disallow invalid nested attributes" do
|
26
|
+
begin
|
27
|
+
post :update, :bar => {:foo => 'hi'}
|
28
|
+
raise "should fail"
|
29
|
+
rescue ParamAccessible::Error => e
|
30
|
+
e.inaccessible_params.should == %w(bar[foo])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe MergeController do
|
4
|
+
include RSpec::Rails::ControllerExampleGroup
|
5
|
+
|
6
|
+
it "should allow a combination of all rules following the options" do
|
7
|
+
post :create, :a => 'hi', :b => 'ho', :h => {:b => 'hey', :c => 'fo'}
|
8
|
+
response.code.should == "200"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not allow combinations outside of the options" do
|
12
|
+
begin
|
13
|
+
post :update, :a => 'hi', :b => 'ho', :h => {:b => 'hey', :c => 'fo'}
|
14
|
+
raise "should fail"
|
15
|
+
rescue ParamAccessible::Error => e
|
16
|
+
e.inaccessible_params.should == %w(a h[c])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe NotAcceptableController do
|
4
|
+
include RSpec::Rails::ControllerExampleGroup
|
5
|
+
|
6
|
+
it "should rescue_from HTML and render 406" do
|
7
|
+
post :create, :bar => 'hi'
|
8
|
+
response.code.should == "406"
|
9
|
+
response.body.should include "bar is an invalid parameter"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should rescue_from json and render 406" do
|
13
|
+
post :create, :bar => 'hi', :format => "json"
|
14
|
+
response.code.should == "406"
|
15
|
+
response.body.should == {:error => {:message => "You supplied invalid parameters: bar"}}.to_json
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should rescue_from xml and render 406" do
|
19
|
+
post :create, :bar => 'hi', :format => "json"
|
20
|
+
response.code.should == "406"
|
21
|
+
response.body.should == {:error => {:message => "You supplied invalid parameters: bar"}}.to_json
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should rescue_from js and render 406" do
|
25
|
+
post :create, :bar => 'hi', :format => "js"
|
26
|
+
response.code.should == "406"
|
27
|
+
response.body.should == "// invalid parameters: bar\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe OnlyController do
|
4
|
+
include RSpec::Rails::ControllerExampleGroup
|
5
|
+
|
6
|
+
it "should limit those attribute to ONLY those actions" do
|
7
|
+
post :create, :foo => "hi"
|
8
|
+
response.code.should == "200"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should disallow unknown attributes from those actions" do
|
12
|
+
begin
|
13
|
+
post :create, :bar => "hi"
|
14
|
+
raise "should fail"
|
15
|
+
rescue ParamAccessible::Error => e
|
16
|
+
e.inaccessible_params.should == %w(bar)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should obey nested attributes" do
|
21
|
+
post :update, :bar => {:baz => 'hi'}
|
22
|
+
response.code.should == "200"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should catch invalid nested attributes for those actions" do
|
26
|
+
begin
|
27
|
+
post :update, :bar => {:foo => 'hi'}
|
28
|
+
raise "should fail"
|
29
|
+
rescue ParamAccessible::Error => e
|
30
|
+
e.inaccessible_params.should == %w(bar[foo])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe SimpleController do
|
4
|
+
include RSpec::Rails::ControllerExampleGroup
|
5
|
+
|
6
|
+
it "should not complain if the attributes are missing" do
|
7
|
+
post :create
|
8
|
+
response.code.should == "200"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not complain if a subset of those attributes are given" do
|
12
|
+
post :create, :foo => 'hi'
|
13
|
+
response.code.should == "200"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should not complain if exactly those attributes are given" do
|
17
|
+
post :create, :foo => 'hi', :bar => {:baz => 'hey', :nuts => 'ho'}
|
18
|
+
response.code.should == "200"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should not complain on actions outside of the before_filter" do
|
22
|
+
get :show, :unknown => 'hi'
|
23
|
+
response.code.should == '200'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should complain an unknown attribute is given" do
|
27
|
+
begin
|
28
|
+
post :create, :unknown => 'hi'
|
29
|
+
raise "should fail"
|
30
|
+
rescue ParamAccessible::Error => e
|
31
|
+
e.inaccessible_params.should == %w(unknown)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should complain an unknown nested attribute is given" do
|
36
|
+
begin
|
37
|
+
post :create, :bar => {:unknown => 'hi'}
|
38
|
+
raise "should fail"
|
39
|
+
rescue ParamAccessible::Error => e
|
40
|
+
e.inaccessible_params.should == %w(bar[unknown])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should handle nested arrays" do
|
45
|
+
post :create, :bar => [:baz => 'hi']
|
46
|
+
response.code.should == '200'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should be fine when the ONLY value is a value but not an options hash" do
|
50
|
+
SimpleController.param_accessible :bar => []
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should raise an error when the last value is a hash, but not an options hash" do
|
54
|
+
lambda { SimpleController.param_accessible :foo, :bar => [] }.should raise_error(ArgumentError)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe UnlessFalseController do
|
4
|
+
include RSpec::Rails::ControllerExampleGroup
|
5
|
+
|
6
|
+
it "should allow valid attributes" do
|
7
|
+
post :create, :foo => "hi"
|
8
|
+
response.code.should == "200"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should disallow invalid attributes" do
|
12
|
+
begin
|
13
|
+
post :create, :nuts => "hi"
|
14
|
+
raise "should fail"
|
15
|
+
rescue ParamAccessible::Error => e
|
16
|
+
e.inaccessible_params.should == %w(nuts)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should allow valid nested attributes" do
|
21
|
+
post :update, :bar => {:baz => 'hi'}
|
22
|
+
response.code.should == "200"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should disallow invalid nested attributes" do
|
26
|
+
begin
|
27
|
+
post :update, :bar => {:foo => 'hi'}
|
28
|
+
raise "should fail"
|
29
|
+
rescue ParamAccessible::Error => e
|
30
|
+
e.inaccessible_params.should == %w(bar[foo])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe UnlessTrueController do
|
4
|
+
include RSpec::Rails::ControllerExampleGroup
|
5
|
+
|
6
|
+
it "should not allow the attribute" do
|
7
|
+
begin
|
8
|
+
post :create, :foo => "hi"
|
9
|
+
raise "should fail"
|
10
|
+
rescue ParamAccessible::Error => e
|
11
|
+
e.inaccessible_params.should == %w(foo)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should not allow the nested attribute" do
|
16
|
+
begin
|
17
|
+
post :create, :bar => {:baz => "hi"}
|
18
|
+
raise "should fail"
|
19
|
+
rescue ParamAccessible::Error => e
|
20
|
+
e.inaccessible_params.should == %w(bar)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require "#{File.dirname(__FILE__)}/app_root/config/environment"
|
5
|
+
|
6
|
+
require 'simplecov'
|
7
|
+
SimpleCov.start do
|
8
|
+
add_filter do |src|
|
9
|
+
src.filename =~ /\/spec\//
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'rspec'
|
14
|
+
require 'rspec/rails'
|
15
|
+
require 'param_accessible'
|
metadata
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: param_accessible
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dan Cunning
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: &177970 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *177970
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: actionpack
|
27
|
+
requirement: &177640 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.0.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *177640
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rails
|
38
|
+
requirement: &177410 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 3.0.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *177410
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec-rails
|
49
|
+
requirement: &177110 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *177110
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: simplecov
|
60
|
+
requirement: &176790 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *176790
|
69
|
+
description: Help secure your controllers from malicious parameters
|
70
|
+
email:
|
71
|
+
- dan@topdan.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .travis.yml
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/param_accessible.rb
|
83
|
+
- lib/param_accessible/controller_ext.rb
|
84
|
+
- lib/param_accessible/error.rb
|
85
|
+
- lib/param_accessible/not_acceptable_helper.rb
|
86
|
+
- lib/param_accessible/rule.rb
|
87
|
+
- lib/param_accessible/rules.rb
|
88
|
+
- lib/param_accessible/version.rb
|
89
|
+
- param_accessible.gemspec
|
90
|
+
- spec/app_root/app/controllers/application_controller.rb
|
91
|
+
- spec/app_root/app/controllers/except_controller.rb
|
92
|
+
- spec/app_root/app/controllers/if_false_controller.rb
|
93
|
+
- spec/app_root/app/controllers/if_true_controller.rb
|
94
|
+
- spec/app_root/app/controllers/merge_controller.rb
|
95
|
+
- spec/app_root/app/controllers/not_acceptable_controller.rb
|
96
|
+
- spec/app_root/app/controllers/only_controller.rb
|
97
|
+
- spec/app_root/app/controllers/simple_controller.rb
|
98
|
+
- spec/app_root/app/controllers/unless_false_controller.rb
|
99
|
+
- spec/app_root/app/controllers/unless_true_controller.rb
|
100
|
+
- spec/app_root/config/application.rb
|
101
|
+
- spec/app_root/config/environment.rb
|
102
|
+
- spec/app_root/config/routes.rb
|
103
|
+
- spec/lib/except_spec.rb
|
104
|
+
- spec/lib/if_false_spec.rb
|
105
|
+
- spec/lib/if_true_spec.rb
|
106
|
+
- spec/lib/merge_spec.rb
|
107
|
+
- spec/lib/not_acceptable_helper_spec.rb
|
108
|
+
- spec/lib/only_spec.rb
|
109
|
+
- spec/lib/simple_spec.rb
|
110
|
+
- spec/lib/unless_false_spec.rb
|
111
|
+
- spec/lib/unless_true_spec.rb
|
112
|
+
- spec/spec_helper.rb
|
113
|
+
homepage: ''
|
114
|
+
licenses: []
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
127
|
+
requirements:
|
128
|
+
- - ! '>='
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 1.8.10
|
134
|
+
signing_key:
|
135
|
+
specification_version: 3
|
136
|
+
summary: Help secure your controllers from malicious parameters
|
137
|
+
test_files:
|
138
|
+
- spec/app_root/app/controllers/application_controller.rb
|
139
|
+
- spec/app_root/app/controllers/except_controller.rb
|
140
|
+
- spec/app_root/app/controllers/if_false_controller.rb
|
141
|
+
- spec/app_root/app/controllers/if_true_controller.rb
|
142
|
+
- spec/app_root/app/controllers/merge_controller.rb
|
143
|
+
- spec/app_root/app/controllers/not_acceptable_controller.rb
|
144
|
+
- spec/app_root/app/controllers/only_controller.rb
|
145
|
+
- spec/app_root/app/controllers/simple_controller.rb
|
146
|
+
- spec/app_root/app/controllers/unless_false_controller.rb
|
147
|
+
- spec/app_root/app/controllers/unless_true_controller.rb
|
148
|
+
- spec/app_root/config/application.rb
|
149
|
+
- spec/app_root/config/environment.rb
|
150
|
+
- spec/app_root/config/routes.rb
|
151
|
+
- spec/lib/except_spec.rb
|
152
|
+
- spec/lib/if_false_spec.rb
|
153
|
+
- spec/lib/if_true_spec.rb
|
154
|
+
- spec/lib/merge_spec.rb
|
155
|
+
- spec/lib/not_acceptable_helper_spec.rb
|
156
|
+
- spec/lib/only_spec.rb
|
157
|
+
- spec/lib/simple_spec.rb
|
158
|
+
- spec/lib/unless_false_spec.rb
|
159
|
+
- spec/lib/unless_true_spec.rb
|
160
|
+
- spec/spec_helper.rb
|