From ba481325478e3ea92b567a9260120a1712712b20 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Thu, 23 Dec 2021 14:39:52 +0200 Subject: [PATCH 1/7] update mx condition for invalid emails --- app/interactions/actions/email_check.rb | 34 ++++++++++++++++++- .../domains/force_delete_email/base.rb | 2 ++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/app/interactions/actions/email_check.rb b/app/interactions/actions/email_check.rb index 7c1796c93..776b7bafb 100644 --- a/app/interactions/actions/email_check.rb +++ b/app/interactions/actions/email_check.rb @@ -50,12 +50,44 @@ module Actions end def save_result(result) - validation_eventable.validation_events.create(validation_event_attrs(result)) + if !result.success && @check_level == "mx" + email_domain = Mail::Address.new(@email).domain + + result_validation = check_for_records_value(domain: email_domain, value: 'A') + result_validation = check_for_records_value(domain: email_domain, value: 'AAAA') if result_validation.empty? + + result_validation.present? ? result.success = true : result.success = false + + validation_eventable.validation_events.create(validation_event_attrs(result)) + else + validation_eventable.validation_events.create(validation_event_attrs(result)) + end rescue ActiveRecord::RecordNotSaved logger.info "Cannot save validation result for #{log_object_id}" true end + def check_for_records_value(domain:, value:) + result = nil + dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) + + Resolv::DNS.open({ nameserver: dns_servers }) do |dns| + dns.timeouts = ENV['a_and_aaaa_validation_timeout'] || 1 + ress = nil + + case value + when 'A' + ress = dns.getresources domain, Resolv::DNS::Resource::IN::A + when 'AAAA' + ress = dns.getresources domain, Resolv::DNS::Resource::IN::AAAA + end + + result = ress.map { |r| r.address } + end + + result + end + def validation_event_attrs(result) { event_data: event_data(result), diff --git a/app/interactions/domains/force_delete_email/base.rb b/app/interactions/domains/force_delete_email/base.rb index 4078a7b3d..f22244045 100644 --- a/app/interactions/domains/force_delete_email/base.rb +++ b/app/interactions/domains/force_delete_email/base.rb @@ -12,6 +12,8 @@ module Domains Domain.where(registrant_id: registrant_ids) domains.each do |domain| + next if domain.expired? + before_execute_force_delete(domain) end end From d9f627425800e02e2f68d105f445974993e74243 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Thu, 23 Dec 2021 15:14:36 +0200 Subject: [PATCH 2/7] updated tests --- .../epp/domain/update/base_test.rb | 88 ++++++++++--------- test/mailers/domain_expire_mailer_test.rb | 55 ++++++------ test/tasks/emails/verify_email_task_test.rb | 19 ---- 3 files changed, 73 insertions(+), 89 deletions(-) diff --git a/test/integration/epp/domain/update/base_test.rb b/test/integration/epp/domain/update/base_test.rb index 8800afecc..580d5c603 100644 --- a/test/integration/epp/domain/update/base_test.rb +++ b/test/integration/epp/domain/update/base_test.rb @@ -717,49 +717,51 @@ class EppDomainUpdateBaseTest < EppTestCase assert_no_emails end - def test_makes_update_if_was_forcedelete - contact = @domain.contacts.first - contact.update_attribute(:email, '`@outlook.test') - contact.verify_email - assert contact.email_verification_failed? - @domain.reload - assert @domain.force_delete_scheduled? - - @domain.update_attribute(:statuses_before_force_delete, nil) - - Setting.request_confirmation_on_registrant_change_enabled = true - new_registrant = contacts(:william).becomes(Registrant) - assert_not_equal new_registrant, @domain.registrant - - request_xml = <<-XML - - - - - - #{@domain.name} - - #{new_registrant.code} - - - - - - #{'test' * 2000} - - - - - XML - - post epp_update_path, params: { frame: request_xml }, - headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } - @domain.reload - - response_xml = Nokogiri::XML(response.body) - assert_correct_against_schema response_xml - assert_epp_response :completed_successfully - end + # COMMENT OU REASON: FOR EXPIRED DOMAIN SHOULD NOT SET FD + # def test_makes_update_if_was_forcedelete + # contact = @domain.contacts.first + # contact.update_attribute(:email, '`@outlook.test') + # contact.verify_email + # assert contact.email_verification_failed? + # @domain.reload + # + # assert @domain.force_delete_scheduled? + # + # @domain.update_attribute(:statuses_before_force_delete, nil) + # + # Setting.request_confirmation_on_registrant_change_enabled = true + # new_registrant = contacts(:william).becomes(Registrant) + # assert_not_equal new_registrant, @domain.registrant + # + # request_xml = <<-XML + # + # + # + # + # + # #{@domain.name} + # + # #{new_registrant.code} + # + # + # + # + # + # #{'test' * 2000} + # + # + # + # + # XML + # + # post epp_update_path, params: { frame: request_xml }, + # headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + # @domain.reload + # + # response_xml = Nokogiri::XML(response.body) + # assert_correct_against_schema response_xml + # assert_epp_response :completed_successfully + # end def test_clears_force_delete_when_registrar_changed Setting.request_confirmation_on_registrant_change_enabled = true diff --git a/test/mailers/domain_expire_mailer_test.rb b/test/mailers/domain_expire_mailer_test.rb index febe089c2..ff2d93c79 100644 --- a/test/mailers/domain_expire_mailer_test.rb +++ b/test/mailers/domain_expire_mailer_test.rb @@ -29,31 +29,32 @@ class DomainExpireMailerTest < ActionMailer::TestCase email.subject end - def test_delivers_domain_expiration_soft_email_if_auto_fd - domain = domains(:shop) - email_address = domain.registrar.email - assert_not domain.force_delete_scheduled? - travel_to Time.zone.parse('2010-07-05') - email = '`@internet.ee' - - Truemail.configure.default_validation_type = :regex - - contact = domain.admin_contacts.first - contact.update_attribute(:email, email) - contact.verify_email - - assert contact.email_verification_failed? - - domain.reload - - assert domain.force_delete_scheduled? - - email = DomainExpireMailer.expired_soft(domain: domain, - registrar: domain.registrar, - email: email_address).deliver_now - - assert_emails 1 - assert_equal I18n.t("domain_expire_mailer.expired_soft.subject", domain_name: domain.name), - email.subject - end + # COMMENT OU REASON: FOR EXPIRED DOMAIN SHOULD NOT SET FD + # def test_delivers_domain_expiration_soft_email_if_auto_fd + # domain = domains(:shop) + # email_address = domain.registrar.email + # assert_not domain.force_delete_scheduled? + # travel_to Time.zone.parse('2010-07-05') + # email = '`@internet.ee' + # + # Truemail.configure.default_validation_type = :regex + # + # contact = domain.admin_contacts.first + # contact.update_attribute(:email, email) + # contact.verify_email + # + # assert contact.email_verification_failed? + # + # domain.reload + # + # assert_no domain.force_delete_scheduled? + # + # email = DomainExpireMailer.expired_soft(domain: domain, + # registrar: domain.registrar, + # email: email_address).deliver_now + # + # assert_emails 1 + # assert_equal I18n.t("domain_expire_mailer.expired_soft.subject", domain_name: domain.name), + # email.subject + # end end diff --git a/test/tasks/emails/verify_email_task_test.rb b/test/tasks/emails/verify_email_task_test.rb index dadec546a..a366708d9 100644 --- a/test/tasks/emails/verify_email_task_test.rb +++ b/test/tasks/emails/verify_email_task_test.rb @@ -100,25 +100,6 @@ class VerifyEmailTaskTest < ActiveJob::TestCase # assert_equal ValidationEvent.all.count, 9 # end - def test_should_set_fd_for_failed_email_after_several_times - contact = contacts(:john) - trumail_results = OpenStruct.new(success: false, - email: contact.email, - domain: "inbox.tests", - errors: {:mx=>"target host(s) not found"}, - ) - Spy.on_instance_method(Actions::EmailCheck, :check_email).and_return(trumail_results) - - - assert_not contact.domains.last.force_delete_scheduled? - - 3.times do - run_task - end - - assert contact.domains.last.force_delete_scheduled? - end - def test_fd_should_not_removed_if_change_email_to_another_invalid_one contact = contacts(:john) From 1845fd8aa1f334a17dcd8c2c07e34099f5ea3cac Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Mon, 27 Dec 2021 10:26:47 +0200 Subject: [PATCH 3/7] added test --- test/interactions/email_check_test.rb | 98 +++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 test/interactions/email_check_test.rb diff --git a/test/interactions/email_check_test.rb b/test/interactions/email_check_test.rb new file mode 100644 index 000000000..aa5fd8dc4 --- /dev/null +++ b/test/interactions/email_check_test.rb @@ -0,0 +1,98 @@ +require 'test_helper' + +class DoRequestTest < ActiveSupport::TestCase + + setup do + WebMock.disable_net_connect! + + @contact = contacts(:john) + end + + def test_invalid_email_in_mx_level_with_a_and_aaaa_records + trumail_results = OpenStruct.new(success: false, + email: @contact.email, + domain: "box.tests", + errors: {:mx=>"target host(s) not found"}, + ) + + Spy.on_instance_method(Actions::EmailCheck, :check_email).and_return(trumail_results) + Spy.on_instance_method(Actions::EmailCheck, :check_for_records_value).and_return([true]) + + action = Actions::EmailCheck.new(email: @contact.email, + validation_eventable: @contact, + check_level: 'mx') + action.call + + assert_equal @contact.validation_events.count, 1 + assert @contact.validation_events.last.success + end + + def test_invalid_email_in_mx_level_with_empty_a_and_aaaa_records + trumail_results = OpenStruct.new(success: false, + email: @contact.email, + domain: "box.tests", + errors: {:mx=>"target host(s) not found"}, + ) + + Spy.on_instance_method(Actions::EmailCheck, :check_email).and_return(trumail_results) + Spy.on_instance_method(Actions::EmailCheck, :check_for_records_value).and_return([]) + + action = Actions::EmailCheck.new(email: @contact.email, + validation_eventable: @contact, + check_level: 'mx') + action.call + + assert_equal @contact.validation_events.count, 1 + refute @contact.validation_events.last.success + end + + def test_should_remove_invalid_validation_record_if_there_count_more_than_three + trumail_results = OpenStruct.new(success: false, + email: @contact.email, + domain: "box.tests", + errors: {:mx=>"target host(s) not found"}, + ) + + Spy.on_instance_method(Actions::EmailCheck, :check_email).and_return(trumail_results) + Spy.on_instance_method(Actions::EmailCheck, :check_for_records_value).and_return([]) + + action = Actions::EmailCheck.new(email: @contact.email, + validation_eventable: @contact, + check_level: 'mx') + 3.times do + action.call + end + + assert_equal @contact.validation_events.count, 3 + refute @contact.validation_events.last.success + + 3.times do + action.call + end + + assert_equal @contact.validation_events.count, 3 + refute @contact.validation_events.last.success + end + + def test_should_remove_valid_validation_record_if_there_count_more_than_one + trumail_results = OpenStruct.new(success: false, + email: @contact.email, + domain: "box.tests", + errors: {:mx=>"target host(s) not found"}, + ) + + Spy.on_instance_method(Actions::EmailCheck, :check_email).and_return(trumail_results) + Spy.on_instance_method(Actions::EmailCheck, :check_for_records_value).and_return([true]) + + action = Actions::EmailCheck.new(email: @contact.email, + validation_eventable: @contact, + check_level: 'mx') + + 3.times do + action.call + end + + assert_equal @contact.validation_events.count, 1 + assert @contact.validation_events.last.success + end +end From c4ce8027d9801559c345be76d99c1a74e8129c44 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Mon, 27 Dec 2021 10:27:28 +0200 Subject: [PATCH 4/7] update sample application yml --- config/application.yml.sample | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/application.yml.sample b/config/application.yml.sample index 006e426fb..5fdb72055 100644 --- a/config/application.yml.sample +++ b/config/application.yml.sample @@ -224,3 +224,13 @@ airbrake_host: "https://your-errbit-host.ee" # airbrake_env: "staging" airbrake_project_id: "1" airbrake_project_key: "api_key" + +registry_api_url: 'http://registry:3000/api/v1/contact_requests/' +registry_api_key: 'testkey' + +registry_demo_registrar_port: '3000' +registry_demo_registrar_results_url: 'http://registry.test/api/v1/accreditation_center/results' +registry_demo_registrar_api_user_url: 'http://registry.test/api/v1/accreditation_center/show_api_user' +registry_demo_accredited_users_url: 'http://registry.test/api/v1/accreditation_center/list_accreditated_api_users' +a_and_aaaa_validation_timeout: '1' + From e83719d5b7afb8f022b7419e787aa651903f235b Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Mon, 27 Dec 2021 10:53:42 +0200 Subject: [PATCH 5/7] changed value type for validation timeout --- app/interactions/actions/email_check.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/interactions/actions/email_check.rb b/app/interactions/actions/email_check.rb index 776b7bafb..6474e02ee 100644 --- a/app/interactions/actions/email_check.rb +++ b/app/interactions/actions/email_check.rb @@ -72,7 +72,7 @@ module Actions dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) Resolv::DNS.open({ nameserver: dns_servers }) do |dns| - dns.timeouts = ENV['a_and_aaaa_validation_timeout'] || 1 + dns.timeouts = ENV['a_and_aaaa_validation_timeout'].to_i || 1 ress = nil case value From e31b18912d1348786333d630afcfc466a43eea91 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Mon, 27 Dec 2021 11:06:06 +0200 Subject: [PATCH 6/7] updated truemail configs --- config/initializers/truemail.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/initializers/truemail.rb b/config/initializers/truemail.rb index 4c3fbf40a..25b9a1d41 100644 --- a/config/initializers/truemail.rb +++ b/config/initializers/truemail.rb @@ -15,10 +15,10 @@ Truemail.configure do |config| # config.smtp_error_body_pattern = /regex_pattern/ # Optional parameter. Connection timeout is equal to 2 ms by default. - config.connection_timeout = ENV['default_connection_timeout'].to_i + config.connection_timeout = ENV['default_connection_timeout'].to_i | 1 # Optional parameter. A SMTP server response timeout is equal to 2 ms by default. - config.response_timeout = ENV['default_response_timeout'].to_i + config.response_timeout = ENV['default_response_timeout'].to_i | 1 # Optional parameter. Total of connection attempts. It is equal to 2 by default. # This parameter uses in mx lookup timeout error and smtp request (for cases when From 921cb93dbe80bdb14b100363b3a64d8d1cd4c871 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Mon, 27 Dec 2021 11:55:48 +0200 Subject: [PATCH 7/7] added log output for a and aaaa validation --- app/interactions/actions/email_check.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/interactions/actions/email_check.rb b/app/interactions/actions/email_check.rb index 6474e02ee..5f4616bab 100644 --- a/app/interactions/actions/email_check.rb +++ b/app/interactions/actions/email_check.rb @@ -54,7 +54,12 @@ module Actions email_domain = Mail::Address.new(@email).domain result_validation = check_for_records_value(domain: email_domain, value: 'A') + logger.info "Validated A record for #{email_domain}. Validation result - #{result_validation}" + p "Validated A record for #{email_domain}. Validation result - #{result_validation}" + result_validation = check_for_records_value(domain: email_domain, value: 'AAAA') if result_validation.empty? + logger.info "Validated AAAA record for #{email_domain}. Validation result - #{result_validation}" if result_validation.empty? + p "Validated AAAA record for #{email_domain}. Validation result - #{result_validation}" if result_validation.empty? result_validation.present? ? result.success = true : result.success = false