From 2782fe538532e45e9a13be36d538721a24ef4dc1 Mon Sep 17 00:00:00 2001 From: Ian Bayne Date: Sat, 17 Aug 2024 09:33:22 +0900 Subject: [PATCH] change: deprecate blacklist and whitelist naming, #205 --- README.md | 12 +++--- config/blacklisted_email_domains.yml | 1 - config/deny_listed_email_domains.yml | 1 + lib/helpers/deprecation_helper.rb | 12 ++++++ lib/valid_email2.rb | 14 +++++- lib/valid_email2/address.rb | 11 ++++- lib/valid_email2/email_validator.rb | 21 +++++++-- spec/valid_email2_spec.rb | 64 ++++++++++++++-------------- valid_email2.gemspec | 4 +- 9 files changed, 92 insertions(+), 48 deletions(-) delete mode 100644 config/blacklisted_email_domains.yml create mode 100644 config/deny_listed_email_domains.yml create mode 100644 lib/helpers/deprecation_helper.rb diff --git a/README.md b/README.md index 42a62b7..674d6f1 100644 --- a/README.md +++ b/README.md @@ -73,20 +73,20 @@ To validate that the domain is not a disposable email (checks domain only, does validates :email, 'valid_email_2/email': { disposable_domain: true } ``` -To validate that the domain is not a disposable email or a disposable email (checks domain and MX server) but whitelisted (under config/whitelisted_email_domains.yml): +To validate that the domain is not a disposable email or a disposable email (checks domain and MX server) but allow-listed (under config/allow_listed_email_domains.yml): ```ruby -validates :email, 'valid_email_2/email': { disposable_with_whitelist: true } +validates :email, 'valid_email_2/email': { disposable_with_allow_list: true } ``` -To validate that the domain is not a disposable email or a disposable email (checks domain only, does not check MX server) but whitelisted (under config/whitelisted_email_domains.yml): +To validate that the domain is not a disposable email or a disposable email (checks domain only, does not check MX server) but allow-listed (under config/allow_listed_email_domains.yml): ```ruby -validates :email, 'valid_email_2/email': { disposable_domain_with_whitelist: true } +validates :email, 'valid_email_2/email': { disposable_domain_with_allow_list: true } ``` -To validate that the domain is not blacklisted (under config/blacklisted_email_domains.yml): +To validate that the domain is not on the deny list (under config/deny_list_email_domains.yml): ```ruby -validates :email, 'valid_email_2/email': { blacklist: true } +validates :email, 'valid_email_2/email': { deny_list: true } ``` To validate that email is not subaddressed: diff --git a/config/blacklisted_email_domains.yml b/config/blacklisted_email_domains.yml deleted file mode 100644 index b02120f..0000000 --- a/config/blacklisted_email_domains.yml +++ /dev/null @@ -1 +0,0 @@ -- blacklisted-test.com diff --git a/config/deny_listed_email_domains.yml b/config/deny_listed_email_domains.yml new file mode 100644 index 0000000..19ec635 --- /dev/null +++ b/config/deny_listed_email_domains.yml @@ -0,0 +1 @@ +- deny-listed-test.com diff --git a/lib/helpers/deprecation_helper.rb b/lib/helpers/deprecation_helper.rb new file mode 100644 index 0000000..a957870 --- /dev/null +++ b/lib/helpers/deprecation_helper.rb @@ -0,0 +1,12 @@ +module DeprecationHelper + def deprecate_method(old_method, new_method) + define_method(old_method) do |*args, &block| + warn "Warning: `#{old_method}` is deprecated; use `#{new_method}` instead." + send(new_method, *args, &block) + end + end + + def deprecation_message(old_name, new_name) + warn "Warning: `#{old_name}` is deprecated; use `#{new_name}` instead." + end +end \ No newline at end of file diff --git a/lib/valid_email2.rb b/lib/valid_email2.rb index 17247f2..f85d7ba 100644 --- a/lib/valid_email2.rb +++ b/lib/valid_email2.rb @@ -1,24 +1,34 @@ # frozen_string_literal: true require "valid_email2/email_validator" +require_relative "./helpers/deprecation_helper" module ValidEmail2 + BLACKLIST_FILE = "config/blacklisted_email_domains.yml" + DENY_LIST_FILE = "config/deny_listed_email_domains.yml" WHITELIST_FILE = "config/whitelisted_email_domains.yml" + ALLOW_LIST_FILE = "config/allow_listed_email_domains.yml" DISPOSABLE_FILE = File.expand_path('../config/disposable_email_domains.txt', __dir__) class << self + extend DeprecationHelper + def disposable_emails @disposable_emails ||= load_file(DISPOSABLE_FILE) end def blacklist - @blacklist ||= load_if_exists(BLACKLIST_FILE) + @deny_list ||= load_if_exists(DENY_LIST_FILE || BLACKLIST_FILE) end + alias_method :deny_list, :blacklist + deprecate_method :blacklist, :deny_list def whitelist - @whitelist ||= load_if_exists(WHITELIST_FILE) + @allow_list ||= load_if_exists(ALLOW_LIST_FILE || WHITELIST_FILE) end + alias_method :allow_list, :whitelist + deprecate_method :whitelist, :allow_list private diff --git a/lib/valid_email2/address.rb b/lib/valid_email2/address.rb index 31f58e1..0d35c7b 100644 --- a/lib/valid_email2/address.rb +++ b/lib/valid_email2/address.rb @@ -3,9 +3,12 @@ require "valid_email2" require "resolv" require "mail" +require_relative "../helpers/deprecation_helper" module ValidEmail2 class Address + extend DeprecationHelper + attr_accessor :address PROHIBITED_DOMAIN_CHARACTERS_REGEX = /[+!_\/\s'`]/ @@ -85,12 +88,16 @@ def disposable_mx_server? end def whitelisted? - domain_is_in?(ValidEmail2.whitelist) + domain_is_in?(ValidEmail2.allow_list) end + alias_method :allow_listed?, :whitelisted? + deprecate_method :whitelisted?, :allow_listed? def blacklisted? - valid? && domain_is_in?(ValidEmail2.blacklist) + valid? && domain_is_in?(ValidEmail2.deny_list) end + alias_method :deny_listed?, :blacklisted? + deprecate_method :blacklisted?, :deny_listed? def valid_mx? return false unless valid? diff --git a/lib/valid_email2/email_validator.rb b/lib/valid_email2/email_validator.rb index 0016c71..47f9e50 100644 --- a/lib/valid_email2/email_validator.rb +++ b/lib/valid_email2/email_validator.rb @@ -1,9 +1,12 @@ require "valid_email2/address" require "active_model" require "active_model/validations" +require_relative "../helpers/deprecation_helper" module ValidEmail2 class EmailValidator < ActiveModel::EachValidator + include DeprecationHelper + def default_options { disposable: false, mx: false, strict_mx: false, disallow_subaddressing: false, multiple: false, dns_timeout: 5, dns_nameserver: nil } end @@ -33,15 +36,27 @@ def validate_each(record, attribute, value) end if options[:disposable_with_whitelist] - error(record, attribute) && return if addresses.any? { |address| address.disposable? && !address.whitelisted? } + deprecation_message(:disposable_with_whitelist, :disposable_with_allow_list) + end + + if options[:disposable_with_allow_list] || options[:disposable_with_whitelist] + error(record, attribute) && return if addresses.any? { |address| address.disposable? && !address.allow_listed? } end if options[:disposable_domain_with_whitelist] - error(record, attribute) && return if addresses.any? { |address| address.disposable_domain? && !address.whitelisted? } + deprecation_message(:disposable_domain_with_whitelist, :disposable_domain_with_allow_list) + end + + if options[:disposable_domain_with_allow_list] || options[:disposable_domain_with_whitelist] + error(record, attribute) && return if addresses.any? { |address| address.disposable_domain? && !address.allow_listed? } end if options[:blacklist] - error(record, attribute) && return if addresses.any?(&:blacklisted?) + deprecation_message(:blacklist, :deny_list) + end + + if options[:deny_list] || options[:blacklist] + error(record, attribute) && return if addresses.any?(&:deny_listed?) end if options[:mx] diff --git a/spec/valid_email2_spec.rb b/spec/valid_email2_spec.rb index 97eb659..c1c1a3a 100644 --- a/spec/valid_email2_spec.rb +++ b/spec/valid_email2_spec.rb @@ -47,16 +47,16 @@ class TestUserDisallowDisposableDomain < TestModel validates :email, 'valid_email_2/email': { disposable_domain: true } end -class TestUserDisallowDisposableWithWhitelist < TestModel - validates :email, 'valid_email_2/email': { disposable_with_whitelist: true } +class TestUserDisallowDisposableWithAllowList < TestModel + validates :email, 'valid_email_2/email': { disposable_with_allow_list: true } end -class TestUserDisallowDisposableDomainWithWhitelist < TestModel - validates :email, 'valid_email_2/email': { disposable_domain_with_whitelist: true } +class TestUserDisallowDisposableDomainWithAllowList < TestModel + validates :email, 'valid_email_2/email': { disposable_domain_with_allow_list: true } end -class TestUserDisallowBlacklisted < TestModel - validates :email, 'valid_email_2/email': { blacklist: true } +class TestUserDisallowDenyListed < TestModel + validates :email, 'valid_email_2/email': { deny_list: true } end class TestUserMessage < TestModel @@ -208,58 +208,58 @@ class TestUserMultiple < TestModel end end - describe "with whitelisted emails" do - let(:whitelist_domain) { disposable_domain } - let(:whitelist_file_path) { "config/whitelisted_email_domains.yml" } + describe "with allow-listed emails" do + let(:allow_list_domain) { disposable_domain } + let(:allow_list_file_path) { "config/allow_listed_email_domains.yml" } - # Some of the specs below need to explictly set the whitelist var or it + # Some of the specs below need to explictly set the allow list var or it # may be cached to an empty set - def set_whitelist + def set_allow_list ValidEmail2.instance_variable_set( - :@whitelist, - ValidEmail2.send(:load_if_exists, ValidEmail2::WHITELIST_FILE) + :@allow_list, + ValidEmail2.send(:load_if_exists, ValidEmail2::ALLOW_LIST_FILE) ) end after do - FileUtils.rm(whitelist_file_path, force: true) - set_whitelist + FileUtils.rm(allow_list_file_path, force: true) + set_allow_list end - it "is invalid if the domain is disposable and not in the whitelist" do - user = TestUserDisallowDisposableWithWhitelist.new(email: "foo@#{whitelist_domain}") + it "is invalid if the domain is disposable and not in the allow list" do + user = TestUserDisallowDisposableWithAllowList.new(email: "foo@#{allow_list_domain}") expect(user.valid?).to be_falsey end - it "is valid if the domain is disposable but in the whitelist" do - File.open(whitelist_file_path, "w") { |f| f.write [whitelist_domain].to_yaml } - set_whitelist - user = TestUserDisallowDisposableWithWhitelist.new(email: "foo@#{whitelist_domain}") + it "is valid if the domain is disposable but in the allow list" do + File.open(allow_list_file_path, "w") { |f| f.write [allow_list_domain].to_yaml } + set_allow_list + user = TestUserDisallowDisposableWithAllowList.new(email: "foo@#{allow_list_domain}") expect(user.valid?).to be_truthy end - it "is invalid if the domain is a disposable_domain and not in the whitelist" do - user = TestUserDisallowDisposableDomainWithWhitelist.new(email: "foo@#{whitelist_domain}") + it "is invalid if the domain is a disposable_domain and not in the allow list" do + user = TestUserDisallowDisposableDomainWithAllowList.new(email: "foo@#{allow_list_domain}") expect(user.valid?).to be_falsey end - it "is valid if the domain is a disposable_domain but in the whitelist" do - File.open(whitelist_file_path, "w") { |f| f.write [whitelist_domain].to_yaml } - set_whitelist - user = TestUserDisallowDisposableDomainWithWhitelist.new(email: "foo@#{whitelist_domain}") + it "is valid if the domain is a disposable_domain but in the allow list" do + File.open(allow_list_file_path, "w") { |f| f.write [allow_list_domain].to_yaml } + set_allow_list + user = TestUserDisallowDisposableDomainWithAllowList.new(email: "foo@#{allow_list_domain}") expect(user.valid?).to be_truthy end end end - describe "with blacklist validation" do - it "is valid if the domain is not blacklisted" do - user = TestUserDisallowBlacklisted.new(email: "foo@gmail.com") + describe "with deny list validation" do + it "is valid if the domain is not deny-listed" do + user = TestUserDisallowDenyListed.new(email: "foo@gmail.com") expect(user.valid?).to be_truthy end - it "is invalid if the domain is blacklisted" do - user = TestUserDisallowBlacklisted.new(email: "foo@blacklisted-test.com") + it "is invalid if the domain is deny-listed" do + user = TestUserDisallowDenyListed.new(email: "foo@deny-listed-test.com") expect(user.valid?).to be_falsey end end diff --git a/valid_email2.gemspec b/valid_email2.gemspec index 0b05b66..ee9d136 100644 --- a/valid_email2.gemspec +++ b/valid_email2.gemspec @@ -8,8 +8,8 @@ Gem::Specification.new do |spec| spec.version = ValidEmail2::VERSION spec.authors = ["Micke Lisinge"] spec.email = ["hi@micke.me"] - spec.description = %q{ActiveModel validation for email. Including MX lookup and disposable email blacklist} - spec.summary = %q{ActiveModel validation for email. Including MX lookup and disposable email blacklist} + spec.description = %q{ActiveModel validation for email. Including MX lookup and disposable email deny list} + spec.summary = %q{ActiveModel validation for email. Including MX lookup and disposable email deny list} spec.homepage = "https://github.com/micke/valid_email2" spec.license = "MIT"