Merge pull request #1770 from internetee/1769-move-domain-release-processing-to-interactor

Move domain delete confirm procedure to interactor
This commit is contained in:
Timo Võhmar 2020-12-16 16:46:42 +02:00 committed by GitHub
commit 2fc4c9df14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 174 additions and 45 deletions

View file

@ -0,0 +1,53 @@
module Domains
module DeleteConfirm
class Base < ActiveInteraction::Base
object :domain,
class: Domain,
description: 'Domain to confirm release'
string :action
string :initiator,
default: nil
validates :domain, :action, presence: true
validates :action, inclusion: { in: [RegistrantVerification::CONFIRMED,
RegistrantVerification::REJECTED] }
def raise_errors!(domain)
return unless domain.errors.any?
message = "domain #{domain.name} failed with errors #{domain.errors.full_messages}"
throw message
end
def notify_registrar(message_key)
domain.registrar.notifications.create!(
text: "#{I18n.t(message_key)}: #{domain.name}",
attached_obj_id: domain.id,
attached_obj_type: domain.class.to_s
)
end
def preclean_pendings
domain.registrant_verification_token = nil
domain.registrant_verification_asked_at = nil
end
def clean_pendings!
domain.is_admin = true
domain.registrant_verification_token = nil
domain.registrant_verification_asked_at = nil
domain.pending_json = {}
clear_statuses
domain.save
end
def clear_statuses
domain.statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION)
domain.statuses.delete(DomainStatus::PENDING_UPDATE)
domain.statuses.delete(DomainStatus::PENDING_DELETE)
domain.status_notes[DomainStatus::PENDING_UPDATE] = ''
domain.status_notes[DomainStatus::PENDING_DELETE] = ''
end
end
end
end

View file

@ -0,0 +1,17 @@
module Domains
module DeleteConfirm
class ProcessAction < Base
def execute
::PaperTrail.request.whodunnit = "interaction - #{self.class.name} - #{action} by"\
" #{initiator}"
case action
when RegistrantVerification::CONFIRMED
compose(ProcessDeleteConfirmed, inputs)
when RegistrantVerification::REJECTED
compose(ProcessDeleteRejected, inputs)
end
end
end
end
end

View file

@ -0,0 +1,50 @@
module Domains
module DeleteConfirm
class ProcessDeleteConfirmed < Base
def execute
notify_registrar(:poll_pending_delete_confirmed_by_registrant)
domain.apply_pending_delete!
raise_errors!(domain)
end
def apply_pending_delete!
preclean_pendings
clean_pendings!
DomainDeleteMailer.accepted(domain).deliver_now
domain.set_pending_delete!
end
def set_pending_delete!
unless domain.pending_deletable?
add_epp_error
return
end
domain.delete_date = delete_date
domain.statuses << DomainStatus::PENDING_DELETE
set_server_hold if server_holdable?
domain.save(validate: false)
end
def set_server_hold
domain.statuses << DomainStatus::SERVER_HOLD
domain.outzone_at = Time.current
end
def server_holdable?
return false if domain.statuses.include?(DomainStatus::SERVER_HOLD)
return false if domain.statuses.include?(DomainStatus::SERVER_MANUAL_INZONE)
true
end
def delete_date
Time.zone.today + Setting.redemption_grace_period.days + 1.day
end
def add_epp_error
domain.add_epp_error('2304', nil, nil, I18n.t(:object_status_prohibits_operation))
end
end
end
end

View file

@ -0,0 +1,32 @@
module Domains
module DeleteConfirm
class ProcessDeleteRejected < Base
def execute
domain.cancel_pending_delete
notify_registrar(:poll_pending_delete_rejected_by_registrant)
domain.save(validate: false)
raise_errors!(domain)
send_domain_delete_rejected_email
end
def send_domain_delete_rejected_email
if domain.registrant_verification_token.blank?
warn "EMAIL NOT DELIVERED: registrant_verification_token is missing for #{domain.name}"
elsif domain.registrant_verification_asked_at.blank?
warn "EMAIL NOT DELIVERED: registrant_verification_asked_at is missing for #{domain.name}"
else
send_email
end
end
def warn(message)
Rails.logger.warn(message)
end
def send_email
DomainDeleteMailer.rejected(domain).deliver_now
end
end
end
end

View file

@ -1,5 +1,5 @@
module Domains module Domains
module DeleteConfirm module DeleteConfirmEmail
class SendRequest < ActiveInteraction::Base class SendRequest < ActiveInteraction::Base
object :domain, object :domain,
class: Domain, class: Domain,

View file

@ -1,39 +1,11 @@
class DomainDeleteConfirmJob < Que::Job class DomainDeleteConfirmJob < ApplicationJob
def run(domain_id, action, initiator = nil) queue_as :default
::PaperTrail.request.whodunnit = "job - #{self.class.name} - #{action} by #{initiator}"
# it's recommended to keep transaction against job table as short as possible.
ActiveRecord::Base.transaction do
domain = Epp::Domain.find(domain_id)
case action def perform(domain_id, action, initiator = nil)
when RegistrantVerification::CONFIRMED domain = Epp::Domain.find(domain_id)
domain.notify_registrar(:poll_pending_delete_confirmed_by_registrant)
domain.apply_pending_delete!
raise_errors!(domain)
when RegistrantVerification::REJECTED Domains::DeleteConfirm::ProcessAction.run(domain: domain,
domain.statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION) action: action,
domain.notify_registrar(:poll_pending_delete_rejected_by_registrant) initiator: initiator)
domain.cancel_pending_delete
domain.save(validate: false)
raise_errors!(domain)
if domain.registrant_verification_token.blank?
Rails.logger.warn "EMAIL NOT DELIVERED: registrant_verification_token is missing for #{domain.name}"
elsif domain.registrant_verification_asked_at.blank?
Rails.logger.warn "EMAIL NOT DELIVERED: registrant_verification_asked_at is missing for #{domain.name}"
else
DomainDeleteMailer.rejected(domain).deliver_now
end
end
destroy # it's best to destroy the job in the same transaction
end
end
def raise_errors!(domain)
throw "domain #{domain.name} failed with errors #{domain.errors.full_messages}" if domain.errors.any?
end end
end end

View file

@ -421,7 +421,7 @@ class Domain < ApplicationRecord
pending_delete_confirmation! pending_delete_confirmation!
save(validate: false) # should check if this did succeed save(validate: false) # should check if this did succeed
Domains::DeleteConfirm::SendRequest.run(domain: self) Domains::DeleteConfirmEmail::SendRequest.run(domain: self)
end end
def cancel_pending_delete def cancel_pending_delete

View file

@ -30,12 +30,12 @@ class RegistrantVerification < ApplicationRecord
def domain_registrant_delete_confirm!(initiator) def domain_registrant_delete_confirm!(initiator)
self.action_type = DOMAIN_DELETE self.action_type = DOMAIN_DELETE
self.action = CONFIRMED self.action = CONFIRMED
DomainDeleteConfirmJob.enqueue domain.id, CONFIRMED, initiator if save DomainDeleteConfirmJob.perform_later domain.id, CONFIRMED, initiator if save
end end
def domain_registrant_delete_reject!(initiator) def domain_registrant_delete_reject!(initiator)
self.action_type = DOMAIN_DELETE self.action_type = DOMAIN_DELETE
self.action = REJECTED self.action = REJECTED
DomainDeleteConfirmJob.enqueue domain.id, REJECTED, initiator if save DomainDeleteConfirmJob.perform_later domain.id, REJECTED, initiator if save
end end
end end

View file

@ -18,7 +18,7 @@ class DomainDeleteConfirmJobTest < ActiveSupport::TestCase
new_registrant_email: @new_registrant.email, new_registrant_email: @new_registrant.email,
current_user_id: @user.id }) current_user_id: @user.id })
DomainDeleteConfirmJob.enqueue(@domain.id, RegistrantVerification::REJECTED) DomainDeleteConfirmJob.perform_now(@domain.id, RegistrantVerification::REJECTED)
last_registrar_notification = @domain.registrar.notifications.last last_registrar_notification = @domain.registrar.notifications.last
assert_equal(last_registrar_notification.attached_obj_id, @domain.id) assert_equal(last_registrar_notification.attached_obj_id, @domain.id)
@ -31,7 +31,7 @@ class DomainDeleteConfirmJobTest < ActiveSupport::TestCase
new_registrant_email: @new_registrant.email, new_registrant_email: @new_registrant.email,
current_user_id: @user.id }) current_user_id: @user.id })
DomainDeleteConfirmJob.enqueue(@domain.id, RegistrantVerification::CONFIRMED) DomainDeleteConfirmJob.perform_now(@domain.id, RegistrantVerification::CONFIRMED)
last_registrar_notification = @domain.registrar.notifications.last last_registrar_notification = @domain.registrar.notifications.last
assert_equal(last_registrar_notification.attached_obj_id, @domain.id) assert_equal(last_registrar_notification.attached_obj_id, @domain.id)
@ -51,7 +51,7 @@ class DomainDeleteConfirmJobTest < ActiveSupport::TestCase
assert @domain.registrant_delete_confirmable?(@domain.registrant_verification_token) assert @domain.registrant_delete_confirmable?(@domain.registrant_verification_token)
assert_equal @user.id, @domain.pending_json['current_user_id'] assert_equal @user.id, @domain.pending_json['current_user_id']
DomainDeleteConfirmJob.enqueue(@domain.id, RegistrantVerification::CONFIRMED) DomainDeleteConfirmJob.perform_now(@domain.id, RegistrantVerification::CONFIRMED)
@domain.reload @domain.reload
assert @domain.statuses.include? DomainStatus::PENDING_DELETE assert @domain.statuses.include? DomainStatus::PENDING_DELETE
@ -72,7 +72,7 @@ class DomainDeleteConfirmJobTest < ActiveSupport::TestCase
assert @domain.registrant_delete_confirmable?(@domain.registrant_verification_token) assert @domain.registrant_delete_confirmable?(@domain.registrant_verification_token)
assert_equal @user.id, @domain.pending_json['current_user_id'] assert_equal @user.id, @domain.pending_json['current_user_id']
DomainDeleteConfirmJob.enqueue(@domain.id, RegistrantVerification::REJECTED) DomainDeleteConfirmJob.perform_now(@domain.id, RegistrantVerification::REJECTED)
@domain.reload @domain.reload
assert_equal ['ok'], @domain.statuses assert_equal ['ok'], @domain.statuses

View file

@ -1,6 +1,7 @@
require 'application_system_test_case' require 'application_system_test_case'
class DomainDeleteConfirmsTest < ApplicationSystemTestCase class DomainDeleteConfirmsTest < ApplicationSystemTestCase
include ActionMailer::TestHelper
setup do setup do
@user = users(:registrant) @user = users(:registrant)
sign_in @user sign_in @user
@ -13,7 +14,9 @@ class DomainDeleteConfirmsTest < ApplicationSystemTestCase
def test_enqueues_approve_job_after_verification def test_enqueues_approve_job_after_verification
visit registrant_domain_delete_confirm_url(@domain.id, token: @domain.registrant_verification_token) visit registrant_domain_delete_confirm_url(@domain.id, token: @domain.registrant_verification_token)
click_on 'Confirm domain delete' perform_enqueued_jobs do
click_on 'Confirm domain delete'
end
assert_text 'Domain registrant change has successfully received.' assert_text 'Domain registrant change has successfully received.'
@domain.reload @domain.reload
@ -23,7 +26,9 @@ class DomainDeleteConfirmsTest < ApplicationSystemTestCase
def test_enqueues_reject_job_after_verification def test_enqueues_reject_job_after_verification
visit registrant_domain_delete_confirm_url(@domain.id, token: @domain.registrant_verification_token) visit registrant_domain_delete_confirm_url(@domain.id, token: @domain.registrant_verification_token)
click_on 'Reject domain delete' perform_enqueued_jobs do
click_on 'Reject domain delete'
end
assert_text 'Domain registrant change has been rejected successfully.' assert_text 'Domain registrant change has been rejected successfully.'
@domain.reload @domain.reload