You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
1.7 KiB

  1. # frozen_string_literal: true
  2. # == Schema Information
  3. #
  4. # Table name: email_domain_blocks
  5. #
  6. # id :bigint(8) not null, primary key
  7. # domain :string default(""), not null
  8. # created_at :datetime not null
  9. # updated_at :datetime not null
  10. # parent_id :bigint(8)
  11. # ips :inet is an Array
  12. # last_refresh_at :datetime
  13. #
  14. class EmailDomainBlock < ApplicationRecord
  15. include DomainNormalizable
  16. belongs_to :parent, class_name: 'EmailDomainBlock', optional: true
  17. has_many :children, class_name: 'EmailDomainBlock', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy
  18. validates :domain, presence: true, uniqueness: true, domain: true
  19. # Used for adding multiple blocks at once
  20. attr_accessor :other_domains
  21. def history
  22. @history ||= Trends::History.new('email_domain_blocks', id)
  23. end
  24. def self.block?(domain_or_domains, ips: [], attempt_ip: nil)
  25. domains = Array(domain_or_domains).map do |str|
  26. domain = begin
  27. if str.include?('@')
  28. str.split('@', 2).last
  29. else
  30. str
  31. end
  32. end
  33. TagManager.instance.normalize_domain(domain) if domain.present?
  34. rescue Addressable::URI::InvalidURIError
  35. nil
  36. end
  37. # If some of the inputs passed in are invalid, we definitely want to
  38. # block the attempt, but we also want to register hits against any
  39. # other valid matches
  40. blocked = domains.any?(&:nil?)
  41. scope = where(domain: domains)
  42. scope = scope.or(where('ips && ARRAY[?]::inet[]', ips)) if ips.any?
  43. scope.find_each do |block|
  44. blocked = true
  45. block.history.add(attempt_ip) if attempt_ip.present?
  46. end
  47. blocked
  48. end
  49. end