mirror of
https://github.com/internetee/registry.git
synced 2025-06-06 04:37:30 +02:00
Merge pull request #1733 from internetee/1177-bulk-force-delete
Admin: Mass action for soft force delete
This commit is contained in:
commit
d387113d86
15 changed files with 227 additions and 5 deletions
27
app/controllers/admin/mass_actions_controller.rb
Normal file
27
app/controllers/admin/mass_actions_controller.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class MassActionsController < BaseController
|
||||
before_action :authorize_admin
|
||||
|
||||
# GET /admin/mass_actions
|
||||
def index; end
|
||||
|
||||
# POST /admin/mass_actions
|
||||
def create
|
||||
res = MassAction.process(params[:mass_action], params[:entry_list].path)
|
||||
notice = if res
|
||||
"#{params[:mass_action]} completed for #{res[:ok]}.\n" \
|
||||
"Failed: #{res[:fail]}"
|
||||
else
|
||||
"Dataset integrity validation failed for #{params[:mass_action]}"
|
||||
end
|
||||
|
||||
redirect_to(admin_mass_actions_path, notice: notice)
|
||||
end
|
||||
|
||||
def authorize_admin
|
||||
authorize! :manage, :mass_actions
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,6 +10,9 @@ module Domains
|
|||
boolean :notify_by_email,
|
||||
default: false,
|
||||
description: 'Do we need to send email notification'
|
||||
string :reason,
|
||||
default: nil,
|
||||
description: 'Which mail template to use explicitly'
|
||||
|
||||
validates :type, inclusion: { in: %i[fast_track soft] }
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ module Domains
|
|||
send_email
|
||||
domain.update(contact_notification_sent_date: Time.zone.today)
|
||||
else
|
||||
domain.update(template_name: domain.notification_template)
|
||||
domain.update(template_name: domain.notification_template(explicit: reason))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ class Ability
|
|||
can :destroy, :pending
|
||||
can :create, :zonefile
|
||||
can :access, :settings_menu
|
||||
can :manage, :mass_actions
|
||||
can :manage, BouncedMailAddress
|
||||
end
|
||||
|
||||
|
|
|
@ -19,7 +19,10 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
|
|||
end
|
||||
end
|
||||
|
||||
def notification_template
|
||||
def notification_template(explicit: nil)
|
||||
reason = explicit&.downcase
|
||||
return reason if %w[invalid_email invalid_phone].include?(reason)
|
||||
|
||||
if contact_emails_verification_failed.present?
|
||||
'invalid_email'
|
||||
elsif registrant.org?
|
||||
|
@ -33,9 +36,8 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
|
|||
statuses.include?(DomainStatus::FORCE_DELETE)
|
||||
end
|
||||
|
||||
def schedule_force_delete(type: :fast_track, notify_by_email: false)
|
||||
Domains::ForceDelete::SetForceDelete.run(domain: self,
|
||||
type: type,
|
||||
def schedule_force_delete(type: :fast_track, notify_by_email: false, reason: nil)
|
||||
Domains::ForceDelete::SetForceDelete.run(domain: self, type: type, reason: reason,
|
||||
notify_by_email: notify_by_email)
|
||||
end
|
||||
|
||||
|
|
42
app/models/mass_action.rb
Normal file
42
app/models/mass_action.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
class MassAction
|
||||
def self.process(action_type, entries)
|
||||
entries = CSV.read(entries, headers: true)
|
||||
case action_type
|
||||
when 'force_delete'
|
||||
process_force_delete(entries)
|
||||
else
|
||||
false
|
||||
end
|
||||
rescue StandardError
|
||||
false
|
||||
end
|
||||
|
||||
def self.process_force_delete(entries)
|
||||
return false unless force_delete_entries_valid?(entries)
|
||||
|
||||
apply_force_deletes(entries)
|
||||
end
|
||||
|
||||
def self.apply_force_deletes(entries)
|
||||
log = { ok: [], fail: [] }
|
||||
entries.each do |e|
|
||||
dn = Domain.find_by(name_puny: e['domain_name'])
|
||||
log[:fail] << e['domain_name'] and next unless dn
|
||||
|
||||
dn.schedule_force_delete(type: :soft, notify_by_email: true, reason: e['delete_reason'])
|
||||
|
||||
log[:ok] << dn.name
|
||||
end
|
||||
|
||||
log
|
||||
end
|
||||
|
||||
def self.force_delete_entries_valid?(entries)
|
||||
entries.each do |e|
|
||||
reasons = %w[ENTITY_BURIED INVALID_EMAIL INVALID_PHONE]
|
||||
return false unless e['domain_name'].present? && reasons.include?(e['delete_reason'])
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
end
|
|
@ -33,6 +33,7 @@
|
|||
%li= link_to t('.blocked_domains'), admin_blocked_domains_path
|
||||
%li= link_to t('.reserved_domains'), admin_reserved_domains_path
|
||||
%li= link_to t('.disputed_domains'), admin_disputes_path
|
||||
%li= link_to t('.bulk_actions'), admin_mass_actions_path
|
||||
%li= link_to t('.bounced_email_addresses'), admin_bounced_mail_addresses_path
|
||||
%li= link_to t('.epp_log'), admin_epp_logs_path(created_after: 'today')
|
||||
%li= link_to t('.repp_log'), admin_repp_logs_path(created_after: 'today')
|
||||
|
|
19
app/views/admin/mass_actions/index.html.erb
Normal file
19
app/views/admin/mass_actions/index.html.erb
Normal file
|
@ -0,0 +1,19 @@
|
|||
<div class="page-header">
|
||||
<h1>Bulk actions</h1>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Bulk Domain Force Delete</div>
|
||||
<div class="panel-body">
|
||||
<p>Triggers <b>soft</b> force delete procedure for uploaded domain list. List must be in <b>CSV</b> format. First row of the CSV file must contain column headings with <b>domain_name</b> for the first and <b>delete_reason</b> for the second column. Each domain entry must be on separate line. Domain names are expected to be in punycode format, valid reasons are listed below.</p>
|
||||
<p>Allowed delete reasons: <b>ENTITY_BURIED</b> | <b>INVALID_PHONE</b> | <b>INVALID_EMAIL</b></p>
|
||||
<%= form_tag admin_mass_actions_path, multipart: true, method: :post do %>
|
||||
<%= label_tag :entry_list %>
|
||||
<%= file_field_tag :entry_list, required: true, accept: 'text/csv' %>
|
||||
<%= hidden_field_tag :mass_action, 'force_delete' %>
|
||||
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
||||
<br>
|
||||
<%= submit_tag "Start force delete process", class: 'btn btn-danger', id: 'fd_submit' %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,47 @@
|
|||
<p>Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt</p>
|
||||
|
||||
<p>Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et domeeni <%= @domain.name %> kontakti(de) telefoni number või numbrid on puudulikud.</p>
|
||||
|
||||
<p>Et see olukord on vastuolus .ee <a href='https://www.internet.ee/domains/ee-domain-regulation'>domeenireeglitega</a> algatas EIS <%= @delete_period_length %> päeva pikkuse kustutusmenetluse. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.</p>
|
||||
|
||||
<p>Andmete parandamiseks pöörduge palun oma registripidaja <%= @registrar.name %> poole või isiklike ja oma ettevõtte andmete puhul <a href="https://registrant.internet.ee/">registreerija portaali</a>.</p>
|
||||
|
||||
<p>Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile <a href="https://auction.internet.ee">.ee oksjonikeskkonda</a>. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe <a href="https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused">siit</a>.</p>
|
||||
|
||||
<p>Lisaküsimuste korral võtke palun ühendust oma registripidajaga:</p>
|
||||
<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %>
|
||||
|
||||
<%= render 'mailers/shared/signatures/signature.et.html' %>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Dear registrant/administrative contact of .ee domain,</p>
|
||||
|
||||
<p>Estonian Internet Foundation has learned that contact(s) phone number data of the domain <%= @domain.name %> are invalid.</p>
|
||||
|
||||
<p>Since this is a violation of <a href='https://www.internet.ee/domains/ee-domain-regulation'>Estonian domain regulations</a>, <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.</p>
|
||||
|
||||
<p>Please, contact your registrar <%= @registrar.name %> with updated contact data, or in case of your personal or business data use <a href="https://registrant.internet.ee/">.ee portal for registrants</a></p>
|
||||
|
||||
<p>If the data is not fixed within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the <a href="https://auction.internet.ee">.ee auction environment</a>. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">here</a>.</p>
|
||||
|
||||
<p>Should you have additional questions, please contact your registrar:</p>
|
||||
<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %>
|
||||
|
||||
<%= render 'mailers/shared/signatures/signature.en.html' %>
|
||||
<hr>
|
||||
|
||||
<p>Уважаемый регистрант/административный контакт домена .ee</p>
|
||||
|
||||
<p>Целевому учреждению Eesti Internet (EIS) стало известно, что контактные данные домена <%= @domain.name %> неверны - телефонные номера.</p>
|
||||
|
||||
<p>Так как это является нарушением <a href='https://www.internet.ee/domains/ee-domain-regulation'>Правил домена .ee</a>, <%= @delete_period_length %>-дневный процесс удаления начат для доменного имени <%= @domain.name %>. В течение первых <%= @expire_warning_period %> дней домен будет доступен в интернете.</p>
|
||||
|
||||
<p>Для уточнения контактных данных, пожалуйста, свяжитесь с регистратором <%= @registrar.name %>, либо воспользуйтесь <a href="https://registrant.internet.ee/">порталом для регистрантов</a></p>
|
||||
|
||||
<p>Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в <a href="https://auction.internet.ee">аукционной среде.ee</a>. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">здесь</a>.</p>
|
||||
|
||||
<p>В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором:
|
||||
<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %></p>
|
||||
|
||||
<%= render 'mailers/shared/signatures/signature.ru.html' %>
|
|
@ -0,0 +1,47 @@
|
|||
<p>Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt</p>
|
||||
|
||||
<p>Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et domeeni <%= @domain.name %> kontakti(de) telefoni number või numbrid on puudulikud.</p>
|
||||
|
||||
<p>Et see olukord on vastuolus .ee <a href='https://www.internet.ee/domains/ee-domain-regulation'>domeenireeglitega</a> algatas EIS <%= @delete_period_length %> päeva pikkuse kustutusmenetluse. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.</p>
|
||||
|
||||
<p>Andmete parandamiseks pöörduge palun oma registripidaja <%= @registrar.name %> poole või isiklike ja oma ettevõtte andmete puhul <a href="https://registrant.internet.ee/">registreerija portaali</a>.</p>
|
||||
|
||||
<p>Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile <a href="https://auction.internet.ee">.ee oksjonikeskkonda</a>. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe <a href="https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused">siit</a>.</p>
|
||||
|
||||
<p>Lisaküsimuste korral võtke palun ühendust oma registripidajaga:</p>
|
||||
<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %>
|
||||
|
||||
<%= render 'mailers/shared/signatures/signature.et.html' %>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Dear registrant/administrative contact of .ee domain,</p>
|
||||
|
||||
<p>Estonian Internet Foundation has learned that contact(s) phone number data of the domain <%= @domain.name %> are invalid.</p>
|
||||
|
||||
<p>Since this is a violation of <a href='https://www.internet.ee/domains/ee-domain-regulation'>Estonian domain regulations</a>, <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.</p>
|
||||
|
||||
<p>Please, contact your registrar <%= @registrar.name %> with updated contact data, or in case of your personal or business data use <a href="https://registrant.internet.ee/">.ee portal for registrants</a></p>
|
||||
|
||||
<p>If the data is not fixed within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the <a href="https://auction.internet.ee">.ee auction environment</a>. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">here</a>.</p>
|
||||
|
||||
<p>Should you have additional questions, please contact your registrar:</p>
|
||||
<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %>
|
||||
|
||||
<%= render 'mailers/shared/signatures/signature.en.html' %>
|
||||
<hr>
|
||||
|
||||
<p>Уважаемый регистрант/административный контакт домена .ee</p>
|
||||
|
||||
<p>Целевому учреждению Eesti Internet (EIS) стало известно, что контактные данные домена <%= @domain.name %> неверны - телефонные номера.</p>
|
||||
|
||||
<p>Так как это является нарушением <a href='https://www.internet.ee/domains/ee-domain-regulation'>Правил домена .ee</a>, <%= @delete_period_length %>-дневный процесс удаления начат для доменного имени <%= @domain.name %>. В течение первых <%= @expire_warning_period %> дней домен будет доступен в интернете.</p>
|
||||
|
||||
<p>Для уточнения контактных данных, пожалуйста, свяжитесь с регистратором <%= @registrar.name %>, либо воспользуйтесь <a href="https://registrant.internet.ee/">порталом для регистрантов</a></p>
|
||||
|
||||
<p>Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в <a href="https://auction.internet.ee">аукционной среде.ee</a>. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">здесь</a>.</p>
|
||||
|
||||
<p>В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором:
|
||||
<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %></p>
|
||||
|
||||
<%= render 'mailers/shared/signatures/signature.ru.html' %>
|
|
@ -14,6 +14,7 @@ en:
|
|||
blocked_domains: Blocked domains
|
||||
reserved_domains: Reserved domains
|
||||
disputed_domains: Disputed domains
|
||||
bulk_actions: Bulk actions
|
||||
bounced_email_addresses: Bounced emails
|
||||
epp_log: EPP log
|
||||
repp_log: REPP log
|
||||
|
|
|
@ -322,6 +322,7 @@ Rails.application.routes.draw do
|
|||
resources :delayed_jobs
|
||||
resources :epp_logs
|
||||
resources :repp_logs
|
||||
resources :mass_actions, only: %i[index create]
|
||||
resources :bounced_mail_addresses, only: %i[index show destroy]
|
||||
|
||||
authenticate :admin_user do
|
||||
|
|
2
test/fixtures/files/mass_actions/invalid_mass_force_delete_list.csv
vendored
Normal file
2
test/fixtures/files/mass_actions/invalid_mass_force_delete_list.csv
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
domain_name,delete_reason
|
||||
sh\á;[]c'
|
|
5
test/fixtures/files/mass_actions/valid_mass_force_delete_list.csv
vendored
Normal file
5
test/fixtures/files/mass_actions/valid_mass_force_delete_list.csv
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
domain_name,delete_reason
|
||||
shop.test,ENTITY_BURIED
|
||||
airport.test,INVALID_PHONE
|
||||
library.test,INVALID_EMAIL
|
||||
nonexistant.test,ENTITY_BURIED
|
|
|
@ -0,0 +1,24 @@
|
|||
require 'application_system_test_case'
|
||||
require 'test_helper'
|
||||
|
||||
class AdminAreaMassActionsForceDeleteTest < ApplicationSystemTestCase
|
||||
def setup
|
||||
sign_in users(:admin)
|
||||
end
|
||||
|
||||
def test_processes_uploaded_valid_csv
|
||||
visit admin_mass_actions_path
|
||||
|
||||
attach_file('entry_list', Rails.root.join('test', 'fixtures', 'files', 'mass_actions', 'valid_mass_force_delete_list.csv').to_s)
|
||||
click_link_or_button 'Start force delete process'
|
||||
assert_text 'force_delete completed for ["shop.test", "airport.test", "library.test"]. Failed: ["nonexistant.test"]'
|
||||
end
|
||||
|
||||
def test_processes_uploaded_invalid_csv
|
||||
visit admin_mass_actions_path
|
||||
|
||||
attach_file(:entry_list, Rails.root.join('test', 'fixtures', 'files', 'mass_actions', 'invalid_mass_force_delete_list.csv').to_s)
|
||||
click_link_or_button 'Start force delete process'
|
||||
assert_text 'Dataset integrity validation failed for force_delete'
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue