Replace EmailHelper module with normalizes via model concern (#35702)
Some checks are pending
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.2) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions

This commit is contained in:
Matt Jankowski 2025-08-07 09:47:47 -04:00 committed by GitHub
parent 496a5f423e
commit a485f97d21
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 47 additions and 25 deletions

View File

@ -1,18 +0,0 @@
# frozen_string_literal: true
module EmailHelper
def self.included(base)
base.extend(self)
end
def email_to_canonical_email(str)
username, domain = str.downcase.split('@', 2)
username, = username.delete('.').split('+', 2)
"#{username}@#{domain}"
end
def email_to_canonical_email_hash(str)
Digest::SHA2.new(256).hexdigest(email_to_canonical_email(str))
end
end

View File

@ -12,24 +12,29 @@
#
class CanonicalEmailBlock < ApplicationRecord
include EmailHelper
include CanonicalEmail
include Paginable
belongs_to :reference_account, class_name: 'Account', optional: true
validates :canonical_email_hash, presence: true, uniqueness: true
scope :matching_email, ->(email) { where(canonical_email_hash: email_to_canonical_email_hash(email)) }
scope :matching_email, ->(email) { where(canonical_email_hash: digest(normalize_value_for(:email, email))) }
def self.block?(email)
matching_email(email).exists?
end
def self.digest(value)
Digest::SHA256.hexdigest(value)
end
def to_log_human_identifier
canonical_email_hash
end
def email=(email)
self.canonical_email_hash = email_to_canonical_email_hash(email)
end
def self.block?(email)
matching_email(email).exists?
super
self.canonical_email_hash = self.class.digest(self.email)
end
end

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
module CanonicalEmail
extend ActiveSupport::Concern
included do
normalizes :email, with: ->(value) { canonicalize_email(value) }
end
class_methods do
def canonicalize_email(email)
email
.downcase
.split('@', 2)
.then { |local, domain| [canonical_username(local), domain] }
.join('@')
end
def canonical_username(username)
username
.to_s
.delete('.')
.split('+', 2)
.first
end
end
end

View File

@ -7,6 +7,14 @@ RSpec.describe CanonicalEmailBlock do
it { is_expected.to belong_to(:reference_account).class_name('Account').optional }
end
describe 'Normalizations' do
describe 'email' do
it { is_expected.to normalize(:email).from('TEST@HOST.EXAMPLE').to('test@host.example') }
it { is_expected.to normalize(:email).from('test+more@host.example').to('test@host.example') }
it { is_expected.to normalize(:email).from('test.user@host.example').to('testuser@host.example') }
end
end
describe 'Scopes' do
describe '.matching_email' do
subject { described_class.matching_email(email) }