mirror of
https://github.com/internetee/registry.git
synced 2025-08-06 09:45:11 +02:00
Merge remote-tracking branch 'origin/master' into repp-domains
This commit is contained in:
commit
221e4ba578
140 changed files with 2575 additions and 731 deletions
62
app/interactions/domains/bulk_renew/single_domain_renew.rb
Normal file
62
app/interactions/domains/bulk_renew/single_domain_renew.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
module Domains
|
||||
module BulkRenew
|
||||
class SingleDomainRenew < ActiveInteraction::Base
|
||||
object :domain,
|
||||
class: Epp::Domain
|
||||
integer :period
|
||||
string :unit
|
||||
object :registrar
|
||||
|
||||
def execute
|
||||
in_transaction_with_retries do
|
||||
success = domain.renew(domain.valid_to, period, unit)
|
||||
if success
|
||||
check_balance
|
||||
reduce_balance
|
||||
else
|
||||
add_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def check_balance
|
||||
compose(Domains::CheckBalance::SingleDomain,
|
||||
domain: domain,
|
||||
operation: 'renew',
|
||||
period: period,
|
||||
unit: unit)
|
||||
end
|
||||
|
||||
def reduce_balance
|
||||
domain_pricelist = domain.pricelist('renew', period, unit)
|
||||
registrar.debit!(sum: domain_pricelist.price.amount,
|
||||
description: "#{I18n.t('renew')} #{domain.name}",
|
||||
activity_type: AccountActivity::RENEW,
|
||||
price: domain_pricelist)
|
||||
end
|
||||
|
||||
def in_transaction_with_retries
|
||||
if Rails.env.test?
|
||||
yield
|
||||
else
|
||||
transaction_wrapper { yield }
|
||||
end
|
||||
rescue ActiveRecord::StatementInvalid
|
||||
sleep rand / 100
|
||||
retry
|
||||
end
|
||||
|
||||
def transaction_wrapper
|
||||
ActiveRecord::Base.transaction(isolation: :serializable) do
|
||||
yield if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_error
|
||||
errors.add(:domain, I18n.t('domain_renew_error_for_domain', domain: domain.name))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
56
app/interactions/domains/bulk_renew/start.rb
Normal file
56
app/interactions/domains/bulk_renew/start.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
module Domains
|
||||
module BulkRenew
|
||||
class Start < ActiveInteraction::Base
|
||||
array :domains do
|
||||
object class: Epp::Domain
|
||||
end
|
||||
string :period_element
|
||||
object :registrar
|
||||
|
||||
def execute
|
||||
if renewable?
|
||||
domains.each do |domain|
|
||||
task = run_task(domain)
|
||||
manage_errors(task)
|
||||
end
|
||||
else
|
||||
manage_errors(mass_check_balance)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def renewable?
|
||||
mass_check_balance.valid? && mass_check_balance.result
|
||||
end
|
||||
|
||||
def period
|
||||
period_element.to_i.zero? ? 1 : period_element.to_i
|
||||
end
|
||||
|
||||
def unit
|
||||
period_element[-1] || 'y'
|
||||
end
|
||||
|
||||
def mass_check_balance
|
||||
Domains::CheckBalance::Mass.run(domains: domains,
|
||||
operation: 'renew',
|
||||
period: period,
|
||||
unit: unit,
|
||||
balance: registrar.balance)
|
||||
end
|
||||
|
||||
def manage_errors(task)
|
||||
task.errors.each { |k, v| errors.add(k, v) } unless task.valid?
|
||||
errors.add(:domain, I18n.t('not_enough_funds')) unless task.result
|
||||
end
|
||||
|
||||
def run_task(domain)
|
||||
Domains::BulkRenew::SingleDomainRenew.run(domain: domain,
|
||||
period: period,
|
||||
unit: unit,
|
||||
registrar: registrar)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
9
app/interactions/domains/cancel_force_delete/base.rb
Normal file
9
app/interactions/domains/cancel_force_delete/base.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
module Domains
|
||||
module CancelForceDelete
|
||||
class Base < ActiveInteraction::Base
|
||||
object :domain,
|
||||
class: Domain,
|
||||
description: 'Domain to cancel ForceDelete on'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
module Domains
|
||||
module CancelForceDelete
|
||||
class CancelForceDelete < Base
|
||||
def execute
|
||||
compose(RemoveForceDeleteStatuses, inputs)
|
||||
compose(RestoreStatusesBeforeForceDelete, inputs)
|
||||
compose(ClearForceDeleteData, inputs)
|
||||
compose(NotifyRegistrar, inputs)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
module Domains
|
||||
module CancelForceDelete
|
||||
class ClearForceDeleteData < Base
|
||||
def execute
|
||||
domain.force_delete_data = nil
|
||||
domain.force_delete_date = nil
|
||||
domain.force_delete_start = nil
|
||||
domain.save(validate: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
module Domains
|
||||
module CancelForceDelete
|
||||
class NotifyRegistrar < Base
|
||||
def execute
|
||||
domain.registrar.notifications.create!(text: I18n.t('force_delete_cancelled',
|
||||
domain_name: domain.name))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
module Domains
|
||||
module CancelForceDelete
|
||||
class RemoveForceDeleteStatuses < Base
|
||||
def execute
|
||||
domain.statuses.delete(DomainStatus::FORCE_DELETE)
|
||||
domain.statuses.delete(DomainStatus::SERVER_RENEW_PROHIBITED)
|
||||
domain.statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED)
|
||||
domain.statuses.delete(DomainStatus::CLIENT_HOLD)
|
||||
domain.save(validate: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
module Domains
|
||||
module CancelForceDelete
|
||||
class RestoreStatusesBeforeForceDelete < Base
|
||||
def execute
|
||||
domain.statuses = domain.statuses_before_force_delete
|
||||
domain.statuses_before_force_delete = nil
|
||||
domain.save(validate: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
33
app/interactions/domains/check_balance/mass.rb
Normal file
33
app/interactions/domains/check_balance/mass.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
module Domains
|
||||
module CheckBalance
|
||||
class Mass < ActiveInteraction::Base
|
||||
array :domains do
|
||||
object class: Epp::Domain
|
||||
end
|
||||
string :operation
|
||||
integer :period
|
||||
string :unit
|
||||
float :balance
|
||||
|
||||
attr_accessor :total_price
|
||||
|
||||
def execute
|
||||
calculate_total_price
|
||||
|
||||
balance >= @total_price
|
||||
end
|
||||
|
||||
def calculate_total_price
|
||||
@total_price = 0
|
||||
domains.each do |domain|
|
||||
task = Domains::CheckBalance::SingleDomain.run(domain: domain,
|
||||
operation: 'renew',
|
||||
period: period,
|
||||
unit: unit)
|
||||
|
||||
task.valid? ? @total_price += task.result : errors.merge!(task.errors)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
26
app/interactions/domains/check_balance/single_domain.rb
Normal file
26
app/interactions/domains/check_balance/single_domain.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
module Domains
|
||||
module CheckBalance
|
||||
class SingleDomain < ActiveInteraction::Base
|
||||
object :domain,
|
||||
class: Epp::Domain
|
||||
|
||||
string :operation
|
||||
integer :period
|
||||
string :unit
|
||||
|
||||
def execute
|
||||
return domain_pricelist.price.amount if domain_pricelist.try(:price)
|
||||
|
||||
errors.add(:domain, I18n.t(:active_price_missing_for_operation_with_domain,
|
||||
domain: domain.name))
|
||||
false
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def domain_pricelist
|
||||
domain.pricelist(operation, period.try(:to_i), unit)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
10
app/interactions/domains/client_hold/base.rb
Normal file
10
app/interactions/domains/client_hold/base.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
module Domains
|
||||
module ClientHold
|
||||
class Base < ActiveInteraction::Base
|
||||
def to_stdout(message)
|
||||
time = Time.zone.now.utc
|
||||
STDOUT << "#{time} - #{message}\n" unless Rails.env.test?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
69
app/interactions/domains/client_hold/process_client_hold.rb
Normal file
69
app/interactions/domains/client_hold/process_client_hold.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
module Domains
|
||||
module ClientHold
|
||||
class ProcessClientHold < Base
|
||||
object :domain,
|
||||
class: Domain,
|
||||
description: 'Domain to set ClientHold on'
|
||||
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def execute
|
||||
notify_on_grace_period if should_notify_on_soft_force_delete?
|
||||
|
||||
return unless client_holdable?
|
||||
|
||||
domain.statuses << DomainStatus::CLIENT_HOLD
|
||||
to_stdout("DomainCron.start_client_hold: #{domain.id} (#{domain.name}) #{domain.changes}\n")
|
||||
|
||||
domain.save(validate: false)
|
||||
notify_client_hold
|
||||
|
||||
to_stdout("Successfully set client_hold on (#{domain.name})")
|
||||
end
|
||||
|
||||
def notify_on_grace_period
|
||||
domain.registrar.notifications.create!(text: I18n.t('grace_period_started_domain',
|
||||
domain_name: domain.name,
|
||||
date: domain.force_delete_start))
|
||||
send_mail if domain.template_name.present?
|
||||
domain.update(contact_notification_sent_date: Time.zone.today)
|
||||
end
|
||||
|
||||
def notify_client_hold
|
||||
domain.registrar.notifications.create!(text: I18n.t('force_delete_set_on_domain',
|
||||
domain_name: domain.name,
|
||||
outzone_date: domain.outzone_date,
|
||||
purge_date: domain.purge_date))
|
||||
end
|
||||
|
||||
def send_mail
|
||||
DomainDeleteMailer.forced(domain: domain,
|
||||
registrar: domain.registrar,
|
||||
registrant: domain.registrant,
|
||||
template_name: domain.template_name).deliver_now
|
||||
end
|
||||
|
||||
def should_notify_on_soft_force_delete?
|
||||
domain.force_delete_scheduled? && domain.contact_notification_sent_date.blank? &&
|
||||
domain.force_delete_start.to_date <= Time.zone.now.to_date &&
|
||||
domain.force_delete_type.to_sym == :soft &&
|
||||
!domain.statuses.include?(DomainStatus::CLIENT_HOLD)
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
def client_holdable?
|
||||
domain.force_delete_scheduled? &&
|
||||
!domain.statuses.include?(DomainStatus::CLIENT_HOLD) &&
|
||||
domain.force_delete_start.present? &&
|
||||
force_delete_lte_today && force_delete_lte_valid_date
|
||||
end
|
||||
|
||||
def force_delete_lte_today
|
||||
domain.force_delete_start + Setting.expire_warning_period.days <= Time.zone.now
|
||||
end
|
||||
|
||||
def force_delete_lte_valid_date
|
||||
domain.force_delete_start + Setting.expire_warning_period.days <= domain.valid_to
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
17
app/interactions/domains/client_hold/set_client_hold.rb
Normal file
17
app/interactions/domains/client_hold/set_client_hold.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
module Domains
|
||||
module ClientHold
|
||||
class SetClientHold < Base
|
||||
def execute
|
||||
to_stdout('Setting client_hold to domains\n')
|
||||
|
||||
::PaperTrail.request.whodunnit = "cron - #{self.class.name}"
|
||||
|
||||
::Domain.force_delete_scheduled.each do |domain|
|
||||
Domains::ClientHold::ProcessClientHold.run(domain: domain)
|
||||
end
|
||||
|
||||
to_stdout('All client_hold setting are done\n')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
9
app/interactions/domains/delete/base.rb
Normal file
9
app/interactions/domains/delete/base.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
module Domains
|
||||
module Delete
|
||||
class Base < ActiveInteraction::Base
|
||||
object :domain,
|
||||
class: Domain,
|
||||
description: 'Domain to delete'
|
||||
end
|
||||
end
|
||||
end
|
13
app/interactions/domains/delete/do_delete.rb
Normal file
13
app/interactions/domains/delete/do_delete.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
module Domains
|
||||
module Delete
|
||||
class DoDelete < Base
|
||||
def execute
|
||||
::PaperTrail.request.whodunnit = "interaction - #{self.class.name}"
|
||||
WhoisRecord.where(domain_id: domain.id).destroy_all
|
||||
|
||||
domain.destroy
|
||||
compose(Domains::Delete::NotifyRegistrar, inputs)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
app/interactions/domains/delete/notify_registrar.rb
Normal file
14
app/interactions/domains/delete/notify_registrar.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Domains
|
||||
module Delete
|
||||
class NotifyRegistrar < Base
|
||||
def execute
|
||||
bye_bye = domain.versions.last
|
||||
domain.registrar.notifications.create!(
|
||||
text: "#{I18n.t(:domain_deleted)}: #{domain.name}",
|
||||
attached_obj_id: bye_bye.id,
|
||||
attached_obj_type: bye_bye.class.to_s
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
53
app/interactions/domains/delete_confirm/base.rb
Normal file
53
app/interactions/domains/delete_confirm/base.rb
Normal 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
|
17
app/interactions/domains/delete_confirm/process_action.rb
Normal file
17
app/interactions/domains/delete_confirm/process_action.rb
Normal 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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,24 @@
|
|||
module Domains
|
||||
module DeleteConfirmEmail
|
||||
class SendRequest < ActiveInteraction::Base
|
||||
object :domain,
|
||||
class: Domain,
|
||||
description: 'Domain to send delete confirmation'
|
||||
|
||||
def execute
|
||||
log
|
||||
DomainDeleteMailer.confirmation_request(domain: domain,
|
||||
registrar: domain.registrar,
|
||||
registrant: domain.registrant).deliver_later
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def log
|
||||
message = "Send DomainDeleteMailer#confirm email for domain #{domain.name} (##{domain.id})"\
|
||||
" to #{domain.registrant.email}"
|
||||
Rails.logger.info(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
10
app/interactions/domains/expire_period/base.rb
Normal file
10
app/interactions/domains/expire_period/base.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
module Domains
|
||||
module ExpirePeriod
|
||||
class Base < ActiveInteraction::Base
|
||||
def to_stdout(message)
|
||||
time = Time.zone.now.utc
|
||||
STDOUT << "#{time} - #{message}\n" unless Rails.env.test?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
28
app/interactions/domains/expire_period/process_expired.rb
Normal file
28
app/interactions/domains/expire_period/process_expired.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
module Domains
|
||||
module ExpirePeriod
|
||||
class ProcessExpired < Base
|
||||
object :domain,
|
||||
class: Domain,
|
||||
description: 'Domain to set expiration'
|
||||
|
||||
def execute
|
||||
set_graceful_expired
|
||||
to_stdout("start_expire_period: ##{domain.id} (#{domain.name}) #{domain.changes}")
|
||||
|
||||
saved = domain.save(validate: false)
|
||||
|
||||
DomainExpireEmailJob.enqueue(domain.id, run_at: send_time) if saved
|
||||
end
|
||||
|
||||
def set_graceful_expired
|
||||
domain.outzone_at = domain.expire_time + Domain.expire_warning_period
|
||||
domain.delete_date = domain.outzone_at + Domain.redemption_grace_period
|
||||
domain.statuses |= [DomainStatus::EXPIRED]
|
||||
end
|
||||
|
||||
def send_time
|
||||
domain.valid_to + Setting.expiration_reminder_mail.to_i.days
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
19
app/interactions/domains/expire_period/start.rb
Normal file
19
app/interactions/domains/expire_period/start.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
module Domains
|
||||
module ExpirePeriod
|
||||
class Start < Base
|
||||
def execute
|
||||
::PaperTrail.request.whodunnit = "cron - #{self.class.name}"
|
||||
count = 0
|
||||
|
||||
Domain.expired.each do |domain|
|
||||
next unless domain.expirable?
|
||||
|
||||
count += 1
|
||||
Domains::ExpirePeriod::ProcessExpired.run(domain: domain)
|
||||
end
|
||||
|
||||
to_stdout("Successfully expired #{count}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
10
app/interactions/domains/expired_pendings/base.rb
Normal file
10
app/interactions/domains/expired_pendings/base.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
module Domains
|
||||
module ExpiredPendings
|
||||
class Base < ActiveInteraction::Base
|
||||
def to_stdout(message)
|
||||
time = Time.zone.now.utc
|
||||
STDOUT << "#{time} - #{message}\n" unless Rails.env.test?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
35
app/interactions/domains/expired_pendings/clean_all.rb
Normal file
35
app/interactions/domains/expired_pendings/clean_all.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
module Domains
|
||||
module ExpiredPendings
|
||||
class CleanAll < Base
|
||||
def execute
|
||||
to_stdout('Clean expired domain pendings')
|
||||
|
||||
::PaperTrail.request.whodunnit = "cron - #{self.class.name}"
|
||||
|
||||
count = 0
|
||||
expired_pending_domains.each do |domain|
|
||||
log_error(domain) && next unless need_to_be_cleared?(domain)
|
||||
count += 1
|
||||
Domains::ExpiredPendings::ProcessClean.run(domain: domain)
|
||||
end
|
||||
to_stdout("Successfully cancelled #{count} domain pendings")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def need_to_be_cleared?(domain)
|
||||
domain.pending_update? || domain.pending_delete? || domain.pending_delete_confirmation?
|
||||
end
|
||||
|
||||
def log_error(domain)
|
||||
to_stdout("ISSUE: DOMAIN #{domain.id}: #{domain.name} IS IN EXPIRED PENDING LIST, "\
|
||||
'but no pendingDelete/pendingUpdate state present!')
|
||||
end
|
||||
|
||||
def expired_pending_domains
|
||||
expire_at = Setting.expire_pending_confirmation.hours.ago
|
||||
Domain.where('registrant_verification_asked_at <= ?', expire_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
60
app/interactions/domains/expired_pendings/process_clean.rb
Normal file
60
app/interactions/domains/expired_pendings/process_clean.rb
Normal file
|
@ -0,0 +1,60 @@
|
|||
module Domains
|
||||
module ExpiredPendings
|
||||
class ProcessClean < Base
|
||||
object :domain,
|
||||
class: Domain
|
||||
|
||||
def execute
|
||||
check_notify
|
||||
clean_pendings
|
||||
|
||||
to_stdout("DomainCron.clean_expired_pendings: ##{domain.id} (#{domain.name})")
|
||||
UpdateWhoisRecordJob.enqueue domain.name, 'domain'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def notify_pending_update
|
||||
RegistrantChangeMailer.expired(domain: domain,
|
||||
registrar: domain.registrar,
|
||||
registrant: domain.registrant).deliver_later
|
||||
end
|
||||
|
||||
def notify_pending_delete
|
||||
DomainDeleteMailer.expired(domain).deliver_later
|
||||
end
|
||||
|
||||
def clean_pendings
|
||||
clean_verification_data
|
||||
domain.pending_json = {}
|
||||
clean_statuses
|
||||
domain.save
|
||||
end
|
||||
|
||||
def statuses_to_clean
|
||||
[DomainStatus::PENDING_DELETE_CONFIRMATION,
|
||||
DomainStatus::PENDING_UPDATE,
|
||||
DomainStatus::PENDING_DELETE]
|
||||
end
|
||||
|
||||
def clean_statuses
|
||||
domain.statuses = domain.statuses - statuses_to_clean
|
||||
domain.status_notes[DomainStatus::PENDING_UPDATE] = ''
|
||||
domain.status_notes[DomainStatus::PENDING_DELETE] = ''
|
||||
end
|
||||
|
||||
def clean_verification_data
|
||||
domain.registrant_verification_token = nil
|
||||
domain.registrant_verification_asked_at = nil
|
||||
end
|
||||
|
||||
def check_notify
|
||||
notify_pending_update if domain.pending_update?
|
||||
|
||||
return unless domain.pending_delete? || domain.pending_delete_confirmation?
|
||||
|
||||
notify_pending_delete
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
17
app/interactions/domains/force_delete/base.rb
Normal file
17
app/interactions/domains/force_delete/base.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
module Domains
|
||||
module ForceDelete
|
||||
class Base < ActiveInteraction::Base
|
||||
object :domain,
|
||||
class: Domain,
|
||||
description: 'Domain to set ForceDelete on'
|
||||
symbol :type,
|
||||
default: :fast_track,
|
||||
description: 'Force delete type, might be :fast_track or :soft'
|
||||
boolean :notify_by_email,
|
||||
default: false,
|
||||
description: 'Do we need to send email notification'
|
||||
|
||||
validates :type, inclusion: { in: %i[fast_track soft] }
|
||||
end
|
||||
end
|
||||
end
|
12
app/interactions/domains/force_delete/check_discarded.rb
Normal file
12
app/interactions/domains/force_delete/check_discarded.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
module Domains
|
||||
module ForceDelete
|
||||
class CheckDiscarded < Base
|
||||
def execute
|
||||
return true unless domain.discarded?
|
||||
|
||||
message = 'Force delete procedure cannot be scheduled while a domain is discarded'
|
||||
errors.add(:domain, message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
23
app/interactions/domains/force_delete/notify_by_email.rb
Normal file
23
app/interactions/domains/force_delete/notify_by_email.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
module Domains
|
||||
module ForceDelete
|
||||
class NotifyByEmail < Base
|
||||
def execute
|
||||
return unless notify_by_email
|
||||
|
||||
if type == :fast_track
|
||||
send_email
|
||||
domain.update(contact_notification_sent_date: Time.zone.today)
|
||||
else
|
||||
domain.update(template_name: domain.notification_template)
|
||||
end
|
||||
end
|
||||
|
||||
def send_email
|
||||
DomainDeleteMailer.forced(domain: domain,
|
||||
registrar: domain.registrar,
|
||||
registrant: domain.registrant,
|
||||
template_name: domain.notification_template).deliver_now
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
12
app/interactions/domains/force_delete/notify_registrar.rb
Normal file
12
app/interactions/domains/force_delete/notify_registrar.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
module Domains
|
||||
module ForceDelete
|
||||
class NotifyRegistrar < Base
|
||||
def execute
|
||||
domain.registrar.notifications.create!(text: I18n.t('force_delete_set_on_domain',
|
||||
domain_name: domain.name,
|
||||
outzone_date: domain.outzone_date,
|
||||
purge_date: domain.purge_date))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
19
app/interactions/domains/force_delete/post_set_process.rb
Normal file
19
app/interactions/domains/force_delete/post_set_process.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
module Domains
|
||||
module ForceDelete
|
||||
class PostSetProcess < Base
|
||||
def execute
|
||||
statuses = domain.statuses
|
||||
# Stop all pending actions
|
||||
statuses.delete(DomainStatus::PENDING_UPDATE)
|
||||
statuses.delete(DomainStatus::PENDING_TRANSFER)
|
||||
statuses.delete(DomainStatus::PENDING_RENEW)
|
||||
statuses.delete(DomainStatus::PENDING_CREATE)
|
||||
|
||||
# Allow deletion
|
||||
statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED)
|
||||
statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
|
||||
domain.save(validate: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
15
app/interactions/domains/force_delete/prepare_domain.rb
Normal file
15
app/interactions/domains/force_delete/prepare_domain.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
module Domains
|
||||
module ForceDelete
|
||||
class PrepareDomain < Base
|
||||
STATUSES_TO_SET = [DomainStatus::FORCE_DELETE,
|
||||
DomainStatus::SERVER_RENEW_PROHIBITED,
|
||||
DomainStatus::SERVER_TRANSFER_PROHIBITED].freeze
|
||||
|
||||
def execute
|
||||
domain.statuses_before_force_delete = domain.statuses
|
||||
domain.statuses |= STATUSES_TO_SET
|
||||
domain.save(validate: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
app/interactions/domains/force_delete/set_force_delete.rb
Normal file
14
app/interactions/domains/force_delete/set_force_delete.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Domains
|
||||
module ForceDelete
|
||||
class SetForceDelete < Base
|
||||
def execute
|
||||
compose(CheckDiscarded, inputs)
|
||||
compose(PrepareDomain, inputs)
|
||||
compose(SetStatus, inputs)
|
||||
compose(PostSetProcess, inputs)
|
||||
compose(NotifyRegistrar, inputs)
|
||||
compose(NotifyByEmail, inputs)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
40
app/interactions/domains/force_delete/set_status.rb
Normal file
40
app/interactions/domains/force_delete/set_status.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
module Domains
|
||||
module ForceDelete
|
||||
class SetStatus < Base
|
||||
def execute
|
||||
domain.force_delete_type = type
|
||||
type == :fast_track ? force_delete_fast_track : force_delete_soft
|
||||
domain.save(validate: false)
|
||||
end
|
||||
|
||||
def force_delete_fast_track
|
||||
domain.force_delete_date = Time.zone.today +
|
||||
expire_warning_period_days +
|
||||
redemption_grace_period_days
|
||||
domain.force_delete_start = Time.zone.today + 1.day
|
||||
end
|
||||
|
||||
def force_delete_soft
|
||||
years = (domain.valid_to.to_date - Time.zone.today).to_i / 365
|
||||
soft_forcedelete_dates(years) if years.positive?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def soft_forcedelete_dates(years)
|
||||
domain.force_delete_start = domain.valid_to - years.years
|
||||
domain.force_delete_date = domain.force_delete_start +
|
||||
Setting.expire_warning_period.days +
|
||||
Setting.redemption_grace_period.days
|
||||
end
|
||||
|
||||
def redemption_grace_period_days
|
||||
Setting.redemption_grace_period.days + 1.day
|
||||
end
|
||||
|
||||
def expire_warning_period_days
|
||||
Setting.expire_warning_period.days
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
10
app/interactions/domains/redemption_grace_period/base.rb
Normal file
10
app/interactions/domains/redemption_grace_period/base.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
module Domains
|
||||
module RedemptionGracePeriod
|
||||
class Base < ActiveInteraction::Base
|
||||
def to_stdout(message)
|
||||
time = Time.zone.now.utc
|
||||
STDOUT << "#{time} - #{message}\n" unless Rails.env.test?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
module Domains
|
||||
module RedemptionGracePeriod
|
||||
class ProcessGracePeriod < Base
|
||||
object :domain,
|
||||
class: Domain
|
||||
|
||||
def execute
|
||||
domain.statuses << DomainStatus::SERVER_HOLD
|
||||
to_stdout(process_msg)
|
||||
domain.save(validate: false)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process_msg
|
||||
"start_redemption_grace_period: #{domain.id} (#{domain.name}) #{domain.changes}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
20
app/interactions/domains/redemption_grace_period/start.rb
Normal file
20
app/interactions/domains/redemption_grace_period/start.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
module Domains
|
||||
module RedemptionGracePeriod
|
||||
class Start < Base
|
||||
def execute
|
||||
to_stdout('Setting server_hold to domains')
|
||||
|
||||
::PaperTrail.request.whodunnit = "cron - #{self.class.name}"
|
||||
count = 0
|
||||
|
||||
Domain.outzone_candidates.each do |domain|
|
||||
next unless domain.server_holdable?
|
||||
|
||||
count += 1
|
||||
Domains::RedemptionGracePeriod::ProcessGracePeriod.run(domain: domain)
|
||||
end
|
||||
to_stdout("Successfully set server_hold to #{count} of domains")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
53
app/interactions/domains/update_confirm/base.rb
Normal file
53
app/interactions/domains/update_confirm/base.rb
Normal file
|
@ -0,0 +1,53 @@
|
|||
module Domains
|
||||
module UpdateConfirm
|
||||
class Base < ActiveInteraction::Base
|
||||
object :domain,
|
||||
class: Domain,
|
||||
description: 'Domain to confirm update'
|
||||
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
|
17
app/interactions/domains/update_confirm/process_action.rb
Normal file
17
app/interactions/domains/update_confirm/process_action.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
module Domains
|
||||
module UpdateConfirm
|
||||
class ProcessAction < Base
|
||||
def execute
|
||||
::PaperTrail.request.whodunnit = "interaction - #{self.class.name} - #{action} by"\
|
||||
" #{initiator}"
|
||||
|
||||
case action
|
||||
when RegistrantVerification::CONFIRMED
|
||||
compose(ProcessUpdateConfirmed, inputs)
|
||||
when RegistrantVerification::REJECTED
|
||||
compose(ProcessUpdateRejected, inputs)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,37 @@
|
|||
module Domains
|
||||
module UpdateConfirm
|
||||
class ProcessUpdateConfirmed < Base
|
||||
def execute
|
||||
ActiveRecord::Base.transaction do
|
||||
old_registrant = domain.registrant
|
||||
notify_registrar(:poll_pending_update_confirmed_by_registrant)
|
||||
|
||||
apply_pending_update!
|
||||
raise_errors!(domain)
|
||||
RegistrantChange.new(domain: domain, old_registrant: old_registrant).confirm
|
||||
end
|
||||
end
|
||||
|
||||
def apply_pending_update!
|
||||
preclean_pendings
|
||||
update_domain
|
||||
clean_pendings!
|
||||
|
||||
WhoisRecord.find_by(domain_id: domain.id).save # need to reload model
|
||||
end
|
||||
|
||||
def update_domain
|
||||
user = ApiUser.find(domain.pending_json['current_user_id'])
|
||||
frame = domain.pending_json['frame'] ? domain.pending_json['frame'].with_indifferent_access : {}
|
||||
|
||||
#self.statuses.delete(DomainStatus::PENDING_UPDATE)
|
||||
domain.upid = user.registrar.id if user.registrar
|
||||
domain.up_date = Time.zone.now
|
||||
|
||||
Actions::DomainUpdate.new(domain, frame, true).call
|
||||
|
||||
#save!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
module Domains
|
||||
module UpdateConfirm
|
||||
class ProcessUpdateRejected < Base
|
||||
def execute
|
||||
ActiveRecord::Base.transaction do
|
||||
RegistrantChangeMailer.rejected(domain: domain,
|
||||
registrar: domain.registrar,
|
||||
registrant: domain.registrant).deliver_now
|
||||
|
||||
notify_registrar(:poll_pending_update_rejected_by_registrant)
|
||||
|
||||
preclean_pendings
|
||||
clean_pendings!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue