bundle exec rails g migration CreateEmailBlacklistDomains value:string:uniq notes:string
bundle exec rails g migration CreateEmailBlacklistIpRanges value:string:uniq notes:string
bundle exec rake db:migrate
Created
May 2, 2014 19:56
-
-
Save larsthegeek/f703c907662ec93ff5f2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/email_blacklist_domain.rb | |
class EmailBlacklistDomain < ActiveRecord::Base | |
validates :value, presence: true, uniqueness: { case_sensitive: false } | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/email_blacklist_ip_range.rb | |
class EmailBlacklistIpRange < ActiveRecord::Base | |
validates :value, presence: true, uniqueness: true, ip_addr: true | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/validators/email_validator.rb | |
class EmailValidator < ActiveModel::EachValidator | |
def validate_each(record, attribute, value) | |
result = false | |
# change to /\A[^@\s]+@(([^@.\s]+\.)*[^@.\s]+)\z/ to allow local hosts to work | |
if value =~ /\A[^@\s]+@(([^@.\s]+\.)+[^@.\s]+)\z/ | |
domain = $2 | |
result = dns_domain_exists?(domain) && ! forbidden?(domain) | |
end | |
record.errors[attribute] << (options[:message] || 'is not a valid email address') unless result | |
end | |
protected | |
def forbidden?(domain) | |
forbidden_dns_domain?(domain) || forbidden_any_ip?(domain) | |
end | |
def dns_domain_records(domain) | |
Resolv::DNS.open do |dns| | |
dns_records = dns.getresources(domain, Resolv::DNS::Resource::IN::ANY) | |
yield(dns_records) | |
end | |
end | |
def dns_domain_exists?(domain) | |
dns_domain_records(domain) do |dns_records| | |
return true | |
end | |
return false | |
end | |
def forbidden_dns_domain?(domain) | |
domain = domain.to_s | |
EmailBlacklistDomain.all.each { |email_blacklist_domain| | |
if domain =~ /\A.*#{email_blacklist_domain.value}.*\z/i | |
return true | |
end | |
} | |
return false | |
end | |
def forbidden_any_ip?(domain) | |
dns_domain_records(domain) do |dns_records| | |
dns_records.map { |dns_record| | |
next unless dns_record.respond_to? :address | |
return true if forbidden_ip?(dns_record.address) | |
} | |
end | |
return false | |
end | |
def forbidden_ip?(ip) | |
EmailBlacklistIpRange.all.each { |email_blacklist_ip_record| | |
begin | |
value = email_blacklist_ip_record.value | |
return true if IPAddr.new(value).include? ip.to_s | |
rescue IPAddr::InvalidAddressError | |
logger.warn "invalid ip addr or ip range in email_blacklist_ip table: #{email_blacklist_ip_record}" | |
end | |
} | |
return false | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/validators/ip_addr_validator.rb | |
require 'ipaddr' | |
class IpAddrValidator < ActiveModel::EachValidator | |
def validate_each(record, attribute, value) | |
IPAddr.new value | |
rescue IPAddr::InvalidAddressError | |
record.errors[attribute] << (options[:message] || 'is not a valid IP (v4/v6) addresss or range') | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# db/seeds.rb | |
### append the following to your seeds.rb | |
# EmailBlacklistIPRange | |
[ | |
# mailinator.com | |
'207.198.106.56', | |
# yopmail | |
'213.251.128.128/28', | |
'213.251.188.128/28', | |
'2001:41d0:1:1980::1/60', | |
'2001:41d0:1:4a80::1/60', | |
].map { |value| EmailBlacklistIpRange.create! value: value } | |
# EmailBlacklistDomain | |
%w[ | |
deadaddress\.com | |
sharklasers\.com | |
mailinator\.com | |
yopmail\.com | |
].map { |value| EmailBlacklistDomain.create! value: value } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment