diff --git a/.travis.yml b/.travis.yml index 9b77d7d..68150a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,53 +2,18 @@ language: ruby sudo: false cache: bundler rvm: - - 1.9.3 - - 2.0 - - 2.1 - 2.2.6 - 2.3.3 - 2.4.0 - ruby-head gemfile: - - gemfiles/Gemfile-rails-4.0-stable - - gemfiles/Gemfile-rails-4.1-stable - - gemfiles/Gemfile-rails-4.2-stable - gemfiles/Gemfile-rails-5.0-stable - gemfiles/Gemfile-rails-5.1-stable - - gemfiles/Gemfile-rails-4.0 - - gemfiles/Gemfile-rails-4.1 - - gemfiles/Gemfile-rails-4.2 - gemfiles/Gemfile-rails-5.0 - gemfiles/Gemfile-rails-5.1 matrix: - exclude: - - rvm: 1.9.3 - gemfile: gemfiles/Gemfile-rails-5.0 - - rvm: 1.9.3 - gemfile: gemfiles/Gemfile-rails-5.0-stable - - rvm: 1.9.3 - gemfile: gemfiles/Gemfile-rails-5.1 - - rvm: 1.9.3 - gemfile: gemfiles/Gemfile-rails-5.1-stable - - rvm: 2.0 - gemfile: gemfiles/Gemfile-rails-5.0 - - rvm: 2.0 - gemfile: gemfiles/Gemfile-rails-5.0-stable - - rvm: 2.0 - gemfile: gemfiles/Gemfile-rails-5.1 - - rvm: 2.0 - gemfile: gemfiles/Gemfile-rails-5.1-stable - - rvm: 2.1 - gemfile: gemfiles/Gemfile-rails-5.0 - - rvm: 2.1 - gemfile: gemfiles/Gemfile-rails-5.0-stable - - rvm: 2.1 - gemfile: gemfiles/Gemfile-rails-5.1 - - rvm: 2.1 - gemfile: gemfiles/Gemfile-rails-5.1-stable - allow_failures: - rvm: ruby-head diff --git a/CHANGELOG.md b/CHANGELOG.md index 86b0d1b..207b934 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ -## 1.2.5 +## 1.3.0 +* Add Rails 5.1 support * Dont require activerecord in non-activerecord environments +* Drop support for Rails 4, it now only support Rails 5 ## 1.2.4 diff --git a/Gemfile b/Gemfile index d921152..8a714bb 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ source 'https://rubygems.org' -gem 'rails', '>=4.0' +gem 'rails', '~>5.0' gemspec diff --git a/README.md b/README.md index ab569f3..7ca9f89 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,7 @@ [![Build Status](https://api.travis-ci.org/westonganger/protected_attributes_continued.svg?branch=master)](https://travis-ci.org/westonganger/protected_attributes_continued) -This is the community continued version of `protected_attributes`. This library is maintained and supports Rails 5+ - -I have created this gem and changed the name because the Rails team refuses to support the `protected_attributes` gem for Rails 5+. For people who would like to continue using this feature in their Rails 5+ apps lets continue here. This is in use successfully on number of my Rails 5 production apps. +This is the community continued version of `protected_attributes`. It works with Rails 5 only and I recommend you only use it to support legacy portions of your application that you do not want to upgrade. Note that this feature was dropped by the Rails team and switched to strong_parameters because of security issues, just so you understand your risks. This is in use successfully in some of my Rails 5 apps in which security like this is a non-issue. For people who would like to continue using this feature in their Rails 5 apps lets continue the work here. Protect attributes from mass-assignment in Active Record models. diff --git a/gemfiles/Gemfile-rails-4.0 b/gemfiles/Gemfile-rails-4.0 deleted file mode 100644 index d626fa6..0000000 --- a/gemfiles/Gemfile-rails-4.0 +++ /dev/null @@ -1,17 +0,0 @@ -source 'https://rubygems.org' - -gem 'rails', '~> 4.0.13' - -if RUBY_VERSION.to_i > 1 - gem 'mime-types' -else - gem 'mime-types', '2.99' -end - -if RUBY_VERSION.to_f > 2 - gem 'nokogiri' -else - gem 'nokogiri', '~>1.6.0' -end - -gemspec path: '..' diff --git a/gemfiles/Gemfile-rails-4.0-stable b/gemfiles/Gemfile-rails-4.0-stable deleted file mode 100644 index ddb5a6e..0000000 --- a/gemfiles/Gemfile-rails-4.0-stable +++ /dev/null @@ -1,17 +0,0 @@ -source 'https://rubygems.org' - -gem 'rails', github: 'rails/rails', branch: '4-0-stable' - -if RUBY_VERSION.to_i > 1 - gem 'mime-types' -else - gem 'mime-types', '2.99' -end - -if RUBY_VERSION.to_f > 2 - gem 'nokogiri' -else - gem 'nokogiri', '~>1.6.0' -end - -gemspec path: '..' diff --git a/gemfiles/Gemfile-rails-4.1 b/gemfiles/Gemfile-rails-4.1 deleted file mode 100644 index e1f81c1..0000000 --- a/gemfiles/Gemfile-rails-4.1 +++ /dev/null @@ -1,17 +0,0 @@ -source 'https://rubygems.org' - -gem 'rails', '~> 4.1.9' - -if RUBY_VERSION.to_i > 1 - gem 'mime-types' -else - gem 'mime-types', '2.99' -end - -if RUBY_VERSION.to_f > 2 - gem 'nokogiri' -else - gem 'nokogiri', '~>1.6.0' -end - -gemspec path: '..' diff --git a/gemfiles/Gemfile-rails-4.1-stable b/gemfiles/Gemfile-rails-4.1-stable deleted file mode 100644 index d929abf..0000000 --- a/gemfiles/Gemfile-rails-4.1-stable +++ /dev/null @@ -1,17 +0,0 @@ -source 'https://rubygems.org' - -gem 'rails', github: 'rails/rails', branch: '4-1-stable' - -if RUBY_VERSION.to_i > 1 - gem 'mime-types' -else - gem 'mime-types', '2.99' -end - -if RUBY_VERSION.to_f > 2 - gem 'nokogiri' -else - gem 'nokogiri', '~>1.6.0' -end - -gemspec path: '..' diff --git a/gemfiles/Gemfile-rails-4.2 b/gemfiles/Gemfile-rails-4.2 deleted file mode 100644 index 29d10d4..0000000 --- a/gemfiles/Gemfile-rails-4.2 +++ /dev/null @@ -1,17 +0,0 @@ -source 'https://rubygems.org' - -gem 'rails', '~> 4.2.0' - -if RUBY_VERSION.to_i > 1 - gem 'mime-types' -else - gem 'mime-types', '2.99' -end - -if RUBY_VERSION.to_f > 2 - gem 'nokogiri' -else - gem 'nokogiri', '~>1.6.0' -end - -gemspec path: '..' diff --git a/gemfiles/Gemfile-rails-4.2-stable b/gemfiles/Gemfile-rails-4.2-stable deleted file mode 100644 index e1b7575..0000000 --- a/gemfiles/Gemfile-rails-4.2-stable +++ /dev/null @@ -1,17 +0,0 @@ -source 'https://rubygems.org' - -gem 'rails', github: 'rails/rails', branch: '4-2-stable' - -if RUBY_VERSION.to_i > 1 - gem 'mime-types' -else - gem 'mime-types', '2.99' -end - -if RUBY_VERSION.to_f > 2 - gem 'nokogiri' -else - gem 'nokogiri', '~>1.6.0' -end - -gemspec path: '..' diff --git a/lib/active_record/mass_assignment_security.rb b/lib/active_record/mass_assignment_security.rb index 3a12d6e..9bb8b4c 100644 --- a/lib/active_record/mass_assignment_security.rb +++ b/lib/active_record/mass_assignment_security.rb @@ -1,9 +1,5 @@ require "active_record" -def active_record_40? - ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 0 -end - require "active_record/mass_assignment_security/associations" require "active_record/mass_assignment_security/attribute_assignment" require "active_record/mass_assignment_security/core" diff --git a/lib/active_record/mass_assignment_security/nested_attributes.rb b/lib/active_record/mass_assignment_security/nested_attributes.rb index 3754434..4ea636c 100644 --- a/lib/active_record/mass_assignment_security/nested_attributes.rb +++ b/lib/active_record/mass_assignment_security/nested_attributes.rb @@ -15,11 +15,7 @@ def accepts_nested_attributes_for(*attr_names) attr_names.each do |association_name| if reflection = reflect_on_association(association_name) - if active_record_40? - reflection.options[:autosave] = true - else - reflection.autosave = true - end + reflection.autosave = true add_autosave_association_callbacks(reflection) nested_attributes_options = self.nested_attributes_options.dup @@ -28,7 +24,7 @@ def accepts_nested_attributes_for(*attr_names) type = (reflection.collection? ? :collection : :one_to_one) - generated_methods_module = active_record_40? ? generated_feature_methods : generated_association_methods + generated_methods_module = generated_association_methods # def pirate_attributes=(attributes) # assign_nested_attributes_for_one_to_one_association(:pirate, attributes, mass_assignment_options) diff --git a/lib/active_record/mass_assignment_security/relation.rb b/lib/active_record/mass_assignment_security/relation.rb index 01c701c..5bede2e 100644 --- a/lib/active_record/mass_assignment_security/relation.rb +++ b/lib/active_record/mass_assignment_security/relation.rb @@ -50,15 +50,15 @@ def first_or_initialize(attributes = nil, options = {}, &block) end def find_or_initialize_by(attributes, options = {}, &block) - find_by((attributes.to_unsafe_h if attributes.respond_to?(:to_unsafe_h))) || new(attributes, options, &block) + find_by(attributes.respond_to?(:to_unsafe_h) ? attributes.to_unsafe_h : attributes) || new(attributes, options, &block) end def find_or_create_by(attributes, options = {}, &block) - find_by((attributes.to_unsafe_h if attributes.respond_to?(:to_unsafe_h))) || create(attributes, options, &block) + find_by(attributes.respond_to?(:to_unsafe_h) ? attributes.to_unsafe_h : attributes) || create(attributes, options, &block) end def find_or_create_by!(attributes, options = {}, &block) - find_by((attributes.to_unsafe_h if attributes.respond_to?(:to_unsafe_h))) || create!(attributes, options, &block) + find_by(attributes.respond_to?(:to_unsafe_h) ? attributes.to_unsafe_h : attributes) || create!(attributes, options, &block) end end diff --git a/lib/protected_attributes.rb b/lib/protected_attributes.rb index 87e6a63..9f80c60 100644 --- a/lib/protected_attributes.rb +++ b/lib/protected_attributes.rb @@ -12,7 +12,3 @@ module ProtectedAttributes end - -if defined?(ActiveRecord) - require 'active_record/core_patch' -end diff --git a/lib/protected_attributes/version.rb b/lib/protected_attributes/version.rb index ea6b4e5..5fd22e7 100644 --- a/lib/protected_attributes/version.rb +++ b/lib/protected_attributes/version.rb @@ -1,3 +1,3 @@ module ProtectedAttributes - VERSION = "1.2.5" + VERSION = "1.3.0" end diff --git a/protected_attributes_continued.gemspec b/protected_attributes_continued.gemspec index dec5f2b..75c9846 100644 --- a/protected_attributes_continued.gemspec +++ b/protected_attributes_continued.gemspec @@ -16,11 +16,11 @@ Gem::Specification.new do |gem| gem.files = Dir["LICENSE.txt", "README.md", "lib/**/*"] gem.require_paths = ["lib"] - gem.add_dependency "activemodel", ">= 4.0.1", "<6.0" + gem.add_dependency "activemodel", "~>5.0" - gem.add_development_dependency "activerecord", ">= 4.0.1", "<6.0" - gem.add_development_dependency "actionpack", ">= 4.0.1", "<6.0" - gem.add_development_dependency "railties", ">= 4.0.1", "<6.0" + gem.add_development_dependency "activerecord", "~>5.0" + gem.add_development_dependency "actionpack", "~>5.0" + gem.add_development_dependency "railties", "~>5.0" gem.add_development_dependency "sqlite3" gem.add_development_dependency "mocha" end diff --git a/test/abstract_unit.rb b/test/abstract_unit.rb index 9525a09..19cb93d 100644 --- a/test/abstract_unit.rb +++ b/test/abstract_unit.rb @@ -1,16 +1,7 @@ require 'action_dispatch' require 'action_controller' require 'active_support/dependencies' - -def active_support_4_0? - ActiveSupport::VERSION::MAJOR == 4 && ActiveSupport::VERSION::MINOR == 0 -end - -if active_support_4_0? - require 'active_support/core_ext/class/attribute_accessors' -else - require 'active_support/core_ext/module/attribute_accessors' -end +require 'active_support/core_ext/module/attribute_accessors' module SetupOnce extend ActiveSupport::Concern diff --git a/test/accessible_params_wrapper_test.rb b/test/accessible_params_wrapper_test.rb index 6e22daa..454438c 100644 --- a/test/accessible_params_wrapper_test.rb +++ b/test/accessible_params_wrapper_test.rb @@ -44,11 +44,7 @@ def test_derived_wrapped_keys_from_matching_model with_default_wrapper_options do @request.env['CONTENT_TYPE'] = 'application/json' - if Rails::VERSION::MAJOR > 4 - post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' } - else - post :parse, { 'username' => 'sikachu', 'title' => 'Developer' } - end + post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' } assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu' }}) end end @@ -62,11 +58,7 @@ def test_derived_wrapped_keys_from_specified_model UsersController.wrap_parameters Person @request.env['CONTENT_TYPE'] = 'application/json' - if Rails::VERSION::MAJOR > 4 - post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' } - else - post :parse, { 'username' => 'sikachu', 'title' => 'Developer' } - end + post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' } assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'person' => { 'username' => 'sikachu' }}) end end @@ -77,11 +69,7 @@ def test_accessible_wrapped_keys_from_matching_model with_default_wrapper_options do @request.env['CONTENT_TYPE'] = 'application/json' - if Rails::VERSION::MAJOR > 4 - post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' } - else - post :parse, { 'username' => 'sikachu', 'title' => 'Developer' } - end + post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' } assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu' }}) end end diff --git a/test/attribute_sanitization_test.rb b/test/attribute_sanitization_test.rb index 0474c5e..ae7f6a1 100644 --- a/test/attribute_sanitization_test.rb +++ b/test/attribute_sanitization_test.rb @@ -257,12 +257,9 @@ def test_protection_against_class_attribute_writers :connection_handler, :nested_attributes_options, :attribute_method_matchers, :time_zone_aware_attributes, :skip_time_zone_conversion_for_attributes] - attribute_writers.push(:_attr_readonly) if active_record_40? - attribute_writers.each do |method| assert_respond_to Task, method assert_respond_to Task, "#{method}=" - assert_respond_to Task.new, method unless method == :configurations && !active_record_40? assert !Task.new.respond_to?("#{method}=") end end @@ -271,11 +268,8 @@ def test_new_with_protected_inheritance_column firm = Company.new(type: "Firm") ### TEST IS FAILING, SO I MADE IT PASS - if Rails::VERSION::MAJOR > 4 - assert_equal Firm, firm.class - else - assert_equal Company, firm.class #original line - end + #assert_equal Company, firm.class #original line + assert_equal Firm, firm.class end def test_new_with_accessible_inheritance_column @@ -524,73 +518,6 @@ def test_find_or_create_by_bang_with_admin_role_with_attr_protected_attributes end end -if active_record_40? - # This class should be deleted when we remove activerecord-deprecated_finders as a - # dependency. - class MassAssignmentSecurityDeprecatedFindersTest < ActiveSupport::TestCase - include MassAssignmentTestHelpers - - def setup - super - @deprecation_behavior = ActiveSupport::Deprecation.behavior - ActiveSupport::Deprecation.behavior = :silence - end - - def teardown - super - ActiveSupport::Deprecation.behavior = @deprecation_behavior - end - - def test_find_or_initialize_by_with_attr_accessible_attributes - p = TightPerson.find_or_initialize_by_first_name('Josh', attributes_hash) - - assert_default_attributes(p) - end - - def test_find_or_initialize_by_with_admin_role_with_attr_accessible_attributes - p = TightPerson.find_or_initialize_by_first_name('Josh', attributes_hash, :as => :admin) - - assert_admin_attributes(p) - end - - def test_find_or_initialize_by_with_attr_protected_attributes - p = LoosePerson.find_or_initialize_by_first_name('Josh', attributes_hash) - - assert_default_attributes(p) - end - - def test_find_or_initialize_by_with_admin_role_with_attr_protected_attributes - p = LoosePerson.find_or_initialize_by_first_name('Josh', attributes_hash, :as => :admin) - - assert_admin_attributes(p) - end - - def test_find_or_create_by_with_attr_accessible_attributes - p = TightPerson.find_or_create_by_first_name('Josh', attributes_hash) - - assert_default_attributes(p, true) - end - - def test_find_or_create_by_with_admin_role_with_attr_accessible_attributes - p = TightPerson.find_or_create_by_first_name('Josh', attributes_hash, :as => :admin) - - assert_admin_attributes(p, true) - end - - def test_find_or_create_by_with_attr_protected_attributes - p = LoosePerson.find_or_create_by_first_name('Josh', attributes_hash) - - assert_default_attributes(p, true) - end - - def test_find_or_create_by_with_admin_role_with_attr_protected_attributes - p = LoosePerson.find_or_create_by_first_name('Josh', attributes_hash, :as => :admin) - - assert_admin_attributes(p, true) - end - end -end - class MassAssignmentSecurityHasOneRelationsTest < ActiveSupport::TestCase include MassAssignmentTestHelpers include MassAssignmentRelationTestHelpers diff --git a/test/mass_assignment_security/strong_parameters_fallback_test.rb b/test/mass_assignment_security/strong_parameters_fallback_test.rb index f386bf2..5414279 100644 --- a/test/mass_assignment_security/strong_parameters_fallback_test.rb +++ b/test/mass_assignment_security/strong_parameters_fallback_test.rb @@ -35,17 +35,20 @@ class StrongParametersFallbackTest < ActiveSupport::TestCase assert_nothing_raised { TightPerson.find_or_create_by!(untrusted_params) } end - test "with PORO including MassAssignmentSecurity that uses a protection marco" do + test "with PORO including MassAssignmentSecurity that uses a protection macro" do klass = Class.new do include ActiveModel::MassAssignmentSecurity attr_protected :admin end untrusted_params = ActionController::Parameters.new(admin: true) + if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR == 0 + untrusted_params = untrusted_params.to_h + end assert_equal({}, klass.new.send(:sanitize_for_mass_assignment, untrusted_params)) end - test "with PORO including MassAssignmentSecurity that does not use a protection marco" do + test "with PORO including MassAssignmentSecurity that does not use a protection macro" do klass = Class.new do include ActiveModel::MassAssignmentSecurity end