diff options
author | Claire <claire.github-309c@sitedethib.com> | 2022-08-25 05:07:39 +0200 |
---|---|---|
committer | Claire <claire.github-309c@sitedethib.com> | 2022-08-25 05:07:39 +0200 |
commit | 2d1d4210f9d394ea8e7357df08f8ca2cc925384a (patch) | |
tree | a5c69693d11b59a673b1981ea2d85bbc17991c42 /app/models/email_domain_block.rb | |
parent | 5a3d09dc8e30198b4d8d921ef0b1ba0a35fe01d9 (diff) | |
parent | 861b35dd54d266bc0a40b3cacb28e5b82ff6faaa (diff) |
Merge branch 'main' into glitch-soc/merge-upstream
Diffstat (limited to 'app/models/email_domain_block.rb')
-rw-r--r-- | app/models/email_domain_block.rb | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb index 0e1e663c1..f9d74332b 100644 --- a/app/models/email_domain_block.rb +++ b/app/models/email_domain_block.rb @@ -30,32 +30,56 @@ class EmailDomainBlock < ApplicationRecord @history ||= Trends::History.new('email_domain_blocks', id) end - def self.block?(domain_or_domains, attempt_ip: nil) - domains = Array(domain_or_domains).map do |str| - domain = begin - if str.include?('@') - str.split('@', 2).last - else - str - end - end + class Matcher + def initialize(domain_or_domains, attempt_ip: nil) + @uris = extract_uris(domain_or_domains) + @attempt_ip = attempt_ip + end - TagManager.instance.normalize_domain(domain) if domain.present? - rescue Addressable::URI::InvalidURIError - nil + def match? + blocking? || invalid_uri? end - # If some of the inputs passed in are invalid, we definitely want to - # block the attempt, but we also want to register hits against any - # other valid matches + private - blocked = domains.any?(&:nil?) + def invalid_uri? + @uris.any?(&:nil?) + end - where(domain: domains).find_each do |block| - blocked = true - block.history.add(attempt_ip) if attempt_ip.present? + def blocking? + blocks = EmailDomainBlock.where(domain: domains_with_variants).order(Arel.sql('char_length(domain) desc')) + blocks.each { |block| block.history.add(@attempt_ip) } if @attempt_ip.present? + blocks.any? end - blocked + def domains_with_variants + @uris.flat_map do |uri| + next if uri.nil? + + segments = uri.normalized_host.split('.') + + segments.map.with_index { |_, i| segments[i..-1].join('.') } + end + end + + def extract_uris(domain_or_domains) + Array(domain_or_domains).map do |str| + domain = begin + if str.include?('@') + str.split('@', 2).last + else + str + end + end + + Addressable::URI.new.tap { |u| u.host = domain.strip } if domain.present? + rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError + nil + end + end + end + + def self.block?(domain_or_domains, attempt_ip: nil) + Matcher.new(domain_or_domains, attempt_ip: attempt_ip).match? end end |