about summary refs log tree commit diff
path: root/app/validators/email_mx_validator.rb
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-12-10 22:53:25 +0100
committerGitHub <noreply@github.com>2018-12-10 22:53:25 +0100
commitdbb1ee269fa4a6ee097dfea5f77bb2c9428af93b (patch)
treedacb7fda6c7c2a9ef94a85f1508d3cc870ff446d /app/validators/email_mx_validator.rb
parent3f12c07ff5f60d22cfbff050a2639345ecbaec57 (diff)
Improve e-mail MX validator and add tests (#9489)
Diffstat (limited to 'app/validators/email_mx_validator.rb')
-rw-r--r--app/validators/email_mx_validator.rb19
1 files changed, 14 insertions, 5 deletions
diff --git a/app/validators/email_mx_validator.rb b/app/validators/email_mx_validator.rb
index 8d1e58b38..5b4c684b2 100644
--- a/app/validators/email_mx_validator.rb
+++ b/app/validators/email_mx_validator.rb
@@ -4,7 +4,6 @@ require 'resolv'
 
 class EmailMxValidator < ActiveModel::Validator
   def validate(user)
-    return if Rails.env.test? || Rails.env.development?
     user.errors.add(:email, I18n.t('users.invalid_email')) if invalid_mx?(user.email)
   end
 
@@ -15,13 +14,23 @@ class EmailMxValidator < ActiveModel::Validator
 
     return true if domain.nil?
 
-    records = Resolv::DNS.new.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }
-    records = Resolv::DNS.new.getresources(domain, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.address.to_s } if records.empty?
+    hostnames = []
+    ips       = []
 
-    records.empty? || on_blacklist?(records)
+    Resolv::DNS.open do |dns|
+      dns.timeouts = 1
+
+      hostnames = dns.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }
+
+      ([domain] + hostnames).uniq.each do |hostname|
+        ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.address.to_s })
+      end
+    end
+
+    ips.empty? || on_blacklist?(hostnames + ips)
   end
 
   def on_blacklist?(values)
-    EmailDomainBlock.where(domain: values).any?
+    EmailDomainBlock.where(domain: values.uniq).any?
   end
 end