about summary refs log tree commit diff
path: root/app/validators
diff options
context:
space:
mode:
authorClaire <claire.github-309c@sitedethib.com>2022-02-26 09:29:23 +0100
committerClaire <claire.github-309c@sitedethib.com>2022-02-26 09:29:23 +0100
commitbe493b6c0d60778257cbd6247f9287f939fc7e4e (patch)
tree07c127fc0e059ccd185c40a3c4497706f3bcacc7 /app/validators
parente48eaf64cc7cb0cfab388331c4823ee5fb580d59 (diff)
parenta5c24d5c4d75f3f3144f69c8f60f542707a82584 (diff)
Merge branch 'main' into glitch-soc/merge-upstream
Conflicts:
- `app/models/account.rb`:
  Not a real conflict, just upstream getting rid of unused constants too close
  to glitch-soc-specific contents.
  Removed unused constants like upstream did.
- `app/models/trends.rb`:
  Conflict because glitch-soc disabled email notifications for trending links.
  Upstream has refactored this quite a bit and added trending posts.
  Took upstream code, but disabling the extra trending stuff will come in
  another commit.
- `app/views/admin/trends/links/index.html.haml`:
  Conflict due to glitch-soc's theming system.
  Ported upstream changes accordingly.
Diffstat (limited to 'app/validators')
-rw-r--r--app/validators/blacklisted_email_validator.rb26
-rw-r--r--app/validators/email_mx_validator.rb20
2 files changed, 22 insertions, 24 deletions
diff --git a/app/validators/blacklisted_email_validator.rb b/app/validators/blacklisted_email_validator.rb
index eb66ad93d..9b3f2e33e 100644
--- a/app/validators/blacklisted_email_validator.rb
+++ b/app/validators/blacklisted_email_validator.rb
@@ -4,41 +4,39 @@ class BlacklistedEmailValidator < ActiveModel::Validator
   def validate(user)
     return if user.valid_invitation? || user.email.blank?
 
-    @email = user.email
-
-    user.errors.add(:email, :blocked) if blocked_email_provider?
-    user.errors.add(:email, :taken) if blocked_canonical_email?
+    user.errors.add(:email, :blocked) if blocked_email_provider?(user.email, user.sign_up_ip)
+    user.errors.add(:email, :taken) if blocked_canonical_email?(user.email)
   end
 
   private
 
-  def blocked_email_provider?
-    disallowed_through_email_domain_block? || disallowed_through_configuration? || not_allowed_through_configuration?
+  def blocked_email_provider?(email, ip)
+    disallowed_through_email_domain_block?(email, ip) || disallowed_through_configuration?(email) || not_allowed_through_configuration?(email)
   end
 
-  def blocked_canonical_email?
-    CanonicalEmailBlock.block?(@email)
+  def blocked_canonical_email?(email)
+    CanonicalEmailBlock.block?(email)
   end
 
-  def disallowed_through_email_domain_block?
-    EmailDomainBlock.block?(@email)
+  def disallowed_through_email_domain_block?(email, ip)
+    EmailDomainBlock.block?(email, attempt_ip: ip)
   end
 
-  def not_allowed_through_configuration?
+  def not_allowed_through_configuration?(email)
     return false if Rails.configuration.x.email_domains_whitelist.blank?
 
     domains = Rails.configuration.x.email_domains_whitelist.gsub('.', '\.')
     regexp  = Regexp.new("@(.+\\.)?(#{domains})$", true)
 
-    @email !~ regexp
+    email !~ regexp
   end
 
-  def disallowed_through_configuration?
+  def disallowed_through_configuration?(email)
     return false if Rails.configuration.x.email_domains_blacklist.blank?
 
     domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.')
     regexp  = Regexp.new("@(.+\\.)?(#{domains})", true)
 
-    regexp.match?(@email)
+    regexp.match?(email)
   end
 end
diff --git a/app/validators/email_mx_validator.rb b/app/validators/email_mx_validator.rb
index dceef5029..237ca4c7b 100644
--- a/app/validators/email_mx_validator.rb
+++ b/app/validators/email_mx_validator.rb
@@ -11,11 +11,11 @@ class EmailMxValidator < ActiveModel::Validator
     if domain.blank?
       user.errors.add(:email, :invalid)
     elsif !on_allowlist?(domain)
-      ips, hostnames = resolve_mx(domain)
+      resolved_ips, resolved_domains = resolve_mx(domain)
 
-      if ips.empty?
+      if resolved_ips.empty?
         user.errors.add(:email, :unreachable)
-      elsif on_blacklist?(hostnames + ips)
+      elsif on_blacklist?(resolved_domains, resolved_ips, user.sign_up_ip)
         user.errors.add(:email, :blocked)
       end
     end
@@ -40,24 +40,24 @@ class EmailMxValidator < ActiveModel::Validator
   end
 
   def resolve_mx(domain)
-    hostnames = []
-    ips       = []
+    records = []
+    ips     = []
 
     Resolv::DNS.open do |dns|
       dns.timeouts = 5
 
-      hostnames = dns.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }
+      records = dns.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }
 
-      ([domain] + hostnames).uniq.each do |hostname|
+      ([domain] + records).uniq.each do |hostname|
         ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.address.to_s })
         ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::AAAA).to_a.map { |e| e.address.to_s })
       end
     end
 
-    [ips, hostnames]
+    [ips, records]
   end
 
-  def on_blacklist?(values)
-    EmailDomainBlock.where(domain: values.uniq).any?
+  def on_blacklist?(domains, resolved_ips, attempt_ip)
+    EmailDomainBlock.block?(domains, ips: resolved_ips, attempt_ip: attempt_ip)
   end
 end