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.

This commit is contained in:
Neil Lalonde 2013-10-22 18:55:30 -04:00
parent 6394d924c8
commit c1008f4359
5 changed files with 21 additions and 7 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -3,9 +3,17 @@
class IpAddressFormatValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless record.ip_address.nil? or record.ip_address.split('/').first =~ Resolv::AddressRegex
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
end

View File

@ -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