diff options
-rw-r--r-- | actionpack/CHANGELOG.md | 6 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/strong_parameters.rb | 25 | ||||
-rw-r--r-- | actionpack/lib/action_controller/railtie.rb | 4 | ||||
-rw-r--r-- | actionpack/test/controller/parameters/always_permitted_parameters_test.rb | 29 | ||||
-rw-r--r-- | activemodel/lib/active_model/dirty.rb | 8 | ||||
-rw-r--r-- | activerecord/CHANGELOG.md | 6 | ||||
-rw-r--r-- | activerecord/test/cases/associations/belongs_to_associations_test.rb | 31 | ||||
-rw-r--r-- | activerecord/test/schema/schema.rb | 1 | ||||
-rw-r--r-- | activesupport/CHANGELOG.md | 7 | ||||
-rw-r--r-- | activesupport/lib/active_support/cache.rb | 21 | ||||
-rw-r--r-- | activesupport/lib/active_support/callbacks.rb | 3 | ||||
-rw-r--r-- | guides/source/configuring.md | 2 | ||||
-rw-r--r-- | railties/test/application/configuration_test.rb | 38 |
13 files changed, 130 insertions, 51 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index c38b31903b..cc72aa3081 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,9 @@ +* Add `config.action_controller.always_permitted_parameters` to configure which + parameters are permitted globally. The default value of this configuration is + `['controller', 'action']`. + + *Gary S. Weaver*, *Rafael Chacon* + * Fix env['PATH_INFO'] missing leading slash when a rack app mounted at '/'. Fixes #15511. diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index b70962cf44..bc27ecaa20 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -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' @@ -39,7 +40,7 @@ module ActionController # == Action Controller \Parameters # # Allows to choose which attributes should be whitelisted for mass updating - # and thus prevent accidentally exposing that which shouldn’t 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. @@ -101,9 +102,23 @@ module ActionController 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 @@ -389,7 +404,7 @@ module ActionController end def unpermitted_keys(params) - self.keys - params.keys - NEVER_UNPERMITTED_PARAMS + self.keys - params.keys - self.always_permitted_parameters end # diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index a2fc814221..28b20052b5 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -23,6 +23,10 @@ module ActionController 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 diff --git a/actionpack/test/controller/parameters/always_permitted_parameters_test.rb b/actionpack/test/controller/parameters/always_permitted_parameters_test.rb new file mode 100644 index 0000000000..059f310d49 --- /dev/null +++ b/actionpack/test/controller/parameters/always_permitted_parameters_test.rb @@ -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 diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index 98ffffeb10..f57588b96d 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -84,9 +84,11 @@ module ActiveModel # person.changed # => ["name"] # person.changes # => {"name" => ["Bill", "Bob"]} # - # If an attribute is modified in-place then make use of <tt>[attribute_name]_will_change!</tt> - # to mark that the attribute is changing. Otherwise ActiveModel can't track - # changes to in-place attributes. + # If an attribute is modified in-place then make use of + # +[attribute_name]_will_change!+ to mark that the attribute is changing. + # Otherwise Active Model can't track changes to in-place attributes. Note + # that Active Record can detect in-place modifications automatically. You do + # not need to call +[attribute_name]_will_change!+ on Active Record models. # # person.name_will_change! # person.name_change # => ["Bill", "Bill"] diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index b17ca22544..7e40373163 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,7 +1,7 @@ -* PostgreSQL renaming table doesn't attempt to rename non existent sequences - +* PostgreSQL renaming table doesn't attempt to rename non existent sequences. + *Abdelkader Boudih* - + * Move 'dependent: :destroy' handling for 'belongs_to' from 'before_destroy' to 'after_destroy' callback chain diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 65b6068df4..4238681905 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -936,38 +936,13 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end end +unless current_adapter?(:MysqlAdapter, :Mysql2Adapter) class BelongsToWithForeignKeyTest < ActiveRecord::TestCase - def setup - ActiveRecord::Schema.define do - drop_table :authors, if_exists: true - drop_table :author_addresses, if_exists: true - - create_table :author_addresses do |t| - end - - exec_query <<-eos - create table authors( - id int, - author_address_id int, - name varchar(255), - PRIMARY KEY (id), - FOREIGN KEY (author_address_id) REFERENCES author_addresses(id) - ); - eos - end - end - - def teardown - ActiveRecord::Schema.define do - drop_table :authors, if_exists: true - drop_table :author_addresses, if_exists: true - end - end - def test_destroy_linked_models address = AuthorAddress.create! - author = Author.create! id: 1, name: "Author", author_address_id: address.id + author = Author.create! name: "Author", author_address_id: address.id author.destroy! end end +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 03d33c151a..be134fde11 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -83,6 +83,7 @@ ActiveRecord::Schema.define do create_table :author_addresses, force: true do |t| end + add_foreign_key :authors, :author_address create_table :author_favorites, force: true do |t| t.column :author_id, :integer diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index f8e8544e72..8eccc2de90 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,10 @@ +* Always instrument `ActiveSupport::Cache`. + + Since `ActiveSupport::Notifications` only instrument items when there + are subscriber we don't need to disable instrumentation. + + *Peter Wagenet* + * Make the `apply_inflections` method case-insensitive when checking whether a word is uncountable or not. diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index a627fa8651..a3f672d4cc 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -8,6 +8,7 @@ require 'active_support/core_ext/numeric/bytes' require 'active_support/core_ext/numeric/time' require 'active_support/core_ext/object/to_param' require 'active_support/core_ext/string/inflections' +require 'active_support/deprecation' module ActiveSupport # See ActiveSupport::Cache::Store for documentation. @@ -178,14 +179,16 @@ module ActiveSupport @silence = previous_silence end - # Set to +true+ if cache stores should be instrumented. - # Default is +false+. + # :deprecated: def self.instrument=(boolean) - Thread.current[:instrument_cache_store] = boolean + ActiveSupport::Deprecation.warn "ActiveSupport::Cache.instrument= is deprecated and will be removed in Rails 5. Instrumentation is now always on so you can safely stop using it." + true end + # :deprecated: def self.instrument - Thread.current[:instrument_cache_store] || false + ActiveSupport::Deprecation.warn "ActiveSupport::Cache.instrument is deprecated and will be removed in Rails 5. Instrumentation is now always on so you can safely stop using it." + true end # Fetches data from the cache, using the given key. If there is data in @@ -539,13 +542,9 @@ module ActiveSupport def instrument(operation, key, options = nil) log(operation, key, options) - if self.class.instrument - payload = { :key => key } - payload.merge!(options) if options.is_a?(Hash) - ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) } - else - yield(nil) - end + payload = { :key => key } + payload.merge!(options) if options.is_a?(Hash) + ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) } end def log(operation, key, options = nil) diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 06505bddf9..e5dbe214b4 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -71,7 +71,8 @@ module ActiveSupport # order. # # If the callback chain was halted, returns +false+. Otherwise returns the - # result of the block, or +true+ if no block is given. + # result of the block, nil if no callbacks have been set, or +true+ + # if callbacks have been set but no block is given. # # run_callbacks :save do # save diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 3d6b2f79c6..f74fbaa7c3 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -330,6 +330,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. diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 207a0c7e86..17b406f6a3 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -714,6 +714,44 @@ module ApplicationTests 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" |