diff --git a/app/assets/javascripts/admin/mass_actions/force_delete.js b/app/assets/javascripts/admin/mass_actions/force_delete.js new file mode 100644 index 000000000..62ecc1cf9 --- /dev/null +++ b/app/assets/javascripts/admin/mass_actions/force_delete.js @@ -0,0 +1,3 @@ +$('input:file').on("change", function() { + $('input:submit').prop('disabled', !$(this).val()); +}); diff --git a/app/controllers/admin/mass_actions_controller.rb b/app/controllers/admin/mass_actions_controller.rb new file mode 100644 index 000000000..b342a9ef1 --- /dev/null +++ b/app/controllers/admin/mass_actions_controller.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Admin + class MassActionsController < BaseController + authorize_resource + + # GET /admin/disputes + def index; end + + # POST /admin/disputes + def create + res = MassAction.process(params[:mass_action], params[:entry_list].path) + backlog = "#{params[:mass_action]} done for #{res[:ok].join(',')}.\n" \ + "Failed: objects: #{res[:fail].join(',')}" + + redirect_to(admin_mass_actions_path, notice: backlog) + end + end +end diff --git a/app/models/ability.rb b/app/models/ability.rb index dce8a515b..71c28e7e7 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -109,6 +109,7 @@ class Ability can :destroy, :pending can :create, :zonefile can :access, :settings_menu + can :manage, MassAction end def static_registrant diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index 9b75d1e92..d62c1f9a1 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -42,12 +42,12 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength force_delete_start + Setting.expire_warning_period.days <= valid_to end - def schedule_force_delete(type: :fast_track) + def schedule_force_delete(type: :fast_track, notify: false) 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 + type == :fast_track ? force_delete_fast_track : force_delete_soft(notify: notify) end def add_force_delete_type(force_delete_type) @@ -65,7 +65,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength save(validate: false) end - def force_delete_soft + def force_delete_soft(notify: false) preserve_current_statuses_for_force_delete add_force_delete_statuses add_force_delete_type(:soft) @@ -73,6 +73,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength stop_all_pending_actions allow_deletion save(validate: false) + notify_parties if notify end def clear_force_delete_data @@ -148,4 +149,13 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength def force_delete_fast_track_start_date Time.zone.today + Setting.expire_warning_period.days + Setting.redemption_grace_period.days end + + def notify_parties + self.template_name = registrant.org? ? 'legal_person' : 'private_person' + save(validate: false) + registrar.notifications.create!(text: I18n.t('force_delete_set_on_domain', + domain_name: name, + outzone_date: outzone_date, + purge_date: purge_date)) + end end diff --git a/app/models/mass_action.rb b/app/models/mass_action.rb new file mode 100644 index 000000000..fc389be80 --- /dev/null +++ b/app/models/mass_action.rb @@ -0,0 +1,21 @@ +class MassAction + def self.process(action_type, entries) + return process_force_delete(entries) if action_type == 'force_delete' + + false + end + + def self.process_force_delete(entries) + log = { ok: [], fail: [] } + entries = CSV.read(entries, headers: true) + 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: true) + log[:ok] << dn.name + end + + log + end +end diff --git a/app/views/admin/base/_menu.haml b/app/views/admin/base/_menu.haml index a327419fd..beba92716 100644 --- a/app/views/admin/base/_menu.haml +++ b/app/views/admin/base/_menu.haml @@ -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('.mass_actions'), admin_mass_actions_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') %li= link_to t('.que'), '/admin/que' diff --git a/app/views/admin/mass_actions/index.html.erb b/app/views/admin/mass_actions/index.html.erb new file mode 100644 index 000000000..192168f42 --- /dev/null +++ b/app/views/admin/mass_actions/index.html.erb @@ -0,0 +1,17 @@ +
Triggers soft force delete procedure for uploaded domain list. List must be in CSV format. Each domain entry must be on separate line. Line must include domain name with delete reason, separated by comma.
+Allowed delete reasons: IDENT_BURIED | PHONE | EMAIL
+ <%= form_tag admin_mass_actions_path, multipart: true do %> + <%= file_field_tag :entry_list, accept: 'text/csv' %> + <%= hidden_field_tag :mass_action, 'force_delete' %> +