Translate asterisks in ip addresses to mask format so people can enter things like 127.*.*.* in screened ip addresses form

This commit is contained in:
Neil Lalonde 2014-02-18 13:00:46 -05:00
parent 69e0342d8f
commit d0ecccb7e4
2 changed files with 55 additions and 3 deletions

View file

@ -18,7 +18,22 @@ class ScreenedIpAddress < ActiveRecord::Base
# In Rails 4.0.1, an exception is raised before validation happens, so we need this hack for
# inet/cidr columns:
def ip_address=(val)
if val.nil?
self.errors.add(:ip_address, :invalid)
return
end
num_wildcards = val.count('*')
if num_wildcards == 0
write_attribute(:ip_address, val)
else
v = val.gsub(/\/.*/, '')
if v[v.index('*')..-1] =~ /[^\.\*]/
self.errors.add(:ip_address, :invalid)
return
end
write_attribute(:ip_address, "#{v.gsub('*', '0')}/#{32 - (num_wildcards * 8)}")
end
# this gets even messier, Ruby 1.9.2 raised a different exception to Ruby 2.0.0
# handle both exceptions

View file

@ -47,6 +47,45 @@ describe ScreenedIpAddress do
end
end
describe "ip_address=" do
let(:record) { described_class.new }
def test_good_value(arg, expected)
record.ip_address = arg
record.ip_address_with_mask.should == expected
end
def test_bad_value(arg)
r = described_class.new
r.ip_address = arg
r.should_not be_valid
r.errors[:ip_address].should be_present
end
it "handles valid ip addresses" do
test_good_value("210.56.12.12", "210.56.12.12")
test_good_value("210.56.0.0/16", "210.56.0.0/16")
test_good_value("fc00::/7", "fc00::/7")
end
it "translates * characters" do
test_good_value("123.*.*.*", "123.0.0.0/8")
test_good_value("123.12.*.*", "123.12.0.0/16")
test_good_value("123.12.1.*", "123.12.1.0/24")
test_good_value("123.12.*.*/16", "123.12.0.0/16")
end
it "handles bad input" do
test_bad_value(nil)
test_bad_value("123.123")
test_bad_value("my house")
test_bad_value("123.*.1.12")
test_bad_value("*.123.*.12")
test_bad_value("*.*.*.12")
test_bad_value("123.*.1.12/8")
end
end
describe '#watch' do
context 'ip_address is not being watched' do
it 'should create a new record' do
@ -122,8 +161,6 @@ describe ScreenedIpAddress do
it "doesn't block fc00::/7 addresses (IPv6)" do
described_class.watch('fd12:db8::ff00:42:8329').action_type.should == described_class.actions[:do_nothing]
end
end
describe '#should_block?' do