From c1008f43592912b309e7e6d2d5685d4e7d226223 Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Tue, 22 Oct 2013 18:55:30 -0400 Subject: [PATCH] Fixes for postgresql inet columns in Rails 4. They're backed by an IPAddr class now, which breaks sql parameter marker support, and automatically sets the attribute to nil when trying to assign an invalid ip address. --- Gemfile_rails4.lock | 4 ++-- app/models/screened_ip_address.rb | 2 +- app/services/staff_action_logger.rb | 2 +- lib/validators/ip_address_format_validator.rb | 12 ++++++++++-- .../validators/ip_address_format_validator_spec.rb | 8 +++++++- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Gemfile_rails4.lock b/Gemfile_rails4.lock index 62abe0984b9..15c1374f4a5 100644 --- a/Gemfile_rails4.lock +++ b/Gemfile_rails4.lock @@ -23,7 +23,7 @@ GIT GIT remote: git://github.com/rails/rails.git - revision: 0785008a64f4af8d09379683303d49d160cd444d + revision: 81432139a9ca5bf90f08273d88e6e4f583c4189b branch: 4-0-stable specs: actionmailer (4.0.0) @@ -434,7 +434,7 @@ GEM multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.0.0) + sprockets-rails (2.0.1) actionpack (>= 3.0) activesupport (>= 3.0) sprockets (~> 2.8) diff --git a/app/models/screened_ip_address.rb b/app/models/screened_ip_address.rb index 009e0efae4d..6822e45c32d 100644 --- a/app/models/screened_ip_address.rb +++ b/app/models/screened_ip_address.rb @@ -21,7 +21,7 @@ class ScreenedIpAddress < ActiveRecord::Base # # http://www.postgresql.org/docs/9.1/static/datatype-net-types.html # http://www.postgresql.org/docs/9.1/static/functions-net.html - where('? <<= ip_address', ip_address).first + where("'#{ip_address.to_s}' <<= ip_address").first end def self.should_block?(ip_address) diff --git a/app/services/staff_action_logger.rb b/app/services/staff_action_logger.rb index f291ae20efc..51a11d417a5 100644 --- a/app/services/staff_action_logger.rb +++ b/app/services/staff_action_logger.rb @@ -11,7 +11,7 @@ class StaffActionLogger action: UserHistory.actions[:delete_user], target_user_id: deleted_user.id, email: deleted_user.email, - ip_address: deleted_user.ip_address, + ip_address: deleted_user.ip_address.to_s, details: [:id, :username, :name, :created_at, :trust_level, :last_seen_at, :last_emailed_at].map { |x| "#{x}: #{deleted_user.send(x)}" }.join(', ') })) end diff --git a/lib/validators/ip_address_format_validator.rb b/lib/validators/ip_address_format_validator.rb index a08e2901444..460eda40f61 100644 --- a/lib/validators/ip_address_format_validator.rb +++ b/lib/validators/ip_address_format_validator.rb @@ -3,8 +3,16 @@ class IpAddressFormatValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) - unless record.ip_address.nil? or record.ip_address.split('/').first =~ Resolv::AddressRegex - record.errors.add(attribute, :invalid) + if rails4? + # In Rails 4, ip_address will be nil if an invalid IP address was assigned. + # https://github.com/jetthoughts/rails/commit/0aa95a71b04f2893921c58a7c1d9fca60dbdcbc2 + if record.ip_address.nil? + record.errors.add(attribute, :invalid) + end + else + unless !record.ip_address.nil? and record.ip_address.to_s.split('/').first =~ Resolv::AddressRegex + record.errors.add(attribute, :invalid) + end end end diff --git a/spec/components/validators/ip_address_format_validator_spec.rb b/spec/components/validators/ip_address_format_validator_spec.rb index fa34e16e5ba..5f06345b5ca 100644 --- a/spec/components/validators/ip_address_format_validator_spec.rb +++ b/spec/components/validators/ip_address_format_validator_spec.rb @@ -6,7 +6,7 @@ describe IpAddressFormatValidator do let(:validator) { described_class.new({attributes: :ip_address}) } subject(:validate) { validator.validate_each(record, :ip_address, record.ip_address) } - [nil, '99.232.23.123', '99.232.0.0/16', 'fd12:db8::ff00:42:8329', 'fc00::/7'].each do |arg| + ['99.232.23.123', '99.232.0.0/16', 'fd12:db8::ff00:42:8329', 'fc00::/7'].each do |arg| it "should not add an error for #{arg}" do record.ip_address = arg validate @@ -14,6 +14,12 @@ describe IpAddressFormatValidator do end end + it 'should add an error for nil IP address' do + record.ip_address = nil + validate + record.errors[:ip_address].should be_present + end + it 'should add an error for invalid IP address' do record.ip_address = '99.99.99' validate