Skip to content

Commit

Permalink
Merge pull request #1430 from internetee/1428-new-force-delete-proced…
Browse files Browse the repository at this point in the history
…ures

Add new ForceDelete procedures
  • Loading branch information
vohmar authored Jan 18, 2020
2 parents c8bf5b3 + e758124 commit df5fcd8
Show file tree
Hide file tree
Showing 19 changed files with 396 additions and 53 deletions.
33 changes: 26 additions & 7 deletions app/controllers/admin/domains/force_delete_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,25 @@ def create
authorize! :manage, domain

domain.transaction do
domain.schedule_force_delete
domain.schedule_force_delete(type: force_delete_type)
domain.registrar.notifications.create!(text: t('force_delete_set_on_domain',
domain_name: domain.name))

if notify_by_email?
DomainDeleteMailer.forced(domain: domain,
registrar: domain.registrar,
registrant: domain.registrant,
template_name: params[:template_name]).deliver_now
end
notify_by_email if notify_by_email?
end

redirect_to edit_admin_domain_url(domain), notice: t('.scheduled')
end

def notify_by_email
if force_delete_type == :fast_track
send_email
domain.update(contact_notification_sent_date: Time.zone.today)
else
domain.update(template_name: params[:template_name])
end
end

def destroy
authorize! :manage, domain
domain.cancel_force_delete
Expand All @@ -35,6 +39,21 @@ def domain
def notify_by_email?
ActiveRecord::Type::Boolean.new.cast(params[:notify_by_email])
end

def send_email
DomainDeleteMailer.forced(domain: domain,
registrar: domain.registrar,
registrant: domain.registrant,
template_name: params[:template_name]).deliver_now
end

def force_delete_type
soft_delete? ? :soft : :fast_track
end

def soft_delete?
ActiveRecord::Type::Boolean.new.cast(params[:soft_delete])
end
end
end
end
2 changes: 1 addition & 1 deletion app/controllers/registrant/domains_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ def search_params
params.require(:q).permit(:name_matches, :registrant_ident_eq, :valid_to_gteq, :valid_to_lteq,
:results_per_page)
end
end
end
94 changes: 82 additions & 12 deletions app/models/concerns/domain/force_delete.rb
Original file line number Diff line number Diff line change
@@ -1,32 +1,106 @@
module Concerns::Domain::ForceDelete
module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
extend ActiveSupport::Concern

included do
store_accessor :force_delete_data,
:force_delete_type,
:contact_notification_sent_date,
:template_name

scope :notification_not_sent,
lambda {
where("(force_delete_data->>'contact_notification_sent_date') is null")
}
end

class_methods do
def force_delete_scheduled
where('force_delete_start <= ?', Time.zone.now)
end
end

def force_delete_scheduled?
statuses.include?(DomainStatus::FORCE_DELETE)
end

def schedule_force_delete
def should_notify_on_soft_force_delete?
force_delete_scheduled? && contact_notification_sent_date.blank? &&
force_delete_start.to_date <= Time.zone.now.to_date && force_delete_type.to_sym == :soft
end

def client_holdable?
force_delete_scheduled? && !statuses.include?(DomainStatus::CLIENT_HOLD) &&
force_delete_start.present? && force_delete_lte_today && force_delete_lte_valid_date
end

def force_delete_lte_today
force_delete_start + Setting.expire_warning_period.days <= Time.zone.now
end

def force_delete_lte_valid_date
force_delete_start + Setting.expire_warning_period.days <= valid_to
end

def schedule_force_delete(type: :fast_track)
if discarded?
raise StandardError, 'Force delete procedure cannot be scheduled while a domain is discarded'
end

type == :fast_track ? force_delete_fast_track : force_delete_soft
end

def add_force_delete_type(force_delete_type)
self.force_delete_type = force_delete_type
end

def force_delete_fast_track
preserve_current_statuses_for_force_delete
add_force_delete_statuses
self.force_delete_date = Time.zone.today + Setting.redemption_grace_period.days + 1.day
add_force_delete_type(:fast)
self.force_delete_date = force_delete_fast_track_start_date + 1.day
self.force_delete_start = Time.zone.today + 1.day
stop_all_pending_actions
allow_deletion
save(validate: false)
end

def force_delete_soft
preserve_current_statuses_for_force_delete
add_force_delete_statuses
add_force_delete_type(:soft)
calculate_soft_delete_date
stop_all_pending_actions
allow_deletion
save(validate: false)
end

def clear_force_delete_data
self.force_delete_data = nil
end

def cancel_force_delete
restore_statuses_before_force_delete
remove_force_delete_statuses
clear_force_delete_data
self.force_delete_date = nil
self.force_delete_start = nil
save(validate: false)
registrar.notifications.create!(text: I18n.t('force_delete_cancelled', domain_name: name))
end

private

def calculate_soft_delete_date
years = (valid_to.to_date - Time.zone.today).to_i / 365
soft_delete_dates(years) if years.positive?
end

def soft_delete_dates(years)
self.force_delete_start = valid_to - years.years + 1.day
self.force_delete_date = force_delete_start + Setting.expire_warning_period.days +
Setting.redemption_grace_period.days
end

def stop_all_pending_actions
statuses.delete(DomainStatus::PENDING_UPDATE)
statuses.delete(DomainStatus::PENDING_TRANSFER)
Expand All @@ -47,25 +121,21 @@ def add_force_delete_statuses
statuses << DomainStatus::FORCE_DELETE
statuses << DomainStatus::SERVER_RENEW_PROHIBITED
statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED
statuses << DomainStatus::SERVER_UPDATE_PROHIBITED
statuses << DomainStatus::PENDING_DELETE

if (statuses & [DomainStatus::SERVER_HOLD, DomainStatus::CLIENT_HOLD]).empty?
statuses << DomainStatus::SERVER_MANUAL_INZONE
end
end

def remove_force_delete_statuses
statuses.delete(DomainStatus::FORCE_DELETE)
statuses.delete(DomainStatus::SERVER_RENEW_PROHIBITED)
statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED)
statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED)
statuses.delete(DomainStatus::PENDING_DELETE)
statuses.delete(DomainStatus::SERVER_MANUAL_INZONE)
statuses.delete(DomainStatus::CLIENT_HOLD)
end

def allow_deletion
statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
end

def force_delete_fast_track_start_date
Time.zone.today + Setting.expire_warning_period.days + Setting.redemption_grace_period.days
end
end
31 changes: 31 additions & 0 deletions app/models/concerns/job/force_delete.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module Concerns
module Job
module ForceDelete
extend ActiveSupport::Concern

class_methods do
def start_client_hold
log_prepare_client_hold

::PaperTrail.whodunnit = "cron - #{__method__}"

::Domain.force_delete_scheduled.each do |domain|
proceed_client_hold(domain: domain)
log_end_end_client_hold(domain)
end
end

def proceed_client_hold(domain:)
notify_on_grace_period(domain) if domain.should_notify_on_soft_force_delete?
return unless domain.client_holdable?

domain.statuses << DomainStatus::CLIENT_HOLD
log_start_client_hold(domain)

domain.save(validate: false)
notify_client_hold(domain)
end
end
end
end
end
28 changes: 28 additions & 0 deletions app/models/concerns/job/force_delete_logging.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Concerns
module Job
module ForceDeleteLogging
extend ActiveSupport::Concern

class_methods do
def log_prepare_client_hold
return if Rails.env.test?

STDOUT << "#{Time.zone.now.utc} - Setting client_hold to domains\n"
end

def log_start_client_hold(domain)
return if Rails.env.test?

STDOUT << "#{Time.zone.now.utc} DomainCron.start_client_hold: ##{domain.id} "\
"(#{domain.name}) #{domain.changes}\n"
end

def log_end_end_client_hold(domain)
return if Rails.env.test?

STDOUT << "#{Time.zone.now.utc} - Successfully set client_hold on (#{domain.name})"
end
end
end
end
end
30 changes: 30 additions & 0 deletions app/models/concerns/job/force_delete_notify.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module Concerns
module Job
module ForceDeleteNotify
extend ActiveSupport::Concern

class_methods do
def notify_client_hold(domain)
domain.registrar.notifications.create!(text: I18n.t('client_hold_set_on_domain',
domain_name: domain.name,
date: domain.force_delete_start))
end

def notify_on_grace_period(domain)
domain.registrar.notifications.create!(text: I18n.t('grace_period_started_domain',
domain_name: domain.name,
date: domain.force_delete_start))
send_mail(domain)
domain.update(contact_notification_sent_date: Time.zone.today)
end

def send_mail(domain)
DomainDeleteMailer.forced(domain: domain,
registrar: domain.registrar,
registrant: domain.registrant,
template_name: domain.template_name).deliver_now
end
end
end
end
end
2 changes: 2 additions & 0 deletions app/models/domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,8 @@ def manage_automatic_statuses
activate if nameservers.reject(&:marked_for_destruction?).size >= Setting.ns_min_count
end

cancel_force_delete if force_delete_scheduled? && pending_json['new_registrant_id']

if statuses.empty? && valid?
statuses << DomainStatus::OK
elsif (statuses.length > 1 && active?) || !valid?
Expand Down
3 changes: 3 additions & 0 deletions app/models/domain_cron.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
class DomainCron
include Concerns::Job::ForceDelete
include Concerns::Job::ForceDeleteLogging
include Concerns::Job::ForceDeleteNotify

def self.clean_expired_pendings
STDOUT << "#{Time.zone.now.utc} - Clean expired domain pendings\n" unless Rails.env.test?
Expand Down
11 changes: 11 additions & 0 deletions app/views/admin/domains/_force_delete_dialog.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@

<%= form_tag admin_domain_force_delete_path(domain), id: 'domain-force-delete-form',
class: 'modal-body form-horizontal' do %>
<div class="form-group force-delete-type">
<div class="col-md-9">
<div class="checkbox">
<label>
<%= check_box_tag 'soft_delete', 1, true %>
<%= t '.use_soft_delete' %>
</label>
</div>
</div>
</div>

<div class="form-group">
<div class="col-md-9">
<div class="checkbox">
Expand Down
1 change: 1 addition & 0 deletions config/locales/admin/domains.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ en:
force_delete_dialog:
title: Force delete
notify_by_email: Notify registrant and administrative contacts by email
use_soft_delete: Use soft delete procedure
email_template: Email template
close_btn: Close dialog
submit_btn: Force delete domain
Expand Down
3 changes: 3 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,9 @@ en:
created_at_until: 'Created at until'
is_registrant: 'Is registrant'
force_delete_set_on_domain: 'Force delete set on domain %{domain_name}'
client_hold_set_on_domain: 'clientHold status is set for domain %{domain_name}, ForceDelete is in effect from %{date}'
grace_period_started_domain: 'For domain %{domain_name} started 45-days redemption grace period, ForceDelete will be in effect from %{date}'
force_delete_cancelled: 'Force delete is cancelled on domain %{domain_name}'
contact_is_not_valid: 'Contact %{value} is not valid, please fix the invalid contact'
next: 'Next'
previous: 'Previous'
Expand Down
4 changes: 4 additions & 0 deletions config/schedule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
runner 'DomainCron.start_redemption_grace_period'
end

every 1.day do
runner 'DomainCron.start_client_hold'
end

every '0 0 1 * *' do
runner 'Directo.send_monthly_invoices'
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddForceDeleteStartToDomains < ActiveRecord::Migration[5.0]
def change
add_column :domains, :force_delete_start, :datetime
end
end
5 changes: 5 additions & 0 deletions db/migrate/20200115102202_add_force_delete_data_to_domains.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddForceDeleteDataToDomains < ActiveRecord::Migration[5.0]
def change
add_column :domains, :force_delete_data, :hstore
end
end
9 changes: 7 additions & 2 deletions db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;

--
Expand Down Expand Up @@ -742,7 +743,10 @@ CREATE TABLE public.domains (
upid integer,
up_date timestamp without time zone,
uuid uuid DEFAULT public.gen_random_uuid() NOT NULL,
locked_by_registrant_at timestamp without time zone
locked_by_registrant_at timestamp without time zone,
force_delete_start timestamp without time zone,
force_delete_data public.hstore

);


Expand Down Expand Up @@ -4334,6 +4338,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20191206183853'),
('20191212133136'),
('20191227110904'),
('20200113091254');
('20200113091254'),
('20200115102202');


Loading

0 comments on commit df5fcd8

Please sign in to comment.