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 GIT
remote: git://github.com/rails/rails.git remote: git://github.com/rails/rails.git
revision: 0785008a64f4af8d09379683303d49d160cd444d revision: 81432139a9ca5bf90f08273d88e6e4f583c4189b
branch: 4-0-stable branch: 4-0-stable
specs: specs:
actionmailer (4.0.0) actionmailer (4.0.0)
@ -434,7 +434,7 @@ GEM
multi_json (~> 1.0) multi_json (~> 1.0)
rack (~> 1.0) rack (~> 1.0)
tilt (~> 1.1, != 1.3.0) tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.0.0) sprockets-rails (2.0.1)
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
sprockets (~> 2.8) 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/datatype-net-types.html
# http://www.postgresql.org/docs/9.1/static/functions-net.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 end
def self.should_block?(ip_address) def self.should_block?(ip_address)

View File

@ -11,7 +11,7 @@ class StaffActionLogger
action: UserHistory.actions[:delete_user], action: UserHistory.actions[:delete_user],
target_user_id: deleted_user.id, target_user_id: deleted_user.id,
email: deleted_user.email, 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(', ') details: [:id, :username, :name, :created_at, :trust_level, :last_seen_at, :last_emailed_at].map { |x| "#{x}: #{deleted_user.send(x)}" }.join(', ')
})) }))
end end

View File

@ -3,9 +3,17 @@
class IpAddressFormatValidator < ActiveModel::EachValidator class IpAddressFormatValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value) 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) record.errors.add(attribute, :invalid)
end 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
end end

View File

@ -6,7 +6,7 @@ describe IpAddressFormatValidator do
let(:validator) { described_class.new({attributes: :ip_address}) } let(:validator) { described_class.new({attributes: :ip_address}) }
subject(:validate) { validator.validate_each(record, :ip_address, record.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 it "should not add an error for #{arg}" do
record.ip_address = arg record.ip_address = arg
validate validate
@ -14,6 +14,12 @@ describe IpAddressFormatValidator do
end end
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 it 'should add an error for invalid IP address' do
record.ip_address = '99.99.99' record.ip_address = '99.99.99'
validate validate