Refactored and corrected code for domain force delete

This commit is contained in:
Sergei Tsoganov 2023-05-17 16:04:40 +03:00
parent 316f00cadc
commit d3bca1434c
10 changed files with 223 additions and 259 deletions

View file

@ -16,19 +16,28 @@ module Actions
end
def resolve_a_and_aaaa_records(dns_servers:, email_domain:, value:)
Resolv::DNS.open({ nameserver: dns_servers }) do |dns|
dns.timeouts = ENV['a_and_aaaa_validation_timeout'].to_i || 1
ress = nil
Resolv::DNS.open(nameserver: dns_servers, ndots: 1, search: []) do |dns|
dns.timeouts = (ENV['a_and_aaaa_validation_timeout'] || 1).to_i
case value
when 'A'
ress = dns.getresources email_domain, Resolv::DNS::Resource::IN::A
resolve_a_records(dns: dns, domain: email_domain)
when 'AAAA'
ress = dns.getresources email_domain, Resolv::DNS::Resource::IN::AAAA
resolve_aaaa_records(dns: dns, domain: email_domain)
else
[]
end
ress.map(&:address)
end
end
def resolve_a_records(dns:, domain:)
resources = dns.getresources(domain, Resolv::DNS::Resource::IN::A)
resources.map(&:address)
end
def resolve_aaaa_records(dns:, domain:)
resources = dns.getresources(domain, Resolv::DNS::Resource::IN::AAAA)
resources.map(&:address)
end
end
end

View file

@ -2,6 +2,8 @@ module Actions
class EmailCheck
attr_reader :email, :validation_eventable, :check_level
SAVE_RESULTS_BATCH_SIZE = 500
def initialize(email:, validation_eventable:, check_level: nil)
@email = email
@validation_eventable = validation_eventable
@ -11,7 +13,7 @@ module Actions
def call
result = check_email(email)
save_result(result)
result.success ? log_success : log_failure(result)
handle_logging(result)
result.success
end
@ -22,55 +24,63 @@ module Actions
end
def calculate_check_level
Rails.env.test? && check_level == 'smtp' ? :mx : check_level.to_sym
check_level_sym = check_level.to_sym
return :mx if Rails.env.test? && check_level_sym == :smtp
check_level_sym
end
def filtering_old_failed_records(result, contact)
def filter_old_failed_records(result, contact)
ValidationEvent::INVALID_EVENTS_COUNT_BY_LEVEL.each do |level, limit|
handle_failed_records(contact: contact, check_level: level, limit: limit, success: result.success)
end
end
def handle_failed_records(contact:, check_level:, limit:, success:)
if @check_level.to_sym == check_level && !success && contact.validation_events.count > limit
contact.validation_events.order!(created_at: :asc)
while contact.validation_events.count > limit
contact.validation_events.first.destroy
end
end
return unless @check_level.to_sym == check_level.to_sym && !success
excess_events_count = contact.validation_events.count - limit
return unless excess_events_count.positive?
contact.validation_events.order(created_at: :asc).limit(excess_events_count).destroy_all
end
def filtering_old_records(contact:, success:)
return unless success
contact.validation_events.destroy_all
def filter_old_records(contact:, success:)
contact.validation_events.destroy_all if success
end
def save_result(result)
contacts = Contact.where(email: email)
if !result.success && @check_level == 'mx'
result_validation = Actions::AAndAaaaEmailValidation.call(email: @email, value: 'A')
output_a_and_aaaa_validation_results(email: @email, result: result_validation, type: 'A')
result_validation = Actions::AAndAaaaEmailValidation.call(email: @email, value: 'AAAA') if result_validation.empty?
output_a_and_aaaa_validation_results(email: @email, result: result_validation, type: 'AAAA')
result.success = result_validation.present?
end
handle_mx_validation(result) if !result.success && @check_level == 'mx'
result.configuration = nil
contacts.find_in_batches(batch_size: 500) do |contact_batches|
contacts.find_in_batches(batch_size: SAVE_RESULTS_BATCH_SIZE) do |contact_batches|
contact_batches.each do |contact|
# methods should be in this order!
filtering_old_records(contact: contact, success: result.success)
contact.validation_events.create(validation_event_attrs(result))
filtering_old_failed_records(result, contact)
handle_saving_result(contact, result)
end
end
rescue ActiveRecord::RecordNotSaved
logger.info "Cannot save validation result for #{log_object_id}"
true
logger.info "Cannot save validation result for #{log_object_id}" and return true
end
def handle_mx_validation(result)
result_validation = Actions::AAndAaaaEmailValidation.call(email: email, value: 'A')
output_a_and_aaaa_validation_results(email: email, result: result_validation, type: 'A')
if result_validation.empty?
result_validation = Actions::AAndAaaaEmailValidation.call(email: email, value: 'AAAA')
output_a_and_aaaa_validation_results(email: email, result: result_validation, type: 'AAAA')
end
result.success = result_validation.present?
end
def handle_saving_result(contact, result)
filter_old_records(contact: contact, success: result.success)
contact.validation_events.create!(validation_event_attrs(result))
filter_old_failed_records(result, contact)
end
def output_a_and_aaaa_validation_results(email:, result:, type:)
@ -79,27 +89,6 @@ module Actions
logger.info "Validated #{type} record for #{email}. Validation result - #{result}"
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|
timeouts = ENV['a_and_aaaa_validation_timeout'] || '1'
dns.timeouts = timeouts.to_i
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(&:address)
end
result
end
def validation_event_attrs(result)
{
event_data: event_data(result),
@ -116,13 +105,13 @@ module Actions
result.to_h.merge(check_level: check_level)
end
def log_failure(result)
logger.info "Failed to validate email #{email} for the #{log_object_id}."
logger.info "Validation level #{check_level}, the result was #{result}"
end
def log_success
logger.info "Successfully validated email #{email} for the #{log_object_id}."
def handle_logging(result)
if result.success
logger.info "Successfully validated email #{email} for #{log_object_id}."
else
logger.info "Failed to validate email #{email} for #{log_object_id}."
logger.info "Validation level #{check_level}, the result was #{result}"
end
end
def log_object_id

View file

@ -16,25 +16,26 @@ module Domains
end
def force_delete_condition(domain)
domain.force_delete_scheduled? &&
force_delete_scheduled?(domain) &&
template_of_invalid_email?(domain) &&
contact_emails_valid?(domain) &&
bounces_absent?(domain)
end
def force_delete_scheduled?(domain)
domain.force_delete_scheduled?
end
def template_of_invalid_email?(domain)
domain.template_name == 'invalid_email'
end
def contact_emails_valid?(domain)
flag = nil
domain.contacts.each do |c|
flag = c.need_to_lift_force_delete?
return flag unless flag
return false unless c.need_to_lift_force_delete?
end
flag && domain.registrant.need_to_lift_force_delete?
domain.registrant.need_to_lift_force_delete?
end
def bounces_absent?(domain)