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.
Files changed (38) hide show
  1. data/.gitignore +19 -0
  2. data/.travis.yml +4 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +93 -0
  6. data/Rakefile +7 -0
  7. data/lib/param_accessible/controller_ext.rb +41 -0
  8. data/lib/param_accessible/error.rb +19 -0
  9. data/lib/param_accessible/not_acceptable_helper.rb +23 -0
  10. data/lib/param_accessible/rule.rb +93 -0
  11. data/lib/param_accessible/rules.rb +58 -0
  12. data/lib/param_accessible/version.rb +3 -0
  13. data/lib/param_accessible.rb +8 -0
  14. data/param_accessible.gemspec +23 -0
  15. data/spec/app_root/app/controllers/application_controller.rb +34 -0
  16. data/spec/app_root/app/controllers/except_controller.rb +6 -0
  17. data/spec/app_root/app/controllers/if_false_controller.rb +12 -0
  18. data/spec/app_root/app/controllers/if_true_controller.rb +12 -0
  19. data/spec/app_root/app/controllers/merge_controller.rb +6 -0
  20. data/spec/app_root/app/controllers/not_acceptable_controller.rb +6 -0
  21. data/spec/app_root/app/controllers/only_controller.rb +6 -0
  22. data/spec/app_root/app/controllers/simple_controller.rb +4 -0
  23. data/spec/app_root/app/controllers/unless_false_controller.rb +12 -0
  24. data/spec/app_root/app/controllers/unless_true_controller.rb +12 -0
  25. data/spec/app_root/config/application.rb +12 -0
  26. data/spec/app_root/config/environment.rb +5 -0
  27. data/spec/app_root/config/routes.rb +3 -0
  28. data/spec/lib/except_spec.rb +34 -0
  29. data/spec/lib/if_false_spec.rb +24 -0
  30. data/spec/lib/if_true_spec.rb +34 -0
  31. data/spec/lib/merge_spec.rb +20 -0
  32. data/spec/lib/not_acceptable_helper_spec.rb +30 -0
  33. data/spec/lib/only_spec.rb +34 -0
  34. data/spec/lib/simple_spec.rb +57 -0
  35. data/spec/lib/unless_false_spec.rb +34 -0
  36. data/spec/lib/unless_true_spec.rb +24 -0
  37. data/spec/spec_helper.rb +15 -0
  38. metadata +160 -0
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .rspec
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ spec/app_root/log
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in param_accessible.gemspec
4
+ gemspec
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
+ [![Build Status](https://secure.travis-ci.org/topdan/param_accessible.png)](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,7 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ task :test => :spec
7
+ task :default => :test
@@ -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,3 @@
1
+ module ParamAccessible
2
+ VERSION = "0.0.1"
3
+ 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,6 @@
1
+ class ExceptController < ApplicationController
2
+
3
+ param_accessible :foo, :except => :create
4
+ param_accessible({:bar => [:baz]}, :except => :update)
5
+
6
+ end
@@ -0,0 +1,12 @@
1
+ class IfFalseController < ApplicationController
2
+
3
+ param_accessible :foo, :if => :admin?
4
+ param_accessible({:bar => [:baz]}, :if => :admin?)
5
+
6
+ protected
7
+
8
+ def admin?
9
+ false
10
+ end
11
+
12
+ end
@@ -0,0 +1,12 @@
1
+ class IfTrueController < ApplicationController
2
+
3
+ param_accessible :foo, :if => :admin?
4
+ param_accessible({:bar => [:baz]}, :if => :admin?)
5
+
6
+ protected
7
+
8
+ def admin?
9
+ true
10
+ end
11
+
12
+ end
@@ -0,0 +1,6 @@
1
+ class MergeController < ApplicationController
2
+ param_accessible :a, :only => :create
3
+ param_accessible :b
4
+ param_accessible({ :h => :c}, :except => :update)
5
+ param_accessible :h => :b
6
+ end
@@ -0,0 +1,6 @@
1
+ class NotAcceptableController < ApplicationController
2
+ include ParamAccessible::NotAcceptableHelper
3
+
4
+ param_accessible :foo
5
+
6
+ end
@@ -0,0 +1,6 @@
1
+ class OnlyController < ApplicationController
2
+
3
+ param_accessible :foo, :only => :create
4
+ param_accessible({:bar => [:baz]}, :only => :update)
5
+
6
+ end
@@ -0,0 +1,4 @@
1
+ class SimpleController < ApplicationController
2
+ # TODO move action and controller up a level
3
+ param_accessible [:foo, {:bar => [:baz, :nuts]}]
4
+ end
@@ -0,0 +1,12 @@
1
+ class UnlessFalseController < ApplicationController
2
+
3
+ param_accessible :foo, :unless => :admin?
4
+ param_accessible({:bar => [:baz]}, :unless => :admin?)
5
+
6
+ protected
7
+
8
+ def admin?
9
+ false
10
+ end
11
+
12
+ end
@@ -0,0 +1,12 @@
1
+ class UnlessTrueController < ApplicationController
2
+
3
+ param_accessible :foo, :unless => :admin?
4
+ param_accessible({:bar => [:baz]}, :unless => :admin?)
5
+
6
+ protected
7
+
8
+ def admin?
9
+ true
10
+ end
11
+
12
+ 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,5 @@
1
+ # Load the rails application
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the rails application
5
+ TestApp::Application.initialize!
@@ -0,0 +1,3 @@
1
+ TestApp::Application.routes.draw do
2
+ match ':controller(/:action(/:id(.:format)))'
3
+ 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
@@ -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