Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add always permitted parameters as a configurable option. #15933

Merged
merged 2 commits into from
Jun 27, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions actionpack/lib/action_controller/metal/strong_parameters.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/array/wrap'
require 'active_support/deprecation'
require 'active_support/rescuable'
require 'action_dispatch/http/upload'
require 'stringio'
Expand Down Expand Up @@ -38,7 +39,7 @@ def initialize(params) # :nodoc:
# == Action Controller \Parameters
#
# Allows to choose which attributes should be whitelisted for mass updating
# and thus prevent accidentally exposing that which shouldnt be exposed.
# and thus prevent accidentally exposing that which shouldn't be exposed.
# Provides two methods for this purpose: #require and #permit. The former is
# used to mark parameters as required. The latter is used to set the parameter
# as permitted and limit which attributes should be allowed for mass updating.
Expand Down Expand Up @@ -100,9 +101,23 @@ class Parameters < ActiveSupport::HashWithIndifferentAccess
cattr_accessor :permit_all_parameters, instance_accessor: false
cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false

# Never raise an UnpermittedParameters exception because of these params
# are present. They are added by Rails and it's of no concern.
NEVER_UNPERMITTED_PARAMS = %w( controller action )
# By default, never raise an UnpermittedParameters exception if these
# params are present. The default includes both 'controller' and 'action'
# because they are added by Rails and should be of no concern. One way
# to change these is to specify `always_permitted_parameters` in your
# config. For instance:
#
# config.always_permitted_parameters = %w( controller action format )
cattr_accessor :always_permitted_parameters
self.always_permitted_parameters = %w( controller action )

def self.const_missing(const_name)
super unless const_name == :NEVER_UNPERMITTED_PARAMS
ActiveSupport::Deprecation.warn "`ActionController::Parameters::NEVER_UNPERMITTED_PARAMS`"\
" has been deprecated. Use "\
"`ActionController::Parameters.always_permitted_parameters` instead."
self.always_permitted_parameters
end

# Returns a new instance of <tt>ActionController::Parameters</tt>.
# Also, sets the +permitted+ attribute to the default value of
Expand Down Expand Up @@ -361,7 +376,7 @@ def unpermitted_parameters!(params)
end

def unpermitted_keys(params)
self.keys - params.keys - NEVER_UNPERMITTED_PARAMS
self.keys - params.keys - self.always_permitted_parameters
end

#
Expand Down
4 changes: 4 additions & 0 deletions actionpack/lib/action_controller/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class Railtie < Rails::Railtie #:nodoc:
options = app.config.action_controller

ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
if app.config.action_controller[:always_permitted_parameters]
ActionController::Parameters.always_permitted_parameters =
app.config.action_controller.delete(:always_permitted_parameters)
end
ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
(Rails.env.test? || Rails.env.development?) ? :log : false
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require 'abstract_unit'
require 'action_controller/metal/strong_parameters'

class AlwaysPermittedParametersTest < ActiveSupport::TestCase
def setup
ActionController::Parameters.action_on_unpermitted_parameters = :raise
ActionController::Parameters.always_permitted_parameters = %w( controller action format )
end

def teardown
ActionController::Parameters.action_on_unpermitted_parameters = false
ActionController::Parameters.always_permitted_parameters = %w( controller action )
end

test "shows deprecations warning on NEVER_UNPERMITTED_PARAMS" do
assert_deprecated do
ActionController::Parameters::NEVER_UNPERMITTED_PARAMS
end
end

test "permits parameters that are whitelisted" do
params = ActionController::Parameters.new({
book: { pages: 65 },
format: "json"
})
permitted = params.permit book: [:pages]
assert permitted.permitted?
end
end
4 changes: 3 additions & 1 deletion guides/source/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ The schema dumper adds one additional configuration option:

* `config.action_controller.action_on_unpermitted_parameters` enables logging or raising an exception if parameters that are not explicitly permitted are found. Set to `:log` or `:raise` to enable. The default value is `:log` in development and test environments, and `false` in all other environments.

* `config.action_controller.always_permitted_parameters` sets a list of whitelisted parameters that are permitted by default. The default values are `['controller', 'action']`.

### Configuring Action Dispatch

* `config.action_dispatch.session_store` sets the name of the store for session data. The default is `:cookie_store`; other valid options include `:active_record_store`, `:mem_cache_store` or the name of your own custom class.
Expand Down Expand Up @@ -773,7 +775,7 @@ error similar to given below will be thrown.
ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5 seconds. The max pool size is currently 5; consider increasing it:
```

If you get the above error, you might want to increase the size of connection
If you get the above error, you might want to increase the size of connection
pool by incrementing the `pool` option in `database.yml`

NOTE. If you have enabled `Rails.threadsafe!` mode then there could be a chance that several threads may be accessing multiple connections simultaneously. So depending on your current request load, you could very well have multiple threads contending for a limited amount of connections.
38 changes: 38 additions & 0 deletions railties/test/application/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,44 @@ def create
assert_match "We're sorry, but something went wrong", last_response.body
end

test "config.action_controller.always_permitted_parameters are: controller, action by default" do
require "#{app_path}/config/environment"
assert_equal %w(controller action), ActionController::Parameters.always_permitted_parameters
end

test "config.action_controller.always_permitted_parameters = ['controller', 'action', 'format']" do
add_to_config <<-RUBY
config.action_controller.always_permitted_parameters = %w( controller action format )
RUBY
require "#{app_path}/config/environment"
assert_equal %w( controller action format ), ActionController::Parameters.always_permitted_parameters
end

test "config.action_controller.always_permitted_parameters = ['controller','action','format'] does not raise exeception" do
app_file 'app/controllers/posts_controller.rb', <<-RUBY
class PostsController < ActionController::Base
def create
render text: params.permit(post: [:title])
end
end
RUBY

add_to_config <<-RUBY
routes.prepend do
resources :posts
end
config.action_controller.always_permitted_parameters = %w( controller action format )
config.action_controller.action_on_unpermitted_parameters = :raise
RUBY

require "#{app_path}/config/environment"

assert_equal :raise, ActionController::Parameters.action_on_unpermitted_parameters

post "/posts", {post: {"title" =>"zomg"}, format: "json"}
assert_equal 200, last_response.status
end

test "config.action_controller.action_on_unpermitted_parameters is :log by default on development" do
ENV["RAILS_ENV"] = "development"

Expand Down