From 0f3b033f790636c0209a1def1fb45665289a8084 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Wed, 16 Sep 2020 15:59:02 +0300
Subject: [PATCH 001/106] Create bounced_mail_addresses table
---
...916125326_create_bounced_mail_addresses.rb | 12 ++++
db/structure.sql | 65 +++++++++++++++++--
2 files changed, 70 insertions(+), 7 deletions(-)
create mode 100644 db/migrate/20200916125326_create_bounced_mail_addresses.rb
diff --git a/db/migrate/20200916125326_create_bounced_mail_addresses.rb b/db/migrate/20200916125326_create_bounced_mail_addresses.rb
new file mode 100644
index 000000000..c6600afea
--- /dev/null
+++ b/db/migrate/20200916125326_create_bounced_mail_addresses.rb
@@ -0,0 +1,12 @@
+class CreateBouncedMailAddresses < ActiveRecord::Migration[6.0]
+ def change
+ create_table :bounced_mail_addresses do |t|
+ t.string :email, null: false
+ t.string :bounce_reason, null: false
+ t.integer :incidents, null: false, default: 1
+ t.jsonb :response_json
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 6a30fbc84..3ec055386 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -475,6 +475,40 @@ CREATE SEQUENCE public.blocked_domains_id_seq
ALTER SEQUENCE public.blocked_domains_id_seq OWNED BY public.blocked_domains.id;
+--
+-- Name: bounced_mail_addresses; Type: TABLE; Schema: public; Owner: -; Tablespace:
+--
+
+CREATE TABLE public.bounced_mail_addresses (
+ id bigint NOT NULL,
+ email character varying NOT NULL,
+ bounce_reason character varying NOT NULL,
+ incidents integer DEFAULT 1 NOT NULL,
+ response_json jsonb,
+ created_at timestamp(6) without time zone NOT NULL,
+ updated_at timestamp(6) without time zone NOT NULL
+);
+
+
+--
+-- Name: bounced_mail_addresses_id_seq; Type: SEQUENCE; Schema: public; Owner: -
+--
+
+CREATE SEQUENCE public.bounced_mail_addresses_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: bounced_mail_addresses_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
+--
+
+ALTER SEQUENCE public.bounced_mail_addresses_id_seq OWNED BY public.bounced_mail_addresses.id;
+
+
--
-- Name: certificates; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@@ -1706,7 +1740,7 @@ ALTER SEQUENCE public.log_payment_orders_id_seq OWNED BY public.log_payment_orde
--
--- Name: log_prices; Type: TABLE; Schema: public; Owner: -
+-- Name: log_prices; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE public.log_prices (
@@ -1744,7 +1778,7 @@ ALTER SEQUENCE public.log_prices_id_seq OWNED BY public.log_prices.id;
--
--- Name: log_registrant_verifications; Type: TABLE; Schema: public; Owner: -
+-- Name: log_registrant_verifications; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE public.log_registrant_verifications (
@@ -2658,6 +2692,13 @@ ALTER TABLE ONLY public.bank_transactions ALTER COLUMN id SET DEFAULT nextval('p
ALTER TABLE ONLY public.blocked_domains ALTER COLUMN id SET DEFAULT nextval('public.blocked_domains_id_seq'::regclass);
+--
+-- Name: id; Type: DEFAULT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.bounced_mail_addresses ALTER COLUMN id SET DEFAULT nextval('public.bounced_mail_addresses_id_seq'::regclass);
+
+
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -2876,14 +2917,14 @@ ALTER TABLE ONLY public.log_payment_orders ALTER COLUMN id SET DEFAULT nextval('
--
--- Name: log_prices id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.log_prices ALTER COLUMN id SET DEFAULT nextval('public.log_prices_id_seq'::regclass);
--
--- Name: log_registrant_verifications id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.log_registrant_verifications ALTER COLUMN id SET DEFAULT nextval('public.log_registrant_verifications_id_seq'::regclass);
@@ -3100,6 +3141,14 @@ ALTER TABLE ONLY public.blocked_domains
ADD CONSTRAINT blocked_domains_pkey PRIMARY KEY (id);
+--
+-- Name: bounced_mail_addresses_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
+--
+
+ALTER TABLE ONLY public.bounced_mail_addresses
+ ADD CONSTRAINT bounced_mail_addresses_pkey PRIMARY KEY (id);
+
+
--
-- Name: certificates_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@@ -3349,7 +3398,7 @@ ALTER TABLE ONLY public.log_payment_orders
--
--- Name: log_prices log_prices_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: log_prices_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY public.log_prices
@@ -3357,7 +3406,7 @@ ALTER TABLE ONLY public.log_prices
--
--- Name: log_registrant_verifications log_registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: log_registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY public.log_registrant_verifications
@@ -4906,5 +4955,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200902131603'),
('20200908131554'),
('20200910085157'),
-('20200910102028');
+('20200910102028'),
+('20200916125326');
+
From 188cca0c063325b91d641e808fbd3592a38f66eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 17 Sep 2020 11:12:01 +0300
Subject: [PATCH 002/106] Create views for bounced emails
---
.../bounced_mail_addresses_controller.rb | 60 +++++++++++++++++++
app/models/ability.rb | 1 +
app/models/bounced_mail_address.rb | 2 +
.../bounced_mail_addresses/_form.html.erb | 37 ++++++++++++
.../bounced_mail_addresses/edit.html.erb | 6 ++
.../bounced_mail_addresses/index.html.erb | 33 ++++++++++
.../admin/bounced_mail_addresses/new.html.erb | 5 ++
.../bounced_mail_addresses/show.html.erb | 24 ++++++++
config/routes.rb | 1 +
9 files changed, 169 insertions(+)
create mode 100644 app/controllers/admin/bounced_mail_addresses_controller.rb
create mode 100644 app/models/bounced_mail_address.rb
create mode 100644 app/views/admin/bounced_mail_addresses/_form.html.erb
create mode 100644 app/views/admin/bounced_mail_addresses/edit.html.erb
create mode 100644 app/views/admin/bounced_mail_addresses/index.html.erb
create mode 100644 app/views/admin/bounced_mail_addresses/new.html.erb
create mode 100644 app/views/admin/bounced_mail_addresses/show.html.erb
diff --git a/app/controllers/admin/bounced_mail_addresses_controller.rb b/app/controllers/admin/bounced_mail_addresses_controller.rb
new file mode 100644
index 000000000..a33f90ab3
--- /dev/null
+++ b/app/controllers/admin/bounced_mail_addresses_controller.rb
@@ -0,0 +1,60 @@
+module Admin
+ class BouncedMailAddressesController < BaseController
+ before_action :set_bounced_mail_address, only: %i[show edit update destroy]
+ load_and_authorize_resource
+
+ # GET /bounced_mail_addresses
+ def index
+ @bounced_mail_addresses = BouncedMailAddress.all
+ end
+
+ # GET /bounced_mail_addresses/1
+ def show; end
+
+ # GET /bounced_mail_addresses/new
+ def new
+ @bounced_mail_address = BouncedMailAddress.new
+ end
+
+ # GET /bounced_mail_addresses/1/edit
+ def edit; end
+
+ # POST /bounced_mail_addresses
+ def create
+ @bounced_mail_address = BouncedMailAddress.new(bounced_mail_address_params)
+
+ if @bounced_mail_address.save
+ redirect_to(admin_bounced_mail_addresses_url, notice: 'Bounced mail address was successfully created.')
+ else
+ render(:new)
+ end
+ end
+
+ # PATCH/PUT /bounced_mail_addresses/1
+ def update
+ if @bounced_mail_address.update(bounced_mail_address_params)
+ redirect_to(@bounced_mail_address, notice: 'Bounced mail address was successfully updated.')
+ else
+ render(:edit)
+ end
+ end
+
+ # DELETE /bounced_mail_addresses/1
+ def destroy
+ @bounced_mail_address.destroy
+ redirect_to(admin_bounced_mail_addresses_url, notice: 'Bounced mail address was successfully destroyed.')
+ end
+
+ private
+
+ # Use callbacks to share common setup or constraints between actions.
+ def set_bounced_mail_address
+ @bounced_mail_address = BouncedMailAddress.find(params[:id])
+ end
+
+ # Only allow a trusted parameter "white list" through.
+ def bounced_mail_address_params
+ params.require(:bounced_mail_address).permit(:email, :bounce_reason, :incidents, :response_json)
+ end
+ end
+end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index dce8a515b..31637b8ea 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, BouncedMailAddress
end
def static_registrant
diff --git a/app/models/bounced_mail_address.rb b/app/models/bounced_mail_address.rb
new file mode 100644
index 000000000..d8f6a037b
--- /dev/null
+++ b/app/models/bounced_mail_address.rb
@@ -0,0 +1,2 @@
+class BouncedMailAddress < ApplicationRecord
+end
diff --git a/app/views/admin/bounced_mail_addresses/_form.html.erb b/app/views/admin/bounced_mail_addresses/_form.html.erb
new file mode 100644
index 000000000..7a384bd3f
--- /dev/null
+++ b/app/views/admin/bounced_mail_addresses/_form.html.erb
@@ -0,0 +1,37 @@
+<%= form_for([:admin, @bounced_mail_address], html: { class: 'form-horizontal' }) do |form| %>
+ <% if @bounced_mail_address.errors.any? %>
+
+
<%= pluralize(bounced_mail_address.errors.count, "error") %> prohibited this bounced_mail_address from being saved:
+
+
+ <% @bounced_mail_address.errors.full_messages.each do |message| %>
+ - <%= message %>
+ <% end %>
+
+
+ <% end %>
+
+
+ <%= form.label :email %>
+ <%= form.text_field :email %>
+
+
+
+ <%= form.label :bounce_reason %>
+ <%= form.text_field :bounce_reason %>
+
+
+
+ <%= form.label :incidents %>
+ <%= form.number_field :incidents %>
+
+
+
+ <%= form.label :response_json %>
+ <%= form.text_field :response_json %>
+
+
+
+ <%= form.submit %>
+
+<% end %>
diff --git a/app/views/admin/bounced_mail_addresses/edit.html.erb b/app/views/admin/bounced_mail_addresses/edit.html.erb
new file mode 100644
index 000000000..a3dfe2d84
--- /dev/null
+++ b/app/views/admin/bounced_mail_addresses/edit.html.erb
@@ -0,0 +1,6 @@
+Editing Bounced Mail Address
+
+<%= render 'form', bounced_mail_address: @bounced_mail_address %>
+
+<%= link_to 'Show', admin_bounced_mail_address_path(@bounced_mail_address)%> |
+<%= link_to 'Back', admin_bounced_mail_addresses_path %>
diff --git a/app/views/admin/bounced_mail_addresses/index.html.erb b/app/views/admin/bounced_mail_addresses/index.html.erb
new file mode 100644
index 000000000..c2f95ca68
--- /dev/null
+++ b/app/views/admin/bounced_mail_addresses/index.html.erb
@@ -0,0 +1,33 @@
+<%= notice %>
+
+Bounced Mail Addresses
+
+
+
+
+ Email |
+ Bounce reason |
+ Incidents |
+ Response json |
+ |
+
+
+
+
+ <% @bounced_mail_addresses.each do |mail_addr| %>
+
+ <%= mail_addr.email %> |
+ <%= mail_addr.bounce_reason %> |
+ <%= mail_addr.incidents %> |
+ <%= mail_addr.response_json %> |
+ <%= link_to 'Show', admin_bounced_mail_address_path(mail_addr) %> |
+ <%= link_to 'Edit', edit_admin_bounced_mail_address_path(mail_addr) %> |
+ <%= link_to 'Destroy', admin_bounced_mail_address_path(mail_addr), method: :delete, data: { confirm: 'Are you sure?' } %> |
+
+ <% end %>
+
+
+
+
+
+<%= link_to 'New Bounced Mail Address', new_admin_bounced_mail_address_path %>
diff --git a/app/views/admin/bounced_mail_addresses/new.html.erb b/app/views/admin/bounced_mail_addresses/new.html.erb
new file mode 100644
index 000000000..010ac79dc
--- /dev/null
+++ b/app/views/admin/bounced_mail_addresses/new.html.erb
@@ -0,0 +1,5 @@
+New Bounced Mail Address
+
+<%= render 'form', bounced_mail_address: @bounced_mail_address %>
+
+<%= link_to 'Back', admin_bounced_mail_addresses_path %>
diff --git a/app/views/admin/bounced_mail_addresses/show.html.erb b/app/views/admin/bounced_mail_addresses/show.html.erb
new file mode 100644
index 000000000..1f48ad5cf
--- /dev/null
+++ b/app/views/admin/bounced_mail_addresses/show.html.erb
@@ -0,0 +1,24 @@
+<%= notice %>
+
+
+ Email:
+ <%= @bounced_mail_address.email %>
+
+
+
+ Bounce reason:
+ <%= @bounced_mail_address.bounce_reason %>
+
+
+
+ Incidents:
+ <%= @bounced_mail_address.incidents %>
+
+
+
+ Response json:
+ <%= @bounced_mail_address.response_json %>
+
+
+<%= link_to 'Edit', edit_admin_bounced_mail_address_path(@bounced_mail_address) %> |
+<%= link_to 'Back', admin_bounced_mail_addresses_path %>
diff --git a/config/routes.rb b/config/routes.rb
index 223cf3171..cdbd63f31 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -298,6 +298,7 @@ Rails.application.routes.draw do
resources :delayed_jobs
resources :epp_logs
resources :repp_logs
+ resources :bounced_mail_addresses
authenticate :admin_user do
mount Que::Web, at: 'que'
From 22f9c2058d137a021034030c66ac33f8049f17a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 17 Sep 2020 11:55:52 +0300
Subject: [PATCH 003/106] Create api/v1/bounces endpoint
---
app/controllers/api/v1/bounces_controller.rb | 12 ++++++++++++
config/routes.rb | 1 +
2 files changed, 13 insertions(+)
create mode 100644 app/controllers/api/v1/bounces_controller.rb
diff --git a/app/controllers/api/v1/bounces_controller.rb b/app/controllers/api/v1/bounces_controller.rb
new file mode 100644
index 000000000..cff8c3efe
--- /dev/null
+++ b/app/controllers/api/v1/bounces_controller.rb
@@ -0,0 +1,12 @@
+module Api
+ module V1
+ class BouncesController < BaseController
+ before_action :authenticate
+
+ def create
+ bounced_mail_address = BouncedMailAddress.record(json)
+ bounced_mail_address ? render(head: :ok) : render(head: :failed)
+ end
+ end
+ end
+end
diff --git a/config/routes.rb b/config/routes.rb
index cdbd63f31..89f8f0cd6 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -64,6 +64,7 @@ Rails.application.routes.draw do
end
resources :auctions, only: %i[index show update], param: :uuid
+ resources :bounces, only: %i[create]
end
match '*all', controller: 'cors', action: 'cors_preflight_check', via: [:options],
From 140df0acf78a9e0139301649b244247c66b612e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 17 Sep 2020 13:26:00 +0300
Subject: [PATCH 004/106] Fix CC issues
---
.../admin/bounced_mail_addresses_controller.rb | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/app/controllers/admin/bounced_mail_addresses_controller.rb b/app/controllers/admin/bounced_mail_addresses_controller.rb
index a33f90ab3..551413e2c 100644
--- a/app/controllers/admin/bounced_mail_addresses_controller.rb
+++ b/app/controllers/admin/bounced_mail_addresses_controller.rb
@@ -24,7 +24,10 @@ module Admin
@bounced_mail_address = BouncedMailAddress.new(bounced_mail_address_params)
if @bounced_mail_address.save
- redirect_to(admin_bounced_mail_addresses_url, notice: 'Bounced mail address was successfully created.')
+ redirect_to(
+ admin_bounced_mail_addresses_url,
+ notice: 'Bounced mail address was successfully created.'
+ )
else
render(:new)
end
@@ -42,7 +45,10 @@ module Admin
# DELETE /bounced_mail_addresses/1
def destroy
@bounced_mail_address.destroy
- redirect_to(admin_bounced_mail_addresses_url, notice: 'Bounced mail address was successfully destroyed.')
+ redirect_to(
+ admin_bounced_mail_addresses_url,
+ notice: 'Bounced mail address was successfully destroyed.'
+ )
end
private
@@ -54,7 +60,12 @@ module Admin
# Only allow a trusted parameter "white list" through.
def bounced_mail_address_params
- params.require(:bounced_mail_address).permit(:email, :bounce_reason, :incidents, :response_json)
+ params.require(:bounced_mail_address).permit(
+ :email,
+ :bounce_reason,
+ :incidents,
+ :response_json
+ )
end
end
end
From 6af37a787dc56ec7b4d89079d6bf11d5ddf58651 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 17 Sep 2020 13:26:48 +0300
Subject: [PATCH 005/106] Restructure bounced mails view
---
app/models/bounced_mail_address.rb | 22 +++++++
.../bounced_mail_addresses/index.html.erb | 61 ++++++++++---------
2 files changed, 55 insertions(+), 28 deletions(-)
diff --git a/app/models/bounced_mail_address.rb b/app/models/bounced_mail_address.rb
index d8f6a037b..6609829da 100644
--- a/app/models/bounced_mail_address.rb
+++ b/app/models/bounced_mail_address.rb
@@ -1,2 +1,24 @@
class BouncedMailAddress < ApplicationRecord
+ validates :email, presence: true
+ validates :bounce_reason, presence: true
+
+ def diagnostic
+ response_json['diagnosticCode']
+ end
+
+ def action
+ response_json['action']
+ end
+
+ def status
+ response_json['status']
+ end
+
+ def self.record(json)
+ bounced_records = json['bounce']['bouncedRecipients']
+ bounced_records.each do |record|
+ bounce_record = BouncedMailAddress.new(email: record['emailAddress'], response_json: record)
+ bounce_record.save
+ end
+ end
end
diff --git a/app/views/admin/bounced_mail_addresses/index.html.erb b/app/views/admin/bounced_mail_addresses/index.html.erb
index c2f95ca68..b6a019282 100644
--- a/app/views/admin/bounced_mail_addresses/index.html.erb
+++ b/app/views/admin/bounced_mail_addresses/index.html.erb
@@ -2,32 +2,37 @@
Bounced Mail Addresses
-
-
-
- Email |
- Bounce reason |
- Incidents |
- Response json |
- |
-
-
+
+
+
+
+
+
+
+ Email |
+ Action |
+ Status |
+ Diagnostic |
+ Tracked |
+ Actions |
+
+
-
- <% @bounced_mail_addresses.each do |mail_addr| %>
-
- <%= mail_addr.email %> |
- <%= mail_addr.bounce_reason %> |
- <%= mail_addr.incidents %> |
- <%= mail_addr.response_json %> |
- <%= link_to 'Show', admin_bounced_mail_address_path(mail_addr) %> |
- <%= link_to 'Edit', edit_admin_bounced_mail_address_path(mail_addr) %> |
- <%= link_to 'Destroy', admin_bounced_mail_address_path(mail_addr), method: :delete, data: { confirm: 'Are you sure?' } %> |
-
- <% end %>
-
-
-
-
-
-<%= link_to 'New Bounced Mail Address', new_admin_bounced_mail_address_path %>
+
+ <% @bounced_mail_addresses.each do |mail_addr| %>
+
+ <%= mail_addr.email %> |
+ <%= mail_addr.action %> |
+ <%= mail_addr.status %> |
+ <%= mail_addr.diagnostic %> |
+ <%= mail_addr.created_at %> |
+ <%= link_to 'Detailed', admin_bounced_mail_address_path(mail_addr) %> |
+ <%= link_to 'Destroy', admin_bounced_mail_address_path(mail_addr), method: :delete, data: { confirm: 'Are you sure?' } %> |
+
+ <% end %>
+
+
+
+
+
+
From 834b2c95bc7e56c2c4ba15a60d64f7cd9b89cbfa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 17 Sep 2020 14:21:25 +0300
Subject: [PATCH 006/106] Add full request JSON to bounced mail, remove unused
views
---
.../bounced_mail_addresses_controller.rb | 35 +-----------------
app/models/bounced_mail_address.rb | 15 ++++++--
app/views/admin/base/_menu.haml | 1 +
.../bounced_mail_addresses/_form.html.erb | 37 -------------------
.../bounced_mail_addresses/edit.html.erb | 6 ---
.../admin/bounced_mail_addresses/new.html.erb | 5 ---
.../bounced_mail_addresses/show.html.erb | 10 +++--
config/locales/admin/menu.en.yml | 1 +
..._recipient_json_to_bounced_mail_address.rb | 5 +++
db/structure.sql | 6 ++-
10 files changed, 31 insertions(+), 90 deletions(-)
delete mode 100644 app/views/admin/bounced_mail_addresses/_form.html.erb
delete mode 100644 app/views/admin/bounced_mail_addresses/edit.html.erb
delete mode 100644 app/views/admin/bounced_mail_addresses/new.html.erb
create mode 100644 db/migrate/20200917104213_add_recipient_json_to_bounced_mail_address.rb
diff --git a/app/controllers/admin/bounced_mail_addresses_controller.rb b/app/controllers/admin/bounced_mail_addresses_controller.rb
index 551413e2c..da9421450 100644
--- a/app/controllers/admin/bounced_mail_addresses_controller.rb
+++ b/app/controllers/admin/bounced_mail_addresses_controller.rb
@@ -1,47 +1,16 @@
module Admin
class BouncedMailAddressesController < BaseController
- before_action :set_bounced_mail_address, only: %i[show edit update destroy]
+ before_action :set_bounced_mail_address, only: %i[show destroy]
load_and_authorize_resource
# GET /bounced_mail_addresses
def index
- @bounced_mail_addresses = BouncedMailAddress.all
+ @bounced_mail_addresses = BouncedMailAddress.all.order(created_at: :desc)
end
# GET /bounced_mail_addresses/1
def show; end
- # GET /bounced_mail_addresses/new
- def new
- @bounced_mail_address = BouncedMailAddress.new
- end
-
- # GET /bounced_mail_addresses/1/edit
- def edit; end
-
- # POST /bounced_mail_addresses
- def create
- @bounced_mail_address = BouncedMailAddress.new(bounced_mail_address_params)
-
- if @bounced_mail_address.save
- redirect_to(
- admin_bounced_mail_addresses_url,
- notice: 'Bounced mail address was successfully created.'
- )
- else
- render(:new)
- end
- end
-
- # PATCH/PUT /bounced_mail_addresses/1
- def update
- if @bounced_mail_address.update(bounced_mail_address_params)
- redirect_to(@bounced_mail_address, notice: 'Bounced mail address was successfully updated.')
- else
- render(:edit)
- end
- end
-
# DELETE /bounced_mail_addresses/1
def destroy
@bounced_mail_address.destroy
diff --git a/app/models/bounced_mail_address.rb b/app/models/bounced_mail_address.rb
index 6609829da..78f37c374 100644
--- a/app/models/bounced_mail_address.rb
+++ b/app/models/bounced_mail_address.rb
@@ -1,23 +1,30 @@
class BouncedMailAddress < ApplicationRecord
validates :email, presence: true
validates :bounce_reason, presence: true
+ before_validation :assign_bounce_reason
+
+ def assign_bounce_reason
+ self.bounce_reason = "#{action} (#{status} #{diagnostic})"
+ end
def diagnostic
- response_json['diagnosticCode']
+ recipient_json['diagnosticCode']
end
def action
- response_json['action']
+ recipient_json['action']
end
def status
- response_json['status']
+ recipient_json['status']
end
def self.record(json)
bounced_records = json['bounce']['bouncedRecipients']
bounced_records.each do |record|
- bounce_record = BouncedMailAddress.new(email: record['emailAddress'], response_json: record)
+ bounce_record = BouncedMailAddress.new(email: record['emailAddress'], recipient_json: record,
+ response_json: json)
+
bounce_record.save
end
end
diff --git a/app/views/admin/base/_menu.haml b/app/views/admin/base/_menu.haml
index a327419fd..5853bd3e6 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('.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')
%li= link_to t('.que'), '/admin/que'
diff --git a/app/views/admin/bounced_mail_addresses/_form.html.erb b/app/views/admin/bounced_mail_addresses/_form.html.erb
deleted file mode 100644
index 7a384bd3f..000000000
--- a/app/views/admin/bounced_mail_addresses/_form.html.erb
+++ /dev/null
@@ -1,37 +0,0 @@
-<%= form_for([:admin, @bounced_mail_address], html: { class: 'form-horizontal' }) do |form| %>
- <% if @bounced_mail_address.errors.any? %>
-
-
<%= pluralize(bounced_mail_address.errors.count, "error") %> prohibited this bounced_mail_address from being saved:
-
-
- <% @bounced_mail_address.errors.full_messages.each do |message| %>
- - <%= message %>
- <% end %>
-
-
- <% end %>
-
-
- <%= form.label :email %>
- <%= form.text_field :email %>
-
-
-
- <%= form.label :bounce_reason %>
- <%= form.text_field :bounce_reason %>
-
-
-
- <%= form.label :incidents %>
- <%= form.number_field :incidents %>
-
-
-
- <%= form.label :response_json %>
- <%= form.text_field :response_json %>
-
-
-
- <%= form.submit %>
-
-<% end %>
diff --git a/app/views/admin/bounced_mail_addresses/edit.html.erb b/app/views/admin/bounced_mail_addresses/edit.html.erb
deleted file mode 100644
index a3dfe2d84..000000000
--- a/app/views/admin/bounced_mail_addresses/edit.html.erb
+++ /dev/null
@@ -1,6 +0,0 @@
-Editing Bounced Mail Address
-
-<%= render 'form', bounced_mail_address: @bounced_mail_address %>
-
-<%= link_to 'Show', admin_bounced_mail_address_path(@bounced_mail_address)%> |
-<%= link_to 'Back', admin_bounced_mail_addresses_path %>
diff --git a/app/views/admin/bounced_mail_addresses/new.html.erb b/app/views/admin/bounced_mail_addresses/new.html.erb
deleted file mode 100644
index 010ac79dc..000000000
--- a/app/views/admin/bounced_mail_addresses/new.html.erb
+++ /dev/null
@@ -1,5 +0,0 @@
-New Bounced Mail Address
-
-<%= render 'form', bounced_mail_address: @bounced_mail_address %>
-
-<%= link_to 'Back', admin_bounced_mail_addresses_path %>
diff --git a/app/views/admin/bounced_mail_addresses/show.html.erb b/app/views/admin/bounced_mail_addresses/show.html.erb
index 1f48ad5cf..752bd7b0a 100644
--- a/app/views/admin/bounced_mail_addresses/show.html.erb
+++ b/app/views/admin/bounced_mail_addresses/show.html.erb
@@ -16,9 +16,13 @@
- Response json:
- <%= @bounced_mail_address.response_json %>
+ Bounced recipient JSON:
+
<%= JSON.pretty_generate(@bounced_mail_address.recipient_json) %>
+
+
+
+ Bounce payload:
+
<%= JSON.pretty_generate(@bounced_mail_address.response_json) %>
-<%= link_to 'Edit', edit_admin_bounced_mail_address_path(@bounced_mail_address) %> |
<%= link_to 'Back', admin_bounced_mail_addresses_path %>
diff --git a/config/locales/admin/menu.en.yml b/config/locales/admin/menu.en.yml
index 617341c6a..cb1060e6f 100644
--- a/config/locales/admin/menu.en.yml
+++ b/config/locales/admin/menu.en.yml
@@ -14,6 +14,7 @@ en:
blocked_domains: Blocked domains
reserved_domains: Reserved domains
disputed_domains: Disputed domains
+ bounced_email_addresses: Bounced emails
epp_log: EPP log
repp_log: REPP log
que: Que
diff --git a/db/migrate/20200917104213_add_recipient_json_to_bounced_mail_address.rb b/db/migrate/20200917104213_add_recipient_json_to_bounced_mail_address.rb
new file mode 100644
index 000000000..bad3d846e
--- /dev/null
+++ b/db/migrate/20200917104213_add_recipient_json_to_bounced_mail_address.rb
@@ -0,0 +1,5 @@
+class AddRecipientJsonToBouncedMailAddress < ActiveRecord::Migration[6.0]
+ def change
+ add_column :bounced_mail_addresses, :recipient_json, :jsonb, null: false
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 3ec055386..23669c665 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -486,7 +486,8 @@ CREATE TABLE public.bounced_mail_addresses (
incidents integer DEFAULT 1 NOT NULL,
response_json jsonb,
created_at timestamp(6) without time zone NOT NULL,
- updated_at timestamp(6) without time zone NOT NULL
+ updated_at timestamp(6) without time zone NOT NULL,
+ recipient_json jsonb NOT NULL
);
@@ -4956,6 +4957,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200908131554'),
('20200910085157'),
('20200910102028'),
-('20200916125326');
+('20200916125326'),
+('20200917104213');
From b2c5a9a5ec69ac8b27e7fa7ab8fef96f292f1485 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 17 Sep 2020 15:55:37 +0300
Subject: [PATCH 007/106] Verify param integrity for bounces
---
app/controllers/api/v1/bounces_controller.rb | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/app/controllers/api/v1/bounces_controller.rb b/app/controllers/api/v1/bounces_controller.rb
index cff8c3efe..40a3c1c91 100644
--- a/app/controllers/api/v1/bounces_controller.rb
+++ b/app/controllers/api/v1/bounces_controller.rb
@@ -1,11 +1,20 @@
module Api
module V1
class BouncesController < BaseController
- before_action :authenticate
-
+ # POST api/v1/bounces/
def create
- bounced_mail_address = BouncedMailAddress.record(json)
- bounced_mail_address ? render(head: :ok) : render(head: :failed)
+ BouncedMailAddress.record(bounce_params)
+ head(:ok)
+ rescue ActionController::ParameterMissing
+ head(:bad_request)
+ end
+
+ def bounce_params
+ params.require(:data).require(:bounce).require(:bouncedRecipients).each do |r|
+ r.require(:emailAddress)
+ end
+
+ params.require(:data)
end
end
end
From 03182f92227acceae7c1cf6a08e192e1c44472d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 17 Sep 2020 16:26:50 +0300
Subject: [PATCH 008/106] Implement shared key authentication to bounces API
---
app/controllers/api/v1/base_controller.rb | 5 +++++
app/controllers/api/v1/bounces_controller.rb | 4 +++-
config/application.yml.sample | 3 +++
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb
index 54930edf9..b62b3e063 100644
--- a/app/controllers/api/v1/base_controller.rb
+++ b/app/controllers/api/v1/base_controller.rb
@@ -10,6 +10,11 @@ module Api
head :unauthorized unless ip_allowed
end
+ def authenticate_shared_key
+ api_key = "Basic #{ENV['api_shared_key']}"
+ head(:unauthorized) unless api_key == request.authorization
+ end
+
def not_found_error
uuid = params['uuid']
json = { error: 'Not Found', uuid: uuid, message: 'Record not found' }
diff --git a/app/controllers/api/v1/bounces_controller.rb b/app/controllers/api/v1/bounces_controller.rb
index 40a3c1c91..296c9d9bd 100644
--- a/app/controllers/api/v1/bounces_controller.rb
+++ b/app/controllers/api/v1/bounces_controller.rb
@@ -1,10 +1,12 @@
module Api
module V1
class BouncesController < BaseController
+ before_action :authenticate_shared_key
+
# POST api/v1/bounces/
def create
BouncedMailAddress.record(bounce_params)
- head(:ok)
+ head(:created)
rescue ActionController::ParameterMissing
head(:bad_request)
end
diff --git a/config/application.yml.sample b/config/application.yml.sample
index 72b55e2ea..237617be3 100644
--- a/config/application.yml.sample
+++ b/config/application.yml.sample
@@ -87,6 +87,9 @@ sk_digi_doc_service_name: 'Testimine'
registrant_api_base_url:
registrant_api_auth_allowed_ips: '127.0.0.1, 0.0.0.0' #ips, separated with commas
+# Bounces API
+api_shared_key: testkey
+
#
# MISC
From 036a3a37207f4a89d01aad6361e59bd7d7297ba9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Fri, 18 Sep 2020 10:52:14 +0300
Subject: [PATCH 009/106] Return empty user object when authorized user not
found
---
app/controllers/registrar/sessions_controller.rb | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/app/controllers/registrar/sessions_controller.rb b/app/controllers/registrar/sessions_controller.rb
index 5bebe5619..709e66955 100644
--- a/app/controllers/registrar/sessions_controller.rb
+++ b/app/controllers/registrar/sessions_controller.rb
@@ -158,12 +158,15 @@ class Registrar
def find_user_by_idc_and_allowed(idc)
return User.new unless idc
+
possible_users = ApiUser.where(identity_code: idc) || User.new
possible_users.each do |selected_user|
- if selected_user.registrar.white_ips.registrar_area.include_ip?(request.ip)
- return selected_user
- end
+ next unless selected_user.registrar.white_ips.registrar_area.include_ip?(request.ip)
+
+ return selected_user
end
+
+ User.new
end
def check_ip_restriction
From 7d8c24533af3727b0817db6822b89eb35b373472 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Fri, 18 Sep 2020 14:44:40 +0300
Subject: [PATCH 010/106] Create unit tests for bounced mail address
---
app/models/bounced_mail_address.rb | 11 ++++-
test/models/bounced_mail_address_test.rb | 61 ++++++++++++++++++++++++
2 files changed, 70 insertions(+), 2 deletions(-)
create mode 100644 test/models/bounced_mail_address_test.rb
diff --git a/app/models/bounced_mail_address.rb b/app/models/bounced_mail_address.rb
index 78f37c374..f12c7f19c 100644
--- a/app/models/bounced_mail_address.rb
+++ b/app/models/bounced_mail_address.rb
@@ -1,21 +1,28 @@
class BouncedMailAddress < ApplicationRecord
validates :email, presence: true
- validates :bounce_reason, presence: true
+ validates :bounce_reason, :recipient_json, :response_json, presence: true
before_validation :assign_bounce_reason
def assign_bounce_reason
- self.bounce_reason = "#{action} (#{status} #{diagnostic})"
+ if recipient_json
+ self.bounce_reason = "#{action} (#{status} #{diagnostic})"
+ else
+ self.bounce_reason = nil
+ end
end
def diagnostic
+ return nil unless recipient_json
recipient_json['diagnosticCode']
end
def action
+ return nil unless recipient_json
recipient_json['action']
end
def status
+ return nil unless recipient_json
recipient_json['status']
end
diff --git a/test/models/bounced_mail_address_test.rb b/test/models/bounced_mail_address_test.rb
new file mode 100644
index 000000000..2caea7d98
--- /dev/null
+++ b/test/models/bounced_mail_address_test.rb
@@ -0,0 +1,61 @@
+require 'test_helper'
+
+class BouncedMailAddressTest < ActiveSupport::TestCase
+ include ActionMailer::TestHelper
+
+ def setup
+ @bounced_mail = BouncedMailAddress.new
+ @bounced_mail.email = 'recipient@registry.test'
+ @bounced_mail.bounce_reason = 'failed (5.1.1 smtp; 550 5.1.1 user unknown)'
+ @bounced_mail.response_json = {"mail"=>{"source"=>"noreply@internet.test", "sourceIp"=>"195.43.86.5", "messageId"=>"010f0174a0c7d348-ea6e2fc1-0854-4073-b71f-5cecf9b0d0b2-000000", "sourceArn"=>"arn:aws:ses:us-east-2:650268220328:identity/noreply@internet.test", "timestamp"=>"2020-09-18T10:34:44.000Z", "destination"=>["#{@bounced_mail.email}"], "sendingAccountId"=>"650268220328"}, "bounce"=>{"timestamp"=>"2020-09-18T10:34:44.911Z", "bounceType"=>"Permanent", "feedbackId"=>"010f0174a0c7d4f9-27d59756-6111-xxxx-a507-26bee0d55fa2-000000", "remoteMtaIp"=>"127.0.0.1", "reportingMTA"=>"dsn; xxx.amazonses.com", "bounceSubType"=>"General", "bouncedRecipients"=>[{"action"=>"failed", "status"=>"5.1.1", "emailAddress"=>"#{@bounced_mail.email}", "diagnosticCode"=>"smtp; 550 5.1.1 user unknown"}]}, "notificationType"=>"Bounce"}
+ @bounced_mail.recipient_json = {"action"=>"failed", "status"=>"5.1.1", "emailAddress"=>"#{@bounced_mail.email}", "diagnosticCode"=>"smtp; 550 5.1.1 user unknown"}
+
+ end
+
+ def test_bounce_reason_is_autoassigned
+ assert @bounced_mail.valid?
+ @bounced_mail.bounce_reason = nil
+ assert @bounced_mail.valid?
+
+ assert_equal 'failed (5.1.1 smtp; 550 5.1.1 user unknown)', @bounced_mail.bounce_reason
+ end
+
+ def test_response_json_is_required
+ assert @bounced_mail.valid?
+ @bounced_mail.response_json = nil
+ assert_not @bounced_mail.valid?
+ assert @bounced_mail.errors.full_messages.include? 'Response json is missing'
+ end
+
+ def test_recipient_json_is_required
+ assert @bounced_mail.valid?
+ @bounced_mail.recipient_json = nil
+ assert_not @bounced_mail.valid?
+
+ assert @bounced_mail.errors.full_messages.include? 'Recipient json is missing'
+ end
+
+ def test_status_is_determined_dynamically
+ assert @bounced_mail.valid?
+ assert_equal '5.1.1', @bounced_mail.status
+ @bounced_mail.recipient_json['status'] = 'xxx_status'
+ assert_equal 'xxx_status', @bounced_mail.status
+ end
+
+ def test_action_is_determined_dynamically
+ assert @bounced_mail.valid?
+ assert_equal 'failed', @bounced_mail.action
+ @bounced_mail.recipient_json['action'] = 'xxx_action'
+ assert_equal 'xxx_action', @bounced_mail.action
+ end
+
+ def test_diagnostic_is_determined_dynamically
+ assert @bounced_mail.valid?
+ assert_equal 'smtp; 550 5.1.1 user unknown', @bounced_mail.diagnostic
+ @bounced_mail.recipient_json['diagnosticCode'] = 'xxx_diagnostic'
+ assert_equal 'xxx_diagnostic', @bounced_mail.diagnostic
+ end
+
+ def test_creates_objects_from_sns_json
+ end
+end
From 64308e11040fcc172ce2dd30b25a7179258e58a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Fri, 18 Sep 2020 14:49:27 +0300
Subject: [PATCH 011/106] Fix CC issues
---
.../registrar/sessions_controller.rb | 8 ++--
app/models/bounced_mail_address.rb | 17 +++++----
test/models/bounced_mail_address_test.rb | 38 +++++++++++++++++++
3 files changed, 50 insertions(+), 13 deletions(-)
diff --git a/app/controllers/registrar/sessions_controller.rb b/app/controllers/registrar/sessions_controller.rb
index 709e66955..df90ea57b 100644
--- a/app/controllers/registrar/sessions_controller.rb
+++ b/app/controllers/registrar/sessions_controller.rb
@@ -161,12 +161,10 @@ class Registrar
possible_users = ApiUser.where(identity_code: idc) || User.new
possible_users.each do |selected_user|
- next unless selected_user.registrar.white_ips.registrar_area.include_ip?(request.ip)
-
- return selected_user
+ if selected_user.registrar.white_ips.registrar_area.include_ip?(request.ip)
+ return selected_user
+ end
end
-
- User.new
end
def check_ip_restriction
diff --git a/app/models/bounced_mail_address.rb b/app/models/bounced_mail_address.rb
index f12c7f19c..02bb42337 100644
--- a/app/models/bounced_mail_address.rb
+++ b/app/models/bounced_mail_address.rb
@@ -4,25 +4,26 @@ class BouncedMailAddress < ApplicationRecord
before_validation :assign_bounce_reason
def assign_bounce_reason
- if recipient_json
- self.bounce_reason = "#{action} (#{status} #{diagnostic})"
- else
- self.bounce_reason = nil
- end
+ return self.bounce_reason = nil unless recipient_json
+
+ self.bounce_reason = "#{action} (#{status} #{diagnostic})"
end
def diagnostic
- return nil unless recipient_json
+ return unless recipient_json
+
recipient_json['diagnosticCode']
end
def action
- return nil unless recipient_json
+ return unless recipient_json
+
recipient_json['action']
end
def status
- return nil unless recipient_json
+ return unless recipient_json
+
recipient_json['status']
end
diff --git a/test/models/bounced_mail_address_test.rb b/test/models/bounced_mail_address_test.rb
index 2caea7d98..0e6a62ab8 100644
--- a/test/models/bounced_mail_address_test.rb
+++ b/test/models/bounced_mail_address_test.rb
@@ -57,5 +57,43 @@ class BouncedMailAddressTest < ActiveSupport::TestCase
end
def test_creates_objects_from_sns_json
+ BouncedMailAddress.record(sns_bounce_payload)
+
+ bounced_mail = BouncedMailAddress.last
+ assert_equal domains(:shop).registrant.email, bounced_mail.email
+ assert_equal 'failed', bounced_mail.action
+ assert_equal '5.1.1', bounced_mail.status
+ assert_equal 'smtp; 550 5.1.1 user unknown', bounced_mail.diagnostic
+ end
+
+ def sns_bounce_payload
+ {
+ "notificationType": "Bounce",
+ "mail": {
+ "source": "noreply@registry.test",
+ "sourceIp": "195.43.86.5",
+ "messageId": "010f0174a0c7d348-ea6e2fc1-0854-4073-b71f-5cecf9b0d0b2-000000",
+ "sourceArn": "arn:aws:ses:us-east-2:65026820000:identity/noreply@registry.test",
+ "timestamp": "2020-09-18T10:34:44.000Z",
+ "destination": [ "#{domains(:shop).registrant.email}" ],
+ "sendingAccountId": "650268220000"
+ },
+ "bounce": {
+ "timestamp": "2020-09-18T10:34:44.911Z",
+ "bounceType": "Permanent",
+ "feedbackId": "010f0174a0c7d4f9-27d59756-6111-4d5f-xxxx-26bee0d55fa2-000000",
+ "remoteMtaIp": "127.0.01",
+ "reportingMTA": "dsn; xxx.amazonses.com",
+ "bounceSubType": "General",
+ "bouncedRecipients": [
+ {
+ "action": "failed",
+ "status": "5.1.1",
+ "emailAddress": "#{domains(:shop).registrant.email}",
+ "diagnosticCode": "smtp; 550 5.1.1 user unknown"
+ }
+ ]
+ }
+ }.as_json
end
end
From 101d5d4a7846fea4c3e242dcf3c57af5eb4b5bd3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Fri, 18 Sep 2020 16:17:42 +0300
Subject: [PATCH 012/106] Add tests for admin bounced mails views
---
.../bounced_mail_addresses_controller.rb | 10 -----
.../bounced_mail_addresses/index.html.erb | 2 -
.../bounced_mail_addresses/show.html.erb | 4 +-
test/fixtures/bounced_mail_addresses.yml | 40 ++++++++++++++++++
.../admin_area/bounced_mail_addresses_test.rb | 41 +++++++++++++++++++
5 files changed, 82 insertions(+), 15 deletions(-)
create mode 100644 test/fixtures/bounced_mail_addresses.yml
create mode 100644 test/system/admin_area/bounced_mail_addresses_test.rb
diff --git a/app/controllers/admin/bounced_mail_addresses_controller.rb b/app/controllers/admin/bounced_mail_addresses_controller.rb
index da9421450..1c59acaa4 100644
--- a/app/controllers/admin/bounced_mail_addresses_controller.rb
+++ b/app/controllers/admin/bounced_mail_addresses_controller.rb
@@ -26,15 +26,5 @@ module Admin
def set_bounced_mail_address
@bounced_mail_address = BouncedMailAddress.find(params[:id])
end
-
- # Only allow a trusted parameter "white list" through.
- def bounced_mail_address_params
- params.require(:bounced_mail_address).permit(
- :email,
- :bounce_reason,
- :incidents,
- :response_json
- )
- end
end
end
diff --git a/app/views/admin/bounced_mail_addresses/index.html.erb b/app/views/admin/bounced_mail_addresses/index.html.erb
index b6a019282..913cbd19d 100644
--- a/app/views/admin/bounced_mail_addresses/index.html.erb
+++ b/app/views/admin/bounced_mail_addresses/index.html.erb
@@ -1,5 +1,3 @@
-<%= notice %>
-
Bounced Mail Addresses
diff --git a/app/views/admin/bounced_mail_addresses/show.html.erb b/app/views/admin/bounced_mail_addresses/show.html.erb
index 752bd7b0a..9b0b5919f 100644
--- a/app/views/admin/bounced_mail_addresses/show.html.erb
+++ b/app/views/admin/bounced_mail_addresses/show.html.erb
@@ -1,6 +1,3 @@
-
<%= notice %>
-
-
Email:
<%= @bounced_mail_address.email %>
@@ -26,3 +23,4 @@
<%= link_to 'Back', admin_bounced_mail_addresses_path %>
+<%= link_to 'Destroy', admin_bounced_mail_address_path(@bounced_mail_address), method: :delete, data: { confirm: 'Are you sure?' } %>
diff --git a/test/fixtures/bounced_mail_addresses.yml b/test/fixtures/bounced_mail_addresses.yml
new file mode 100644
index 000000000..1261f1429
--- /dev/null
+++ b/test/fixtures/bounced_mail_addresses.yml
@@ -0,0 +1,40 @@
+one:
+ email: bounced@registry.test
+ bounce_reason: failed (5.1.1 smtp; 550 5.1.1 user unknown)
+ incidents: 1
+ recipient_json: {
+ "action": "failed",
+ "status": "5.1.1",
+ "emailAddress": "bounced@registry.test",
+ "diagnosticCode": "smtp; 550 5.1.1 user unknown"
+ }
+ response_json: {
+ "notificationType": "Bounce",
+ "mail": {
+ "source": "noreply@registry.test",
+ "sourceIp": "195.43.86.5",
+ "messageId": "010f0174a0c7d348-ea6e2fc1-0854-4073-b71f-5cecf9b0d0b2-000000",
+ "sourceArn": "arn:aws:ses:us-east-2:65026820000:identity/noreply@registry.test",
+ "timestamp": "2020-09-18T10:34:44.000Z",
+ "destination": [ "bounced@registry.test" ],
+ "sendingAccountId": "650268220000"
+ },
+ "bounce": {
+ "timestamp": "2020-09-18T10:34:44.911Z",
+ "bounceType": "Permanent",
+ "feedbackId": "010f0174a0c7d4f9-27d59756-6111-4d5f-xxxx-26bee0d55fa2-000000",
+ "remoteMtaIp": "127.0.01",
+ "reportingMTA": "dsn; xxx.amazonses.com",
+ "bounceSubType": "General",
+ "bouncedRecipients": [
+ {
+ "action": "failed",
+ "status": "5.1.1",
+ "emailAddress": "bounced@registry.test",
+ "diagnosticCode": "smtp; 550 5.1.1 user unknown"
+ }
+ ]
+ }
+ }
+ created_at: <%= Time.zone.parse('2010-07-05').to_s(:db) %>
+ updated_at: <%= Time.zone.parse('2010-07-05').to_s(:db) %>
diff --git a/test/system/admin_area/bounced_mail_addresses_test.rb b/test/system/admin_area/bounced_mail_addresses_test.rb
new file mode 100644
index 000000000..5500f4375
--- /dev/null
+++ b/test/system/admin_area/bounced_mail_addresses_test.rb
@@ -0,0 +1,41 @@
+require 'application_system_test_case'
+
+class AdminBouncedMailAddressesTest < ApplicationSystemTestCase
+ include ActionView::Helpers::NumberHelper
+
+ def setup
+ @bounced_mail = bounced_mail_addresses(:one)
+ @original_default_language = Setting.default_language
+ sign_in users(:admin)
+ end
+
+ def teardown
+ Setting.default_language = @original_default_language
+ end
+
+ def test_shows_bounced_emails
+ visit admin_bounced_mail_addresses_path
+ assert_text @bounced_mail.status
+ assert_text @bounced_mail.action
+ assert_text @bounced_mail.diagnostic
+ assert_text @bounced_mail.email
+ end
+
+ def test_shows_detailed_bounced_email
+ visit admin_bounced_mail_address_path(@bounced_mail)
+ assert_text @bounced_mail.status
+ assert_text @bounced_mail.action
+ assert_text @bounced_mail.diagnostic
+ assert_text @bounced_mail.email
+
+ assert_text 'bouncedRecipients'
+ assert_text '010f0174a0c7d4f9-27d59756-6111-4d5f-xxxx-26bee0d55fa2-000000'
+ end
+
+ def test_deletes_registrar
+ visit admin_bounced_mail_address_path(@bounced_mail)
+ click_on 'Destroy'
+
+ assert_text 'Bounced mail address was successfully destroyed.'
+ end
+end
From 6a93395fa493252f5f717799a0f5943257e1ddb7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 21 Sep 2020 11:37:31 +0300
Subject: [PATCH 013/106] Add integration tests for Bounces API
---
app/controllers/api/v1/bounces_controller.rb | 2 +
.../integration/api/v1/bounces/create_test.rb | 75 +++++++++++++++++++
2 files changed, 77 insertions(+)
create mode 100644 test/integration/api/v1/bounces/create_test.rb
diff --git a/app/controllers/api/v1/bounces_controller.rb b/app/controllers/api/v1/bounces_controller.rb
index 296c9d9bd..fd10a3398 100644
--- a/app/controllers/api/v1/bounces_controller.rb
+++ b/app/controllers/api/v1/bounces_controller.rb
@@ -5,6 +5,8 @@ module Api
# POST api/v1/bounces/
def create
+ return head(:bad_request) unless bounce_params[:bounce][:bouncedRecipients].any?
+
BouncedMailAddress.record(bounce_params)
head(:created)
rescue ActionController::ParameterMissing
diff --git a/test/integration/api/v1/bounces/create_test.rb b/test/integration/api/v1/bounces/create_test.rb
new file mode 100644
index 000000000..899b6c5c7
--- /dev/null
+++ b/test/integration/api/v1/bounces/create_test.rb
@@ -0,0 +1,75 @@
+require 'test_helper'
+
+class BouncesApiV1CreateTest < ActionDispatch::IntegrationTest
+ def setup
+ @api_key = "Basic #{ENV['api_shared_key']}"
+ @headers = { "Authorization": "#{@api_key}" }
+ @json_body = { "data": valid_bounce_request }.as_json
+ end
+
+ def test_authorizes_api_request
+ post api_v1_bounces_path, params: @json_body, headers: @headers
+ assert_response :created
+
+ invalid_headers = { "Authorization": "Basic invalid_api_key" }
+ post api_v1_bounces_path, params: @json_body, headers: invalid_headers
+ assert_response :unauthorized
+ end
+
+ def test_returns_bad_request_if_invalid_payload
+ invalid_json_body = @json_body.dup
+ invalid_json_body['data']['bounce']['bouncedRecipients'] = nil
+
+ post api_v1_bounces_path, params: invalid_json_body, headers: @headers
+ assert_response :bad_request
+
+ invalid_json_body = 'aaaa'
+ post api_v1_bounces_path, params: invalid_json_body, headers: @headers
+ assert_response :bad_request
+ end
+
+ def test_saves_new_bounce_object
+ request_body = @json_body.dup
+ random_mail = "#{rand(10000..99999)}@registry.test"
+ request_body['data']['bounce']['bouncedRecipients'][0]['emailAddress'] = random_mail
+
+ post api_v1_bounces_path, params: request_body, headers: @headers
+ assert_response :created
+
+ bounced_mail = BouncedMailAddress.last
+ assert bounced_mail.email = random_mail
+ assert '5.1.1', bounced_mail.status
+ assert 'failed', bounced_mail.action
+ end
+
+ def valid_bounce_request
+ {
+ "notificationType": "Bounce",
+ "mail": {
+ "source": "noreply@registry.test",
+ "sourceIp": "195.43.86.5",
+ "messageId": "010f0174a0c7d348-ea6e2fc1-0854-4073-b71f-5cecf9b0d0b2-000000",
+ "sourceArn": "arn:aws:ses:us-east-2:65026820000:identity/noreply@registry.test",
+ "timestamp": "2020-09-18T10:34:44.000Z",
+ "destination": [ "bounced@registry.test" ],
+ "sendingAccountId": "650268220000"
+ },
+ "bounce": {
+ "timestamp": "2020-09-18T10:34:44.911Z",
+ "bounceType": "Permanent",
+ "feedbackId": "010f0174a0c7d4f9-27d59756-6111-4d5f-xxxx-26bee0d55fa2-000000",
+ "remoteMtaIp": "127.0.01",
+ "reportingMTA": "dsn; xxx.amazonses.com",
+ "bounceSubType": "General",
+ "bouncedRecipients": [
+ {
+ "action": "failed",
+ "status": "5.1.1",
+ "emailAddress": "bounced@registry.test",
+ "diagnosticCode": "smtp; 550 5.1.1 user unknown"
+ }
+ ]
+ }
+ }.as_json
+ end
+end
From 818869d249d4e5ebdf1945f454968a0ebcd8c78e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 21 Sep 2020 11:46:42 +0300
Subject: [PATCH 014/106] Remove incidents count from bounced mails
---
app/views/admin/bounced_mail_addresses/show.html.erb | 5 -----
...84356_remove_incidents_from_bounced_mail_addresses.rb | 9 +++++++++
db/structure.sql | 4 ++--
test/fixtures/bounced_mail_addresses.yml | 1 -
4 files changed, 11 insertions(+), 8 deletions(-)
create mode 100644 db/migrate/20200921084356_remove_incidents_from_bounced_mail_addresses.rb
diff --git a/app/views/admin/bounced_mail_addresses/show.html.erb b/app/views/admin/bounced_mail_addresses/show.html.erb
index 9b0b5919f..98eeabcd2 100644
--- a/app/views/admin/bounced_mail_addresses/show.html.erb
+++ b/app/views/admin/bounced_mail_addresses/show.html.erb
@@ -7,11 +7,6 @@
<%= @bounced_mail_address.bounce_reason %>
-
- Incidents:
- <%= @bounced_mail_address.incidents %>
-
-
Bounced recipient JSON:
<%= JSON.pretty_generate(@bounced_mail_address.recipient_json) %>
diff --git a/db/migrate/20200921084356_remove_incidents_from_bounced_mail_addresses.rb b/db/migrate/20200921084356_remove_incidents_from_bounced_mail_addresses.rb
new file mode 100644
index 000000000..0704795df
--- /dev/null
+++ b/db/migrate/20200921084356_remove_incidents_from_bounced_mail_addresses.rb
@@ -0,0 +1,9 @@
+class RemoveIncidentsFromBouncedMailAddresses < ActiveRecord::Migration[6.0]
+ def up
+ remove_column :bounced_mail_addresses, :incidents
+ end
+
+ def down
+ add_column :bounced_mail_addresses, :incidents, :integer, null: false, default: 1
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 23669c665..74e784408 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -483,7 +483,6 @@ CREATE TABLE public.bounced_mail_addresses (
id bigint NOT NULL,
email character varying NOT NULL,
bounce_reason character varying NOT NULL,
- incidents integer DEFAULT 1 NOT NULL,
response_json jsonb,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL,
@@ -4958,6 +4957,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200910085157'),
('20200910102028'),
('20200916125326'),
-('20200917104213');
+('20200917104213'),
+('20200921084356');
diff --git a/test/fixtures/bounced_mail_addresses.yml b/test/fixtures/bounced_mail_addresses.yml
index 1261f1429..345b2ef22 100644
--- a/test/fixtures/bounced_mail_addresses.yml
+++ b/test/fixtures/bounced_mail_addresses.yml
@@ -1,7 +1,6 @@
one:
email: bounced@registry.test
bounce_reason: failed (5.1.1 smtp; 550 5.1.1 user unknown)
- incidents: 1
recipient_json: {
"action": "failed",
"status": "5.1.1",
From fae620c19d87fc4df9710be88e3608a4192b29a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 21 Sep 2020 13:12:23 +0300
Subject: [PATCH 015/106] Define routing scope for :bounced_mail_addresses
---
config/routes.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/routes.rb b/config/routes.rb
index 89f8f0cd6..9938403e7 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -299,7 +299,7 @@ Rails.application.routes.draw do
resources :delayed_jobs
resources :epp_logs
resources :repp_logs
- resources :bounced_mail_addresses
+ resources :bounced_mail_addresses, only: %i[index show destroy]
authenticate :admin_user do
mount Que::Web, at: 'que'
From 659cb7f4e67ee51545b6ea0ce5b20e030e881591 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 21 Sep 2020 13:34:34 +0300
Subject: [PATCH 016/106] Combine migrations, remove json objects from bounced
mails
---
...0200916125326_create_bounced_mail_addresses.rb | 9 ++++++---
..._add_recipient_json_to_bounced_mail_address.rb | 5 -----
...emove_incidents_from_bounced_mail_addresses.rb | 9 ---------
db/structure.sql | 15 ++++++++-------
4 files changed, 14 insertions(+), 24 deletions(-)
delete mode 100644 db/migrate/20200917104213_add_recipient_json_to_bounced_mail_address.rb
delete mode 100644 db/migrate/20200921084356_remove_incidents_from_bounced_mail_addresses.rb
diff --git a/db/migrate/20200916125326_create_bounced_mail_addresses.rb b/db/migrate/20200916125326_create_bounced_mail_addresses.rb
index c6600afea..e1744cc9a 100644
--- a/db/migrate/20200916125326_create_bounced_mail_addresses.rb
+++ b/db/migrate/20200916125326_create_bounced_mail_addresses.rb
@@ -2,9 +2,12 @@ class CreateBouncedMailAddresses < ActiveRecord::Migration[6.0]
def change
create_table :bounced_mail_addresses do |t|
t.string :email, null: false
- t.string :bounce_reason, null: false
- t.integer :incidents, null: false, default: 1
- t.jsonb :response_json
+ t.string :message_id, null: false
+ t.string :bounce_type, null: false
+ t.string :bounce_subtype, null: false
+ t.string :action, null: false
+ t.string :status, null: false
+ t.string :diagnostic, null: true
t.timestamps
end
diff --git a/db/migrate/20200917104213_add_recipient_json_to_bounced_mail_address.rb b/db/migrate/20200917104213_add_recipient_json_to_bounced_mail_address.rb
deleted file mode 100644
index bad3d846e..000000000
--- a/db/migrate/20200917104213_add_recipient_json_to_bounced_mail_address.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddRecipientJsonToBouncedMailAddress < ActiveRecord::Migration[6.0]
- def change
- add_column :bounced_mail_addresses, :recipient_json, :jsonb, null: false
- end
-end
diff --git a/db/migrate/20200921084356_remove_incidents_from_bounced_mail_addresses.rb b/db/migrate/20200921084356_remove_incidents_from_bounced_mail_addresses.rb
deleted file mode 100644
index 0704795df..000000000
--- a/db/migrate/20200921084356_remove_incidents_from_bounced_mail_addresses.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class RemoveIncidentsFromBouncedMailAddresses < ActiveRecord::Migration[6.0]
- def up
- remove_column :bounced_mail_addresses, :incidents
- end
-
- def down
- add_column :bounced_mail_addresses, :incidents, :integer, null: false, default: 1
- end
-end
diff --git a/db/structure.sql b/db/structure.sql
index 74e784408..e064d968f 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -482,11 +482,14 @@ ALTER SEQUENCE public.blocked_domains_id_seq OWNED BY public.blocked_domains.id;
CREATE TABLE public.bounced_mail_addresses (
id bigint NOT NULL,
email character varying NOT NULL,
- bounce_reason character varying NOT NULL,
- response_json jsonb,
+ message_id character varying NOT NULL,
+ bounce_type character varying NOT NULL,
+ bounce_subtype character varying NOT NULL,
+ action character varying NOT NULL,
+ status character varying NOT NULL,
+ diagnostic character varying,
created_at timestamp(6) without time zone NOT NULL,
- updated_at timestamp(6) without time zone NOT NULL,
- recipient_json jsonb NOT NULL
+ updated_at timestamp(6) without time zone NOT NULL
);
@@ -4956,8 +4959,6 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200908131554'),
('20200910085157'),
('20200910102028'),
-('20200916125326'),
-('20200917104213'),
-('20200921084356');
+('20200916125326');
From 98674ab3817148e6c5e15acd7b48a956e3ef58d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 21 Sep 2020 13:47:57 +0300
Subject: [PATCH 017/106] Reflect new bounced mail structure
---
app/models/bounced_mail_address.rb | 36 ++++++++-----------
.../bounced_mail_addresses/show.html.erb | 18 ++++++----
2 files changed, 26 insertions(+), 28 deletions(-)
diff --git a/app/models/bounced_mail_address.rb b/app/models/bounced_mail_address.rb
index 02bb42337..61679f543 100644
--- a/app/models/bounced_mail_address.rb
+++ b/app/models/bounced_mail_address.rb
@@ -1,6 +1,5 @@
class BouncedMailAddress < ApplicationRecord
- validates :email, presence: true
- validates :bounce_reason, :recipient_json, :response_json, presence: true
+ validates :email, :message_id, :bounce_type, :bounce_subtype, :action, :status, presence: true
before_validation :assign_bounce_reason
def assign_bounce_reason
@@ -9,31 +8,24 @@ class BouncedMailAddress < ApplicationRecord
self.bounce_reason = "#{action} (#{status} #{diagnostic})"
end
- def diagnostic
- return unless recipient_json
-
- recipient_json['diagnosticCode']
- end
-
- def action
- return unless recipient_json
-
- recipient_json['action']
- end
-
- def status
- return unless recipient_json
-
- recipient_json['status']
- end
-
def self.record(json)
bounced_records = json['bounce']['bouncedRecipients']
bounced_records.each do |record|
- bounce_record = BouncedMailAddress.new(email: record['emailAddress'], recipient_json: record,
- response_json: json)
+ bounce_record = BouncedMailAddress.new(params_from_json(json, record))
bounce_record.save
end
end
+
+ def params_from_json(json, bounced_record)
+ {
+ email: bounced_record['emailAddress'],
+ message_id: json['mail']['messageId'],
+ bounce_type: json['bounce']['bounceType'],
+ bounce_subtype: json['bounce']['bounceSubType'],
+ action: bounced_record['action'],
+ status: bounced_record['status'],
+ diagnostic: bounced_record['diagnosticCode'],
+ }
+ end
end
diff --git a/app/views/admin/bounced_mail_addresses/show.html.erb b/app/views/admin/bounced_mail_addresses/show.html.erb
index 98eeabcd2..5183ae5a1 100644
--- a/app/views/admin/bounced_mail_addresses/show.html.erb
+++ b/app/views/admin/bounced_mail_addresses/show.html.erb
@@ -1,20 +1,26 @@
+
Email:
<%= @bounced_mail_address.email %>
- Bounce reason:
- <%= @bounced_mail_address.bounce_reason %>
+ Bounced message ID:
+ <%= @bounced_mail_address.message_id %>
- Bounced recipient JSON:
-
<%= JSON.pretty_generate(@bounced_mail_address.recipient_json) %>
+ Overall bounce type:
+ <%= @bounced_mail_address.bounce_type %> (<%= @bounced_mail_address.bounce_subtype %> )
- Bounce payload:
-
<%= JSON.pretty_generate(@bounced_mail_address.response_json) %>
+ Bounced recipient status:
+ <%= @bounced_mail_address.action %> (<%= @bounced_mail_address.status %>)
+
+
+
+ Bounced recipient diagnostic:
+
<%= @bounced_mail_address.diagnostic %>
<%= link_to 'Back', admin_bounced_mail_addresses_path %>
From 3222a8b9a79b80444a41b8b348c98d8d260aeb4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Wed, 30 Sep 2020 12:48:21 +0300
Subject: [PATCH 018/106] Bounces: Fix tests
---
app/models/bounced_mail_address.rb | 9 +-
test/fixtures/bounced_mail_addresses.yml | 41 ++-------
test/models/bounced_mail_address_test.rb | 91 ++++++++++---------
.../admin_area/bounced_mail_addresses_test.rb | 3 +-
4 files changed, 58 insertions(+), 86 deletions(-)
diff --git a/app/models/bounced_mail_address.rb b/app/models/bounced_mail_address.rb
index 61679f543..73c6a0941 100644
--- a/app/models/bounced_mail_address.rb
+++ b/app/models/bounced_mail_address.rb
@@ -1,11 +1,8 @@
class BouncedMailAddress < ApplicationRecord
validates :email, :message_id, :bounce_type, :bounce_subtype, :action, :status, presence: true
- before_validation :assign_bounce_reason
- def assign_bounce_reason
- return self.bounce_reason = nil unless recipient_json
-
- self.bounce_reason = "#{action} (#{status} #{diagnostic})"
+ def bounce_reason
+ "#{action} (#{status} #{diagnostic})"
end
def self.record(json)
@@ -17,7 +14,7 @@ class BouncedMailAddress < ApplicationRecord
end
end
- def params_from_json(json, bounced_record)
+ def self.params_from_json(json, bounced_record)
{
email: bounced_record['emailAddress'],
message_id: json['mail']['messageId'],
diff --git a/test/fixtures/bounced_mail_addresses.yml b/test/fixtures/bounced_mail_addresses.yml
index 345b2ef22..cbfdff680 100644
--- a/test/fixtures/bounced_mail_addresses.yml
+++ b/test/fixtures/bounced_mail_addresses.yml
@@ -1,39 +1,10 @@
one:
email: bounced@registry.test
- bounce_reason: failed (5.1.1 smtp; 550 5.1.1 user unknown)
- recipient_json: {
- "action": "failed",
- "status": "5.1.1",
- "emailAddress": "bounced@registry.test",
- "diagnosticCode": "smtp; 550 5.1.1 user unknown"
- }
- response_json: {
- "notificationType": "Bounce",
- "mail": {
- "source": "noreply@registry.test",
- "sourceIp": "195.43.86.5",
- "messageId": "010f0174a0c7d348-ea6e2fc1-0854-4073-b71f-5cecf9b0d0b2-000000",
- "sourceArn": "arn:aws:ses:us-east-2:65026820000:identity/noreply@registry.test",
- "timestamp": "2020-09-18T10:34:44.000Z",
- "destination": [ "bounced@registry.test" ],
- "sendingAccountId": "650268220000"
- },
- "bounce": {
- "timestamp": "2020-09-18T10:34:44.911Z",
- "bounceType": "Permanent",
- "feedbackId": "010f0174a0c7d4f9-27d59756-6111-4d5f-xxxx-26bee0d55fa2-000000",
- "remoteMtaIp": "127.0.01",
- "reportingMTA": "dsn; xxx.amazonses.com",
- "bounceSubType": "General",
- "bouncedRecipients": [
- {
- "action": "failed",
- "status": "5.1.1",
- "emailAddress": "bounced@registry.test",
- "diagnosticCode": "smtp; 550 5.1.1 user unknown"
- }
- ]
- }
- }
+ message_id: 010f0174a0c7d348-ea6e2fc1-0854-4073-b71f-5cecf9b0d0b2-000000
+ bounce_type: Permanent
+ bounce_subtype: General
+ action: failed
+ status: '5.1.1'
+ diagnostic: 'smtp; 550 5.1.1 user unknown'
created_at: <%= Time.zone.parse('2010-07-05').to_s(:db) %>
updated_at: <%= Time.zone.parse('2010-07-05').to_s(:db) %>
diff --git a/test/models/bounced_mail_address_test.rb b/test/models/bounced_mail_address_test.rb
index 0e6a62ab8..4af401711 100644
--- a/test/models/bounced_mail_address_test.rb
+++ b/test/models/bounced_mail_address_test.rb
@@ -6,56 +6,61 @@ class BouncedMailAddressTest < ActiveSupport::TestCase
def setup
@bounced_mail = BouncedMailAddress.new
@bounced_mail.email = 'recipient@registry.test'
- @bounced_mail.bounce_reason = 'failed (5.1.1 smtp; 550 5.1.1 user unknown)'
- @bounced_mail.response_json = {"mail"=>{"source"=>"noreply@internet.test", "sourceIp"=>"195.43.86.5", "messageId"=>"010f0174a0c7d348-ea6e2fc1-0854-4073-b71f-5cecf9b0d0b2-000000", "sourceArn"=>"arn:aws:ses:us-east-2:650268220328:identity/noreply@internet.test", "timestamp"=>"2020-09-18T10:34:44.000Z", "destination"=>["#{@bounced_mail.email}"], "sendingAccountId"=>"650268220328"}, "bounce"=>{"timestamp"=>"2020-09-18T10:34:44.911Z", "bounceType"=>"Permanent", "feedbackId"=>"010f0174a0c7d4f9-27d59756-6111-xxxx-a507-26bee0d55fa2-000000", "remoteMtaIp"=>"127.0.0.1", "reportingMTA"=>"dsn; xxx.amazonses.com", "bounceSubType"=>"General", "bouncedRecipients"=>[{"action"=>"failed", "status"=>"5.1.1", "emailAddress"=>"#{@bounced_mail.email}", "diagnosticCode"=>"smtp; 550 5.1.1 user unknown"}]}, "notificationType"=>"Bounce"}
- @bounced_mail.recipient_json = {"action"=>"failed", "status"=>"5.1.1", "emailAddress"=>"#{@bounced_mail.email}", "diagnosticCode"=>"smtp; 550 5.1.1 user unknown"}
-
+ @bounced_mail.message_id = '010f0174a0c7d348-ea6e2fc1-0854-4073-b71f-5cecf9b0d0b2-000000'
+ @bounced_mail.bounce_type = 'Permanent'
+ @bounced_mail.bounce_subtype = 'General'
+ @bounced_mail.action = 'failed'
+ @bounced_mail.status = '5.1.1'
+ @bounced_mail.diagnostic = 'smtp; 550 5.1.1 user unknown'
end
- def test_bounce_reason_is_autoassigned
- assert @bounced_mail.valid?
- @bounced_mail.bounce_reason = nil
+ def test_email_is_required
assert @bounced_mail.valid?
+ @bounced_mail.email = nil
+ assert @bounced_mail.invalid?
+ end
+ def test_message_id_is_required
+ assert @bounced_mail.valid?
+ @bounced_mail.message_id = nil
+ assert @bounced_mail.invalid?
+ end
+
+ def test_bounce_type_is_required
+ assert @bounced_mail.valid?
+ @bounced_mail.bounce_type = nil
+ assert @bounced_mail.invalid?
+ end
+
+ def test_bounce_subtype_is_required
+ assert @bounced_mail.valid?
+ @bounced_mail.bounce_subtype = nil
+ assert @bounced_mail.invalid?
+ end
+
+ def test_action_is_required
+ assert @bounced_mail.valid?
+ @bounced_mail.action = nil
+ assert @bounced_mail.invalid?
+ end
+
+ def test_status_is_required
+ assert @bounced_mail.valid?
+ @bounced_mail.status = nil
+ assert @bounced_mail.invalid?
+ end
+
+ def test_diagnostic_is_not_required
+ assert @bounced_mail.valid?
+ @bounced_mail.diagnostic = nil
+ assert @bounced_mail.valid?
+ end
+
+ def test_bounce_reason_is_determined_dynamically
+ assert @bounced_mail.valid?
assert_equal 'failed (5.1.1 smtp; 550 5.1.1 user unknown)', @bounced_mail.bounce_reason
end
- def test_response_json_is_required
- assert @bounced_mail.valid?
- @bounced_mail.response_json = nil
- assert_not @bounced_mail.valid?
- assert @bounced_mail.errors.full_messages.include? 'Response json is missing'
- end
-
- def test_recipient_json_is_required
- assert @bounced_mail.valid?
- @bounced_mail.recipient_json = nil
- assert_not @bounced_mail.valid?
-
- assert @bounced_mail.errors.full_messages.include? 'Recipient json is missing'
- end
-
- def test_status_is_determined_dynamically
- assert @bounced_mail.valid?
- assert_equal '5.1.1', @bounced_mail.status
- @bounced_mail.recipient_json['status'] = 'xxx_status'
- assert_equal 'xxx_status', @bounced_mail.status
- end
-
- def test_action_is_determined_dynamically
- assert @bounced_mail.valid?
- assert_equal 'failed', @bounced_mail.action
- @bounced_mail.recipient_json['action'] = 'xxx_action'
- assert_equal 'xxx_action', @bounced_mail.action
- end
-
- def test_diagnostic_is_determined_dynamically
- assert @bounced_mail.valid?
- assert_equal 'smtp; 550 5.1.1 user unknown', @bounced_mail.diagnostic
- @bounced_mail.recipient_json['diagnosticCode'] = 'xxx_diagnostic'
- assert_equal 'xxx_diagnostic', @bounced_mail.diagnostic
- end
-
def test_creates_objects_from_sns_json
BouncedMailAddress.record(sns_bounce_payload)
diff --git a/test/system/admin_area/bounced_mail_addresses_test.rb b/test/system/admin_area/bounced_mail_addresses_test.rb
index 5500f4375..36b81f0f8 100644
--- a/test/system/admin_area/bounced_mail_addresses_test.rb
+++ b/test/system/admin_area/bounced_mail_addresses_test.rb
@@ -28,8 +28,7 @@ class AdminBouncedMailAddressesTest < ApplicationSystemTestCase
assert_text @bounced_mail.diagnostic
assert_text @bounced_mail.email
- assert_text 'bouncedRecipients'
- assert_text '010f0174a0c7d4f9-27d59756-6111-4d5f-xxxx-26bee0d55fa2-000000'
+ assert_text @bounced_mail.message_id
end
def test_deletes_registrar
From 574846c626e23b2368c30c3088de9046f36e946b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Fri, 2 Oct 2020 16:02:44 +0300
Subject: [PATCH 019/106] Remove unneeded modifications in structure.sql
---
db/structure.sql | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/db/structure.sql b/db/structure.sql
index e064d968f..acf134a55 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -1743,7 +1743,7 @@ ALTER SEQUENCE public.log_payment_orders_id_seq OWNED BY public.log_payment_orde
--
--- Name: log_prices; Type: TABLE; Schema: public; Owner: -; Tablespace:
+-- Name: log_prices; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.log_prices (
@@ -1781,7 +1781,7 @@ ALTER SEQUENCE public.log_prices_id_seq OWNED BY public.log_prices.id;
--
--- Name: log_registrant_verifications; Type: TABLE; Schema: public; Owner: -; Tablespace:
+-- Name: log_registrant_verifications; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.log_registrant_verifications (
@@ -3401,7 +3401,7 @@ ALTER TABLE ONLY public.log_payment_orders
--
--- Name: log_prices_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
+-- Name: log_prices_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.log_prices
@@ -3409,7 +3409,7 @@ ALTER TABLE ONLY public.log_prices
--
--- Name: log_registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
+-- Name: log_registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.log_registrant_verifications
From ef5c4bd54ebcdcab6f6544cf5b490494126c4110 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 19 Nov 2020 16:15:23 +0200
Subject: [PATCH 020/106] Return total domain count in domains query
---
app/controllers/api/v1/registrant/domains_controller.rb | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/app/controllers/api/v1/registrant/domains_controller.rb b/app/controllers/api/v1/registrant/domains_controller.rb
index b985ef390..48cb95cf2 100644
--- a/app/controllers/api/v1/registrant/domains_controller.rb
+++ b/app/controllers/api/v1/registrant/domains_controller.rb
@@ -18,14 +18,13 @@ module Api
status: :bad_request) && return
end
- @domains = current_user_domains.limit(limit).offset(offset)
-
- serialized_domains = @domains.map do |item|
+ domains = current_user_domains
+ serialized_domains = domains.limit(limit).offset(offset).map do |item|
serializer = Serializers::RegistrantApi::Domain.new(item)
serializer.to_json
end
- render json: serialized_domains
+ render json: {count: domains.count, domains: serialized_domains}
end
def show
From 556008debee12987dfc31edabc4be62a4566cb4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 19 Nov 2020 16:18:25 +0200
Subject: [PATCH 021/106] Fix CC issues
---
app/controllers/api/v1/registrant/domains_controller.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/controllers/api/v1/registrant/domains_controller.rb b/app/controllers/api/v1/registrant/domains_controller.rb
index 48cb95cf2..26f9f813b 100644
--- a/app/controllers/api/v1/registrant/domains_controller.rb
+++ b/app/controllers/api/v1/registrant/domains_controller.rb
@@ -24,7 +24,7 @@ module Api
serializer.to_json
end
- render json: {count: domains.count, domains: serialized_domains}
+ render json: { count: domains.count, domains: serialized_domains }
end
def show
From a40116e05e5e80378ef99f861ec824c020ffd276 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Fri, 20 Nov 2020 16:51:05 +0500
Subject: [PATCH 022/106] Move ClientHold procedure to interactor
Closes #1751
---
.../client_hold_interaction/base.rb | 8 +++
.../process_client_hold.rb | 67 +++++++++++++++++++
.../set_client_hold.rb | 15 +++++
app/models/concerns/domain/force_delete.rb | 19 ------
app/models/concerns/job/force_delete.rb | 34 ----------
.../concerns/job/force_delete_logging.rb | 34 ----------
.../concerns/job/force_delete_notify.rb | 31 ---------
app/models/domain_cron.rb | 8 +--
test/models/domain/force_delete_test.rb | 13 ++--
9 files changed, 102 insertions(+), 127 deletions(-)
create mode 100644 app/interactions/client_hold_interaction/base.rb
create mode 100644 app/interactions/client_hold_interaction/process_client_hold.rb
create mode 100644 app/interactions/client_hold_interaction/set_client_hold.rb
delete mode 100644 app/models/concerns/job/force_delete.rb
delete mode 100644 app/models/concerns/job/force_delete_logging.rb
delete mode 100644 app/models/concerns/job/force_delete_notify.rb
diff --git a/app/interactions/client_hold_interaction/base.rb b/app/interactions/client_hold_interaction/base.rb
new file mode 100644
index 000000000..be8b8b0a8
--- /dev/null
+++ b/app/interactions/client_hold_interaction/base.rb
@@ -0,0 +1,8 @@
+module ClientHoldInteraction
+ class Base < ActiveInteraction::Base
+ def to_stdout(message)
+ time = Time.zone.now.utc
+ STDOUT << "#{time} - #{message}\n" unless Rails.env.test?
+ end
+ end
+end
diff --git a/app/interactions/client_hold_interaction/process_client_hold.rb b/app/interactions/client_hold_interaction/process_client_hold.rb
new file mode 100644
index 000000000..453c400cc
--- /dev/null
+++ b/app/interactions/client_hold_interaction/process_client_hold.rb
@@ -0,0 +1,67 @@
+module ClientHoldInteraction
+ 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
diff --git a/app/interactions/client_hold_interaction/set_client_hold.rb b/app/interactions/client_hold_interaction/set_client_hold.rb
new file mode 100644
index 000000000..d723d5cc8
--- /dev/null
+++ b/app/interactions/client_hold_interaction/set_client_hold.rb
@@ -0,0 +1,15 @@
+module ClientHoldInteraction
+ 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|
+ ClientHoldInteraction::ProcessClientHold.run(domain: domain)
+ end
+
+ to_stdout('All client_hold setting are done\n')
+ end
+ end
+end
diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index ff869fc0a..988c8075a 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -33,25 +33,6 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
statuses.include?(DomainStatus::FORCE_DELETE)
end
- 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 &&
- !statuses.include?(DomainStatus::CLIENT_HOLD)
- 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, notify_by_email: false)
ForceDeleteInteraction::SetForceDelete.run(domain: self,
type: type,
diff --git a/app/models/concerns/job/force_delete.rb b/app/models/concerns/job/force_delete.rb
deleted file mode 100644
index 316612d1e..000000000
--- a/app/models/concerns/job/force_delete.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-module Concerns
- module Job
- module ForceDelete
- extend ActiveSupport::Concern
-
- class_methods do
- def start_client_hold
- log_prepare_client_hold
-
- ::PaperTrail.request.whodunnit = "cron - #{__method__}"
-
- ::Domain.force_delete_scheduled.each do |domain|
- proceed_client_hold(domain: domain)
- end
-
- log_end_end_force_delete_job
- 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)
-
- log_end_end_client_hold(domain)
- end
- end
- end
- end
-end
diff --git a/app/models/concerns/job/force_delete_logging.rb b/app/models/concerns/job/force_delete_logging.rb
deleted file mode 100644
index 8f6ee227c..000000000
--- a/app/models/concerns/job/force_delete_logging.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-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
-
- def log_end_end_force_delete_job
- return if Rails.env.test?
-
- STDOUT << "#{Time.zone.now.utc} - All client_hold setting are done\n"
- end
- end
- end
- end
-end
diff --git a/app/models/concerns/job/force_delete_notify.rb b/app/models/concerns/job/force_delete_notify.rb
deleted file mode 100644
index bc291354e..000000000
--- a/app/models/concerns/job/force_delete_notify.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-module Concerns
- module Job
- module ForceDeleteNotify
- extend ActiveSupport::Concern
-
- class_methods do
- def notify_client_hold(domain)
- 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 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) if domain.template_name.present?
- 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
diff --git a/app/models/domain_cron.rb b/app/models/domain_cron.rb
index ad64456ca..613762062 100644
--- a/app/models/domain_cron.rb
+++ b/app/models/domain_cron.rb
@@ -1,8 +1,4 @@
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?
@@ -81,4 +77,8 @@ class DomainCron
STDOUT << "#{Time.zone.now.utc} - Successfully set server_hold to #{marked} of #{real} domains\n" unless Rails.env.test?
marked
end
+
+ def self.start_client_hold
+ ClientHoldInteraction::SetClientHold.run!
+ end
end
diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb
index 7c205fa74..d9e7a3632 100644
--- a/test/models/domain/force_delete_test.rb
+++ b/test/models/domain/force_delete_test.rb
@@ -206,9 +206,10 @@ class ForceDeleteTest < ActionMailer::TestCase
@domain.schedule_force_delete(type: :soft)
travel_to Time.zone.parse('2010-08-21')
- DomainCron.start_client_hold
+ ClientHoldInteraction::SetClientHold.run!
@domain.reload
+ assert_emails 1
assert_equal(@domain.purge_date.to_date, @domain.force_delete_date.to_date)
assert_equal(@domain.outzone_date.to_date, @domain.force_delete_start.to_date +
Setting.expire_warning_period.days)
@@ -226,8 +227,10 @@ class ForceDeleteTest < ActionMailer::TestCase
@domain.schedule_force_delete(type: :soft)
travel_to Time.zone.parse('2010-08-21')
- DomainCron.start_client_hold
+ ClientHoldInteraction::SetClientHold.run!
@domain.reload
+
+ assert_emails 1
assert_includes(@domain.statuses, asserted_status)
end
@@ -241,7 +244,7 @@ class ForceDeleteTest < ActionMailer::TestCase
@domain.schedule_force_delete(type: :soft)
travel_to Time.zone.parse('2010-07-06')
- DomainCron.start_client_hold
+ ClientHoldInteraction::SetClientHold.run!
@domain.reload
assert_not_includes(@domain.statuses, asserted_status)
@@ -256,7 +259,7 @@ class ForceDeleteTest < ActionMailer::TestCase
@domain.schedule_force_delete(type: :fast_track)
travel_to Time.zone.parse('2010-07-25')
- DomainCron.start_client_hold
+ ClientHoldInteraction::SetClientHold.run!
@domain.reload
assert_includes(@domain.statuses, asserted_status)
@@ -272,7 +275,7 @@ class ForceDeleteTest < ActionMailer::TestCase
@domain.schedule_force_delete(type: :fast_track)
travel_to Time.zone.parse('2010-07-06')
- DomainCron.start_client_hold
+ ClientHoldInteraction::SetClientHold.run!
@domain.reload
assert_not_includes(@domain.statuses, asserted_status)
From a3e6bc4cf90c319a797a3b19cf6188d8360628ff Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 23 Nov 2020 16:31:26 +0500
Subject: [PATCH 023/106] Mode DomainDeleteConfirm job to interactor
---
.../send_request.rb | 22 +++++++++++++++++++
app/jobs/domain_delete_confirm_email_job.rb | 18 +--------------
2 files changed, 23 insertions(+), 17 deletions(-)
create mode 100644 app/interactions/domain_delete_confirm_interaction/send_request.rb
diff --git a/app/interactions/domain_delete_confirm_interaction/send_request.rb b/app/interactions/domain_delete_confirm_interaction/send_request.rb
new file mode 100644
index 000000000..6e734d40d
--- /dev/null
+++ b/app/interactions/domain_delete_confirm_interaction/send_request.rb
@@ -0,0 +1,22 @@
+module DomainDeleteConfirmInteraction
+ 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_now
+ 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
diff --git a/app/jobs/domain_delete_confirm_email_job.rb b/app/jobs/domain_delete_confirm_email_job.rb
index ea5a9bf49..ef9a1ba96 100644
--- a/app/jobs/domain_delete_confirm_email_job.rb
+++ b/app/jobs/domain_delete_confirm_email_job.rb
@@ -1,22 +1,6 @@
class DomainDeleteConfirmEmailJob < Que::Job
def run(domain_id)
domain = Domain.find(domain_id)
-
- log(domain)
- DomainDeleteMailer.confirmation_request(domain: domain,
- registrar: domain.registrar,
- registrant: domain.registrant).deliver_now
- end
-
- private
-
- def log(domain)
- message = "Send DomainDeleteMailer#confirm email for domain #{domain.name} (##{domain.id})" \
- " to #{domain.registrant.email}"
- logger.info(message)
- end
-
- def logger
- Rails.logger
+ DomainDeleteConfirmInteraction::SendRequest.run(domain: domain)
end
end
From cb3cf37331a090d6ab03ef82afdf3bfa228e4568 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 23 Nov 2020 16:57:28 +0500
Subject: [PATCH 024/106] Change email sending from job to delayed send
---
.../send_request.rb | 2 +-
app/jobs/domain_delete_confirm_email_job.rb | 8 ++++----
app/models/domain.rb | 2 +-
test/integration/epp/domain/delete/base_test.rb | 13 +++++++++----
4 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/app/interactions/domain_delete_confirm_interaction/send_request.rb b/app/interactions/domain_delete_confirm_interaction/send_request.rb
index 6e734d40d..bbf4c8d9e 100644
--- a/app/interactions/domain_delete_confirm_interaction/send_request.rb
+++ b/app/interactions/domain_delete_confirm_interaction/send_request.rb
@@ -8,7 +8,7 @@ module DomainDeleteConfirmInteraction
log
DomainDeleteMailer.confirmation_request(domain: domain,
registrar: domain.registrar,
- registrant: domain.registrant).deliver_now
+ registrant: domain.registrant).deliver_later
end
private
diff --git a/app/jobs/domain_delete_confirm_email_job.rb b/app/jobs/domain_delete_confirm_email_job.rb
index ef9a1ba96..d2c814bd8 100644
--- a/app/jobs/domain_delete_confirm_email_job.rb
+++ b/app/jobs/domain_delete_confirm_email_job.rb
@@ -1,6 +1,6 @@
class DomainDeleteConfirmEmailJob < Que::Job
- def run(domain_id)
- domain = Domain.find(domain_id)
- DomainDeleteConfirmInteraction::SendRequest.run(domain: domain)
- end
+ # def run(domain_id)
+ # domain = Domain.find(domain_id)
+ # DomainDeleteConfirmInteraction::SendRequest.run(domain: domain)
+ # end
end
diff --git a/app/models/domain.rb b/app/models/domain.rb
index b15bb7c55..1ef66ffab 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -418,7 +418,7 @@ class Domain < ApplicationRecord
pending_delete_confirmation!
save(validate: false) # should check if this did succeed
- DomainDeleteConfirmEmailJob.enqueue(id)
+ DomainDeleteConfirmInteraction::SendRequest.run(domain: self)
end
def cancel_pending_delete
diff --git a/test/integration/epp/domain/delete/base_test.rb b/test/integration/epp/domain/delete/base_test.rb
index bfdfa9f75..56a3cc31e 100644
--- a/test/integration/epp/domain/delete/base_test.rb
+++ b/test/integration/epp/domain/delete/base_test.rb
@@ -35,7 +35,6 @@ class EppDomainDeleteBaseTest < EppTestCase
XML
post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
- # binding.pry
assert_includes Domain.find_by(name: 'invalid.test').statuses, DomainStatus::PENDING_DELETE_CONFIRMATION
assert_epp_response :completed_successfully_action_pending
end
@@ -90,7 +89,9 @@ class EppDomainDeleteBaseTest < EppTestCase
XML
- post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+ perform_enqueued_jobs do
+ post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+ end
@domain.reload
assert @domain.registrant_verification_asked?
@@ -121,7 +122,9 @@ class EppDomainDeleteBaseTest < EppTestCase
XML
- post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+ perform_enqueued_jobs do
+ post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+ end
@domain.reload
assert_not @domain.registrant_verification_asked?
@@ -152,7 +155,9 @@ class EppDomainDeleteBaseTest < EppTestCase
XML
- post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+ perform_enqueued_jobs do
+ post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+ end
@domain.reload
assert_not @domain.registrant_verification_asked?
From 89c5413fc702c8399474ff18f6f245af531deeba Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 24 Nov 2020 13:26:38 +0500
Subject: [PATCH 025/106] Unused class clean-up
---
app/jobs/domain_delete_confirm_email_job.rb | 6 ------
test/models/whois/record_test.rb | 2 +-
2 files changed, 1 insertion(+), 7 deletions(-)
delete mode 100644 app/jobs/domain_delete_confirm_email_job.rb
diff --git a/app/jobs/domain_delete_confirm_email_job.rb b/app/jobs/domain_delete_confirm_email_job.rb
deleted file mode 100644
index d2c814bd8..000000000
--- a/app/jobs/domain_delete_confirm_email_job.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class DomainDeleteConfirmEmailJob < Que::Job
- # def run(domain_id)
- # domain = Domain.find(domain_id)
- # DomainDeleteConfirmInteraction::SendRequest.run(domain: domain)
- # end
-end
diff --git a/test/models/whois/record_test.rb b/test/models/whois/record_test.rb
index e900a4965..d06b23cae 100644
--- a/test/models/whois/record_test.rb
+++ b/test/models/whois/record_test.rb
@@ -70,6 +70,6 @@ class Whois::RecordTest < ActiveSupport::TestCase
end
def registration_deadline
- Time.zone.now + 10.days
+ @registration_deadline ||= Time.zone.now + 10.days
end
end
From 09a58fa432193dee065ebcbc0556cc96e877e0d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Fri, 27 Nov 2020 18:12:49 +0200
Subject: [PATCH 026/106] Update CHANGELOG.md
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ebbc3d905..44329c4d0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+27.11.2020
+* Refactored delete confirmation for interactors [#1753](https://github.com/internetee/registry/issues/1753)
+
24.11.2020
* Added subnet support for list of allowed IPs [#983](https://github.com/internetee/registry/issues/983)
* Added contact endpoint to Restful EPP API [#1580](https://github.com/internetee/registry/issues/1580)
From 7b3361394168656ce305cbbc0e885555fa5e712f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 30 Nov 2020 10:31:46 +0200
Subject: [PATCH 027/106] Reduce domains list API call
---
.../api/v1/registrant/domains_controller.rb | 4 ++--
lib/serializers/registrant_api/domain.rb | 18 +++++++++++++++++-
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/app/controllers/api/v1/registrant/domains_controller.rb b/app/controllers/api/v1/registrant/domains_controller.rb
index 26f9f813b..390148488 100644
--- a/app/controllers/api/v1/registrant/domains_controller.rb
+++ b/app/controllers/api/v1/registrant/domains_controller.rb
@@ -20,7 +20,7 @@ module Api
domains = current_user_domains
serialized_domains = domains.limit(limit).offset(offset).map do |item|
- serializer = Serializers::RegistrantApi::Domain.new(item)
+ serializer = Serializers::RegistrantApi::Domain.new(item, simplify: true)
serializer.to_json
end
@@ -31,7 +31,7 @@ module Api
@domain = current_user_domains.find_by(uuid: params[:uuid])
if @domain
- serializer = Serializers::RegistrantApi::Domain.new(@domain)
+ serializer = Serializers::RegistrantApi::Domain.new(@domain, simplify: false)
render json: serializer.to_json
else
render json: { errors: [{ base: ['Domain not found'] }] }, status: :not_found
diff --git a/lib/serializers/registrant_api/domain.rb b/lib/serializers/registrant_api/domain.rb
index 542f2d0de..f0c9c1876 100644
--- a/lib/serializers/registrant_api/domain.rb
+++ b/lib/serializers/registrant_api/domain.rb
@@ -3,11 +3,27 @@ module Serializers
class Domain
attr_reader :domain
- def initialize(domain)
+ def initialize(domain, simplify: false)
@domain = domain
+ @simplify = simplify
end
def to_json
+ if simplify
+ return {
+ id: domain.uuid,
+ name: domain.name,
+ registered_at: domain.registered_at,
+ valid_to: domain.valid_to,
+ registrant_verification_asked_at: domain.registrant_verification_asked_at,
+ statuses: domain.statuses,
+ registrar: {
+ name: domain.registrar.name,
+ website: domain.registrar.website
+ }
+ }
+ end
+
{
id: domain.uuid,
name: domain.name,
From 5363c546a598ecfe8460a43c6bb2c105ea764ab0 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 30 Nov 2020 13:46:53 +0500
Subject: [PATCH 028/106] Move all the existing interactors to Domains
namespace
---
.../cancel_force_delete_interaction/base.rb | 7 ----
.../cancel_force_delete.rb | 10 -----
.../clear_force_delete_data.rb | 10 -----
.../notify_registrar.rb | 8 ----
.../remove_force_delete_statuses.rb | 11 -----
.../restore_statuses_before_force_delete.rb | 9 -----
.../send_request.rb | 22 ----------
.../domains/cancel_force_delete/base.rb | 9 +++++
.../cancel_force_delete.rb | 12 ++++++
.../clear_force_delete_data.rb | 12 ++++++
.../cancel_force_delete/notify_registrar.rb | 10 +++++
.../remove_force_delete_statuses.rb | 13 ++++++
.../restore_statuses_before_force_delete.rb | 11 +++++
.../domains/delete_confirm/send_request.rb | 24 +++++++++++
app/interactions/domains/force_delete/base.rb | 17 ++++++++
.../domains/force_delete/check_discarded.rb | 12 ++++++
.../domains/force_delete/notify_by_email.rb | 23 +++++++++++
.../domains/force_delete/notify_registrar.rb | 12 ++++++
.../domains/force_delete/post_set_process.rb | 19 +++++++++
.../domains/force_delete/prepare_domain.rb | 15 +++++++
.../domains/force_delete/set_force_delete.rb | 14 +++++++
.../domains/force_delete/set_status.rb | 40 +++++++++++++++++++
.../force_delete_interaction/base.rb | 16 --------
.../check_discarded.rb | 11 -----
.../notify_by_email.rb | 21 ----------
.../notify_registrar.rb | 10 -----
.../post_set_process.rb | 17 --------
.../prepare_domain.rb | 13 ------
.../set_force_delete.rb | 12 ------
.../force_delete_interaction/set_status.rb | 38 ------------------
app/models/concerns/domain/force_delete.rb | 8 ++--
app/models/domain.rb | 2 +-
test/models/domain/force_delete_test.rb | 2 +-
test/models/domain_test.rb | 2 +-
34 files changed, 250 insertions(+), 222 deletions(-)
delete mode 100644 app/interactions/cancel_force_delete_interaction/base.rb
delete mode 100644 app/interactions/cancel_force_delete_interaction/cancel_force_delete.rb
delete mode 100644 app/interactions/cancel_force_delete_interaction/clear_force_delete_data.rb
delete mode 100644 app/interactions/cancel_force_delete_interaction/notify_registrar.rb
delete mode 100644 app/interactions/cancel_force_delete_interaction/remove_force_delete_statuses.rb
delete mode 100644 app/interactions/cancel_force_delete_interaction/restore_statuses_before_force_delete.rb
delete mode 100644 app/interactions/domain_delete_confirm_interaction/send_request.rb
create mode 100644 app/interactions/domains/cancel_force_delete/base.rb
create mode 100644 app/interactions/domains/cancel_force_delete/cancel_force_delete.rb
create mode 100644 app/interactions/domains/cancel_force_delete/clear_force_delete_data.rb
create mode 100644 app/interactions/domains/cancel_force_delete/notify_registrar.rb
create mode 100644 app/interactions/domains/cancel_force_delete/remove_force_delete_statuses.rb
create mode 100644 app/interactions/domains/cancel_force_delete/restore_statuses_before_force_delete.rb
create mode 100644 app/interactions/domains/delete_confirm/send_request.rb
create mode 100644 app/interactions/domains/force_delete/base.rb
create mode 100644 app/interactions/domains/force_delete/check_discarded.rb
create mode 100644 app/interactions/domains/force_delete/notify_by_email.rb
create mode 100644 app/interactions/domains/force_delete/notify_registrar.rb
create mode 100644 app/interactions/domains/force_delete/post_set_process.rb
create mode 100644 app/interactions/domains/force_delete/prepare_domain.rb
create mode 100644 app/interactions/domains/force_delete/set_force_delete.rb
create mode 100644 app/interactions/domains/force_delete/set_status.rb
delete mode 100644 app/interactions/force_delete_interaction/base.rb
delete mode 100644 app/interactions/force_delete_interaction/check_discarded.rb
delete mode 100644 app/interactions/force_delete_interaction/notify_by_email.rb
delete mode 100644 app/interactions/force_delete_interaction/notify_registrar.rb
delete mode 100644 app/interactions/force_delete_interaction/post_set_process.rb
delete mode 100644 app/interactions/force_delete_interaction/prepare_domain.rb
delete mode 100644 app/interactions/force_delete_interaction/set_force_delete.rb
delete mode 100644 app/interactions/force_delete_interaction/set_status.rb
diff --git a/app/interactions/cancel_force_delete_interaction/base.rb b/app/interactions/cancel_force_delete_interaction/base.rb
deleted file mode 100644
index 595279d87..000000000
--- a/app/interactions/cancel_force_delete_interaction/base.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module CancelForceDeleteInteraction
- class Base < ActiveInteraction::Base
- object :domain,
- class: Domain,
- description: 'Domain to cancel ForceDelete on'
- end
-end
diff --git a/app/interactions/cancel_force_delete_interaction/cancel_force_delete.rb b/app/interactions/cancel_force_delete_interaction/cancel_force_delete.rb
deleted file mode 100644
index 2f45bf0e4..000000000
--- a/app/interactions/cancel_force_delete_interaction/cancel_force_delete.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module CancelForceDeleteInteraction
- class CancelForceDelete < Base
- def execute
- compose(RemoveForceDeleteStatuses, inputs)
- compose(RestoreStatusesBeforeForceDelete, inputs)
- compose(ClearForceDeleteData, inputs)
- compose(NotifyRegistrar, inputs)
- end
- end
-end
diff --git a/app/interactions/cancel_force_delete_interaction/clear_force_delete_data.rb b/app/interactions/cancel_force_delete_interaction/clear_force_delete_data.rb
deleted file mode 100644
index ccc0714f7..000000000
--- a/app/interactions/cancel_force_delete_interaction/clear_force_delete_data.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module CancelForceDeleteInteraction
- 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
diff --git a/app/interactions/cancel_force_delete_interaction/notify_registrar.rb b/app/interactions/cancel_force_delete_interaction/notify_registrar.rb
deleted file mode 100644
index 3ded4c489..000000000
--- a/app/interactions/cancel_force_delete_interaction/notify_registrar.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-module CancelForceDeleteInteraction
- class NotifyRegistrar < Base
- def execute
- domain.registrar.notifications.create!(text: I18n.t('force_delete_cancelled',
- domain_name: domain.name))
- end
- end
-end
diff --git a/app/interactions/cancel_force_delete_interaction/remove_force_delete_statuses.rb b/app/interactions/cancel_force_delete_interaction/remove_force_delete_statuses.rb
deleted file mode 100644
index 1cc4989e5..000000000
--- a/app/interactions/cancel_force_delete_interaction/remove_force_delete_statuses.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-module CancelForceDeleteInteraction
- 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
diff --git a/app/interactions/cancel_force_delete_interaction/restore_statuses_before_force_delete.rb b/app/interactions/cancel_force_delete_interaction/restore_statuses_before_force_delete.rb
deleted file mode 100644
index 06b6bbd18..000000000
--- a/app/interactions/cancel_force_delete_interaction/restore_statuses_before_force_delete.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module CancelForceDeleteInteraction
- 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
diff --git a/app/interactions/domain_delete_confirm_interaction/send_request.rb b/app/interactions/domain_delete_confirm_interaction/send_request.rb
deleted file mode 100644
index bbf4c8d9e..000000000
--- a/app/interactions/domain_delete_confirm_interaction/send_request.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-module DomainDeleteConfirmInteraction
- 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
diff --git a/app/interactions/domains/cancel_force_delete/base.rb b/app/interactions/domains/cancel_force_delete/base.rb
new file mode 100644
index 000000000..b15a3ae77
--- /dev/null
+++ b/app/interactions/domains/cancel_force_delete/base.rb
@@ -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
diff --git a/app/interactions/domains/cancel_force_delete/cancel_force_delete.rb b/app/interactions/domains/cancel_force_delete/cancel_force_delete.rb
new file mode 100644
index 000000000..7c4ca90e1
--- /dev/null
+++ b/app/interactions/domains/cancel_force_delete/cancel_force_delete.rb
@@ -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
diff --git a/app/interactions/domains/cancel_force_delete/clear_force_delete_data.rb b/app/interactions/domains/cancel_force_delete/clear_force_delete_data.rb
new file mode 100644
index 000000000..066df04fd
--- /dev/null
+++ b/app/interactions/domains/cancel_force_delete/clear_force_delete_data.rb
@@ -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
diff --git a/app/interactions/domains/cancel_force_delete/notify_registrar.rb b/app/interactions/domains/cancel_force_delete/notify_registrar.rb
new file mode 100644
index 000000000..0de69e13e
--- /dev/null
+++ b/app/interactions/domains/cancel_force_delete/notify_registrar.rb
@@ -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
diff --git a/app/interactions/domains/cancel_force_delete/remove_force_delete_statuses.rb b/app/interactions/domains/cancel_force_delete/remove_force_delete_statuses.rb
new file mode 100644
index 000000000..c77820ecf
--- /dev/null
+++ b/app/interactions/domains/cancel_force_delete/remove_force_delete_statuses.rb
@@ -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
diff --git a/app/interactions/domains/cancel_force_delete/restore_statuses_before_force_delete.rb b/app/interactions/domains/cancel_force_delete/restore_statuses_before_force_delete.rb
new file mode 100644
index 000000000..c55c06764
--- /dev/null
+++ b/app/interactions/domains/cancel_force_delete/restore_statuses_before_force_delete.rb
@@ -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
diff --git a/app/interactions/domains/delete_confirm/send_request.rb b/app/interactions/domains/delete_confirm/send_request.rb
new file mode 100644
index 000000000..91afaefb8
--- /dev/null
+++ b/app/interactions/domains/delete_confirm/send_request.rb
@@ -0,0 +1,24 @@
+module Domains
+ module DeleteConfirm
+ 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
diff --git a/app/interactions/domains/force_delete/base.rb b/app/interactions/domains/force_delete/base.rb
new file mode 100644
index 000000000..27601c1d2
--- /dev/null
+++ b/app/interactions/domains/force_delete/base.rb
@@ -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
diff --git a/app/interactions/domains/force_delete/check_discarded.rb b/app/interactions/domains/force_delete/check_discarded.rb
new file mode 100644
index 000000000..cbb9c1dc6
--- /dev/null
+++ b/app/interactions/domains/force_delete/check_discarded.rb
@@ -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
diff --git a/app/interactions/domains/force_delete/notify_by_email.rb b/app/interactions/domains/force_delete/notify_by_email.rb
new file mode 100644
index 000000000..b60f54a5e
--- /dev/null
+++ b/app/interactions/domains/force_delete/notify_by_email.rb
@@ -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
diff --git a/app/interactions/domains/force_delete/notify_registrar.rb b/app/interactions/domains/force_delete/notify_registrar.rb
new file mode 100644
index 000000000..522502640
--- /dev/null
+++ b/app/interactions/domains/force_delete/notify_registrar.rb
@@ -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
diff --git a/app/interactions/domains/force_delete/post_set_process.rb b/app/interactions/domains/force_delete/post_set_process.rb
new file mode 100644
index 000000000..904149f93
--- /dev/null
+++ b/app/interactions/domains/force_delete/post_set_process.rb
@@ -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
diff --git a/app/interactions/domains/force_delete/prepare_domain.rb b/app/interactions/domains/force_delete/prepare_domain.rb
new file mode 100644
index 000000000..74eea21ed
--- /dev/null
+++ b/app/interactions/domains/force_delete/prepare_domain.rb
@@ -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
diff --git a/app/interactions/domains/force_delete/set_force_delete.rb b/app/interactions/domains/force_delete/set_force_delete.rb
new file mode 100644
index 000000000..16a0b09fa
--- /dev/null
+++ b/app/interactions/domains/force_delete/set_force_delete.rb
@@ -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
diff --git a/app/interactions/domains/force_delete/set_status.rb b/app/interactions/domains/force_delete/set_status.rb
new file mode 100644
index 000000000..b0a53ad82
--- /dev/null
+++ b/app/interactions/domains/force_delete/set_status.rb
@@ -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
diff --git a/app/interactions/force_delete_interaction/base.rb b/app/interactions/force_delete_interaction/base.rb
deleted file mode 100644
index 4764ce8fe..000000000
--- a/app/interactions/force_delete_interaction/base.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module ForceDeleteInteraction
- 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
-
diff --git a/app/interactions/force_delete_interaction/check_discarded.rb b/app/interactions/force_delete_interaction/check_discarded.rb
deleted file mode 100644
index e0c893294..000000000
--- a/app/interactions/force_delete_interaction/check_discarded.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-module ForceDeleteInteraction
- 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
-
diff --git a/app/interactions/force_delete_interaction/notify_by_email.rb b/app/interactions/force_delete_interaction/notify_by_email.rb
deleted file mode 100644
index 541df258d..000000000
--- a/app/interactions/force_delete_interaction/notify_by_email.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module ForceDeleteInteraction
- 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
diff --git a/app/interactions/force_delete_interaction/notify_registrar.rb b/app/interactions/force_delete_interaction/notify_registrar.rb
deleted file mode 100644
index 691e54f7e..000000000
--- a/app/interactions/force_delete_interaction/notify_registrar.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module ForceDeleteInteraction
- 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
diff --git a/app/interactions/force_delete_interaction/post_set_process.rb b/app/interactions/force_delete_interaction/post_set_process.rb
deleted file mode 100644
index e51acf9b7..000000000
--- a/app/interactions/force_delete_interaction/post_set_process.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module ForceDeleteInteraction
- 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
diff --git a/app/interactions/force_delete_interaction/prepare_domain.rb b/app/interactions/force_delete_interaction/prepare_domain.rb
deleted file mode 100644
index 97f364145..000000000
--- a/app/interactions/force_delete_interaction/prepare_domain.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module ForceDeleteInteraction
- 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
diff --git a/app/interactions/force_delete_interaction/set_force_delete.rb b/app/interactions/force_delete_interaction/set_force_delete.rb
deleted file mode 100644
index 4608b5127..000000000
--- a/app/interactions/force_delete_interaction/set_force_delete.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module ForceDeleteInteraction
- 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
diff --git a/app/interactions/force_delete_interaction/set_status.rb b/app/interactions/force_delete_interaction/set_status.rb
deleted file mode 100644
index 7d104aeee..000000000
--- a/app/interactions/force_delete_interaction/set_status.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-module ForceDeleteInteraction
- 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
diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index ff869fc0a..6e0f6c886 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -53,13 +53,13 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def schedule_force_delete(type: :fast_track, notify_by_email: false)
- ForceDeleteInteraction::SetForceDelete.run(domain: self,
- type: type,
- notify_by_email: notify_by_email)
+ Domains::ForceDelete::SetForceDelete.run(domain: self,
+ type: type,
+ notify_by_email: notify_by_email)
end
def cancel_force_delete
- CancelForceDeleteInteraction::CancelForceDelete.run(domain: self)
+ Domains::CancelForceDelete::CancelForceDelete.run(domain: self)
end
def outzone_date
diff --git a/app/models/domain.rb b/app/models/domain.rb
index 1ef66ffab..dc7d86da8 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -418,7 +418,7 @@ class Domain < ApplicationRecord
pending_delete_confirmation!
save(validate: false) # should check if this did succeed
- DomainDeleteConfirmInteraction::SendRequest.run(domain: self)
+ Domains::DeleteConfirm::SendRequest.run(domain: self)
end
def cancel_pending_delete
diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb
index 7c205fa74..dcb9b80f6 100644
--- a/test/models/domain/force_delete_test.rb
+++ b/test/models/domain/force_delete_test.rb
@@ -113,7 +113,7 @@ class ForceDeleteTest < ActionMailer::TestCase
def test_force_delete_cannot_be_scheduled_when_a_domain_is_discarded
@domain.update!(statuses: [DomainStatus::DELETE_CANDIDATE])
- result = ForceDeleteInteraction::SetForceDelete.run(domain: @domain, type: :fast_track)
+ result = Domains::ForceDelete::SetForceDelete.run(domain: @domain, type: :fast_track)
assert_not result.valid?
assert_not @domain.force_delete_scheduled?
diff --git a/test/models/domain_test.rb b/test/models/domain_test.rb
index cc88cf35f..ae12f4a1e 100644
--- a/test/models/domain_test.rb
+++ b/test/models/domain_test.rb
@@ -414,7 +414,7 @@ class DomainTest < ActiveSupport::TestCase
force_delete_date: nil)
@domain.update(template_name: 'legal_person')
travel_to Time.zone.parse('2010-07-05')
- ForceDeleteInteraction::SetForceDelete.run!(domain: @domain, type: :fast_track)
+ Domains::ForceDelete::SetForceDelete.run!(domain: @domain, type: :fast_track)
assert(@domain.force_delete_scheduled?)
other_registrant = Registrant.find_by(code: 'jane-001')
@domain.pending_json['new_registrant_id'] = other_registrant.id
From 8ff8aa78c8e12ae6523c3cc0ff1524b12de44d81 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 30 Nov 2020 16:08:32 +0500
Subject: [PATCH 029/106] Move interactor to namespace
---
.../client_hold_interaction/base.rb | 8 ---
.../process_client_hold.rb | 67 ------------------
.../set_client_hold.rb | 15 ----
app/interactions/domains/client_hold/base.rb | 10 +++
.../client_hold/process_client_hold.rb | 69 +++++++++++++++++++
.../domains/client_hold/set_client_hold.rb | 17 +++++
app/models/domain_cron.rb | 2 +-
test/models/domain/force_delete_test.rb | 10 +--
8 files changed, 102 insertions(+), 96 deletions(-)
delete mode 100644 app/interactions/client_hold_interaction/base.rb
delete mode 100644 app/interactions/client_hold_interaction/process_client_hold.rb
delete mode 100644 app/interactions/client_hold_interaction/set_client_hold.rb
create mode 100644 app/interactions/domains/client_hold/base.rb
create mode 100644 app/interactions/domains/client_hold/process_client_hold.rb
create mode 100644 app/interactions/domains/client_hold/set_client_hold.rb
diff --git a/app/interactions/client_hold_interaction/base.rb b/app/interactions/client_hold_interaction/base.rb
deleted file mode 100644
index be8b8b0a8..000000000
--- a/app/interactions/client_hold_interaction/base.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-module ClientHoldInteraction
- class Base < ActiveInteraction::Base
- def to_stdout(message)
- time = Time.zone.now.utc
- STDOUT << "#{time} - #{message}\n" unless Rails.env.test?
- end
- end
-end
diff --git a/app/interactions/client_hold_interaction/process_client_hold.rb b/app/interactions/client_hold_interaction/process_client_hold.rb
deleted file mode 100644
index 453c400cc..000000000
--- a/app/interactions/client_hold_interaction/process_client_hold.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-module ClientHoldInteraction
- 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
diff --git a/app/interactions/client_hold_interaction/set_client_hold.rb b/app/interactions/client_hold_interaction/set_client_hold.rb
deleted file mode 100644
index d723d5cc8..000000000
--- a/app/interactions/client_hold_interaction/set_client_hold.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module ClientHoldInteraction
- 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|
- ClientHoldInteraction::ProcessClientHold.run(domain: domain)
- end
-
- to_stdout('All client_hold setting are done\n')
- end
- end
-end
diff --git a/app/interactions/domains/client_hold/base.rb b/app/interactions/domains/client_hold/base.rb
new file mode 100644
index 000000000..c3c626b79
--- /dev/null
+++ b/app/interactions/domains/client_hold/base.rb
@@ -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
diff --git a/app/interactions/domains/client_hold/process_client_hold.rb b/app/interactions/domains/client_hold/process_client_hold.rb
new file mode 100644
index 000000000..8b8d60403
--- /dev/null
+++ b/app/interactions/domains/client_hold/process_client_hold.rb
@@ -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
diff --git a/app/interactions/domains/client_hold/set_client_hold.rb b/app/interactions/domains/client_hold/set_client_hold.rb
new file mode 100644
index 000000000..0e54b531f
--- /dev/null
+++ b/app/interactions/domains/client_hold/set_client_hold.rb
@@ -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
diff --git a/app/models/domain_cron.rb b/app/models/domain_cron.rb
index 613762062..d09141d52 100644
--- a/app/models/domain_cron.rb
+++ b/app/models/domain_cron.rb
@@ -79,6 +79,6 @@ class DomainCron
end
def self.start_client_hold
- ClientHoldInteraction::SetClientHold.run!
+ Domains::ClientHold::SetClientHold.run!
end
end
diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb
index d9e7a3632..304a7a18b 100644
--- a/test/models/domain/force_delete_test.rb
+++ b/test/models/domain/force_delete_test.rb
@@ -206,7 +206,7 @@ class ForceDeleteTest < ActionMailer::TestCase
@domain.schedule_force_delete(type: :soft)
travel_to Time.zone.parse('2010-08-21')
- ClientHoldInteraction::SetClientHold.run!
+ Domains::ClientHold::SetClientHold.run!
@domain.reload
assert_emails 1
@@ -227,7 +227,7 @@ class ForceDeleteTest < ActionMailer::TestCase
@domain.schedule_force_delete(type: :soft)
travel_to Time.zone.parse('2010-08-21')
- ClientHoldInteraction::SetClientHold.run!
+ Domains::ClientHold::SetClientHold.run!
@domain.reload
assert_emails 1
@@ -244,7 +244,7 @@ class ForceDeleteTest < ActionMailer::TestCase
@domain.schedule_force_delete(type: :soft)
travel_to Time.zone.parse('2010-07-06')
- ClientHoldInteraction::SetClientHold.run!
+ Domains::ClientHold::SetClientHold.run!
@domain.reload
assert_not_includes(@domain.statuses, asserted_status)
@@ -259,7 +259,7 @@ class ForceDeleteTest < ActionMailer::TestCase
@domain.schedule_force_delete(type: :fast_track)
travel_to Time.zone.parse('2010-07-25')
- ClientHoldInteraction::SetClientHold.run!
+ Domains::ClientHold::SetClientHold.run!
@domain.reload
assert_includes(@domain.statuses, asserted_status)
@@ -275,7 +275,7 @@ class ForceDeleteTest < ActionMailer::TestCase
@domain.schedule_force_delete(type: :fast_track)
travel_to Time.zone.parse('2010-07-06')
- ClientHoldInteraction::SetClientHold.run!
+ Domains::ClientHold::SetClientHold.run!
@domain.reload
assert_not_includes(@domain.statuses, asserted_status)
From cb7ff317e42a8a1dd2105834301e065e0ab676f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Mon, 30 Nov 2020 14:26:46 +0200
Subject: [PATCH 030/106] Update CHANGELOG.md
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44329c4d0..f418d4034 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+30.11.2020
+* Refactor - interactors moved to domain space [#1762](https://github.com/internetee/registry/pull/1762)
+
27.11.2020
* Refactored delete confirmation for interactors [#1753](https://github.com/internetee/registry/issues/1753)
From dc5bbb587f1490eb714742ff7db3acefc30a8c77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 30 Nov 2020 16:52:28 +0200
Subject: [PATCH 031/106] EPP: Show error when trying to remove unassigned
domain status
---
app/models/epp/domain.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb
index c46732712..a5922f48c 100644
--- a/app/models/epp/domain.rb
+++ b/app/models/epp/domain.rb
@@ -417,7 +417,7 @@ class Epp::Domain < Domain
if statuses.include?(x)
to_destroy << x
else
- add_epp_error('2303', 'status', x, [:domain_statuses, :not_found])
+ add_epp_error('2303', 'status', x, [:statuses, :not_found])
end
end
@@ -432,7 +432,7 @@ class Epp::Domain < Domain
frame.css('status').each do |x|
unless DomainStatus::CLIENT_STATUSES.include?(x['s'])
- add_epp_error('2303', 'status', x['s'], [:domain_statuses, :not_found])
+ add_epp_error('2303', 'status', x['s'], [:statuses, :not_found])
next
end
From 490de2ee4bd89b83df277e8848efbdbe479edbbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 30 Nov 2020 17:05:21 +0200
Subject: [PATCH 032/106] Add test for unassigned domain status removal
---
.../epp/domain/update/base_test.rb | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/test/integration/epp/domain/update/base_test.rb b/test/integration/epp/domain/update/base_test.rb
index 6ce455948..14e806fca 100644
--- a/test/integration/epp/domain/update/base_test.rb
+++ b/test/integration/epp/domain/update/base_test.rb
@@ -503,6 +503,30 @@ class EppDomainUpdateBaseTest < EppTestCase
assert_not_includes(@domain.statuses, DomainStatus::CLIENT_HOLD)
end
+ def test_update_domain_returns_error_when_removing_unassigned_status
+ assert_not_includes(@domain.statuses, DomainStatus::CLIENT_HOLD)
+ request_xml = <<-XML
+
+
+
+
+
+ #{@domain.name}
+
+
+
+
+
+
+
+ XML
+
+ post epp_update_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+ @domain.reload
+ assert_epp_response :object_does_not_exist
+ end
+
private
def assert_verification_and_notification_emails
From e5a2a6cf0f33281c8f16874f5e3343bcf635465f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 30 Nov 2020 17:10:04 +0200
Subject: [PATCH 033/106] Fix CC issues
---
app/models/epp/domain.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb
index a5922f48c..7fb23a6e9 100644
--- a/app/models/epp/domain.rb
+++ b/app/models/epp/domain.rb
@@ -417,7 +417,7 @@ class Epp::Domain < Domain
if statuses.include?(x)
to_destroy << x
else
- add_epp_error('2303', 'status', x, [:statuses, :not_found])
+ add_epp_error('2303', 'status', x, %i[statuses not_found])
end
end
@@ -432,7 +432,7 @@ class Epp::Domain < Domain
frame.css('status').each do |x|
unless DomainStatus::CLIENT_STATUSES.include?(x['s'])
- add_epp_error('2303', 'status', x['s'], [:statuses, :not_found])
+ add_epp_error('2303', 'status', x['s'], %i[statuses not_found])
next
end
From 512b181cd785e79d087f3d491d13ad6ad4787db8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Tue, 1 Dec 2020 10:00:04 +0200
Subject: [PATCH 034/106] Update CHANGELOG.md
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f418d4034..489ba94d3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+01.12.2020
+* Refactored clientHold for interactors [#1751](https://github.com/internetee/registry/issues/1751)
+
30.11.2020
* Refactor - interactors moved to domain space [#1762](https://github.com/internetee/registry/pull/1762)
From c9d4aaded98c98e0b9dc38ed5d64861493ea0ee9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 30 Nov 2020 16:50:14 +0200
Subject: [PATCH 035/106] Fix registrant domain serializer
---
.../api/v1/registrant/domains_controller.rb | 3 ++-
lib/serializers/registrant_api/domain.rb | 11 ++++++++---
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/app/controllers/api/v1/registrant/domains_controller.rb b/app/controllers/api/v1/registrant/domains_controller.rb
index 390148488..73b534598 100644
--- a/app/controllers/api/v1/registrant/domains_controller.rb
+++ b/app/controllers/api/v1/registrant/domains_controller.rb
@@ -7,6 +7,7 @@ module Api
def index
limit = params[:limit] || 200
offset = params[:offset] || 0
+ simple = params[:simple] == 'true' || false
if limit.to_i > 200 || limit.to_i < 1
render(json: { errors: [{ limit: ['parameter is out of range'] }] },
@@ -20,7 +21,7 @@ module Api
domains = current_user_domains
serialized_domains = domains.limit(limit).offset(offset).map do |item|
- serializer = Serializers::RegistrantApi::Domain.new(item, simplify: true)
+ serializer = Serializers::RegistrantApi::Domain.new(item, simplify: simple)
serializer.to_json
end
diff --git a/lib/serializers/registrant_api/domain.rb b/lib/serializers/registrant_api/domain.rb
index f0c9c1876..29362ad5c 100644
--- a/lib/serializers/registrant_api/domain.rb
+++ b/lib/serializers/registrant_api/domain.rb
@@ -9,18 +9,23 @@ module Serializers
end
def to_json
- if simplify
+ if @simplify
return {
id: domain.uuid,
name: domain.name,
registered_at: domain.registered_at,
valid_to: domain.valid_to,
+ outzone_at: domain.outzone_at,
registrant_verification_asked_at: domain.registrant_verification_asked_at,
statuses: domain.statuses,
registrar: {
name: domain.registrar.name,
- website: domain.registrar.website
- }
+ website: domain.registrar.website,
+ },
+ registrant: {
+ name: domain.registrant.name,
+ id: domain.registrant.uuid,
+ },
}
end
From 15e090c3b1710f13ab63ecf25c2bfa5023e54043 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Tue, 1 Dec 2020 12:53:30 +0200
Subject: [PATCH 036/106] Fix CC issue
---
lib/serializers/registrant_api/domain.rb | 32 +++++++++---------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/lib/serializers/registrant_api/domain.rb b/lib/serializers/registrant_api/domain.rb
index 29362ad5c..f8d5bb830 100644
--- a/lib/serializers/registrant_api/domain.rb
+++ b/lib/serializers/registrant_api/domain.rb
@@ -8,26 +8,8 @@ module Serializers
@simplify = simplify
end
- def to_json
- if @simplify
- return {
- id: domain.uuid,
- name: domain.name,
- registered_at: domain.registered_at,
- valid_to: domain.valid_to,
- outzone_at: domain.outzone_at,
- registrant_verification_asked_at: domain.registrant_verification_asked_at,
- statuses: domain.statuses,
- registrar: {
- name: domain.registrar.name,
- website: domain.registrar.website,
- },
- registrant: {
- name: domain.registrant.name,
- id: domain.registrant.uuid,
- },
- }
- end
+ def to_json(_obj = nil)
+ return simple_object if @simplify
{
id: domain.uuid,
@@ -70,6 +52,16 @@ module Serializers
private
+ def simple_object
+ {
+ id: domain.uuid, name: domain.name, registered_at: domain.registered_at,
+ valid_to: domain.valid_to, outzone_at: domain.outzone_at, statuses: domain.statuses,
+ registrant_verification_asked_at: domain.registrant_verification_asked_at,
+ registrar: { name: domain.registrar.name, website: domain.registrar.website },
+ registrant: { name: domain.registrant.name, id: domain.registrant.uuid }
+ }
+ end
+
def dnssec_keys
domain.dnskeys.map do |key|
"#{key.flags} #{key.protocol} #{key.alg} #{key.public_key}"
From 8916cb29d1f631f690371abe24f6d80d50efd071 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Tue, 1 Dec 2020 15:48:13 +0200
Subject: [PATCH 037/106] Update CHANGELOG.md
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 489ba94d3..9774d5cb3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
01.12.2020
* Refactored clientHold for interactors [#1751](https://github.com/internetee/registry/issues/1751)
+* Fixed internal error on removing clientHold status when not present [#1766](https://github.com/internetee/registry/issues/1766)
30.11.2020
* Refactor - interactors moved to domain space [#1762](https://github.com/internetee/registry/pull/1762)
From 15d2ffe200837ddfde536bfb22474ce3fb1099ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 3 Dec 2020 16:12:36 +0200
Subject: [PATCH 038/106] Registrant API: Return associated domains for contact
query
---
.../api/v1/registrant/contacts_controller.rb | 11 ++++++-----
app/models/contact.rb | 13 +++++++++----
lib/serializers/registrant_api/contact.rb | 13 +++++++++----
lib/serializers/registrant_api/domain.rb | 3 ++-
4 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/app/controllers/api/v1/registrant/contacts_controller.rb b/app/controllers/api/v1/registrant/contacts_controller.rb
index 10f9abacf..e11458ff8 100644
--- a/app/controllers/api/v1/registrant/contacts_controller.rb
+++ b/app/controllers/api/v1/registrant/contacts_controller.rb
@@ -19,15 +19,16 @@ module Api
end
contacts = current_user_contacts.limit(limit).offset(offset)
- serialized_contacts = contacts.collect { |contact| serialize_contact(contact) }
+ serialized_contacts = contacts.collect { |contact| serialize_contact(contact, false) }
render json: serialized_contacts
end
def show
contact = current_user_contacts.find_by(uuid: params[:uuid])
+ links = params[:links] == 'true'
if contact
- render json: serialize_contact(contact)
+ render json: serialize_contact(contact, links)
else
render json: { errors: [{ base: ['Contact not found'] }] }, status: :not_found
end
@@ -85,7 +86,7 @@ module Api
contact.registrar.notify(action)
end
- render json: serialize_contact(contact)
+ render json: serialize_contact(contact, false)
end
private
@@ -96,8 +97,8 @@ module Api
current_registrant_user.direct_contacts
end
- def serialize_contact(contact)
- Serializers::RegistrantApi::Contact.new(contact).to_json
+ def serialize_contact(contact, links)
+ Serializers::RegistrantApi::Contact.new(contact, links).to_json
end
end
end
diff --git a/app/models/contact.rb b/app/models/contact.rb
index 8a154c50c..e30312b4a 100644
--- a/app/models/contact.rb
+++ b/app/models/contact.rb
@@ -347,19 +347,24 @@ class Contact < ApplicationRecord
@desc = {}
registrant_domains.each do |dom|
- @desc[dom.name] ||= []
- @desc[dom.name] << :registrant
+ @desc[dom.name] ||= { id: dom.uuid, roles: [] }
+ @desc[dom.name][:roles] << :registrant
end
domain_contacts.each do |dc|
- @desc[dc.domain.name] ||= []
- @desc[dc.domain.name] << dc.name.downcase.to_sym
+ @desc[dc.domain.name] ||= { id: dc.domain.uuid, roles: [] }
+ @desc[dc.domain.name][:roles] << dc.name.downcase.to_sym
@desc[dc.domain.name] = @desc[dc.domain.name].compact
end
@desc
end
+ def related_domains
+ a = related_domain_descriptions
+ a.keys.map { |d| { name: d, id: a[d][:id], roles: a[d][:roles] } }
+ end
+
def status_notes_array=(notes)
self.status_notes = {}
notes ||= []
diff --git a/lib/serializers/registrant_api/contact.rb b/lib/serializers/registrant_api/contact.rb
index dd36b4400..023544174 100644
--- a/lib/serializers/registrant_api/contact.rb
+++ b/lib/serializers/registrant_api/contact.rb
@@ -1,14 +1,15 @@
module Serializers
module RegistrantApi
class Contact
- attr_reader :contact
+ attr_reader :contact, :links
- def initialize(contact)
+ def initialize(contact, links)
@contact = contact
+ @links = links
end
- def to_json
- {
+ def to_json(_obj = nil)
+ obj = {
id: contact.uuid,
name: contact.name,
code: contact.code,
@@ -31,6 +32,10 @@ module Serializers
statuses: contact.statuses,
disclosed_attributes: contact.disclosed_attributes,
}
+
+ obj[:links] = contact.related_domains if @links
+
+ obj
end
end
end
diff --git a/lib/serializers/registrant_api/domain.rb b/lib/serializers/registrant_api/domain.rb
index f8d5bb830..2359d77c9 100644
--- a/lib/serializers/registrant_api/domain.rb
+++ b/lib/serializers/registrant_api/domain.rb
@@ -58,7 +58,8 @@ module Serializers
valid_to: domain.valid_to, outzone_at: domain.outzone_at, statuses: domain.statuses,
registrant_verification_asked_at: domain.registrant_verification_asked_at,
registrar: { name: domain.registrar.name, website: domain.registrar.website },
- registrant: { name: domain.registrant.name, id: domain.registrant.uuid }
+ registrant: { name: domain.registrant.name, id: domain.registrant.uuid,
+ phone: domain.registrant.phone, email: domain.registrant.email }
}
end
From 92b294e81b10e69109e20f2e3d1d54e0d81b6c7c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Fri, 4 Dec 2020 15:24:14 +0200
Subject: [PATCH 039/106] Reflect new behaviour of registrant API in tests
---
.../api/registrant/registrant_api_domains_test.rb | 8 ++++----
test/lib/serializers/registrant_api/contact_test.rb | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/test/integration/api/registrant/registrant_api_domains_test.rb b/test/integration/api/registrant/registrant_api_domains_test.rb
index 22516fecc..61d635e5f 100644
--- a/test/integration/api/registrant/registrant_api_domains_test.rb
+++ b/test/integration/api/registrant/registrant_api_domains_test.rb
@@ -50,10 +50,10 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest
assert_equal(200, response.status)
response_json = JSON.parse(response.body, symbolize_names: true)
- array_of_domain_names = response_json.map { |x| x[:name] }
+ array_of_domain_names = response_json[:domains].map { |x| x[:name] }
assert(array_of_domain_names.include?('hospital.test'))
- array_of_domain_registrars = response_json.map { |x| x[:registrar] }
+ array_of_domain_registrars = response_json[:domains].map { |x| x[:registrar] }
assert(array_of_domain_registrars.include?({name: 'Good Names', website: nil}))
end
@@ -63,12 +63,12 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest
response_json = JSON.parse(response.body, symbolize_names: true)
assert_equal(200, response.status)
- assert_equal(2, response_json.count)
+ assert_equal(2, response_json[:domains].count)
get '/api/v1/registrant/domains', headers: @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
- assert_equal(4, response_json.count)
+ assert_equal(4, response_json[:domains].count)
end
def test_root_does_not_accept_limit_higher_than_200
diff --git a/test/lib/serializers/registrant_api/contact_test.rb b/test/lib/serializers/registrant_api/contact_test.rb
index 165c91e00..8b84abd38 100644
--- a/test/lib/serializers/registrant_api/contact_test.rb
+++ b/test/lib/serializers/registrant_api/contact_test.rb
@@ -4,7 +4,7 @@ require 'serializers/registrant_api/contact'
class SerializersRegistrantApiContactTest < ActiveSupport::TestCase
def setup
@contact = contacts(:william)
- @serializer = Serializers::RegistrantApi::Contact.new(@contact)
+ @serializer = Serializers::RegistrantApi::Contact.new(@contact, false)
@json = @serializer.to_json
end
From 36ff1fcf39b7f6ddf48b9c6157be39ac0760f1f2 Mon Sep 17 00:00:00 2001
From: Georg
Date: Tue, 17 Nov 2020 14:27:12 +0200
Subject: [PATCH 040/106] Create ruby.yml
example workflow
Update ruby.yml
limit builds
Update ruby.yml
postgres service
Update ruby.yml
pg_port
copy config files
Update ruby.yml
Update ruby.yml
Update database_travis.yml
Update ruby.yml
Update ruby.yml
bump wkhtmltopdf-binary
Unlock gem 'wkhtmltopdf-binary'
Update ruby.yml
Update ruby.yml
Update ruby.yml
remove Lockfile
restore Gemfile
test only ubuntu-18.04
bundle env
remove deploy deps
remove mina dep
use rexml from bundle rather then std-lib to support ruby 3.0
install rexml
drop ruby 3.0, cleanup workflow
fix codeclimate sorting issue
Codeclimate reporting
stop using deprecated set-env
use simplecov formater
simplecov in after-build
fix yaml syntax
run in debug mode
Set correct env var to run coverage
cleanup, provide CC_TEST_REPORTER_ID secret
combine multiple results
more variables
pull/commit different envs
Change test command to get more coverage
---
.github/workflows/ruby.yml | 117 +++++++++++++++++++++++++++++++++++++
Gemfile | 6 +-
Gemfile.lock | 14 +----
config/database_travis.yml | 2 +-
test/test_helper.rb | 1 +
5 files changed, 122 insertions(+), 18 deletions(-)
create mode 100644 .github/workflows/ruby.yml
diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml
new file mode 100644
index 000000000..eea0ccc03
--- /dev/null
+++ b/.github/workflows/ruby.yml
@@ -0,0 +1,117 @@
+name: Github Testing
+on: [push]
+
+
+jobs:
+ test:
+ services:
+ postgres:
+ image: postgres:12
+ ports: ["5432:5432"]
+ env:
+ POSTGRES_PASSWORD: password
+ POSTGRES_USERNAME: postgres
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
+
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-18.04]
+ ruby: [2.6, 2.7 ]
+ runs-on: ${{ matrix.os }}
+ continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
+ steps:
+
+ - uses: actions/checkout@v2
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{ matrix.ruby }}
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
+ - name: config bundler
+ run: |
+ bundle config set without 'development staging production'
+ bundle config set deployment '[secure]'
+ bundle env
+ head -n1 $(which bundle)
+
+ - name: Set ENV for codeclimate (pull_request)
+ run: |
+ git fetch --no-tags --prune --depth=1 origin +refs/heads/$GITHUB_HEAD_REF:refs/remotes/origin/$GITHUB_HEAD_REF
+ echo "GIT_BRANCH=$GITHUB_HEAD_REF" >> $GITHUB_ENV
+ echo "GIT_COMMIT_SHA=$(git rev-parse origin/$GITHUB_HEAD_REF)" >> $GITHUB_ENV
+ if: github.event_name == 'pull_request'
+
+ - name: Set ENV for codeclimate (push)
+ run: |
+ echo "GIT_BRANCH=$GITHUB_REF" >> $GITHUB_ENV
+ echo "GIT_COMMIT_SHA=$GITHUB_SHA" >> $GITHUB_ENV
+ if: github.event_name == 'push'
+
+ - name: Prepare CodeClimate
+ env:
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
+ run: |
+ curl -LSs 'https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64' >./cc-test-reporter;
+ chmod +x ./cc-test-reporter
+ ./cc-test-reporter before-build
+
+ - name: Run Tests
+ env:
+ PG_DATABASE: postgres
+ PG_HOST: localhost
+ PG_USER: postgres
+ PG_PASSWORD: password
+ PG_PORT: ${{ job.services.postgres.ports[5432] }}
+ RAILS_ENV: test
+ COVERAGE: true
+ DISABLE_SPRING: 1
+ run: |
+ cp config/application.yml.sample config/application.yml
+ cp config/database_travis.yml config/database.yml
+ echo "openssl_config_path: 'test/fixtures/files/test_ca/openssl.cnf'" >> config/application.yml
+ echo "crl_dir: 'test/fixtures/files/test_ca/crl'" >> config/application.yml
+ echo "crl_path: 'test/fixtures/files/test_ca/crl/crl.pem'" >> config/application.yml
+ echo "ca_cert_path: 'test/fixtures/files/test_ca/certs/ca.crt.pem'" >> config/application.yml
+ echo "ca_key_path: 'test/fixtures/files/test_ca/private/ca.key.pem'" >> config/application.yml
+ echo "ca_key_password: 'password'" >> config/application.yml
+ bundle exec rake db:setup:all
+ bundle exec rails test test/*
+ - name: Save coverage
+ run: ./cc-test-reporter format-coverage --output coverage/codeclimate.${{ matrix.ruby }}.json
+
+ - uses: actions/upload-artifact@v1
+ with:
+ name: coverage-${{ matrix.ruby }}
+ path: coverage/codeclimate.${{ matrix.ruby }}.json
+
+ upload_coverage:
+ runs-on: ubuntu-18.04
+
+ env:
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
+ CC_TEST_REPORTER_URL: https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
+
+ needs: test
+
+ steps:
+ - name: Download test coverage reporter
+ run: curl -L $CC_TEST_REPORTER_URL > cc-test-reporter
+
+ - name: Give test coverage reporter executable permissions
+ run: chmod +x cc-test-reporter
+
+ - uses: actions/download-artifact@v1
+ with:
+ name: coverage-2.6
+ path: coverage
+
+ - uses: actions/download-artifact@v1
+ with:
+ name: coverage-2.7
+ path: coverage
+
+ - name: Aggregate & upload results to Code Climate
+ run: |
+ ./cc-test-reporter sum-coverage coverage/codeclimate.*.json
+ ./cc-test-reporter upload-coverage
+
diff --git a/Gemfile b/Gemfile
index 7ae8d4ef6..9bbcba254 100644
--- a/Gemfile
+++ b/Gemfile
@@ -73,15 +73,11 @@ gem 'e_invoice', github: 'internetee/e_invoice', branch: :master
gem 'lhv', github: 'internetee/lhv', branch: 'master'
gem 'domain_name'
gem 'haml', '~> 5.0'
+gem 'rexml'
gem 'wkhtmltopdf-binary', '~> 0.12.5.1'
gem 'directo', github: 'internetee/directo', branch: 'master'
-group :development do
- # deploy
- gem 'listen', '3.2.1'
- gem 'mina', '0.3.1' # for fast deployment
-end
group :development, :test do
gem 'pry', '0.10.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 72c716aae..2a0bb55b1 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -250,9 +250,6 @@ GEM
kaminari-core (= 1.2.1)
kaminari-core (1.2.1)
libxml-ruby (3.2.0)
- listen (3.2.1)
- rb-fsevent (~> 0.10, >= 0.10.3)
- rb-inotify (~> 0.9, >= 0.9.10)
logger (1.4.2)
loofah (2.7.0)
crass (~> 1.0.2)
@@ -266,9 +263,6 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2020.0512)
mimemagic (0.3.5)
- mina (0.3.1)
- open4 (~> 1.3.4)
- rake
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.14.2)
@@ -296,7 +290,6 @@ GEM
omniauth-rails_csrf_protection (0.1.2)
actionpack (>= 4.2)
omniauth (>= 1.3.1)
- open4 (1.3.4)
openid_connect (1.2.0)
activemodel
attr_required (>= 1.0.0)
@@ -370,9 +363,6 @@ GEM
activesupport (>= 5.2.1)
i18n
polyamorous (= 2.3.2)
- rb-fsevent (0.10.4)
- rb-inotify (0.10.1)
- ffi (~> 1.0)
rbtree3 (0.6.0)
regexp_parser (1.8.0)
request_store (1.5.0)
@@ -385,6 +375,7 @@ GEM
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
+ rexml (3.2.4)
ruby2_keywords (0.0.2)
rubyzip (2.3.0)
sass-rails (6.0.0)
@@ -519,8 +510,6 @@ DEPENDENCIES
jquery-ui-rails (= 5.0.5)
kaminari
lhv!
- listen (= 3.2.1)
- mina (= 0.3.1)
minitest (~> 5.14)
money-rails
nokogiri
@@ -537,6 +526,7 @@ DEPENDENCIES
rails (~> 6.0)
ransack (~> 2.3)
rest-client
+ rexml
sass-rails
select2-rails (= 3.5.9.3)
selectize-rails (= 0.12.1)
diff --git a/config/database_travis.yml b/config/database_travis.yml
index b79e2c453..48ffd5e27 100644
--- a/config/database_travis.yml
+++ b/config/database_travis.yml
@@ -4,7 +4,7 @@ default: &default
encoding: unicode
pool: 5
username: postgres
- password:
+ password: password
test:
<<: *default
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 459d4f8f5..a1634f717 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -6,6 +6,7 @@ if ENV['COVERAGE']
add_filter '/lib/core_monkey_patches/'
add_filter '/lib/daemons/'
add_filter '/lib/gem_monkey_patches/'
+ add_filter '/lib/tasks/'
end
end
From 1b8906a9ccb70d774357f67276384182baf58417 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 7 Dec 2020 13:55:50 +0500
Subject: [PATCH 041/106] Remove Travis support
---
.travis.yml | 35 -----------------------------------
1 file changed, 35 deletions(-)
delete mode 100644 .travis.yml
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 23d4ab6b1..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-language: ruby
-cache: bundler
-env:
- - DB=postgresql
-before_install:
- - "wget -N http://chromedriver.storage.googleapis.com/2.43/chromedriver_linux64.zip -P ~/"
- - "unzip ~/chromedriver_linux64.zip -d ~/"
- - "rm ~/chromedriver_linux64.zip"
- - "sudo mv -f ~/chromedriver /usr/local/share/"
- - "sudo chmod +x /usr/local/share/chromedriver"
- - "sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver"
- - "bundle config set without 'development staging production'"
- - "bundle config set deployment '[secure]'"
-before_script:
- - "cp config/application.yml.sample config/application.yml"
- - "echo \"openssl_config_path: 'test/fixtures/files/test_ca/openssl.cnf'\" >> config/application.yml"
- - "echo \"crl_dir: 'test/fixtures/files/test_ca/crl'\" >> config/application.yml"
- - "echo \"crl_path: 'test/fixtures/files/test_ca/crl/crl.pem'\" >> config/application.yml"
- - "echo \"ca_cert_path: 'test/fixtures/files/test_ca/certs/ca.crt.pem'\" >> config/application.yml"
- - "echo \"ca_key_path: 'test/fixtures/files/test_ca/private/ca.key.pem'\" >> config/application.yml"
- - "echo \"ca_key_password: 'password'\" >> config/application.yml"
- - "cp config/database_travis.yml config/database.yml"
- - "bundle exec rake db:setup:all"
- - "curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter"
- - "chmod +x ./cc-test-reporter"
- - "./cc-test-reporter before-build"
-after_script:
- - "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
-script:
- - "bundle exec rails test test/*"
-services:
- - postgresql
-addons:
- postgresql: "9.4"
- chrome: stable
From d4063349264a9ac3c5d19b4b1af3c6fdd1fe7465 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Wed, 25 Nov 2020 14:26:53 +0500
Subject: [PATCH 042/106] Move DomainDelete to interactor design pattern
---
.../domain_delete_interaction/base.rb | 7 +++++++
.../domain_delete_interaction/delete.rb | 11 ++++++++++
.../nofity_registrar.rb | 12 +++++++++++
app/jobs/domain_delete_job.rb | 21 ++++++++++---------
4 files changed, 41 insertions(+), 10 deletions(-)
create mode 100644 app/interactions/domain_delete_interaction/base.rb
create mode 100644 app/interactions/domain_delete_interaction/delete.rb
create mode 100644 app/interactions/domain_delete_interaction/nofity_registrar.rb
diff --git a/app/interactions/domain_delete_interaction/base.rb b/app/interactions/domain_delete_interaction/base.rb
new file mode 100644
index 000000000..b2895e1d1
--- /dev/null
+++ b/app/interactions/domain_delete_interaction/base.rb
@@ -0,0 +1,7 @@
+module DomainDeleteInteraction
+ class Base < ActiveInteraction::Base
+ object :domain,
+ class: Domain,
+ description: 'Domain to delete'
+ end
+end
diff --git a/app/interactions/domain_delete_interaction/delete.rb b/app/interactions/domain_delete_interaction/delete.rb
new file mode 100644
index 000000000..181431ca1
--- /dev/null
+++ b/app/interactions/domain_delete_interaction/delete.rb
@@ -0,0 +1,11 @@
+module DomainDeleteInteraction
+ class Delete < :Base
+ def execute
+ ::PaperTrail.request.whodunnit = "interaction - #{self.class.name}"
+ WhoisRecord.where(domain_id: domain.id).destroy_all
+
+ domain.destroy
+ compose(NotifyRegistrar, inputs)
+ end
+ end
+end
diff --git a/app/interactions/domain_delete_interaction/nofity_registrar.rb b/app/interactions/domain_delete_interaction/nofity_registrar.rb
new file mode 100644
index 000000000..81a66e6b0
--- /dev/null
+++ b/app/interactions/domain_delete_interaction/nofity_registrar.rb
@@ -0,0 +1,12 @@
+module DomainDeleteInteraction
+ class NotifyRegistrar < Delete
+ 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
diff --git a/app/jobs/domain_delete_job.rb b/app/jobs/domain_delete_job.rb
index 43e0bb844..a41a27f05 100644
--- a/app/jobs/domain_delete_job.rb
+++ b/app/jobs/domain_delete_job.rb
@@ -3,15 +3,16 @@ class DomainDeleteJob < Que::Job
def run(domain_id)
domain = Domain.find(domain_id)
- ::PaperTrail.request.whodunnit = "job - #{self.class.name}"
- WhoisRecord.where(domain_id: domain.id).destroy_all
-
- domain.destroy
- 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
- )
+ DomainDeleteInteraction::Delete.run(domain: domain)
+ # ::PaperTrail.request.whodunnit = "job - #{self.class.name}"
+ # WhoisRecord.where(domain_id: domain.id).destroy_all
+ #
+ # domain.destroy
+ # 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
From 4c7f9f202601bed993a9811d56993b8f7cc04070 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Wed, 25 Nov 2020 17:01:58 +0500
Subject: [PATCH 043/106] Add interactor tests
---
.../domain_delete_interaction/delete.rb | 4 +--
...ofity_registrar.rb => notify_registrar.rb} | 2 +-
app/jobs/domain_delete_job.rb | 10 --------
.../domain_delete_interaction_delete_test.rb | 25 +++++++++++++++++++
4 files changed, 28 insertions(+), 13 deletions(-)
rename app/interactions/domain_delete_interaction/{nofity_registrar.rb => notify_registrar.rb} (90%)
create mode 100644 test/interactions/domain_delete_interaction/domain_delete_interaction_delete_test.rb
diff --git a/app/interactions/domain_delete_interaction/delete.rb b/app/interactions/domain_delete_interaction/delete.rb
index 181431ca1..1a74aae50 100644
--- a/app/interactions/domain_delete_interaction/delete.rb
+++ b/app/interactions/domain_delete_interaction/delete.rb
@@ -1,11 +1,11 @@
module DomainDeleteInteraction
- class Delete < :Base
+ class Delete < Base
def execute
::PaperTrail.request.whodunnit = "interaction - #{self.class.name}"
WhoisRecord.where(domain_id: domain.id).destroy_all
domain.destroy
- compose(NotifyRegistrar, inputs)
+ compose(DomainDeleteInteraction::NotifyRegistrar, inputs)
end
end
end
diff --git a/app/interactions/domain_delete_interaction/nofity_registrar.rb b/app/interactions/domain_delete_interaction/notify_registrar.rb
similarity index 90%
rename from app/interactions/domain_delete_interaction/nofity_registrar.rb
rename to app/interactions/domain_delete_interaction/notify_registrar.rb
index 81a66e6b0..990f74de6 100644
--- a/app/interactions/domain_delete_interaction/nofity_registrar.rb
+++ b/app/interactions/domain_delete_interaction/notify_registrar.rb
@@ -1,5 +1,5 @@
module DomainDeleteInteraction
- class NotifyRegistrar < Delete
+ class NotifyRegistrar < Base
def execute
bye_bye = domain.versions.last
domain.registrar.notifications.create!(
diff --git a/app/jobs/domain_delete_job.rb b/app/jobs/domain_delete_job.rb
index a41a27f05..49ef23aa3 100644
--- a/app/jobs/domain_delete_job.rb
+++ b/app/jobs/domain_delete_job.rb
@@ -4,15 +4,5 @@ class DomainDeleteJob < Que::Job
domain = Domain.find(domain_id)
DomainDeleteInteraction::Delete.run(domain: domain)
- # ::PaperTrail.request.whodunnit = "job - #{self.class.name}"
- # WhoisRecord.where(domain_id: domain.id).destroy_all
- #
- # domain.destroy
- # 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
diff --git a/test/interactions/domain_delete_interaction/domain_delete_interaction_delete_test.rb b/test/interactions/domain_delete_interaction/domain_delete_interaction_delete_test.rb
new file mode 100644
index 000000000..a44140b34
--- /dev/null
+++ b/test/interactions/domain_delete_interaction/domain_delete_interaction_delete_test.rb
@@ -0,0 +1,25 @@
+require 'test_helper'
+
+class DomainDeleteInteractionDeleteTest < ActiveSupport::TestCase
+ setup do
+ @domain = domains(:shop)
+ end
+
+ def test_discards_domains_with_past_delete_date
+ @domain.update!(delete_date: '2010-07-04')
+ travel_to Time.zone.parse('2010-07-05')
+
+ DomainDeleteInteraction::Delete.run(domain: @domain)
+
+ assert @domain.destroyed?
+ end
+
+ def test_sends_notification
+ @domain.update!(delete_date: '2010-07-04')
+ travel_to Time.zone.parse('2010-07-05')
+
+ assert_difference '@domain.registrar.notifications.count', 1 do
+ DomainDeleteInteraction::Delete.run(domain: @domain)
+ end
+ end
+end
From 30ddf83ee42dd21cc4cfc77a6addadda4a6ea16f Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 30 Nov 2020 16:20:24 +0500
Subject: [PATCH 044/106] Move interactor to namespace
---
app/interactions/domain_delete_interaction/base.rb | 7 -------
.../domain_delete_interaction/delete.rb | 11 -----------
.../domain_delete_interaction/notify_registrar.rb | 12 ------------
app/interactions/domains/delete/base.rb | 9 +++++++++
app/interactions/domains/delete/do_delete.rb | 13 +++++++++++++
.../domains/delete/notify_registrar.rb | 14 ++++++++++++++
app/jobs/domain_delete_job.rb | 2 +-
...action_delete_test.rb => domain_delete_test.rb} | 6 +++---
8 files changed, 40 insertions(+), 34 deletions(-)
delete mode 100644 app/interactions/domain_delete_interaction/base.rb
delete mode 100644 app/interactions/domain_delete_interaction/delete.rb
delete mode 100644 app/interactions/domain_delete_interaction/notify_registrar.rb
create mode 100644 app/interactions/domains/delete/base.rb
create mode 100644 app/interactions/domains/delete/do_delete.rb
create mode 100644 app/interactions/domains/delete/notify_registrar.rb
rename test/interactions/domain_delete_interaction/{domain_delete_interaction_delete_test.rb => domain_delete_test.rb} (71%)
diff --git a/app/interactions/domain_delete_interaction/base.rb b/app/interactions/domain_delete_interaction/base.rb
deleted file mode 100644
index b2895e1d1..000000000
--- a/app/interactions/domain_delete_interaction/base.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module DomainDeleteInteraction
- class Base < ActiveInteraction::Base
- object :domain,
- class: Domain,
- description: 'Domain to delete'
- end
-end
diff --git a/app/interactions/domain_delete_interaction/delete.rb b/app/interactions/domain_delete_interaction/delete.rb
deleted file mode 100644
index 1a74aae50..000000000
--- a/app/interactions/domain_delete_interaction/delete.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-module DomainDeleteInteraction
- class Delete < Base
- def execute
- ::PaperTrail.request.whodunnit = "interaction - #{self.class.name}"
- WhoisRecord.where(domain_id: domain.id).destroy_all
-
- domain.destroy
- compose(DomainDeleteInteraction::NotifyRegistrar, inputs)
- end
- end
-end
diff --git a/app/interactions/domain_delete_interaction/notify_registrar.rb b/app/interactions/domain_delete_interaction/notify_registrar.rb
deleted file mode 100644
index 990f74de6..000000000
--- a/app/interactions/domain_delete_interaction/notify_registrar.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module DomainDeleteInteraction
- 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
diff --git a/app/interactions/domains/delete/base.rb b/app/interactions/domains/delete/base.rb
new file mode 100644
index 000000000..434712f72
--- /dev/null
+++ b/app/interactions/domains/delete/base.rb
@@ -0,0 +1,9 @@
+module Domains
+ module Delete
+ class Base < ActiveInteraction::Base
+ object :domain,
+ class: Domain,
+ description: 'Domain to delete'
+ end
+ end
+end
diff --git a/app/interactions/domains/delete/do_delete.rb b/app/interactions/domains/delete/do_delete.rb
new file mode 100644
index 000000000..202c36938
--- /dev/null
+++ b/app/interactions/domains/delete/do_delete.rb
@@ -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
diff --git a/app/interactions/domains/delete/notify_registrar.rb b/app/interactions/domains/delete/notify_registrar.rb
new file mode 100644
index 000000000..d6af00fd8
--- /dev/null
+++ b/app/interactions/domains/delete/notify_registrar.rb
@@ -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
diff --git a/app/jobs/domain_delete_job.rb b/app/jobs/domain_delete_job.rb
index 49ef23aa3..5577908c6 100644
--- a/app/jobs/domain_delete_job.rb
+++ b/app/jobs/domain_delete_job.rb
@@ -3,6 +3,6 @@ class DomainDeleteJob < Que::Job
def run(domain_id)
domain = Domain.find(domain_id)
- DomainDeleteInteraction::Delete.run(domain: domain)
+ Domains::Delete::DoDelete.run(domain: domain)
end
end
diff --git a/test/interactions/domain_delete_interaction/domain_delete_interaction_delete_test.rb b/test/interactions/domain_delete_interaction/domain_delete_test.rb
similarity index 71%
rename from test/interactions/domain_delete_interaction/domain_delete_interaction_delete_test.rb
rename to test/interactions/domain_delete_interaction/domain_delete_test.rb
index a44140b34..9582fae03 100644
--- a/test/interactions/domain_delete_interaction/domain_delete_interaction_delete_test.rb
+++ b/test/interactions/domain_delete_interaction/domain_delete_test.rb
@@ -1,6 +1,6 @@
require 'test_helper'
-class DomainDeleteInteractionDeleteTest < ActiveSupport::TestCase
+class DomainDeleteTest < ActiveSupport::TestCase
setup do
@domain = domains(:shop)
end
@@ -9,7 +9,7 @@ class DomainDeleteInteractionDeleteTest < ActiveSupport::TestCase
@domain.update!(delete_date: '2010-07-04')
travel_to Time.zone.parse('2010-07-05')
- DomainDeleteInteraction::Delete.run(domain: @domain)
+ Domains::Delete::DoDelete.run(domain: @domain)
assert @domain.destroyed?
end
@@ -19,7 +19,7 @@ class DomainDeleteInteractionDeleteTest < ActiveSupport::TestCase
travel_to Time.zone.parse('2010-07-05')
assert_difference '@domain.registrar.notifications.count', 1 do
- DomainDeleteInteraction::Delete.run(domain: @domain)
+ Domains::Delete::DoDelete.run(domain: @domain)
end
end
end
From b4e26952d682342fcbcac42695762ab0a0b1a6c6 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 1 Dec 2020 18:34:43 +0500
Subject: [PATCH 045/106] Fix domain deletion deadline
---
app/models/concerns/domain/deletable.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/models/concerns/domain/deletable.rb b/app/models/concerns/domain/deletable.rb
index bd01ab1c9..81518c739 100644
--- a/app/models/concerns/domain/deletable.rb
+++ b/app/models/concerns/domain/deletable.rb
@@ -20,6 +20,6 @@ module Concerns::Domain::Deletable
end
def deletion_deadline
- delete_date + 24.hours
+ (delete_date || Time.zone.now) + 24.hours
end
-end
\ No newline at end of file
+end
From 31bfe19d77c254e214c25f9efb7ecc90c1dfb8a6 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 26 Nov 2020 14:07:02 +0500
Subject: [PATCH 046/106] Move DomainUpdateConfirm from Que to ActiveJob
---
app/jobs/application_job.rb | 2 ++
app/jobs/domain_update_confirm_job.rb | 7 ++++---
app/models/registrant_verification.rb | 4 ++--
test/jobs/domain_update_confirm_job_test.rb | 8 ++++----
4 files changed, 12 insertions(+), 9 deletions(-)
create mode 100644 app/jobs/application_job.rb
diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb
new file mode 100644
index 000000000..a009ace51
--- /dev/null
+++ b/app/jobs/application_job.rb
@@ -0,0 +1,2 @@
+class ApplicationJob < ActiveJob::Base
+end
diff --git a/app/jobs/domain_update_confirm_job.rb b/app/jobs/domain_update_confirm_job.rb
index f3665f1e8..2025354e6 100644
--- a/app/jobs/domain_update_confirm_job.rb
+++ b/app/jobs/domain_update_confirm_job.rb
@@ -1,5 +1,7 @@
-class DomainUpdateConfirmJob < Que::Job
- def run(domain_id, action, initiator = nil)
+class DomainUpdateConfirmJob < ApplicationJob
+ queue_as :default
+
+ def perform(domain_id, action, initiator = nil)
::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
@@ -27,7 +29,6 @@ class DomainUpdateConfirmJob < Que::Job
domain.preclean_pendings
domain.clean_pendings!
end
- destroy # it's best to destroy the job in the same transaction
end
end
diff --git a/app/models/registrant_verification.rb b/app/models/registrant_verification.rb
index 097f0cfa9..7e238cecc 100644
--- a/app/models/registrant_verification.rb
+++ b/app/models/registrant_verification.rb
@@ -18,13 +18,13 @@ class RegistrantVerification < ApplicationRecord
def domain_registrant_change_confirm!(initiator)
self.action_type = DOMAIN_REGISTRANT_CHANGE
self.action = CONFIRMED
- DomainUpdateConfirmJob.enqueue domain.id, CONFIRMED, initiator if save
+ DomainUpdateConfirmJob.perform_later domain.id, CONFIRMED, initiator if save
end
def domain_registrant_change_reject!(initiator)
self.action_type = DOMAIN_REGISTRANT_CHANGE
self.action = REJECTED
- DomainUpdateConfirmJob.run domain.id, REJECTED, initiator if save
+ DomainUpdateConfirmJob.perform_later domain.id, REJECTED, initiator if save
end
def domain_registrant_delete_confirm!(initiator)
diff --git a/test/jobs/domain_update_confirm_job_test.rb b/test/jobs/domain_update_confirm_job_test.rb
index 9cca81eb7..f01e7c41e 100644
--- a/test/jobs/domain_update_confirm_job_test.rb
+++ b/test/jobs/domain_update_confirm_job_test.rb
@@ -20,7 +20,7 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase
end
def test_rejected_registrant_verification_notifies_registrar
- DomainUpdateConfirmJob.enqueue(@domain.id, RegistrantVerification::REJECTED)
+ DomainUpdateConfirmJob.perform_now(@domain.id, RegistrantVerification::REJECTED)
last_registrar_notification = @domain.registrar.notifications.last
assert_equal(last_registrar_notification.attached_obj_id, @domain.id)
@@ -28,7 +28,7 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase
end
def test_accepted_registrant_verification_notifies_registrar
- DomainUpdateConfirmJob.enqueue(@domain.id, RegistrantVerification::CONFIRMED)
+ DomainUpdateConfirmJob.perform_now(@domain.id, RegistrantVerification::CONFIRMED)
last_registrar_notification = @domain.registrar.notifications.last
assert_equal(last_registrar_notification.attached_obj_id, @domain.id)
@@ -44,7 +44,7 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase
@domain.update(pending_json: @domain.pending_json)
@domain.reload
- DomainUpdateConfirmJob.enqueue(@domain.id, RegistrantVerification::CONFIRMED)
+ DomainUpdateConfirmJob.perform_now(@domain.id, RegistrantVerification::CONFIRMED)
@domain.reload
assert_equal @domain.registrant.code, @new_registrant.code
@@ -58,7 +58,7 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase
@domain.pending_json['frame'] = epp_xml
@domain.update(pending_json: @domain.pending_json)
- DomainUpdateConfirmJob.enqueue(@domain.id, RegistrantVerification::REJECTED)
+ DomainUpdateConfirmJob.perform_now(@domain.id, RegistrantVerification::REJECTED)
@domain.reload
assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE_CONFIRMATION
From 4b7cffbb572ea1e63e8d02962df994791770ef8b Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 26 Nov 2020 15:01:09 +0500
Subject: [PATCH 047/106] Move functionality from job to interactor
---
.../domain_update_confirm_interaction/base.rb | 22 ++++++++++++
.../process_action.rb | 15 ++++++++
.../process_update_confirmed.rb | 20 +++++++++++
.../process_update_rejected.rb | 16 +++++++++
app/jobs/domain_update_confirm_job.rb | 36 +++----------------
5 files changed, 77 insertions(+), 32 deletions(-)
create mode 100644 app/interactions/domain_update_confirm_interaction/base.rb
create mode 100644 app/interactions/domain_update_confirm_interaction/process_action.rb
create mode 100644 app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
create mode 100644 app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
diff --git a/app/interactions/domain_update_confirm_interaction/base.rb b/app/interactions/domain_update_confirm_interaction/base.rb
new file mode 100644
index 000000000..18a96fc99
--- /dev/null
+++ b/app/interactions/domain_update_confirm_interaction/base.rb
@@ -0,0 +1,22 @@
+module DomainUpdateConfirmInteraction
+ 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)
+ if domain.errors.any?
+ message = "domain #{domain.name} failed with errors #{domain.errors.full_messages}"
+ throw message
+ end
+ end
+ end
+end
+
diff --git a/app/interactions/domain_update_confirm_interaction/process_action.rb b/app/interactions/domain_update_confirm_interaction/process_action.rb
new file mode 100644
index 000000000..9def919d1
--- /dev/null
+++ b/app/interactions/domain_update_confirm_interaction/process_action.rb
@@ -0,0 +1,15 @@
+module DomainUpdateConfirmInteraction
+ 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
diff --git a/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb b/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
new file mode 100644
index 000000000..bb235dcb9
--- /dev/null
+++ b/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
@@ -0,0 +1,20 @@
+module DomainUpdateConfirmInteraction
+ class ProcessUpdateConfirmed < Base
+ def execute
+ ActiveRecord::Base.transaction do
+ domain.is_admin = true
+ old_registrant = domain.registrant
+ domain.notify_registrar(:poll_pending_update_confirmed_by_registrant)
+
+ domain.apply_pending_update!
+ raise_errors!(domain)
+
+ domain.clean_pendings!
+ raise_errors!(domain)
+ RegistrantChange.new(domain: domain, old_registrant: old_registrant).confirm
+ end
+ end
+
+
+ end
+end
diff --git a/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb b/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
new file mode 100644
index 000000000..5875d17d5
--- /dev/null
+++ b/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
@@ -0,0 +1,16 @@
+module DomainUpdateConfirmInteraction
+ class ProcessUpdateRejected < Base
+ def execute
+ ActiveRecord::Base.transaction do
+ RegistrantChangeMailer.rejected(domain: domain,
+ registrar: domain.registrar,
+ registrant: domain.registrant).deliver_now
+
+ domain.notify_registrar(:poll_pending_update_rejected_by_registrant)
+
+ domain.preclean_pendings
+ domain.clean_pendings!
+ end
+ end
+ end
+end
diff --git a/app/jobs/domain_update_confirm_job.rb b/app/jobs/domain_update_confirm_job.rb
index 2025354e6..8f1fd1688 100644
--- a/app/jobs/domain_update_confirm_job.rb
+++ b/app/jobs/domain_update_confirm_job.rb
@@ -2,37 +2,9 @@ class DomainUpdateConfirmJob < ApplicationJob
queue_as :default
def perform(domain_id, action, initiator = nil)
- ::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)
- domain.is_admin = true
- case action
- when RegistrantVerification::CONFIRMED
- old_registrant = domain.registrant
- domain.notify_registrar(:poll_pending_update_confirmed_by_registrant)
- raise_errors!(domain)
-
- domain.apply_pending_update!
- raise_errors!(domain)
-
- domain.clean_pendings!
- raise_errors!(domain)
- RegistrantChange.new(domain: domain, old_registrant: old_registrant).confirm
- when RegistrantVerification::REJECTED
- RegistrantChangeMailer.rejected(domain: domain,
- registrar: domain.registrar,
- registrant: domain.registrant).deliver_now
-
- domain.notify_registrar(:poll_pending_update_rejected_by_registrant)
-
- domain.preclean_pendings
- domain.clean_pendings!
- end
- end
- end
-
- def raise_errors!(domain)
- throw "domain #{domain.name} failed with errors #{domain.errors.full_messages}" if domain.errors.any?
+ domain = Epp::Domain.find(domain_id)
+ DomainUpdateConfirmInteraction::ProcessAction.run(domain: domain,
+ action: action,
+ initiator: initiator)
end
end
From 8ef748fc7d61e34e784529722add638d1862d380 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 26 Nov 2020 15:21:22 +0500
Subject: [PATCH 048/106] Move apply_pending_update! method from model to
interactor
---
.codeclimate.yml | 3 ++
.../domain_update_confirm_interaction/base.rb | 17 +++++---
.../process_update_confirmed.rb | 42 ++++++++++++++++---
.../process_update_rejected.rb | 2 +-
app/models/domain.rb | 3 ++
app/models/epp/domain.rb | 19 ---------
6 files changed, 56 insertions(+), 30 deletions(-)
diff --git a/.codeclimate.yml b/.codeclimate.yml
index 2bc90b200..d079d891f 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -20,6 +20,9 @@ plugins:
channel: eslint-5
fixme:
enabled: true
+ checks:
+ TODO:
+ enabled: false
rubocop:
enabled: true
channel: rubocop-0-74
diff --git a/app/interactions/domain_update_confirm_interaction/base.rb b/app/interactions/domain_update_confirm_interaction/base.rb
index 18a96fc99..d78f3a6a9 100644
--- a/app/interactions/domain_update_confirm_interaction/base.rb
+++ b/app/interactions/domain_update_confirm_interaction/base.rb
@@ -12,11 +12,18 @@ module DomainUpdateConfirmInteraction
RegistrantVerification::REJECTED] }
def raise_errors!(domain)
- if domain.errors.any?
- message = "domain #{domain.name} failed with errors #{domain.errors.full_messages}"
- throw message
- end
+ 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
end
end
-
diff --git a/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb b/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
index bb235dcb9..43c053ba2 100644
--- a/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
+++ b/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
@@ -4,17 +4,49 @@ module DomainUpdateConfirmInteraction
ActiveRecord::Base.transaction do
domain.is_admin = true
old_registrant = domain.registrant
- domain.notify_registrar(:poll_pending_update_confirmed_by_registrant)
+ notify_registrar(:poll_pending_update_confirmed_by_registrant)
- domain.apply_pending_update!
- raise_errors!(domain)
-
- domain.clean_pendings!
+ 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!
+ domain.save!
+ WhoisRecord.find_by(domain_id: domain.id).save # need to reload model
+ end
+
+ def preclean_pendings
+ domain.registrant_verification_token = nil
+ domain.registrant_verification_asked_at = nil
+ end
+
+ def update_domain
+ user = ApiUser.find(domain.pending_json['current_user_id'])
+ frame = Nokogiri::XML(domain.pending_json['frame'])
+ domain.upid = user.registrar.id if user.registrar
+ domain.update(frame, user, false)
+ end
+
+ def clean_pendings!
+ domain.up_date = Time.zone.now
+ domain.registrant_verification_token = nil
+ domain.registrant_verification_asked_at = nil
+ domain.pending_json = {}
+ clear_statuses
+ 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
diff --git a/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb b/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
index 5875d17d5..09da14971 100644
--- a/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
+++ b/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
@@ -6,7 +6,7 @@ module DomainUpdateConfirmInteraction
registrar: domain.registrar,
registrant: domain.registrant).deliver_now
- domain.notify_registrar(:poll_pending_update_rejected_by_registrant)
+ notify_registrar(:poll_pending_update_rejected_by_registrant)
domain.preclean_pendings
domain.clean_pendings!
diff --git a/app/models/domain.rb b/app/models/domain.rb
index dc7d86da8..d2f555977 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -327,6 +327,7 @@ class Domain < ApplicationRecord
end
def notify_registrar(message_key)
+ # TODO: To be deleted with DomainDeleteConfirm refactoring
registrar.notifications.create!(
text: "#{I18n.t(message_key)}: #{name}",
attached_obj_id: id,
@@ -335,11 +336,13 @@ class Domain < ApplicationRecord
end
def preclean_pendings
+ # TODO: To be deleted with refactoring
self.registrant_verification_token = nil
self.registrant_verification_asked_at = nil
end
def clean_pendings!
+ # TODO: To be deleted with refactoring
preclean_pendings
self.pending_json = {}
statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION)
diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb
index 7fb23a6e9..d8f5f2bb9 100644
--- a/app/models/epp/domain.rb
+++ b/app/models/epp/domain.rb
@@ -508,25 +508,6 @@ class Epp::Domain < Domain
errors.empty? && super(at)
end
- def apply_pending_update!
- preclean_pendings
- user = ApiUser.find(pending_json['current_user_id'])
- frame = Nokogiri::XML(pending_json['frame'])
-
- self.statuses.delete(DomainStatus::PENDING_UPDATE)
- self.upid = user.registrar.id if user.registrar
- self.up_date = Time.zone.now
-
- return unless update(frame, user, false)
- clean_pendings!
-
- save!
-
- WhoisRecord.find_by(domain_id: id).save # need to reload model
-
- true
- end
-
def apply_pending_delete!
preclean_pendings
statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION)
From 6f0b8b15a3c4994b1719c361c2e447ec5cf609c1 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 26 Nov 2020 16:13:50 +0500
Subject: [PATCH 049/106] Move clean pendings used from model to interactor
base
---
.../domain_update_confirm_interaction/base.rb | 20 ++++++++++++++++
.../process_update_confirmed.rb | 24 +++----------------
.../process_update_rejected.rb | 4 ++--
3 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/app/interactions/domain_update_confirm_interaction/base.rb b/app/interactions/domain_update_confirm_interaction/base.rb
index d78f3a6a9..1a1f61b12 100644
--- a/app/interactions/domain_update_confirm_interaction/base.rb
+++ b/app/interactions/domain_update_confirm_interaction/base.rb
@@ -25,5 +25,25 @@ module DomainUpdateConfirmInteraction
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.registrant_verification_token = nil
+ domain.registrant_verification_asked_at = nil
+ domain.pending_json = {}
+ clear_statuses
+ 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
diff --git a/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb b/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
index 43c053ba2..0e173c533 100644
--- a/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
+++ b/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
@@ -21,32 +21,14 @@ module DomainUpdateConfirmInteraction
WhoisRecord.find_by(domain_id: domain.id).save # need to reload model
end
- def preclean_pendings
- domain.registrant_verification_token = nil
- domain.registrant_verification_asked_at = nil
- end
-
+ # rubocop:disable Metrics/AbcSize
def update_domain
user = ApiUser.find(domain.pending_json['current_user_id'])
frame = Nokogiri::XML(domain.pending_json['frame'])
domain.upid = user.registrar.id if user.registrar
+ domain.up_date = Time.zone.now
domain.update(frame, user, false)
end
-
- def clean_pendings!
- domain.up_date = Time.zone.now
- domain.registrant_verification_token = nil
- domain.registrant_verification_asked_at = nil
- domain.pending_json = {}
- clear_statuses
- 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
+ # rubocop:enable Metrics/AbcSize
end
end
diff --git a/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb b/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
index 09da14971..390f8db49 100644
--- a/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
+++ b/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
@@ -8,8 +8,8 @@ module DomainUpdateConfirmInteraction
notify_registrar(:poll_pending_update_rejected_by_registrant)
- domain.preclean_pendings
- domain.clean_pendings!
+ preclean_pendings
+ clean_pendings!
end
end
end
From 42012863e23a8e2b3a31ad08a84aa1d325f640f6 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 30 Nov 2020 17:53:36 +0500
Subject: [PATCH 050/106] Move interactor to the Domains namespace
---
.../domain_update_confirm_interaction/base.rb | 49 ------------------
.../process_action.rb | 15 ------
.../process_update_confirmed.rb | 34 -------------
.../process_update_rejected.rb | 16 ------
.../domains/update_confirm/base.rb | 51 +++++++++++++++++++
.../domains/update_confirm/process_action.rb | 17 +++++++
.../process_update_confirmed.rb | 36 +++++++++++++
.../update_confirm/process_update_rejected.rb | 18 +++++++
app/jobs/domain_update_confirm_job.rb | 6 +--
9 files changed, 125 insertions(+), 117 deletions(-)
delete mode 100644 app/interactions/domain_update_confirm_interaction/base.rb
delete mode 100644 app/interactions/domain_update_confirm_interaction/process_action.rb
delete mode 100644 app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
delete mode 100644 app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
create mode 100644 app/interactions/domains/update_confirm/base.rb
create mode 100644 app/interactions/domains/update_confirm/process_action.rb
create mode 100644 app/interactions/domains/update_confirm/process_update_confirmed.rb
create mode 100644 app/interactions/domains/update_confirm/process_update_rejected.rb
diff --git a/app/interactions/domain_update_confirm_interaction/base.rb b/app/interactions/domain_update_confirm_interaction/base.rb
deleted file mode 100644
index 1a1f61b12..000000000
--- a/app/interactions/domain_update_confirm_interaction/base.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-module DomainUpdateConfirmInteraction
- 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.registrant_verification_token = nil
- domain.registrant_verification_asked_at = nil
- domain.pending_json = {}
- clear_statuses
- 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
diff --git a/app/interactions/domain_update_confirm_interaction/process_action.rb b/app/interactions/domain_update_confirm_interaction/process_action.rb
deleted file mode 100644
index 9def919d1..000000000
--- a/app/interactions/domain_update_confirm_interaction/process_action.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module DomainUpdateConfirmInteraction
- 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
diff --git a/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb b/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
deleted file mode 100644
index 0e173c533..000000000
--- a/app/interactions/domain_update_confirm_interaction/process_update_confirmed.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-module DomainUpdateConfirmInteraction
- class ProcessUpdateConfirmed < Base
- def execute
- ActiveRecord::Base.transaction do
- domain.is_admin = true
- 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!
- domain.save!
-
- WhoisRecord.find_by(domain_id: domain.id).save # need to reload model
- end
-
- # rubocop:disable Metrics/AbcSize
- def update_domain
- user = ApiUser.find(domain.pending_json['current_user_id'])
- frame = Nokogiri::XML(domain.pending_json['frame'])
- domain.upid = user.registrar.id if user.registrar
- domain.up_date = Time.zone.now
- domain.update(frame, user, false)
- end
- # rubocop:enable Metrics/AbcSize
- end
-end
diff --git a/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb b/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
deleted file mode 100644
index 390f8db49..000000000
--- a/app/interactions/domain_update_confirm_interaction/process_update_rejected.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module DomainUpdateConfirmInteraction
- 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
diff --git a/app/interactions/domains/update_confirm/base.rb b/app/interactions/domains/update_confirm/base.rb
new file mode 100644
index 000000000..ab5584c03
--- /dev/null
+++ b/app/interactions/domains/update_confirm/base.rb
@@ -0,0 +1,51 @@
+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.registrant_verification_token = nil
+ domain.registrant_verification_asked_at = nil
+ domain.pending_json = {}
+ clear_statuses
+ 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
diff --git a/app/interactions/domains/update_confirm/process_action.rb b/app/interactions/domains/update_confirm/process_action.rb
new file mode 100644
index 000000000..6ef8d0fe6
--- /dev/null
+++ b/app/interactions/domains/update_confirm/process_action.rb
@@ -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
diff --git a/app/interactions/domains/update_confirm/process_update_confirmed.rb b/app/interactions/domains/update_confirm/process_update_confirmed.rb
new file mode 100644
index 000000000..0402994dd
--- /dev/null
+++ b/app/interactions/domains/update_confirm/process_update_confirmed.rb
@@ -0,0 +1,36 @@
+module Domains
+ module UpdateConfirm
+ class ProcessUpdateConfirmed < Base
+ def execute
+ ActiveRecord::Base.transaction do
+ domain.is_admin = true
+ 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!
+ domain.save!
+
+ WhoisRecord.find_by(domain_id: domain.id).save # need to reload model
+ end
+
+ # rubocop:disable Metrics/AbcSize
+ def update_domain
+ user = ApiUser.find(domain.pending_json['current_user_id'])
+ frame = Nokogiri::XML(domain.pending_json['frame'])
+ domain.upid = user.registrar.id if user.registrar
+ domain.up_date = Time.zone.now
+ domain.update(frame, user, false)
+ end
+ # rubocop:enable Metrics/AbcSize
+ end
+ end
+end
diff --git a/app/interactions/domains/update_confirm/process_update_rejected.rb b/app/interactions/domains/update_confirm/process_update_rejected.rb
new file mode 100644
index 000000000..1d7b75b0e
--- /dev/null
+++ b/app/interactions/domains/update_confirm/process_update_rejected.rb
@@ -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
diff --git a/app/jobs/domain_update_confirm_job.rb b/app/jobs/domain_update_confirm_job.rb
index 8f1fd1688..403318ca6 100644
--- a/app/jobs/domain_update_confirm_job.rb
+++ b/app/jobs/domain_update_confirm_job.rb
@@ -3,8 +3,8 @@ class DomainUpdateConfirmJob < ApplicationJob
def perform(domain_id, action, initiator = nil)
domain = Epp::Domain.find(domain_id)
- DomainUpdateConfirmInteraction::ProcessAction.run(domain: domain,
- action: action,
- initiator: initiator)
+ Domains::UpdateConfirm::ProcessAction.run(domain: domain,
+ action: action,
+ initiator: initiator)
end
end
From a0bc60ac74a1b29e5f18274f8d8cdd9896d8fb80 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 1 Dec 2020 18:28:34 +0500
Subject: [PATCH 051/106] Fix rejecting changes clearance
---
.../domains/update_confirm/process_update_rejected.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/interactions/domains/update_confirm/process_update_rejected.rb b/app/interactions/domains/update_confirm/process_update_rejected.rb
index 1d7b75b0e..19969d970 100644
--- a/app/interactions/domains/update_confirm/process_update_rejected.rb
+++ b/app/interactions/domains/update_confirm/process_update_rejected.rb
@@ -11,6 +11,7 @@ module Domains
preclean_pendings
clean_pendings!
+ domain.save!
end
end
end
From 6ab08dbd673e2b9d9e8801ec23ff58e903b6d155 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Wed, 2 Dec 2020 13:51:49 +0500
Subject: [PATCH 052/106] Fix rejecting updates
---
.../process_update_confirmed.rb | 2 +-
.../update_confirm/process_update_rejected.rb | 2 +-
test/jobs/domain_update_confirm_job_test.rb | 20 +++++++++++++++++++
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/app/interactions/domains/update_confirm/process_update_confirmed.rb b/app/interactions/domains/update_confirm/process_update_confirmed.rb
index 0402994dd..a4ceb1d3e 100644
--- a/app/interactions/domains/update_confirm/process_update_confirmed.rb
+++ b/app/interactions/domains/update_confirm/process_update_confirmed.rb
@@ -17,7 +17,7 @@ module Domains
preclean_pendings
update_domain
clean_pendings!
- domain.save!
+ domain.save(validate: false)
WhoisRecord.find_by(domain_id: domain.id).save # need to reload model
end
diff --git a/app/interactions/domains/update_confirm/process_update_rejected.rb b/app/interactions/domains/update_confirm/process_update_rejected.rb
index 19969d970..5ce818e66 100644
--- a/app/interactions/domains/update_confirm/process_update_rejected.rb
+++ b/app/interactions/domains/update_confirm/process_update_rejected.rb
@@ -11,7 +11,7 @@ module Domains
preclean_pendings
clean_pendings!
- domain.save!
+ domain.save(validate: false)
end
end
end
diff --git a/test/jobs/domain_update_confirm_job_test.rb b/test/jobs/domain_update_confirm_job_test.rb
index f01e7c41e..38aaa5339 100644
--- a/test/jobs/domain_update_confirm_job_test.rb
+++ b/test/jobs/domain_update_confirm_job_test.rb
@@ -64,4 +64,24 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase
assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE_CONFIRMATION
assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE
end
+
+ def test_clears_pending_update_and_inactive_after_denial
+ epp_xml = "\n\n \n \n \n #{@domain.name}\n" \
+ " \n #{@new_registrant.code}\n \n \n \n \n \n" \
+ " \n #{@legal_doc_path}\n \n" \
+ " \n 20alla-1594199756\n \n\n"
+ @domain.pending_json['frame'] = epp_xml
+ @domain.update(pending_json: @domain.pending_json)
+ @domain.update(statuses: [DomainStatus::INACTIVE, DomainStatus::PENDING_UPDATE])
+ @domain.nameservers.destroy_all
+ @domain.reload
+
+ DomainUpdateConfirmJob.perform_now(@domain.id, RegistrantVerification::REJECTED)
+ @domain.reload
+
+ assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE_CONFIRMATION
+ assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE
+ assert_not @domain.statuses.include? DomainStatus::PENDING_UPDATE
+ assert @domain.statuses.include? DomainStatus::INACTIVE
+ end
end
From 252d39464af5f299d2a9ad1fa101a4564ac67659 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 3 Dec 2020 13:39:58 +0500
Subject: [PATCH 053/106] Fix updating procedure
---
.../domains/update_confirm/base.rb | 2 ++
.../update_confirm/process_update_confirmed.rb | 2 --
.../update_confirm/process_update_rejected.rb | 1 -
test/jobs/domain_update_confirm_job_test.rb | 18 ++++++++++++++++++
4 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/app/interactions/domains/update_confirm/base.rb b/app/interactions/domains/update_confirm/base.rb
index ab5584c03..0e1fa81d3 100644
--- a/app/interactions/domains/update_confirm/base.rb
+++ b/app/interactions/domains/update_confirm/base.rb
@@ -33,10 +33,12 @@ module Domains
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
diff --git a/app/interactions/domains/update_confirm/process_update_confirmed.rb b/app/interactions/domains/update_confirm/process_update_confirmed.rb
index a4ceb1d3e..cb69d042e 100644
--- a/app/interactions/domains/update_confirm/process_update_confirmed.rb
+++ b/app/interactions/domains/update_confirm/process_update_confirmed.rb
@@ -3,7 +3,6 @@ module Domains
class ProcessUpdateConfirmed < Base
def execute
ActiveRecord::Base.transaction do
- domain.is_admin = true
old_registrant = domain.registrant
notify_registrar(:poll_pending_update_confirmed_by_registrant)
@@ -17,7 +16,6 @@ module Domains
preclean_pendings
update_domain
clean_pendings!
- domain.save(validate: false)
WhoisRecord.find_by(domain_id: domain.id).save # need to reload model
end
diff --git a/app/interactions/domains/update_confirm/process_update_rejected.rb b/app/interactions/domains/update_confirm/process_update_rejected.rb
index 5ce818e66..1d7b75b0e 100644
--- a/app/interactions/domains/update_confirm/process_update_rejected.rb
+++ b/app/interactions/domains/update_confirm/process_update_rejected.rb
@@ -11,7 +11,6 @@ module Domains
preclean_pendings
clean_pendings!
- domain.save(validate: false)
end
end
end
diff --git a/test/jobs/domain_update_confirm_job_test.rb b/test/jobs/domain_update_confirm_job_test.rb
index 38aaa5339..afffae157 100644
--- a/test/jobs/domain_update_confirm_job_test.rb
+++ b/test/jobs/domain_update_confirm_job_test.rb
@@ -84,4 +84,22 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase
assert_not @domain.statuses.include? DomainStatus::PENDING_UPDATE
assert @domain.statuses.include? DomainStatus::INACTIVE
end
+
+ def test_clears_pending_update_and_sets_ok_after_denial
+ epp_xml = "\n\n \n \n \n #{@domain.name}\n" \
+ " \n #{@new_registrant.code}\n \n \n \n \n \n" \
+ " \n #{@legal_doc_path}\n \n" \
+ " \n 20alla-1594199756\n \n\n"
+ @domain.pending_json['frame'] = epp_xml
+ @domain.update(pending_json: @domain.pending_json)
+ @domain.update(statuses: [DomainStatus::OK, DomainStatus::PENDING_UPDATE])
+
+ DomainUpdateConfirmJob.perform_now(@domain.id, RegistrantVerification::REJECTED)
+ @domain.reload
+
+ assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE_CONFIRMATION
+ assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE
+ assert_not @domain.statuses.include? DomainStatus::PENDING_UPDATE
+ assert @domain.statuses.include? DomainStatus::OK
+ end
end
From 7a90ef528abb14d0df62b956b6738a26d3593c5e Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Fri, 4 Dec 2020 13:57:53 +0500
Subject: [PATCH 054/106] Add a couple of domain status tests
---
test/jobs/domain_update_confirm_job_test.rb | 39 ++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/test/jobs/domain_update_confirm_job_test.rb b/test/jobs/domain_update_confirm_job_test.rb
index afffae157..ded0d3d8a 100644
--- a/test/jobs/domain_update_confirm_job_test.rb
+++ b/test/jobs/domain_update_confirm_job_test.rb
@@ -48,6 +48,7 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase
@domain.reload
assert_equal @domain.registrant.code, @new_registrant.code
+ assert @domain.statuses.include? DomainStatus::OK
end
def test_clears_pending_update_after_denial
@@ -65,6 +66,42 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase
assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE
end
+ def test_protects_statuses_after_denial
+ epp_xml = "\n\n \n \n \n #{@domain.name}\n" \
+ " \n #{@new_registrant.code}\n \n \n \n \n \n" \
+ " \n #{@legal_doc_path}\n \n" \
+ " \n 20alla-1594199756\n \n\n"
+ @domain.pending_json['frame'] = epp_xml
+ @domain.update(pending_json: @domain.pending_json)
+ @domain.update(statuses: [DomainStatus::DELETE_CANDIDATE, DomainStatus::DISPUTED])
+
+ DomainUpdateConfirmJob.perform_now(@domain.id, RegistrantVerification::REJECTED)
+ @domain.reload
+
+ assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE_CONFIRMATION
+ assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE
+ assert @domain.statuses.include? DomainStatus::DELETE_CANDIDATE
+ assert @domain.statuses.include? DomainStatus::DISPUTED
+ end
+
+ def test_protects_statuses_after_confirm
+ epp_xml = "\n\n \n \n \n #{@domain.name}\n" \
+ " \n #{@new_registrant.code}\n \n \n \n \n \n" \
+ " \n #{@legal_doc_path}\n \n" \
+ " \n 20alla-1594199756\n \n\n"
+ @domain.pending_json['frame'] = epp_xml
+ @domain.update(pending_json: @domain.pending_json)
+ @domain.update(statuses: [DomainStatus::DELETE_CANDIDATE, DomainStatus::DISPUTED])
+
+ DomainUpdateConfirmJob.perform_now(@domain.id, RegistrantVerification::CONFIRMED)
+ @domain.reload
+
+ assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE_CONFIRMATION
+ assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE
+ assert @domain.statuses.include? DomainStatus::DELETE_CANDIDATE
+ assert @domain.statuses.include? DomainStatus::DISPUTED
+ end
+
def test_clears_pending_update_and_inactive_after_denial
epp_xml = "\n\n \n \n \n #{@domain.name}\n" \
" \n #{@new_registrant.code}\n \n \n \n \n \n" \
@@ -72,7 +109,7 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase
" \n 20alla-1594199756\n \n\n"
@domain.pending_json['frame'] = epp_xml
@domain.update(pending_json: @domain.pending_json)
- @domain.update(statuses: [DomainStatus::INACTIVE, DomainStatus::PENDING_UPDATE])
+ @domain.update(statuses: [DomainStatus::PENDING_UPDATE])
@domain.nameservers.destroy_all
@domain.reload
From e8fa79304f7e1b34846d74989deac1d753b6bbf7 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 1 Dec 2020 15:23:23 +0500
Subject: [PATCH 055/106] Move DomainCron#clean_expired_pendings to interactor
---
.../domains/expired_pendings/base.rb | 10 ++++
.../domains/expired_pendings/clean_all.rb | 35 +++++++++++
.../domains/expired_pendings/process_clean.rb | 60 +++++++++++++++++++
app/models/domain_cron.rb | 32 +---------
test/models/domain_cron_test.rb | 8 ++-
5 files changed, 112 insertions(+), 33 deletions(-)
create mode 100644 app/interactions/domains/expired_pendings/base.rb
create mode 100644 app/interactions/domains/expired_pendings/clean_all.rb
create mode 100644 app/interactions/domains/expired_pendings/process_clean.rb
diff --git a/app/interactions/domains/expired_pendings/base.rb b/app/interactions/domains/expired_pendings/base.rb
new file mode 100644
index 000000000..7faa32050
--- /dev/null
+++ b/app/interactions/domains/expired_pendings/base.rb
@@ -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
diff --git a/app/interactions/domains/expired_pendings/clean_all.rb b/app/interactions/domains/expired_pendings/clean_all.rb
new file mode 100644
index 000000000..1dbab266c
--- /dev/null
+++ b/app/interactions/domains/expired_pendings/clean_all.rb
@@ -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
diff --git a/app/interactions/domains/expired_pendings/process_clean.rb b/app/interactions/domains/expired_pendings/process_clean.rb
new file mode 100644
index 000000000..c6277c3c5
--- /dev/null
+++ b/app/interactions/domains/expired_pendings/process_clean.rb
@@ -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
diff --git a/app/models/domain_cron.rb b/app/models/domain_cron.rb
index d09141d52..77de7062a 100644
--- a/app/models/domain_cron.rb
+++ b/app/models/domain_cron.rb
@@ -1,36 +1,6 @@
class DomainCron
def self.clean_expired_pendings
- STDOUT << "#{Time.zone.now.utc} - Clean expired domain pendings\n" unless Rails.env.test?
-
- ::PaperTrail.request.whodunnit = "cron - #{__method__}"
- expire_at = Setting.expire_pending_confirmation.hours.ago
- count = 0
- expired_pending_domains = Domain.where('registrant_verification_asked_at <= ?', expire_at)
- expired_pending_domains.each do |domain|
- unless domain.pending_update? || domain.pending_delete? || domain.pending_delete_confirmation?
- msg = "#{Time.zone.now.utc} - ISSUE: DOMAIN #{domain.id}: #{domain.name} IS IN EXPIRED PENDING LIST, " \
- "but no pendingDelete/pendingUpdate state present!\n"
- STDOUT << msg unless Rails.env.test?
- next
- end
- count += 1
- if domain.pending_update?
- RegistrantChangeExpiredEmailJob.enqueue(domain.id)
- end
- if domain.pending_delete? || domain.pending_delete_confirmation?
- DomainDeleteMailer.expired(domain).deliver_now
- end
-
- domain.preclean_pendings
- domain.clean_pendings!
-
- unless Rails.env.test?
- STDOUT << "#{Time.zone.now.utc} DomainCron.clean_expired_pendings: ##{domain.id} (#{domain.name})\n"
- end
- UpdateWhoisRecordJob.enqueue domain.name, 'domain'
- end
- STDOUT << "#{Time.zone.now.utc} - Successfully cancelled #{count} domain pendings\n" unless Rails.env.test?
- count
+ Domains::ExpiredPendings::CleanAll.run!
end
def self.start_expire_period
diff --git a/test/models/domain_cron_test.rb b/test/models/domain_cron_test.rb
index 0224b1a61..c417df04f 100644
--- a/test/models/domain_cron_test.rb
+++ b/test/models/domain_cron_test.rb
@@ -19,7 +19,9 @@ class DomainCronTest < ActiveSupport::TestCase
registrant_verification_token: 'test',
statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
- DomainCron.clean_expired_pendings
+ perform_enqueued_jobs do
+ DomainCron.clean_expired_pendings
+ end
assert_emails 1
end
@@ -84,7 +86,9 @@ class DomainCronTest < ActiveSupport::TestCase
assert @domain.pending_update?
@domain.reload
- DomainCron.clean_expired_pendings
+ perform_enqueued_jobs do
+ DomainCron.clean_expired_pendings
+ end
@domain.reload
assert_not @domain.pending_update?
From 849010b118addcba6057caef1d2b7685e2568fef Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 1 Dec 2020 16:44:31 +0500
Subject: [PATCH 056/106] Move #process_expired to interactor
---
.../domains/expire_period/base.rb | 10 +++++++
.../domains/expire_period/process_expired.rb | 28 +++++++++++++++++++
.../domains/expire_period/start.rb | 19 +++++++++++++
app/models/domain.rb | 6 ----
app/models/domain_cron.rb | 22 +--------------
5 files changed, 58 insertions(+), 27 deletions(-)
create mode 100644 app/interactions/domains/expire_period/base.rb
create mode 100644 app/interactions/domains/expire_period/process_expired.rb
create mode 100644 app/interactions/domains/expire_period/start.rb
diff --git a/app/interactions/domains/expire_period/base.rb b/app/interactions/domains/expire_period/base.rb
new file mode 100644
index 000000000..eab8171bf
--- /dev/null
+++ b/app/interactions/domains/expire_period/base.rb
@@ -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
diff --git a/app/interactions/domains/expire_period/process_expired.rb b/app/interactions/domains/expire_period/process_expired.rb
new file mode 100644
index 000000000..595de1228
--- /dev/null
+++ b/app/interactions/domains/expire_period/process_expired.rb
@@ -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
diff --git a/app/interactions/domains/expire_period/start.rb b/app/interactions/domains/expire_period/start.rb
new file mode 100644
index 000000000..1ed2342f1
--- /dev/null
+++ b/app/interactions/domains/expire_period/start.rb
@@ -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
diff --git a/app/models/domain.rb b/app/models/domain.rb
index dc7d86da8..33d2dcd58 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -482,12 +482,6 @@ class Domain < ApplicationRecord
Registrant.find_by(id: pending_json['new_registrant_id'])
end
- def set_graceful_expired
- self.outzone_at = expire_time + self.class.expire_warning_period
- self.delete_date = outzone_at + self.class.redemption_grace_period
- self.statuses |= [DomainStatus::EXPIRED]
- end
-
def pending_update?
statuses.include?(DomainStatus::PENDING_UPDATE)
end
diff --git a/app/models/domain_cron.rb b/app/models/domain_cron.rb
index 77de7062a..cd063f901 100644
--- a/app/models/domain_cron.rb
+++ b/app/models/domain_cron.rb
@@ -4,27 +4,7 @@ class DomainCron
end
def self.start_expire_period
- ::PaperTrail.request.whodunnit = "cron - #{__method__}"
- domains = Domain.expired
- marked = 0
- real = 0
-
- domains.each do |domain|
- next unless domain.expirable?
- real += 1
- domain.set_graceful_expired
- STDOUT << "#{Time.zone.now.utc} DomainCron.start_expire_period: ##{domain.id} (#{domain.name}) #{domain.changes}\n" unless Rails.env.test?
-
- send_time = domain.valid_to + Setting.expiration_reminder_mail.to_i.days
- saved = domain.save(validate: false)
-
- if saved
- DomainExpireEmailJob.enqueue(domain.id, run_at: send_time)
- marked += 1
- end
- end
-
- STDOUT << "#{Time.zone.now.utc} - Successfully expired #{marked} of #{real} domains\n" unless Rails.env.test?
+ Domains::ExpirePeriod::Start.run!
end
def self.start_redemption_grace_period
From d17e26c28b81e7ea9dc75d1fecd19ed14df1f623 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 1 Dec 2020 17:04:19 +0500
Subject: [PATCH 057/106] Move #redemption_grace_period to interactor
---
.../domains/redemption_grace_period/base.rb | 10 ++++++++++
.../process_grace_period.rb | 20 +++++++++++++++++++
.../domains/redemption_grace_period/start.rb | 20 +++++++++++++++++++
app/models/domain_cron.rb | 19 +-----------------
4 files changed, 51 insertions(+), 18 deletions(-)
create mode 100644 app/interactions/domains/redemption_grace_period/base.rb
create mode 100644 app/interactions/domains/redemption_grace_period/process_grace_period.rb
create mode 100644 app/interactions/domains/redemption_grace_period/start.rb
diff --git a/app/interactions/domains/redemption_grace_period/base.rb b/app/interactions/domains/redemption_grace_period/base.rb
new file mode 100644
index 000000000..5d1ede289
--- /dev/null
+++ b/app/interactions/domains/redemption_grace_period/base.rb
@@ -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
diff --git a/app/interactions/domains/redemption_grace_period/process_grace_period.rb b/app/interactions/domains/redemption_grace_period/process_grace_period.rb
new file mode 100644
index 000000000..0f120a996
--- /dev/null
+++ b/app/interactions/domains/redemption_grace_period/process_grace_period.rb
@@ -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
diff --git a/app/interactions/domains/redemption_grace_period/start.rb b/app/interactions/domains/redemption_grace_period/start.rb
new file mode 100644
index 000000000..ef7f42e58
--- /dev/null
+++ b/app/interactions/domains/redemption_grace_period/start.rb
@@ -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
diff --git a/app/models/domain_cron.rb b/app/models/domain_cron.rb
index cd063f901..e936c29e6 100644
--- a/app/models/domain_cron.rb
+++ b/app/models/domain_cron.rb
@@ -8,24 +8,7 @@ class DomainCron
end
def self.start_redemption_grace_period
- STDOUT << "#{Time.zone.now.utc} - Setting server_hold to domains\n" unless Rails.env.test?
-
- ::PaperTrail.request.whodunnit = "cron - #{__method__}"
-
- domains = Domain.outzone_candidates
- marked = 0
- real = 0
-
- domains.each do |domain|
- next unless domain.server_holdable?
- real += 1
- domain.statuses << DomainStatus::SERVER_HOLD
- STDOUT << "#{Time.zone.now.utc} DomainCron.start_redemption_grace_period: ##{domain.id} (#{domain.name}) #{domain.changes}\n" unless Rails.env.test?
- domain.save(validate: false) and marked += 1
- end
-
- STDOUT << "#{Time.zone.now.utc} - Successfully set server_hold to #{marked} of #{real} domains\n" unless Rails.env.test?
- marked
+ Domains::RedemptionGracePeriod::Start.run!
end
def self.start_client_hold
From 167b37c61fb4aefae70cbf7e3c1c281322f094ba Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Wed, 2 Dec 2020 14:31:37 +0500
Subject: [PATCH 058/106] Add tests for DOmainCrone#expire_period
---
test/interactions/expire_period/start_test.rb | 28 +++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 test/interactions/expire_period/start_test.rb
diff --git a/test/interactions/expire_period/start_test.rb b/test/interactions/expire_period/start_test.rb
new file mode 100644
index 000000000..168b255bb
--- /dev/null
+++ b/test/interactions/expire_period/start_test.rb
@@ -0,0 +1,28 @@
+require 'test_helper'
+
+class StartTest < ActiveSupport::TestCase
+ include ActionMailer::TestHelper
+
+ setup do
+ @domain = domains(:shop)
+ @domain.update(expire_time: Time.zone.now - 1.day)
+ ActionMailer::Base.deliveries.clear
+ end
+
+ def test_sets_expired
+ job_count = lambda do
+ QueJob.where("args->>0 = '#{@domain.id}'", job_class: DomainExpireEmailJob.name).count
+ end
+
+ assert_difference job_count, 1 do
+ perform_enqueued_jobs do
+ DomainCron.start_expire_period
+ end
+ end
+
+ @domain.reload
+ assert @domain.statuses.include?(DomainStatus::EXPIRED)
+ assert_equal @domain.outzone_at, @domain.expire_time + Domain.expire_warning_period
+ assert_equal @domain.delete_date, (@domain.outzone_at + Domain.redemption_grace_period).to_date
+ end
+end
From ac3860bbd8fc66b7eaa7ba2254516a0482642bad Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Wed, 2 Dec 2020 14:54:37 +0500
Subject: [PATCH 059/106] Add test for redemption grace period
---
.../redemption_grace_period/start_test.rb | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 test/interactions/redemption_grace_period/start_test.rb
diff --git a/test/interactions/redemption_grace_period/start_test.rb b/test/interactions/redemption_grace_period/start_test.rb
new file mode 100644
index 000000000..8958030f0
--- /dev/null
+++ b/test/interactions/redemption_grace_period/start_test.rb
@@ -0,0 +1,25 @@
+require 'test_helper'
+
+class StartTest < ActiveSupport::TestCase
+
+ setup do
+ @domain = domains(:shop)
+ @domain.update(outzone_time: Time.zone.now - 1.day)
+ end
+
+ def test_sets_server_hold
+ DomainCron.start_redemption_grace_period
+
+ @domain.reload
+ assert @domain.statuses.include?(DomainStatus::SERVER_HOLD)
+ end
+
+ def test_doesnt_sets_server_hold_if_not_outzone
+ @domain.update(outzone_time: nil)
+ @domain.reload
+ DomainCron.start_redemption_grace_period
+
+ @domain.reload
+ assert_not @domain.statuses.include?(DomainStatus::SERVER_HOLD)
+ end
+end
From ccf91d306abdadced826e6afb09d6b60dbfa9e5f Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Fri, 4 Dec 2020 17:48:42 +0500
Subject: [PATCH 060/106] Rename email sending interactor
---
.../{delete_confirm => delete_confirm_email}/send_request.rb | 2 +-
app/models/domain.rb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
rename app/interactions/domains/{delete_confirm => delete_confirm_email}/send_request.rb (96%)
diff --git a/app/interactions/domains/delete_confirm/send_request.rb b/app/interactions/domains/delete_confirm_email/send_request.rb
similarity index 96%
rename from app/interactions/domains/delete_confirm/send_request.rb
rename to app/interactions/domains/delete_confirm_email/send_request.rb
index 91afaefb8..7070423a6 100644
--- a/app/interactions/domains/delete_confirm/send_request.rb
+++ b/app/interactions/domains/delete_confirm_email/send_request.rb
@@ -1,5 +1,5 @@
module Domains
- module DeleteConfirm
+ module DeleteConfirmEmail
class SendRequest < ActiveInteraction::Base
object :domain,
class: Domain,
diff --git a/app/models/domain.rb b/app/models/domain.rb
index dc7d86da8..ee3481bb2 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -418,7 +418,7 @@ class Domain < ApplicationRecord
pending_delete_confirmation!
save(validate: false) # should check if this did succeed
- Domains::DeleteConfirm::SendRequest.run(domain: self)
+ Domains::DeleteConfirmEmail::SendRequest.run(domain: self)
end
def cancel_pending_delete
From f6a7a08b2433b20b1c131f7bc307b52a9e98b580 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Fri, 4 Dec 2020 18:09:11 +0500
Subject: [PATCH 061/106] Move job to interactor
---
.../domains/delete_confirm/base.rb | 23 ++++++++++
.../domains/delete_confirm/process_action.rb | 17 ++++++++
.../process_delete_confirmed.rb | 11 +++++
.../delete_confirm/process_delete_rejected.rb | 34 +++++++++++++++
app/jobs/application_job.rb | 2 +
app/jobs/domain_delete_confirm_job.rb | 42 ++++---------------
app/models/registrant_verification.rb | 4 +-
test/jobs/domain_delete_confirm_job_test.rb | 8 ++--
.../domains/domain_delete_confirms_test.rb | 9 +++-
9 files changed, 107 insertions(+), 43 deletions(-)
create mode 100644 app/interactions/domains/delete_confirm/base.rb
create mode 100644 app/interactions/domains/delete_confirm/process_action.rb
create mode 100644 app/interactions/domains/delete_confirm/process_delete_confirmed.rb
create mode 100644 app/interactions/domains/delete_confirm/process_delete_rejected.rb
create mode 100644 app/jobs/application_job.rb
diff --git a/app/interactions/domains/delete_confirm/base.rb b/app/interactions/domains/delete_confirm/base.rb
new file mode 100644
index 000000000..d1d45f006
--- /dev/null
+++ b/app/interactions/domains/delete_confirm/base.rb
@@ -0,0 +1,23 @@
+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
+ end
+ end
+end
diff --git a/app/interactions/domains/delete_confirm/process_action.rb b/app/interactions/domains/delete_confirm/process_action.rb
new file mode 100644
index 000000000..59f23de67
--- /dev/null
+++ b/app/interactions/domains/delete_confirm/process_action.rb
@@ -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
diff --git a/app/interactions/domains/delete_confirm/process_delete_confirmed.rb b/app/interactions/domains/delete_confirm/process_delete_confirmed.rb
new file mode 100644
index 000000000..553809666
--- /dev/null
+++ b/app/interactions/domains/delete_confirm/process_delete_confirmed.rb
@@ -0,0 +1,11 @@
+module Domains
+ module DeleteConfirm
+ class ProcessDeleteConfirmed < Base
+ def execute
+ domain.notify_registrar(:poll_pending_delete_confirmed_by_registrant)
+ domain.apply_pending_delete!
+ raise_errors!(domain)
+ end
+ end
+ end
+end
diff --git a/app/interactions/domains/delete_confirm/process_delete_rejected.rb b/app/interactions/domains/delete_confirm/process_delete_rejected.rb
new file mode 100644
index 000000000..5038ba150
--- /dev/null
+++ b/app/interactions/domains/delete_confirm/process_delete_rejected.rb
@@ -0,0 +1,34 @@
+module Domains
+ module DeleteConfirm
+ class ProcessDeleteRejected < Base
+ def execute
+ domain.statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION)
+ domain.notify_registrar(:poll_pending_delete_rejected_by_registrant)
+
+ domain.cancel_pending_delete
+ domain.save(validate: false)
+ raise_errors!(domain)
+
+ send_domain_deleted_email
+ end
+
+ def send_domain_deleted_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
diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb
new file mode 100644
index 000000000..a009ace51
--- /dev/null
+++ b/app/jobs/application_job.rb
@@ -0,0 +1,2 @@
+class ApplicationJob < ActiveJob::Base
+end
diff --git a/app/jobs/domain_delete_confirm_job.rb b/app/jobs/domain_delete_confirm_job.rb
index e94f2432c..afea3da59 100644
--- a/app/jobs/domain_delete_confirm_job.rb
+++ b/app/jobs/domain_delete_confirm_job.rb
@@ -1,39 +1,11 @@
-class DomainDeleteConfirmJob < Que::Job
- def run(domain_id, action, initiator = nil)
- ::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)
+class DomainDeleteConfirmJob < ApplicationJob
+ queue_as :default
- case action
- when RegistrantVerification::CONFIRMED
- domain.notify_registrar(:poll_pending_delete_confirmed_by_registrant)
- domain.apply_pending_delete!
- raise_errors!(domain)
+ def perform(domain_id, action, initiator = nil)
+ domain = Epp::Domain.find(domain_id)
- when RegistrantVerification::REJECTED
- domain.statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION)
- domain.notify_registrar(:poll_pending_delete_rejected_by_registrant)
-
- 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?
+ Domains::DeleteConfirm::ProcessAction.run(domain: domain,
+ action: action,
+ initiator: initiator)
end
end
diff --git a/app/models/registrant_verification.rb b/app/models/registrant_verification.rb
index 097f0cfa9..f0c9f3b97 100644
--- a/app/models/registrant_verification.rb
+++ b/app/models/registrant_verification.rb
@@ -30,12 +30,12 @@ class RegistrantVerification < ApplicationRecord
def domain_registrant_delete_confirm!(initiator)
self.action_type = DOMAIN_DELETE
self.action = CONFIRMED
- DomainDeleteConfirmJob.enqueue domain.id, CONFIRMED, initiator if save
+ DomainDeleteConfirmJob.perform_later domain.id, CONFIRMED, initiator if save
end
def domain_registrant_delete_reject!(initiator)
self.action_type = DOMAIN_DELETE
self.action = REJECTED
- DomainDeleteConfirmJob.enqueue domain.id, REJECTED, initiator if save
+ DomainDeleteConfirmJob.perform_later domain.id, REJECTED, initiator if save
end
end
diff --git a/test/jobs/domain_delete_confirm_job_test.rb b/test/jobs/domain_delete_confirm_job_test.rb
index b999bd3c7..cbe4b87f1 100644
--- a/test/jobs/domain_delete_confirm_job_test.rb
+++ b/test/jobs/domain_delete_confirm_job_test.rb
@@ -18,7 +18,7 @@ class DomainDeleteConfirmJobTest < ActiveSupport::TestCase
new_registrant_email: @new_registrant.email,
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
assert_equal(last_registrar_notification.attached_obj_id, @domain.id)
@@ -31,7 +31,7 @@ class DomainDeleteConfirmJobTest < ActiveSupport::TestCase
new_registrant_email: @new_registrant.email,
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
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_equal @user.id, @domain.pending_json['current_user_id']
- DomainDeleteConfirmJob.enqueue(@domain.id, RegistrantVerification::CONFIRMED)
+ DomainDeleteConfirmJob.perform_now(@domain.id, RegistrantVerification::CONFIRMED)
@domain.reload
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_equal @user.id, @domain.pending_json['current_user_id']
- DomainDeleteConfirmJob.enqueue(@domain.id, RegistrantVerification::REJECTED)
+ DomainDeleteConfirmJob.perform_now(@domain.id, RegistrantVerification::REJECTED)
@domain.reload
assert_equal ['ok'], @domain.statuses
diff --git a/test/system/registrant_area/domains/domain_delete_confirms_test.rb b/test/system/registrant_area/domains/domain_delete_confirms_test.rb
index 0eb61ada8..765cd0149 100644
--- a/test/system/registrant_area/domains/domain_delete_confirms_test.rb
+++ b/test/system/registrant_area/domains/domain_delete_confirms_test.rb
@@ -1,6 +1,7 @@
require 'application_system_test_case'
class DomainDeleteConfirmsTest < ApplicationSystemTestCase
+ include ActionMailer::TestHelper
setup do
@user = users(:registrant)
sign_in @user
@@ -13,7 +14,9 @@ class DomainDeleteConfirmsTest < ApplicationSystemTestCase
def test_enqueues_approve_job_after_verification
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.'
@domain.reload
@@ -23,7 +26,9 @@ class DomainDeleteConfirmsTest < ApplicationSystemTestCase
def test_enqueues_reject_job_after_verification
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.'
@domain.reload
From 5a059e86bb9bf380e610350adf705062276d726a Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 7 Dec 2020 17:08:54 +0500
Subject: [PATCH 062/106] Move confirmed delete procedures to interactor
---
.../domains/delete_confirm/base.rb | 30 ++++++++++++++
.../process_delete_confirmed.rb | 41 ++++++++++++++++++-
.../delete_confirm/process_delete_rejected.rb | 4 +-
3 files changed, 72 insertions(+), 3 deletions(-)
diff --git a/app/interactions/domains/delete_confirm/base.rb b/app/interactions/domains/delete_confirm/base.rb
index d1d45f006..5bd07f40f 100644
--- a/app/interactions/domains/delete_confirm/base.rb
+++ b/app/interactions/domains/delete_confirm/base.rb
@@ -18,6 +18,36 @@ module Domains
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
diff --git a/app/interactions/domains/delete_confirm/process_delete_confirmed.rb b/app/interactions/domains/delete_confirm/process_delete_confirmed.rb
index 553809666..1f3068107 100644
--- a/app/interactions/domains/delete_confirm/process_delete_confirmed.rb
+++ b/app/interactions/domains/delete_confirm/process_delete_confirmed.rb
@@ -2,10 +2,49 @@ module Domains
module DeleteConfirm
class ProcessDeleteConfirmed < Base
def execute
- domain.notify_registrar(:poll_pending_delete_confirmed_by_registrant)
+ 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
diff --git a/app/interactions/domains/delete_confirm/process_delete_rejected.rb b/app/interactions/domains/delete_confirm/process_delete_rejected.rb
index 5038ba150..1844801ac 100644
--- a/app/interactions/domains/delete_confirm/process_delete_rejected.rb
+++ b/app/interactions/domains/delete_confirm/process_delete_rejected.rb
@@ -9,10 +9,10 @@ module Domains
domain.save(validate: false)
raise_errors!(domain)
- send_domain_deleted_email
+ send_domain_delete_rejected_email
end
- def send_domain_deleted_email
+ 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?
From ce07c5eae83c27f0043d98ad58a99bdb9bbc5dd4 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 7 Dec 2020 17:37:44 +0500
Subject: [PATCH 063/106] Move rejected delete procedures to interactor
---
.../domains/delete_confirm/process_delete_rejected.rb | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/app/interactions/domains/delete_confirm/process_delete_rejected.rb b/app/interactions/domains/delete_confirm/process_delete_rejected.rb
index 1844801ac..25b491660 100644
--- a/app/interactions/domains/delete_confirm/process_delete_rejected.rb
+++ b/app/interactions/domains/delete_confirm/process_delete_rejected.rb
@@ -2,10 +2,8 @@ module Domains
module DeleteConfirm
class ProcessDeleteRejected < Base
def execute
- domain.statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION)
- domain.notify_registrar(:poll_pending_delete_rejected_by_registrant)
-
domain.cancel_pending_delete
+ notify_registrar(:poll_pending_delete_rejected_by_registrant)
domain.save(validate: false)
raise_errors!(domain)
From 6841703349339614256601367f7d352a286d8a05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Tue, 8 Dec 2020 10:35:25 +0200
Subject: [PATCH 064/106] Update CHANGELOG.md
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9774d5cb3..6dd2e66dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+08.12.2020
+* Replaced Travis-CI with GitHub Actions [#1746](https://github.com/internetee/registry/pull/1746)
+
01.12.2020
* Refactored clientHold for interactors [#1751](https://github.com/internetee/registry/issues/1751)
* Fixed internal error on removing clientHold status when not present [#1766](https://github.com/internetee/registry/issues/1766)
From a54249f6ff7ecaddab9d9b6c7e7e174c59db5f25 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 8 Dec 2020 16:08:33 +0500
Subject: [PATCH 065/106] Move WhoisUpdate job to interactor
---
app/interactions/whois/delete_record.rb | 48 ++++++++++++++
app/interactions/whois/update.rb | 39 ++++++++++++
app/interactions/whois/update_record.rb | 32 ++++++++++
app/jobs/update_whois_record_job.rb | 84 +------------------------
4 files changed, 120 insertions(+), 83 deletions(-)
create mode 100644 app/interactions/whois/delete_record.rb
create mode 100644 app/interactions/whois/update.rb
create mode 100644 app/interactions/whois/update_record.rb
diff --git a/app/interactions/whois/delete_record.rb b/app/interactions/whois/delete_record.rb
new file mode 100644
index 000000000..62e416d2f
--- /dev/null
+++ b/app/interactions/whois/delete_record.rb
@@ -0,0 +1,48 @@
+module Whois
+ class DeleteRecord < ActiveInteraction::Base
+ string :name
+ string :type
+
+ validates :type, inclusion: { in: %w[reserved blocked domain disputed zone] }
+
+ def execute
+ send "delete_#{type}", name
+ end
+
+ # 1. deleting own
+ # 2. trying to regenerate reserved in order domain is still in the list
+ def delete_domain(name)
+ WhoisRecord.where(name: name).destroy_all
+
+ BlockedDomain.find_by(name: name).try(:generate_data)
+ ReservedDomain.find_by(name: name).try(:generate_data)
+ Dispute.active.find_by(domain_name: name).try(:generate_data)
+ end
+
+ def delete_reserved(name)
+ remove_status_from_whois(domain_name: name, domain_status: 'Reserved')
+ end
+
+ def delete_blocked(name)
+ delete_reserved(name)
+ end
+
+ def delete_disputed(name)
+ return if Dispute.active.find_by(domain_name: name).present?
+
+ remove_status_from_whois(domain_name: name, domain_status: 'disputed')
+ end
+
+ def delete_zone(name)
+ WhoisRecord.where(name: name).destroy_all
+ Whois::Record.where(name: name).destroy_all
+ end
+
+ def remove_status_from_whois(domain_name:, domain_status:)
+ Whois::Record.where(name: domain_name).each do |r|
+ r.json['status'] = r.json['status'].delete_if { |status| status == domain_status }
+ r.json['status'].blank? ? r.destroy : r.save
+ end
+ end
+ end
+end
diff --git a/app/interactions/whois/update.rb b/app/interactions/whois/update.rb
new file mode 100644
index 000000000..bd37b4576
--- /dev/null
+++ b/app/interactions/whois/update.rb
@@ -0,0 +1,39 @@
+module Whois
+ class Update < ActiveInteraction::Base
+ array :names
+ string :type
+
+ validates :type, inclusion: { in: %w[reserved blocked domain disputed zone] }
+
+ def execute
+ ::PaperTrail.request.whodunnit = "job - #{self.class.name} - #{type}"
+
+ klass = determine_class
+
+ Array(names).each do |name|
+ record = find_record(klass, name)
+ if record
+ Whois::UpdateRecord.run(record: record, type: type)
+ else
+ Whois::DeleteRecord.run(name: name, type: type)
+ end
+ end
+ end
+
+ private
+
+ def determine_class
+ case type
+ when 'reserved' then ReservedDomain
+ when 'blocked' then BlockedDomain
+ when 'domain' then Domain
+ when 'disputed' then Dispute.active
+ else DNS::Zone
+ end
+ end
+
+ def find_record(klass, name)
+ klass == DNS::Zone ? klass.find_by(origin: name) : klass.find_by(name: name)
+ end
+ end
+end
diff --git a/app/interactions/whois/update_record.rb b/app/interactions/whois/update_record.rb
new file mode 100644
index 000000000..6fc838968
--- /dev/null
+++ b/app/interactions/whois/update_record.rb
@@ -0,0 +1,32 @@
+module Whois
+ class UpdateRecord < ActiveInteraction::Base
+ interface :record
+ string :type
+
+ validates :type, inclusion: { in: %w[reserved blocked domain disputed zone] }
+
+ def execute
+ send "update_#{type}", record
+ end
+
+ def update_domain(domain)
+ domain.whois_record ? domain.whois_record.save : domain.create_whois_record
+ end
+
+ def update_reserved(record)
+ record.generate_data
+ end
+
+ def update_blocked(record)
+ update_reserved(record)
+ end
+
+ def update_disputed(record)
+ update_reserved(record)
+ end
+
+ def update_zone(record)
+ update_reserved(record)
+ end
+ end
+end
diff --git a/app/jobs/update_whois_record_job.rb b/app/jobs/update_whois_record_job.rb
index 2973d5a6b..d067807a0 100644
--- a/app/jobs/update_whois_record_job.rb
+++ b/app/jobs/update_whois_record_job.rb
@@ -1,87 +1,5 @@
class UpdateWhoisRecordJob < Que::Job
-
def run(names, type)
- ::PaperTrail.request.whodunnit = "job - #{self.class.name} - #{type}"
-
- klass = determine_class(type)
-
- Array(names).each do |name|
- record = find_record(klass, name)
- if record
- send "update_#{type}", record
- else
- send "delete_#{type}", name
- end
- end
- end
-
- def find_record(klass, name)
- klass == DNS::Zone ? klass.find_by(origin: name) : klass.find_by(name: name)
- end
-
- def determine_class(type)
- case type
- when 'reserved' then ReservedDomain
- when 'blocked' then BlockedDomain
- when 'domain' then Domain
- when 'disputed' then Dispute.active
- when 'zone' then DNS::Zone
- end
- end
-
- def update_domain(domain)
- domain.whois_record ? domain.whois_record.save : domain.create_whois_record
- end
-
- def update_reserved(record)
- record.generate_data
- end
-
- def update_blocked(record)
- update_reserved(record)
- end
-
- def update_disputed(record)
- update_reserved(record)
- end
-
- def update_zone(record)
- update_reserved(record)
- end
-
- # 1. deleting own
- # 2. trying to regenerate reserved in order domain is still in the list
- def delete_domain(name)
- WhoisRecord.where(name: name).destroy_all
-
- BlockedDomain.find_by(name: name).try(:generate_data)
- ReservedDomain.find_by(name: name).try(:generate_data)
- Dispute.active.find_by(domain_name: name).try(:generate_data)
- end
-
- def delete_reserved(name)
- remove_status_from_whois(domain_name: name, domain_status: 'Reserved')
- end
-
- def delete_blocked(name)
- delete_reserved(name)
- end
-
- def delete_disputed(name)
- return if Dispute.active.find_by(domain_name: name).present?
-
- remove_status_from_whois(domain_name: name, domain_status: 'disputed')
- end
-
- def delete_zone(name)
- WhoisRecord.where(name: name).destroy_all
- Whois::Record.where(name: name).destroy_all
- end
-
- def remove_status_from_whois(domain_name:, domain_status:)
- Whois::Record.where(name: domain_name).each do |r|
- r.json['status'] = r.json['status'].delete_if { |status| status == domain_status }
- r.json['status'].blank? ? r.destroy : r.save
- end
+ Whois::Update.run(names: [names].flatten, type: type)
end
end
From 8f6f2433e24cd0f3918c786223abd63d8e38b017 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Tue, 8 Dec 2020 18:17:10 +0200
Subject: [PATCH 066/106] Update CHANGELOG.md
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6dd2e66dd..5e823c7b1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
08.12.2020
* Replaced Travis-CI with GitHub Actions [#1746](https://github.com/internetee/registry/pull/1746)
+* Refactored domain delete for interactors [#1755](https://github.com/internetee/registry/issues/1755)
01.12.2020
* Refactored clientHold for interactors [#1751](https://github.com/internetee/registry/issues/1751)
From 7573a7eac2e1dd7a5540855a491f367dec8113e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Wed, 9 Dec 2020 16:33:23 +0200
Subject: [PATCH 067/106] Update CHANGELOG.md
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e823c7b1..7300adbdb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+09.12.2020
+* Refactored domain update confirm for interactors [#1760](https://github.com/internetee/registry/issues/1760)
+
08.12.2020
* Replaced Travis-CI with GitHub Actions [#1746](https://github.com/internetee/registry/pull/1746)
* Refactored domain delete for interactors [#1755](https://github.com/internetee/registry/issues/1755)
From de37732a56abf42c06b165e208c01c03d91a22e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Mon, 14 Dec 2020 15:21:04 +0200
Subject: [PATCH 068/106] Update CHANGELOG.md
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7300adbdb..60d7c1e24 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+14.12.2020
+* Refactored domain cron jobs for interactors [#1767](https://github.com/internetee/registry/issues/1767)
+
09.12.2020
* Refactored domain update confirm for interactors [#1760](https://github.com/internetee/registry/issues/1760)
From ee2601b8de655359c7de3472cd8ce252ddcab119 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Wed, 9 Dec 2020 16:50:53 +0500
Subject: [PATCH 069/106] Add scaffold for a controller & view
---
Gemfile | 1 +
Gemfile.lock | 7 ++++++
.../registrar/bulk_renew_controller.rb | 9 ++++++++
.../bulk_change/_api_errors.html.erb | 9 ++++++++
.../bulk_change/_bulk_renew_form.html.erb | 22 +++++++++++++++++++
app/views/registrar/bulk_change/new.html.erb | 8 +++++++
config/locales/registrar/bulk_change.en.yml | 5 +++++
config/routes.rb | 2 ++
8 files changed, 63 insertions(+)
create mode 100644 app/controllers/registrar/bulk_renew_controller.rb
create mode 100644 app/views/registrar/bulk_change/_api_errors.html.erb
create mode 100644 app/views/registrar/bulk_change/_bulk_renew_form.html.erb
diff --git a/Gemfile b/Gemfile
index 9bbcba254..9aad8b7ae 100644
--- a/Gemfile
+++ b/Gemfile
@@ -80,6 +80,7 @@ gem 'directo', github: 'internetee/directo', branch: 'master'
group :development, :test do
+ gem 'listen'
gem 'pry', '0.10.1'
gem 'puma'
end
diff --git a/Gemfile.lock b/Gemfile.lock
index 2a0bb55b1..3c9da920e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -250,6 +250,9 @@ GEM
kaminari-core (= 1.2.1)
kaminari-core (1.2.1)
libxml-ruby (3.2.0)
+ listen (3.3.3)
+ rb-fsevent (~> 0.10, >= 0.10.3)
+ rb-inotify (~> 0.9, >= 0.9.10)
logger (1.4.2)
loofah (2.7.0)
crass (~> 1.0.2)
@@ -363,6 +366,9 @@ GEM
activesupport (>= 5.2.1)
i18n
polyamorous (= 2.3.2)
+ rb-fsevent (0.10.4)
+ rb-inotify (0.10.1)
+ ffi (~> 1.0)
rbtree3 (0.6.0)
regexp_parser (1.8.0)
request_store (1.5.0)
@@ -510,6 +516,7 @@ DEPENDENCIES
jquery-ui-rails (= 5.0.5)
kaminari
lhv!
+ listen
minitest (~> 5.14)
money-rails
nokogiri
diff --git a/app/controllers/registrar/bulk_renew_controller.rb b/app/controllers/registrar/bulk_renew_controller.rb
new file mode 100644
index 000000000..8818e416c
--- /dev/null
+++ b/app/controllers/registrar/bulk_renew_controller.rb
@@ -0,0 +1,9 @@
+class Registrar
+ class BulkRenewController < DeppController
+ def index; end
+
+ def new
+ authorize! :manage, :repp
+ end
+ end
+end
diff --git a/app/views/registrar/bulk_change/_api_errors.html.erb b/app/views/registrar/bulk_change/_api_errors.html.erb
new file mode 100644
index 000000000..56bf8c404
--- /dev/null
+++ b/app/views/registrar/bulk_change/_api_errors.html.erb
@@ -0,0 +1,9 @@
+<% if @api_errors %>
+
+
+ <% @api_errors.each do |error| %>
+ - <%= error[:title] %>
+ <% end %>
+
+
+<% end %>
diff --git a/app/views/registrar/bulk_change/_bulk_renew_form.html.erb b/app/views/registrar/bulk_change/_bulk_renew_form.html.erb
new file mode 100644
index 000000000..38134e707
--- /dev/null
+++ b/app/views/registrar/bulk_change/_bulk_renew_form.html.erb
@@ -0,0 +1,22 @@
+<%= form_tag registrar_new_registrar_bulk_renew_path, multipart: true, class: 'form-horizontal' do %>
+ <%= render 'api_errors' %>
+
+
+
+
+
+<% end %>
diff --git a/app/views/registrar/bulk_change/new.html.erb b/app/views/registrar/bulk_change/new.html.erb
index da85899ff..e61270b6d 100644
--- a/app/views/registrar/bulk_change/new.html.erb
+++ b/app/views/registrar/bulk_change/new.html.erb
@@ -19,6 +19,10 @@
<%= t '.bulk_transfer' %>
+
+
+ <%= t '.bulk_renew' %>
+
@@ -34,4 +38,8 @@
<%= render 'bulk_transfer_form' %>
+
+
+ <%= render 'bulk_renew_form' %>
+
diff --git a/config/locales/registrar/bulk_change.en.yml b/config/locales/registrar/bulk_change.en.yml
index 7c1f11da9..d9f932a46 100644
--- a/config/locales/registrar/bulk_change.en.yml
+++ b/config/locales/registrar/bulk_change.en.yml
@@ -6,6 +6,7 @@ en:
technical_contact: Technical contact
nameserver: Nameserver
bulk_transfer: Bulk transfer
+ bulk_renew: Bulk renew
tech_contact_form:
current_contact_id: Current contact ID
@@ -29,3 +30,7 @@ en:
submit_btn: Transfer
help_btn: Toggle help
help: Transfer domains in the csv file with correct transfer code to this registrar
+
+ bulk_renew_form:
+ filter_btn: Filter
+ expire_date: Expire date
diff --git a/config/routes.rb b/config/routes.rb
index 0af3d95c9..2a6930d3f 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -133,6 +133,8 @@ Rails.application.routes.draw do
end
resources :domain_transfers, only: %i[new create]
resource :bulk_change, controller: :bulk_change, only: :new
+ # resource :bulk_renew, controller: :bulk_renew #, only: :index
+ post '/registrar/bulk_renew/new', to: 'bulk_renew#new', as: :new_registrar_bulk_renew
resource :tech_contacts, only: :update
resource :nameservers, only: :update
resources :contacts, constraints: {:id => /[^\/]+(?=#{ ActionController::Renderers::RENDERERS.map{|e| "\\.#{e}\\z"}.join("|") })|[^\/]+/} do
From 9c662471a71671c76a1041a22fba12766f04fdea Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 10 Dec 2020 14:07:07 +0500
Subject: [PATCH 070/106] Fix controller & routes
---
app/controllers/registrar/bulk_change_controller.rb | 7 +++++++
app/controllers/registrar/bulk_renew_controller.rb | 9 ---------
.../registrar/bulk_change/_bulk_renew_form.html.erb | 8 ++++----
config/locales/registrar/bulk_change.en.yml | 2 +-
config/routes.rb | 3 +--
5 files changed, 13 insertions(+), 16 deletions(-)
delete mode 100644 app/controllers/registrar/bulk_renew_controller.rb
diff --git a/app/controllers/registrar/bulk_change_controller.rb b/app/controllers/registrar/bulk_change_controller.rb
index 441127f6c..1d9d606a4 100644
--- a/app/controllers/registrar/bulk_change_controller.rb
+++ b/app/controllers/registrar/bulk_change_controller.rb
@@ -4,9 +4,16 @@ class Registrar
def new
authorize! :manage, :repp
+ @expire_date = Time.zone.now.to_date
render file: 'registrar/bulk_change/new', locals: { active_tab: default_tab }
end
+ def bulk_renew
+ authorize! :manage, :repp
+ @expire_date = params[:expire_date].to_date
+ render file: 'registrar/bulk_change/new', locals: { active_tab: :bulk_renew }
+ end
+
private
def available_contacts
diff --git a/app/controllers/registrar/bulk_renew_controller.rb b/app/controllers/registrar/bulk_renew_controller.rb
deleted file mode 100644
index 8818e416c..000000000
--- a/app/controllers/registrar/bulk_renew_controller.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class Registrar
- class BulkRenewController < DeppController
- def index; end
-
- def new
- authorize! :manage, :repp
- end
- end
-end
diff --git a/app/views/registrar/bulk_change/_bulk_renew_form.html.erb b/app/views/registrar/bulk_change/_bulk_renew_form.html.erb
index 38134e707..4b7cd392b 100644
--- a/app/views/registrar/bulk_change/_bulk_renew_form.html.erb
+++ b/app/views/registrar/bulk_change/_bulk_renew_form.html.erb
@@ -1,14 +1,14 @@
-<%= form_tag registrar_new_registrar_bulk_renew_path, multipart: true, class: 'form-horizontal' do %>
+<%= form_with url: registrar_bulk_renew_path, multipart: true, class: 'form-horizontal' do |f|%>
<%= render 'api_errors' %>
diff --git a/config/locales/registrar/bulk_change.en.yml b/config/locales/registrar/bulk_change.en.yml
index d9f932a46..51e6a8bb3 100644
--- a/config/locales/registrar/bulk_change.en.yml
+++ b/config/locales/registrar/bulk_change.en.yml
@@ -33,4 +33,4 @@ en:
bulk_renew_form:
filter_btn: Filter
- expire_date: Expire date
+ expire_date: Expire date until
diff --git a/config/routes.rb b/config/routes.rb
index 2a6930d3f..7bf1ecd39 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -133,8 +133,7 @@ Rails.application.routes.draw do
end
resources :domain_transfers, only: %i[new create]
resource :bulk_change, controller: :bulk_change, only: :new
- # resource :bulk_renew, controller: :bulk_renew #, only: :index
- post '/registrar/bulk_renew/new', to: 'bulk_renew#new', as: :new_registrar_bulk_renew
+ post '/bulk_renew/new', to: 'bulk_change#bulk_renew', as: :bulk_renew
resource :tech_contacts, only: :update
resource :nameservers, only: :update
resources :contacts, constraints: {:id => /[^\/]+(?=#{ ActionController::Renderers::RENDERERS.map{|e| "\\.#{e}\\z"}.join("|") })|[^\/]+/} do
From 40b22cd433b645c25567c27e440fce93226ba958 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 10 Dec 2020 14:35:04 +0500
Subject: [PATCH 071/106] Add multiple checkboxes to select domains for bulk
renew
---
.../registrar/bulk_change_controller.rb | 10 ++++++++++
.../bulk_change/_bulk_renew_form.html.erb | 17 +++++++++++++++++
config/locales/registrar/bulk_change.en.yml | 1 +
3 files changed, 28 insertions(+)
diff --git a/app/controllers/registrar/bulk_change_controller.rb b/app/controllers/registrar/bulk_change_controller.rb
index 1d9d606a4..358a1949c 100644
--- a/app/controllers/registrar/bulk_change_controller.rb
+++ b/app/controllers/registrar/bulk_change_controller.rb
@@ -11,6 +11,8 @@ class Registrar
def bulk_renew
authorize! :manage, :repp
@expire_date = params[:expire_date].to_date
+ # binding.pry
+ @domains = domains_by_date(@expire_date)
render file: 'registrar/bulk_change/new', locals: { active_tab: :bulk_renew }
end
@@ -23,5 +25,13 @@ class Registrar
def default_tab
:technical_contact
end
+
+ def domains_scope
+ current_registrar_user.registrar.domains
+ end
+
+ def domains_by_date(date)
+ domains_scope.where('valid_to <= ?', date)
+ end
end
end
diff --git a/app/views/registrar/bulk_change/_bulk_renew_form.html.erb b/app/views/registrar/bulk_change/_bulk_renew_form.html.erb
index 4b7cd392b..874dc8eaa 100644
--- a/app/views/registrar/bulk_change/_bulk_renew_form.html.erb
+++ b/app/views/registrar/bulk_change/_bulk_renew_form.html.erb
@@ -12,6 +12,23 @@
+ <% if @domains.present? %>
+
+ <% end %>
+