summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/helpers/email_helper.rb18
-rw-r--r--app/models/account.rb14
-rw-r--r--app/models/canonical_email_block.rb27
-rw-r--r--app/validators/blacklisted_email_validator.rb30
4 files changed, 78 insertions, 11 deletions
diff --git a/app/helpers/email_helper.rb b/app/helpers/email_helper.rb
new file mode 100644
index 00000000000..360783c6287
--- /dev/null
+++ b/app/helpers/email_helper.rb
@@ -0,0 +1,18 @@
+# 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.gsub('.', '').split('+', 2)
+
+ "#{username}@#{domain}"
+ end
+
+ def email_to_canonical_email_hash(str)
+ Digest::SHA2.new(256).hexdigest(email_to_canonical_email(str))
+ end
+end
diff --git a/app/models/account.rb b/app/models/account.rb
index 80689d4aaea..a573365de21 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -235,6 +235,7 @@ class Account < ApplicationRecord
transaction do
create_deletion_request!
update!(suspended_at: date, suspension_origin: origin)
+ create_canonical_email_block!
end
end
@@ -242,6 +243,7 @@ class Account < ApplicationRecord
transaction do
deletion_request&.destroy!
update!(suspended_at: nil, suspension_origin: nil)
+ destroy_canonical_email_block!
end
end
@@ -569,4 +571,16 @@ class Account < ApplicationRecord
def clean_feed_manager
FeedManager.instance.clean_feeds!(:home, [id])
end
+
+ def create_canonical_email_block!
+ return unless local? && user_email.present?
+
+ CanonicalEmailBlock.create(reference_account: self, email: user_email)
+ end
+
+ def destroy_canonical_email_block!
+ return unless local?
+
+ CanonicalEmailBlock.where(reference_account: self).delete_all
+ end
end
diff --git a/app/models/canonical_email_block.rb b/app/models/canonical_email_block.rb
new file mode 100644
index 00000000000..a8546d65af6
--- /dev/null
+++ b/app/models/canonical_email_block.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: canonical_email_blocks
+#
+# id :bigint(8) not null, primary key
+# canonical_email_hash :string default(""), not null
+# reference_account_id :bigint(8) not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+class CanonicalEmailBlock < ApplicationRecord
+ include EmailHelper
+
+ belongs_to :reference_account, class_name: 'Account'
+
+ validates :canonical_email_hash, presence: true
+
+ def email=(email)
+ self.canonical_email_hash = email_to_canonical_email_hash(email)
+ end
+
+ def self.block?(email)
+ where(canonical_email_hash: email_to_canonical_email_hash(email)).exists?
+ end
+end
diff --git a/app/validators/blacklisted_email_validator.rb b/app/validators/blacklisted_email_validator.rb
index 1ca73fdcc15..eb66ad93d7b 100644
--- a/app/validators/blacklisted_email_validator.rb
+++ b/app/validators/blacklisted_email_validator.rb
@@ -6,26 +6,25 @@ class BlacklistedEmailValidator < ActiveModel::Validator
@email = user.email
- user.errors.add(:email, :blocked) if blocked_email?
+ user.errors.add(:email, :blocked) if blocked_email_provider?
+ user.errors.add(:email, :taken) if blocked_canonical_email?
end
private
- def blocked_email?
- on_blacklist? || not_on_whitelist?
+ def blocked_email_provider?
+ disallowed_through_email_domain_block? || disallowed_through_configuration? || not_allowed_through_configuration?
end
- def on_blacklist?
- return true if EmailDomainBlock.block?(@email)
- return false if Rails.configuration.x.email_domains_blacklist.blank?
-
- domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.')
- regexp = Regexp.new("@(.+\\.)?(#{domains})", true)
+ def blocked_canonical_email?
+ CanonicalEmailBlock.block?(@email)
+ end
- regexp.match?(@email)
+ def disallowed_through_email_domain_block?
+ EmailDomainBlock.block?(@email)
end
- def not_on_whitelist?
+ def not_allowed_through_configuration?
return false if Rails.configuration.x.email_domains_whitelist.blank?
domains = Rails.configuration.x.email_domains_whitelist.gsub('.', '\.')
@@ -33,4 +32,13 @@ class BlacklistedEmailValidator < ActiveModel::Validator
@email !~ regexp
end
+
+ def disallowed_through_configuration?
+ 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)
+ end
end