Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Domeeniga on seotud puudulike kontakti objekte, milles tulenevalt on Eesti Interneti SA blokeerinud domeeni pikendamise ja registripidaja vahetuse, kuniks kontaktandmed korrastatakse. Andmete korrastamiseks ja registreeringu pikendamiseks pöörduge palun oma registripidaja poole.
+
+
<%= @domain.name %> pikendamata jätmisel domeen kustub ja läheb <%= @domain.delete_date %> oksjonile .ee oksjonikeskkonda. Domeenioksjonite kohta loe lähemalt siit.
Dear registrant/administrative contact of .ee domain,
+
+
The domain name <%= @domain.name %> has expired and since <%= @domain.on_hold_date %> is no longer available on the Internet. Domain registration has invalid contact data. Renewal and registrar transfer is therefore prohibited until contact data has been fixed. To correct the data and renew your domain registration, please contact your registrar.
+
+
If you do not renew the <%= @domain.name %> domain registration, it is deleted and put on auction to .ee domain auction environment at <%= @domain.delete_date %>. Read more about .ee domain auctions here.
Срок действия доменного имени <%= @domain.name %> истек, и с <%= @domain.on_hold_date %> оно больше не доступно в интернете. У домена указаны неверные контактные данные. Обновление и перенос к другому регистратору заблокированы до исправления контактных данных. Для исправления контактных данных и обновления регистрации вашего домена, пожалуйста, обратитесь в вашему регистратору.
+
+
Если доменное имя не продлено, домен <%= @domain.name %> будет удален и <%= @domain.delete_date %> идет на аукцион в .ee среду аукциона. О проведении доменных аукционов читайте здесь.
+
+<%= render 'mailers/shared/signatures/signature.ru.html' %>
diff --git a/app/views/mailers/domain_expire_mailer/expired_soft.text.erb b/app/views/mailers/domain_expire_mailer/expired_soft.text.erb
new file mode 100644
index 000000000..0e6d9c953
--- /dev/null
+++ b/app/views/mailers/domain_expire_mailer/expired_soft.text.erb
@@ -0,0 +1,48 @@
+Domeen <%= @domain.name %> on aegunud ning suunatud kustutusmenetlusse kuna oleme tuvastanud domeeniga seotud kontaktides olulisi puudusi.
+
+Lugupeetud .ee domeeni registreerija/halduskontakt
+
+Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Domeeniga on seotud puudulike kontakti objekte, milles tulenevalt on Eesti Interneti SA blokeerinud domeeni pikendamise ja registripidaja vahetuse, kuniks kontaktandmed korrastatakse. Andmete korrastamiseks ja registreeringu pikendamiseks pöörduge palun oma registripidaja poole.
+
+<%= @domain.name %> pikendamata jätmisel domeen kustub ja läheb <%= @domain.delete_date %> oksjonile .ee oksjonikeskkonda. Domeenioksjonite kohta loe lähemalt siit https://www.internet.ee/domeenioksjonid.
+
+Domeeni <%= @domain.name %> registripidaja:
+<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %>
+
+Ülevaate kõikidest endaga seotud domeenidest saate registreerija portaalist https://registrant.internet.ee/registrant/.
+
+<%= render 'mailers/shared/signatures/signature.et.html' %>
+
+--------------------------------------
+
+Domain <%= @domain.name %> has expired
+
+Dear registrant/administrative contact of .ee domain,
+
+The domain name <%= @domain.name %> has expired and since <%= @domain.on_hold_date %> is no longer available on the Internet. Domain registration has invalid contact data. Renewal and registrar transfer is therefore prohibited until contact data has been fixed. To correct the data and renew your domain registration, please contact your registrar.
+
+If you do not renew the <%= @domain.name %> domain registration, it is deleted and put on auction to .ee domain auction environment at <%= @domain.delete_date %>. Read more about .ee domain auctions here https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment.
+
+Registrar of the <%= @domain.name %>:
+<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %>
+
+You can find an overview of all your domains at the registrant's portal https://registrant.internet.ee/registrant/.
+
+<%= render 'mailers/shared/signatures/signature.en.html' %>
+
+--------------------------------------
+
+Срок действия домена <%= @domain.name %> истек
+
+Уважаемый регистрант/административный контакт домена .ee
+
+Срок действия доменного имени <%= @domain.name %> истек, и с <%= @domain.on_hold_date %> оно больше не доступно в интернете. У домена указаны неверные контактные данные. Обновление и перенос к другому регистратору заблокированы до исправления контактных данных. Для исправления контактных данных и обновления регистрации вашего домена, пожалуйста, обратитесь в вашему регистратору.
+
+Если доменное имя не продлено, домен <%= @domain.name %> будет удален и <%= @domain.delete_date %> идет на аукцион в .ee среду аукциона. О проведении доменных аукционов читайте здесь https://www.internet.ee/domeny/dogovor-pol-zovatelya-aukcionnoj-sredy#3-usloviya-uchastiya-v-aukcione.
+
+Pегистратор домена <%= @domain.name %>:
+<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>
+
+Обзор всех связанных с вами доменов можете получить на портале регистратора https://registrant.internet.ee/registrant/.
+
+<%= render 'mailers/shared/signatures/signature.ru.html' %>
diff --git a/test/mailers/domain_expire_mailer_test.rb b/test/mailers/domain_expire_mailer_test.rb
index 1502bf2f6..9209652fd 100644
--- a/test/mailers/domain_expire_mailer_test.rb
+++ b/test/mailers/domain_expire_mailer_test.rb
@@ -11,4 +11,13 @@ class DomainExpireMailerTest < ActionMailer::TestCase
assert_equal 'Domeen shop.test on aegunud / Domain shop.test has expired' \
' / Срок действия домена shop.test истек', email.subject
end
-end
\ No newline at end of file
+
+ def test_delivers_domain_expiration_soft_email
+ domain = domains(:shop)
+ assert_equal 'shop.test', domain.name
+
+ DomainExpireMailer.expired_soft(domain: domain, registrar: domain.registrar).deliver_now
+
+ assert_emails 1
+ end
+end
diff --git a/test/mailers/previews/domain_expire_mailer_preview.rb b/test/mailers/previews/domain_expire_mailer_preview.rb
index bec206c0f..4d66d2fad 100644
--- a/test/mailers/previews/domain_expire_mailer_preview.rb
+++ b/test/mailers/previews/domain_expire_mailer_preview.rb
@@ -4,4 +4,10 @@ class DomainExpireMailerPreview < ActionMailer::Preview
DomainExpireMailer.expired(domain: domain,
registrar: domain.registrar)
end
-end
\ No newline at end of file
+
+ def expired_soft
+ domain = Domain.first
+ DomainExpireMailer.expired_soft(domain: domain,
+ registrar: domain.registrar)
+ end
+end
From 344da76dc64904ea103bf99966e5fdaa0381cffd Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 5 Nov 2020 11:22:25 +0500
Subject: [PATCH 086/172] Fix email subject
---
app/mailers/domain_expire_mailer.rb | 6 +++---
config/locales/mailers/domain_expire.en.yml | 7 ++++++-
test/mailers/domain_expire_mailer_test.rb | 8 +++++---
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/app/mailers/domain_expire_mailer.rb b/app/mailers/domain_expire_mailer.rb
index e73b1fa84..229120825 100644
--- a/app/mailers/domain_expire_mailer.rb
+++ b/app/mailers/domain_expire_mailer.rb
@@ -17,7 +17,7 @@ class DomainExpireMailer < ApplicationMailer
logger.info("Send DomainExpireMailer##{method_name} email for #{domain.name} (##{domain.id})" \
" to #{recipient(domain).join(', ')}")
- mail(to: recipient(domain), subject: subject)
+ mail(to: recipient(domain), subject: subject(method_name))
end
def init(domain, registrar)
@@ -29,8 +29,8 @@ class DomainExpireMailer < ApplicationMailer
filter_invalid_emails(emails: domain.primary_contact_emails, domain: @domain)
end
- def subject
- default_i18n_subject(domain_name: @domain.name)
+ def subject(method_name)
+ I18n.t("domain_expire_mailer.#{method_name}.subject", domain_name: @domain.name)
end
def domain_presenter(domain:)
diff --git a/config/locales/mailers/domain_expire.en.yml b/config/locales/mailers/domain_expire.en.yml
index 9a83a7a32..36353a44e 100644
--- a/config/locales/mailers/domain_expire.en.yml
+++ b/config/locales/mailers/domain_expire.en.yml
@@ -4,4 +4,9 @@ en:
subject: >-
Domeen %{domain_name} on aegunud
/ Domain %{domain_name} has expired
- / Срок действия домена %{domain_name} истек
\ No newline at end of file
+ / Срок действия домена %{domain_name} истек
+ expired_soft:
+ subject: >-
+ Domeen %{domain_name} on aegunud ning suunatud kustutusmenetlusse
+ / Domain %{domain_name} has expired and directed into deletion process
+ / Срок действия домена %{domain_name} истек
diff --git a/test/mailers/domain_expire_mailer_test.rb b/test/mailers/domain_expire_mailer_test.rb
index 9209652fd..84e520b78 100644
--- a/test/mailers/domain_expire_mailer_test.rb
+++ b/test/mailers/domain_expire_mailer_test.rb
@@ -8,16 +8,18 @@ class DomainExpireMailerTest < ActionMailer::TestCase
email = DomainExpireMailer.expired(domain: domain, registrar: domain.registrar).deliver_now
assert_emails 1
- assert_equal 'Domeen shop.test on aegunud / Domain shop.test has expired' \
- ' / Срок действия домена shop.test истек', email.subject
+ assert_equal I18n.t("domain_expire_mailer.expired.subject", domain_name: domain.name),
+ email.subject
end
def test_delivers_domain_expiration_soft_email
domain = domains(:shop)
assert_equal 'shop.test', domain.name
- DomainExpireMailer.expired_soft(domain: domain, registrar: domain.registrar).deliver_now
+ email = DomainExpireMailer.expired_soft(domain: domain, registrar: domain.registrar).deliver_now
assert_emails 1
+ assert_equal I18n.t("domain_expire_mailer.expired_soft.subject", domain_name: domain.name),
+ email.subject
end
end
From ee49ffea0271dd0f302fd1673331714aa0d37f74 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 5 Nov 2020 11:02:26 +0500
Subject: [PATCH 087/172] First version of invalid email template on FD
---
.../forced/invalid_email.html.erb | 45 +++++++++++++++++++
1 file changed, 45 insertions(+)
create mode 100644 app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb
diff --git a/app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb b/app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb
new file mode 100644
index 000000000..2dec52905
--- /dev/null
+++ b/app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb
@@ -0,0 +1,45 @@
+
Eesti Interneti Sihtasutusele on saanud teatavaks, et juriidiline isik registrikoodiga <%= @registrant.reg_no %> on äriregistrist kustutatud.
+
+
Kuna äriregistrist kustutatud juriidiline isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes <%= @delete_period_length %> päevane kustutusmenetlus. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.
+
+
Domeeni suhtes õigust omaval isikul on võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus koos seda tõendava dokumendiga.
+
+
Kui üleandmine ei ole <%= @delete_period_length %> päeva jooksul toimunud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.
+
+
Lisaküsimuste korral võtke palun ühendust oma registripidajaga:
Dear registrant/administrative contact of .ee domain,
+
+
Estonian Internet Foundation has learned that contact data of the domain <%= @domain.name %> s invalid - email.
+
+
Since this is a violation of Estonian domain regulations, <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.
+
+
Please, contact your registrar <%= @registrar.name %> with updated contact data, otherwise in <%= @delete_period_length %> days the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction portal. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results.
+
+
Should you have additional questions, please contact your registrar:
Целевому учреждению Eesti Internet (EIS) стало известно, что юридическое лицо с регистрационным кодом <%= @registrant.reg_no %> удалено из коммерческого реестра.
+
+
Поскольку удаленное из коммерческого регистра юридическое лицо не может являться регистрантом домена, начат <%= @delete_period_length %>-дневный процесс удаления домена <%= @domain.name %>. Домен доступен в интернете на протяжении <%= @expire_warning_period %> дней после начала процесса удаления.
+
+
Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче домена, представив вместе с ходатайством подтверждающие документы. Документы должны быть представлены регистратору в течение <%= @delete_period_length %> дней.
+
+
Если передача не состоится в течение <%= @delete_period_length %> дней, <%= @domain.force_delete_date %> домен <%= @domain.name %> отправится на доменный аукцион в аукционной среде .ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». Читайте о других возможных результатах аукциона.
+
+
В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором:
+ <%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>
Eesti Interneti Sihtasutusele on saanud teatavaks, et juriidiline isik registrikoodiga <%= @registrant.reg_no %> on äriregistrist kustutatud.
+
Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et domeeni <%= @domain.name %> kontaktandmed on puudulikud - eposti aadress <%= @domain.contact_emails_verification_failed %>
-
Kuna äriregistrist kustutatud juriidiline isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes <%= @delete_period_length %> päevane kustutusmenetlus. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.
+
Et see olukord on vastuolus .ee domeenireeglitega algatas EIS <%= @delete_period_length %> päeva pikkuse kustutusmenetluse. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.
-
Domeeni suhtes õigust omaval isikul on võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus koos seda tõendava dokumendiga.
+
Andmete parandamiseks pöörduge palun oma registripidaja <%= @registrar.name %> poole või isiklike ja oma ettevõtte andmete puhul registreerija portaali.
-
Kui üleandmine ei ole <%= @delete_period_length %> päeva jooksul toimunud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.
+
Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.
Lisaküsimuste korral võtke palun ühendust oma registripidajaga:
Dear registrant/administrative contact of .ee domain,
-
Estonian Internet Foundation has learned that contact data of the domain <%= @domain.name %> s invalid - email.
+
Estonian Internet Foundation has learned that contact data of the domain <%= @domain.name %> s invalid - email(s) <%= @domain.contact_emails_verification_failed %>.
Since this is a violation of Estonian domain regulations, <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.
-
Please, contact your registrar <%= @registrar.name %> with updated contact data, otherwise in <%= @delete_period_length %> days the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction portal. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results.
+
Please, contact your registrar <%= @registrar.name %> with updated contact data, or in case of your personal or business data use .ee portal for registrants
+
+
If the data is not fixed within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction environment. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results here.
Should you have additional questions, please contact your registrar:
Целевому учреждению Eesti Internet (EIS) стало известно, что юридическое лицо с регистрационным кодом <%= @registrant.reg_no %> удалено из коммерческого реестра.
+
Целевому учреждению Eesti Internet (EIS) стало известно, что контактные данные домена <%= @registrant.reg_no %> неверны - электронная почта <%= @domain.contact_emails_verification_failed %>.
-
Поскольку удаленное из коммерческого регистра юридическое лицо не может являться регистрантом домена, начат <%= @delete_period_length %>-дневный процесс удаления домена <%= @domain.name %>. Домен доступен в интернете на протяжении <%= @expire_warning_period %> дней после начала процесса удаления.
+
Так как это является нарушением Правил домена .ee, <%= @delete_period_length %>-дневный процесс удаления начат для доменного имени <%= @domain.name %>. В течение первых <%= @expire_warning_period %> дней домен будет доступен в интернете.
-
Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче домена, представив вместе с ходатайством подтверждающие документы. Документы должны быть представлены регистратору в течение <%= @delete_period_length %> дней.
+
Для уточнения контактных данных, пожалуйста, свяжитесь с регистратором <%= @registrar.name %>, либо воспользуйтесь порталом для регистрантов
-
Если передача не состоится в течение <%= @delete_period_length %> дней, <%= @domain.force_delete_date %> домен <%= @domain.name %> отправится на доменный аукцион в аукционной среде .ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». Читайте о других возможных результатах аукциона.
+
Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в аукционной среде.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте здесь.
В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором:
- <%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>
Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et domeeni <%= @domain.name %> kontaktandmed on puudulikud - eposti aadress <%= @domain.contact_emails_verification_failed %>
+
+
Et see olukord on vastuolus .ee domeenireeglitega algatas EIS <%= @delete_period_length %> päeva pikkuse kustutusmenetluse. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.
+
+
Andmete parandamiseks pöörduge palun oma registripidaja <%= @registrar.name %> poole või isiklike ja oma ettevõtte andmete puhul registreerija portaali.
+
+
Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.
+
+
Lisaküsimuste korral võtke palun ühendust oma registripidajaga:
Dear registrant/administrative contact of .ee domain,
+
+
Estonian Internet Foundation has learned that contact data of the domain <%= @domain.name %> s invalid - email(s) <%= @domain.contact_emails_verification_failed %>.
+
+
Since this is a violation of Estonian domain regulations, <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.
+
+
Please, contact your registrar <%= @registrar.name %> with updated contact data, or in case of your personal or business data use .ee portal for registrants
+
+
If the data is not fixed within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction environment. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results here.
+
+
Should you have additional questions, please contact your registrar:
Целевому учреждению Eesti Internet (EIS) стало известно, что контактные данные домена <%= @registrant.reg_no %> неверны - электронная почта <%= @domain.contact_emails_verification_failed %>.
+
+
Так как это является нарушением Правил домена .ee, <%= @delete_period_length %>-дневный процесс удаления начат для доменного имени <%= @domain.name %>. В течение первых <%= @expire_warning_period %> дней домен будет доступен в интернете.
+
+
Для уточнения контактных данных, пожалуйста, свяжитесь с регистратором <%= @registrar.name %>, либо воспользуйтесь порталом для регистрантов
+
+
Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в аукционной среде.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте здесь.
+
+
В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором:
+ <%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>
+
+<%= render 'mailers/shared/signatures/signature.ru.html' %>
From 0116531786704f9ccf6f4402bf1c108a4d05e072 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 5 Nov 2020 12:45:59 +0500
Subject: [PATCH 089/172] Fix existing tests
---
app/controllers/admin/domains_controller.rb | 5 -----
app/mailers/domain_delete_mailer.rb | 4 ----
app/models/concerns/domain/force_delete.rb | 8 +++++++-
test/mailers/domain_delete_mailer_test.rb | 7 +------
4 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/app/controllers/admin/domains_controller.rb b/app/controllers/admin/domains_controller.rb
index 2b94607c5..4a8e5961e 100644
--- a/app/controllers/admin/domains_controller.rb
+++ b/app/controllers/admin/domains_controller.rb
@@ -2,7 +2,6 @@ module Admin
class DomainsController < BaseController
before_action :set_domain, only: %i[show edit update keep]
authorize_resource
- helper_method :force_delete_templates
def index
params[:q] ||= {}
@@ -105,9 +104,5 @@ module Admin
params[:q][:valid_to_lteq] = ca_cache
end
-
- def force_delete_templates
- DomainDeleteMailer.force_delete_templates
- end
end
end
diff --git a/app/mailers/domain_delete_mailer.rb b/app/mailers/domain_delete_mailer.rb
index 1f08204bf..dbacab68d 100644
--- a/app/mailers/domain_delete_mailer.rb
+++ b/app/mailers/domain_delete_mailer.rb
@@ -1,8 +1,4 @@
class DomainDeleteMailer < ApplicationMailer
- def self.force_delete_templates
- %w[private_person legal_person]
- end
-
def confirmation_request(domain:, registrar:, registrant:)
@domain = DomainPresenter.new(domain: domain, view: view_context)
@registrar = RegistrarPresenter.new(registrar: registrar, view: view_context)
diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index 78248db80..729a7515b 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -20,7 +20,13 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def notification_template
- registrant.org? ? 'legal_person' : 'private_person'
+ if contact_emails_verification_failed.present?
+ 'invalid_email'
+ elsif registrant.org?
+ 'legal_person'
+ else
+ 'private_person'
+ end
end
def force_delete_scheduled?
diff --git a/test/mailers/domain_delete_mailer_test.rb b/test/mailers/domain_delete_mailer_test.rb
index b65ba5d2e..8e568846c 100644
--- a/test/mailers/domain_delete_mailer_test.rb
+++ b/test/mailers/domain_delete_mailer_test.rb
@@ -5,10 +5,6 @@ class DomainDeleteMailerTest < ActionMailer::TestCase
@domain = domains(:shop)
end
- def test_force_delete_templates
- assert_equal %w[private_person legal_person], DomainDeleteMailer.force_delete_templates
- end
-
def test_delivers_confirmation_request_email
assert_equal 'shop.test', @domain.name
assert_equal 'john@inbox.test', @domain.registrant.email
@@ -68,8 +64,7 @@ class DomainDeleteMailerTest < ActionMailer::TestCase
email = DomainDeleteMailer.forced(domain: @domain,
registrar: @domain.registrar,
registrant: @domain.registrant,
- template_name: DomainDeleteMailer.force_delete_templates
- .first).deliver_now
+ template_name: @domain.notification_template).deliver_now
assert_emails 1
assert_equal ['legal@registry.test'], email.from
From 6a4bb6079d03dee21020102a157c7cf3aedcb946 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 5 Nov 2020 13:32:45 +0500
Subject: [PATCH 090/172] Add tests
---
app/models/concerns/domain/force_delete.rb | 2 +-
app/models/concerns/email_verifable.rb | 2 +-
.../previews/domain_delete_mailer_preview.rb | 4 +--
.../admin_area/domains/force_delete_test.rb | 26 +++++++++++++------
4 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index 729a7515b..670e5db67 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -22,7 +22,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
def notification_template
if contact_emails_verification_failed.present?
'invalid_email'
- elsif registrant.org?
+ elsif registrant.org?
'legal_person'
else
'private_person'
diff --git a/app/models/concerns/email_verifable.rb b/app/models/concerns/email_verifable.rb
index 2168a0754..d0bb6aecb 100644
--- a/app/models/concerns/email_verifable.rb
+++ b/app/models/concerns/email_verifable.rb
@@ -16,7 +16,7 @@ module Concerns
end
def email_verification_failed?
- email_verification.failed?
+ email_verification&.failed?
end
class_methods do
diff --git a/test/mailers/previews/domain_delete_mailer_preview.rb b/test/mailers/previews/domain_delete_mailer_preview.rb
index 916b0af0e..9dd7ae7b2 100644
--- a/test/mailers/previews/domain_delete_mailer_preview.rb
+++ b/test/mailers/previews/domain_delete_mailer_preview.rb
@@ -1,6 +1,6 @@
class DomainDeleteMailerPreview < ActionMailer::Preview
def self.define_forced_templates
- DomainDeleteMailer.force_delete_templates.each do |template_name|
+ %w[private_person legal_person invalid_email].each do |template_name|
define_method "forced_#{template_name}".to_sym do
DomainDeleteMailer.forced(domain: @domain,
registrar: @domain.registrar,
@@ -34,4 +34,4 @@ class DomainDeleteMailerPreview < ActionMailer::Preview
def expired
DomainDeleteMailer.expired(@domain)
end
-end
\ No newline at end of file
+end
diff --git a/test/system/admin_area/domains/force_delete_test.rb b/test/system/admin_area/domains/force_delete_test.rb
index 6aa53be6c..e17695fcc 100644
--- a/test/system/admin_area/domains/force_delete_test.rb
+++ b/test/system/admin_area/domains/force_delete_test.rb
@@ -44,7 +44,7 @@ class AdminAreaDomainForceDeleteTest < ApplicationSystemTestCase
end
@domain.reload
- assert_equal template_name, @domain.template_name
+ assert_equal @domain.notification_template, @domain.template_name
end
def test_uses_legal_template_if_registrant_org
@@ -57,7 +57,23 @@ class AdminAreaDomainForceDeleteTest < ApplicationSystemTestCase
end
@domain.reload
- assert_equal template_name, @domain.template_name
+ assert_equal @domain.notification_template, @domain.template_name
+ end
+
+ def test_uses_legal_template_if_invalid_email
+ verification = @domain.contacts.first.email_verification
+ verification.update(verified_at: Time.zone.now - 1.day, success: false)
+
+ assert_equal @domain.notification_template, 'invalid_email'
+
+ assert_emails 0 do
+ visit edit_admin_domain_url(@domain)
+ find(:css, '#soft_delete').set(true)
+ click_link_or_button 'Force delete domain'
+ end
+
+ @domain.reload
+ assert_equal @domain.notification_template, @domain.template_name
end
def test_allows_to_skip_notifying_registrant_and_admin_contacts_by_email
@@ -87,10 +103,4 @@ class AdminAreaDomainForceDeleteTest < ApplicationSystemTestCase
assert_no_button 'Schedule force delete'
assert_no_link 'Schedule force delete'
end
-
- private
-
- def template_name
- @domain.registrant.org? ? 'legal_person' : 'private_person'
- end
end
From e8c2f33e2d6ca13be7fe91dff6ea313ca949a906 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Thu, 5 Nov 2020 14:12:10 +0500
Subject: [PATCH 091/172] Add presenter method & preview
---
app/presenters/domain_presenter.rb | 4 +++
.../forced/invalid_email.html.erb | 2 +-
.../previews/domain_delete_mailer_preview.rb | 28 +++++++++----------
3 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/app/presenters/domain_presenter.rb b/app/presenters/domain_presenter.rb
index 0915722b1..bcbd5d600 100644
--- a/app/presenters/domain_presenter.rb
+++ b/app/presenters/domain_presenter.rb
@@ -52,6 +52,10 @@ class DomainPresenter
end
end
+ def contact_emails_verification_failed
+ domain.contact_emails_verification_failed.join(', ')
+ end
+
def remove_registry_lock_btn
return unless domain.locked_by_registrant?
diff --git a/app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb b/app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb
index 9e69519e4..817538afd 100644
--- a/app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb
+++ b/app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb
@@ -1,6 +1,6 @@
Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et domeeni <%= @domain.name %> kontaktandmed on puudulikud - eposti aadress <%= @domain.contact_emails_verification_failed %>
+
Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et domeeni <%= @domain.name %> kontaktandmed on puudulikud - eposti aadress <%= @domain.contact_emails_verification_failed %>.
Et see olukord on vastuolus .ee domeenireeglitega algatas EIS <%= @delete_period_length %> päeva pikkuse kustutusmenetluse. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.
diff --git a/test/mailers/previews/domain_delete_mailer_preview.rb b/test/mailers/previews/domain_delete_mailer_preview.rb
index 9dd7ae7b2..fa0d9c6b7 100644
--- a/test/mailers/previews/domain_delete_mailer_preview.rb
+++ b/test/mailers/previews/domain_delete_mailer_preview.rb
@@ -2,9 +2,10 @@ class DomainDeleteMailerPreview < ActionMailer::Preview
def self.define_forced_templates
%w[private_person legal_person invalid_email].each do |template_name|
define_method "forced_#{template_name}".to_sym do
- DomainDeleteMailer.forced(domain: @domain,
- registrar: @domain.registrar,
- registrant: @domain.registrant,
+ domain = Domain.first
+ DomainDeleteMailer.forced(domain: domain,
+ registrar: domain.registrar,
+ registrant: domain.registrant,
template_name: template_name)
end
end
@@ -12,26 +13,25 @@ class DomainDeleteMailerPreview < ActionMailer::Preview
define_forced_templates
- def initialize
- @domain = Domain.first
- super
- end
-
def confirmation_request
- DomainDeleteMailer.confirmation_request(domain: @domain,
- registrar: @domain.registrar,
- registrant: @domain.registrant)
+ domain = Domain.first
+ DomainDeleteMailer.confirmation_request(domain: domain,
+ registrar: domain.registrar,
+ registrant: domain.registrant)
end
def accepted
- DomainDeleteMailer.accepted(@domain)
+ domain = Domain.first
+ DomainDeleteMailer.accepted(domain)
end
def rejected
- DomainDeleteMailer.rejected(@domain)
+ domain = Domain.first
+ DomainDeleteMailer.rejected(domain)
end
def expired
- DomainDeleteMailer.expired(@domain)
+ domain = Domain.first
+ DomainDeleteMailer.expired(domain)
end
end
From 28bede030cd5c255f01789355304b1c439e61d48 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Thu, 5 Nov 2020 12:13:18 +0200
Subject: [PATCH 092/172] Update CHANGELOG.md
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6721791d2..f7156ef51 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+05.11.2020
+* New email template for expired domains in forceDelete [#1725](https://github.com/internetee/registry/issues/1725)
+
04.11.2020
* Email notification templates for forceDelete are now automatically selected according to registrant type [#442](https://github.com/internetee/registry/issues/442)
From 9a491924f8a0a5f19a7c87726c8552446651ad83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Thu, 5 Nov 2020 12:51:51 +0200
Subject: [PATCH 093/172] Update CHANGELOG.md
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f7156ef51..ee8bea7bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
05.11.2020
* New email template for expired domains in forceDelete [#1725](https://github.com/internetee/registry/issues/1725)
+* Cancelling forceDelete (FD) restores the state of the domain prior application of FD [#1136](https://github.com/internetee/registry/issues/1136)
04.11.2020
* Email notification templates for forceDelete are now automatically selected according to registrant type [#442](https://github.com/internetee/registry/issues/442)
From ed7181e0608aeafc600361b343f896c4e101c946 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Thu, 5 Nov 2020 14:54:54 +0200
Subject: [PATCH 094/172] Update CHANGELOG.md
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee8bea7bf..3dd2483f2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,5 @@
05.11.2020
+* Registrant API contact name update feature [#1724](https://github.com/internetee/registry/issues/1724)
* New email template for expired domains in forceDelete [#1725](https://github.com/internetee/registry/issues/1725)
* Cancelling forceDelete (FD) restores the state of the domain prior application of FD [#1136](https://github.com/internetee/registry/issues/1136)
From 451e1f79afc8f2a5c7ffcecc34e71c6b525575ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Fri, 6 Nov 2020 15:51:03 +0200
Subject: [PATCH 095/172] nameserver replacement: scope only to selected
domains
---
app/api/repp/nameservers_v1.rb | 5 ++++-
app/controllers/registrar/nameservers_controller.rb | 12 ++++++++++++
app/models/registrar.rb | 4 +++-
.../registrar/bulk_change/_nameserver_form.html.erb | 12 +++++++++++-
4 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/app/api/repp/nameservers_v1.rb b/app/api/repp/nameservers_v1.rb
index 04d7d4f6a..493665b54 100644
--- a/app/api/repp/nameservers_v1.rb
+++ b/app/api/repp/nameservers_v1.rb
@@ -8,6 +8,7 @@ module Repp
requires :data, type: Hash, allow_blank: false do
requires :type, type: String, allow_blank: false
requires :id, type: String, allow_blank: false
+ optional :domains, type: Array
requires :attributes, type: Hash, allow_blank: false do
requires :hostname, type: String, allow_blank: false
requires :ipv4, type: Array
@@ -28,8 +29,10 @@ module Repp
ipv6: params[:data][:attributes][:ipv6],
}
+ domains = params[:data][:domains] || []
+
begin
- affected_domains = current_user.registrar.replace_nameservers(hostname, new_attributes)
+ affected_domains = current_user.registrar.replace_nameservers(hostname, new_attributes, domains)
rescue ActiveRecord::RecordInvalid => e
error!({ errors: e.record.errors.full_messages.map { |error| { title: error } } }, 400)
end
diff --git a/app/controllers/registrar/nameservers_controller.rb b/app/controllers/registrar/nameservers_controller.rb
index 95da7e329..a266aaa2b 100644
--- a/app/controllers/registrar/nameservers_controller.rb
+++ b/app/controllers/registrar/nameservers_controller.rb
@@ -6,9 +6,13 @@ class Registrar
ipv4 = params[:ipv4].split("\r\n")
ipv6 = params[:ipv6].split("\r\n")
+ domains = domain_list_from_csv
+
+ puts "Domains are #{domains}"
uri = URI.parse("#{ENV['repp_url']}registrar/nameservers")
request = Net::HTTP::Put.new(uri, 'Content-Type' => 'application/json')
request.body = { data: { type: 'nameserver', id: params[:old_hostname],
+ domains: domains,
attributes: { hostname: params[:new_hostname],
ipv4: ipv4,
ipv6: ipv6 } } }.to_json
@@ -55,5 +59,13 @@ class Registrar
render file: 'registrar/bulk_change/new', locals: { active_tab: :nameserver }
end
end
+
+ def domain_list_from_csv
+ return [] if params[:batch_file].blank?
+
+ domains = []
+ CSV.read(params[:batch_file].path, headers: true).each { |b| domains << b['domain_name'] }
+ domains
+ end
end
end
diff --git a/app/models/registrar.rb b/app/models/registrar.rb
index e2ffcbfd4..e1fb693ff 100644
--- a/app/models/registrar.rb
+++ b/app/models/registrar.rb
@@ -141,11 +141,13 @@ class Registrar < ApplicationRecord
end
# Audit log is needed, therefore no raw SQL
- def replace_nameservers(hostname, new_attributes)
+ def replace_nameservers(hostname, new_attributes, domains)
transaction do
domain_list = []
nameservers.where(hostname: hostname).find_each do |original_nameserver|
+ next unless domains.include?(original_nameserver.domain.name_puny) || domains.empty?
+
new_nameserver = Nameserver.new
new_nameserver.domain = original_nameserver.domain
new_nameserver.attributes = new_attributes
diff --git a/app/views/registrar/bulk_change/_nameserver_form.html.erb b/app/views/registrar/bulk_change/_nameserver_form.html.erb
index e3f4a0214..491786df7 100644
--- a/app/views/registrar/bulk_change/_nameserver_form.html.erb
+++ b/app/views/registrar/bulk_change/_nameserver_form.html.erb
@@ -1,4 +1,4 @@
-<%= form_tag registrar_nameservers_path, method: :patch, class: 'form-horizontal' do %>
+<%= form_tag registrar_nameservers_path, multipart: true, method: :patch, class: 'form-horizontal' do %>
<%= render 'registrar/domain_transfers/form/api_errors' %>
@@ -44,6 +44,16 @@
+
+
+ <%= label_tag 'List of domains' %>
+
+
+ <%= file_field_tag :batch_file, required: false, accept: 'text/csv' %>
+ CSV format, must have domain_name field. List of domains that nameserver change should be scoped to.
+
+
+
- <%= file_field_tag :batch_file, required: false, accept: 'text/csv' %>
+ <%= file_field_tag :puny_file, required: false, accept: 'text/csv' %>
CSV format, must have domain_name field. List of domains that nameserver change should be scoped to.
diff --git a/test/system/registrar_area/bulk_change/nameserver_test.rb b/test/system/registrar_area/bulk_change/nameserver_test.rb
index d6b3170d5..3d4b4dc70 100644
--- a/test/system/registrar_area/bulk_change/nameserver_test.rb
+++ b/test/system/registrar_area/bulk_change/nameserver_test.rb
@@ -8,6 +8,7 @@ class RegistrarAreaNameserverBulkChangeTest < ApplicationSystemTestCase
def test_replaces_current_registrar_nameservers
request_body = { data: { type: 'nameserver',
id: 'ns1.bestnames.test',
+ domains: [],
attributes: { hostname: 'new-ns.bestnames.test',
ipv4: %w[192.0.2.55 192.0.2.56],
ipv6: %w[2001:db8::55 2001:db8::56] } } }
From 0570e4352f2cc5095f349c2f0f1308aa46c0f7c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Fri, 6 Nov 2020 17:51:18 +0200
Subject: [PATCH 098/172] Update CHANGELOG.md
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 72be40d5a..21f710645 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,5 @@
06.11.2020
+* Csv option to limit list of domains for bulk nameserver change in registrar portal [#1737](https://github.com/internetee/registry/issues/1737)
* New forceDelete email template for invalid contact data [#1178](https://github.com/internetee/registry/issues/1178)
05.11.2020
From 4b980a07f52a7f785a74facdf97211d07657dab9 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 9 Nov 2020 17:26:07 +0500
Subject: [PATCH 099/172] Add basic interactor/organizer support
---
Gemfile | 2 ++
Gemfile.lock | 6 ++++
app/interactors/domain/force_delete/base.rb | 16 +++++++++
.../domain/force_delete/check_discarded.rb | 14 ++++++++
.../domain/force_delete/post_set_process.rb | 21 +++++++++++
.../domain/force_delete/prepare_domain.rb | 14 ++++++++
.../domain/force_delete/set_status.rb | 36 +++++++++++++++++++
app/models/concerns/domain/force_delete.rb | 4 +++
8 files changed, 113 insertions(+)
create mode 100644 app/interactors/domain/force_delete/base.rb
create mode 100644 app/interactors/domain/force_delete/check_discarded.rb
create mode 100644 app/interactors/domain/force_delete/post_set_process.rb
create mode 100644 app/interactors/domain/force_delete/prepare_domain.rb
create mode 100644 app/interactors/domain/force_delete/set_status.rb
diff --git a/Gemfile b/Gemfile
index 25c3eafff..c4f5a7cf8 100644
--- a/Gemfile
+++ b/Gemfile
@@ -2,6 +2,8 @@ source 'https://rubygems.org'
# core
gem 'bootsnap', '>= 1.1.0', require: false
+gem 'interactor', '~> 3.0'
+gem 'interactor-rails', '~> 2.0'
gem 'iso8601', '0.12.1' # for dates and times
gem 'rails', '~> 6.0'
gem 'rest-client'
diff --git a/Gemfile.lock b/Gemfile.lock
index c628257a2..cc59a8f41 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -251,6 +251,10 @@ GEM
i18n (1.8.5)
concurrent-ruby (~> 1.0)
i18n_data (0.10.0)
+ interactor (3.1.2)
+ interactor-rails (2.2.1)
+ interactor (~> 3.0)
+ rails (>= 4.2)
isikukood (0.1.2)
iso8601 (0.12.1)
jquery-rails (4.4.0)
@@ -544,6 +548,8 @@ DEPENDENCIES
figaro (= 1.1.1)
grape
haml (~> 5.0)
+ interactor (~> 3.0)
+ interactor-rails (~> 2.0)
isikukood
iso8601 (= 0.12.1)
jquery-rails
diff --git a/app/interactors/domain/force_delete/base.rb b/app/interactors/domain/force_delete/base.rb
new file mode 100644
index 000000000..79de3cf2f
--- /dev/null
+++ b/app/interactors/domain/force_delete/base.rb
@@ -0,0 +1,16 @@
+class Domain
+ module ForceDelete
+ class Base
+ include Interactor::Organizer
+
+ # As per https://github.com/collectiveidea/interactor#organizers
+
+ organize Domain::ForceDelete::CheckDiscarded,
+ Domain::ForceDelete::PrepareDomain,
+ Domain::ForceDelete::SetStatus,
+ Domain::ForceDelete::PostSetProcess,
+ Domain::ForceDelete::NotifyRegistrar,
+ Domain::ForceDelete::NotifyByEmail
+ end
+ end
+end
diff --git a/app/interactors/domain/force_delete/check_discarded.rb b/app/interactors/domain/force_delete/check_discarded.rb
new file mode 100644
index 000000000..a13c16778
--- /dev/null
+++ b/app/interactors/domain/force_delete/check_discarded.rb
@@ -0,0 +1,14 @@
+class Domain
+ module ForceDelete
+ class CheckDiscarded
+ include Interactor
+
+ def call
+ return unless context.domain.discarded?
+
+ raise StandardError,
+ 'Force delete procedure cannot be scheduled while a domain is discarded'
+ end
+ end
+ end
+end
diff --git a/app/interactors/domain/force_delete/post_set_process.rb b/app/interactors/domain/force_delete/post_set_process.rb
new file mode 100644
index 000000000..a2fc531b2
--- /dev/null
+++ b/app/interactors/domain/force_delete/post_set_process.rb
@@ -0,0 +1,21 @@
+class Domain
+ module ForceDelete
+ class PostSetProcess
+ include Interactor
+
+ def call
+ statuses = context.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)
+ context.domain.save(validate: false)
+ end
+ end
+ end
+end
diff --git a/app/interactors/domain/force_delete/prepare_domain.rb b/app/interactors/domain/force_delete/prepare_domain.rb
new file mode 100644
index 000000000..4b3b83064
--- /dev/null
+++ b/app/interactors/domain/force_delete/prepare_domain.rb
@@ -0,0 +1,14 @@
+class Domain
+ module ForceDelete
+ class PrepareDomain
+ include Interactor
+
+ def call
+ domain = context.domain
+ domain.statuses_before_force_delete = domain.statuses
+ domain.statuses |= domain.class.STATUSES_TO_SET
+ domain.save(validate: false)
+ end
+ end
+ end
+end
diff --git a/app/interactors/domain/force_delete/set_status.rb b/app/interactors/domain/force_delete/set_status.rb
new file mode 100644
index 000000000..7ce481623
--- /dev/null
+++ b/app/interactors/domain/force_delete/set_status.rb
@@ -0,0 +1,36 @@
+class Domain
+ module ForceDelete
+ class SetStatus
+ include Interactor
+
+ def call
+ domain.force_delete_type = context.type
+ context.type == :fast_track ? force_delete_fast_track : force_delete_soft
+ domain.save(validate: false)
+ end
+
+ private
+
+ def domain
+ @domain |= context.domain
+ end
+
+ def force_delete_fast_track
+ domain.force_delete_date = force_delete_fast_track_start_date + 1.day
+ domain.force_delete_start = Time.zone.today + 1.day
+ end
+
+ def force_delete_soft
+ years = (valid_to.to_date - Time.zone.today).to_i / 365
+ soft_forcedelete_dates(years)
+ end
+
+ 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
+ end
+ end
+end
diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index f3bf96975..c6f9b598f 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -7,6 +7,10 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
:contact_notification_sent_date,
:template_name
+ STATUSES_TO_SET = [DomainStatus::FORCE_DELETE,
+ DomainStatus::SERVER_RENEW_PROHIBITED,
+ DomainStatus::SERVER_TRANSFER_PROHIBITED].freeze
+
scope :notification_not_sent,
lambda {
where("(force_delete_data->>'contact_notification_sent_date') is null")
From 09389ea6620150df572dbeedcc493a431bda58e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 9 Nov 2020 16:24:25 +0200
Subject: [PATCH 100/172] Registrant confirms: Poll domain change application
---
.../api/v1/registrant/confirms_controller.rb | 55 +++++++++++++++++++
config/routes.rb | 4 +-
2 files changed, 57 insertions(+), 2 deletions(-)
create mode 100644 app/controllers/api/v1/registrant/confirms_controller.rb
diff --git a/app/controllers/api/v1/registrant/confirms_controller.rb b/app/controllers/api/v1/registrant/confirms_controller.rb
new file mode 100644
index 000000000..cbc8c5413
--- /dev/null
+++ b/app/controllers/api/v1/registrant/confirms_controller.rb
@@ -0,0 +1,55 @@
+require 'serializers/registrant_api/domain'
+
+module Api
+ module V1
+ module Registrant
+ class ConfirmsController < ::Api::V1::Registrant::BaseController
+ skip_before_action :authenticate, :set_paper_trail_whodunnit
+ before_action :set_domain, only: %i[index update]
+ before_action :verify_updateable, only: %i[index update]
+
+ def index
+ render json: {
+ domain_name: @domain.name,
+ current_registrant: serialized_registrant(@domain.registrant),
+ new_registrant: serialized_registrant(@domain.pending_registrant)
+ }
+ end
+
+ def update
+ end
+
+ private
+
+ def serialized_registrant(registrant)
+ {
+ name: registrant.try(:name),
+ ident: registrant.try(:ident),
+ country: registrant.try(:ident_country_code)
+ }
+ end
+
+ def confirmation_params
+ params do |p|
+ p.require(:name)
+ p.require(:token)
+ end
+ end
+
+ def set_domain
+ @domain = Domain.find_by(name: confirmation_params[:name])
+ return if @domain
+
+ render json: { error: 'Domain not found' }, status: :not_found
+ end
+
+ def verify_updateable
+ return if @domain.registrant_update_confirmable?(confirmation_params[:token])
+
+ render json: { error: 'Application expired or not found' },
+ status: :unauthorized
+ end
+ end
+ end
+ end
+end
diff --git a/config/routes.rb b/config/routes.rb
index f58063fae..0b74a2b97 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -56,12 +56,12 @@ Rails.application.routes.draw do
namespace :v1 do
namespace :registrant do
post 'auth/eid', to: 'auth#eid'
-
+ get 'confirms/:name/:token', to: 'confirms#index', constraints: { name: /[^\/]+/ }
+ post 'confirms/:name/:token', to: 'confirms#update', constraints: { name: /[^\/]+/ }
resources :domains, only: %i[index show], param: :uuid do
resource :registry_lock, only: %i[create destroy]
end
resources :contacts, only: %i[index show update], param: :uuid
- resources :companies, only: %i[index]
end
resources :auctions, only: %i[index show update], param: :uuid
From 03754b542b917fb6f10209f40a20ee038b610f5b Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 10 Nov 2020 13:50:38 +0500
Subject: [PATCH 101/172] Complete creation of interactors
---
.../admin/domains/force_delete_controller.rb | 18 ++++++-----
.../domain/force_delete/check_discarded.rb | 4 +--
.../domain/force_delete/notify_by_email.rb | 31 +++++++++++++++++++
.../domain/force_delete/notify_registrar.rb | 16 ++++++++++
.../domain/force_delete/prepare_domain.rb | 6 +++-
.../domain/force_delete/set_status.rb | 5 ++-
app/models/concerns/domain/force_delete.rb | 15 +++++----
7 files changed, 78 insertions(+), 17 deletions(-)
create mode 100644 app/interactors/domain/force_delete/notify_by_email.rb
create mode 100644 app/interactors/domain/force_delete/notify_registrar.rb
diff --git a/app/controllers/admin/domains/force_delete_controller.rb b/app/controllers/admin/domains/force_delete_controller.rb
index 6a111926f..ca5588964 100644
--- a/app/controllers/admin/domains/force_delete_controller.rb
+++ b/app/controllers/admin/domains/force_delete_controller.rb
@@ -5,19 +5,21 @@ module Admin
authorize! :manage, domain
domain.transaction do
- domain.schedule_force_delete(type: force_delete_type)
- domain.registrar.notifications.create!(text: t('force_delete_set_on_domain',
- domain_name: domain.name,
- outzone_date: domain.outzone_date,
- purge_date: domain.purge_date))
-
- notify_by_email if notify_by_email?
+ # domain.schedule_force_delete(type: force_delete_type)
+ # domain.registrar.notifications.create!(text: t('force_delete_set_on_domain',
+ # domain_name: domain.name,
+ # outzone_date: domain.outzone_date,
+ # purge_date: domain.purge_date)) # added to interactor
+ #
+ # notify_by_email if notify_by_email? # added to interactor
+ Domain::ForceDelete::Base.call(domain: domain, type: force_delete_type)
end
redirect_to edit_admin_domain_url(domain), notice: t('.scheduled')
end
def notify_by_email
+ # added to interactor
if force_delete_type == :fast_track
send_email
domain.update(contact_notification_sent_date: Time.zone.today)
@@ -39,10 +41,12 @@ module Admin
end
def notify_by_email?
+ # added to interactor
ActiveRecord::Type::Boolean.new.cast(params[:notify_by_email])
end
def send_email
+ # added to interactor
DomainDeleteMailer.forced(domain: domain,
registrar: domain.registrar,
registrant: domain.registrant,
diff --git a/app/interactors/domain/force_delete/check_discarded.rb b/app/interactors/domain/force_delete/check_discarded.rb
index a13c16778..ac2cd31b6 100644
--- a/app/interactors/domain/force_delete/check_discarded.rb
+++ b/app/interactors/domain/force_delete/check_discarded.rb
@@ -6,8 +6,8 @@ class Domain
def call
return unless context.domain.discarded?
- raise StandardError,
- 'Force delete procedure cannot be scheduled while a domain is discarded'
+ message = 'Force delete procedure cannot be scheduled while a domain is discarded'
+ context.fail!( message: message )
end
end
end
diff --git a/app/interactors/domain/force_delete/notify_by_email.rb b/app/interactors/domain/force_delete/notify_by_email.rb
new file mode 100644
index 000000000..949dd5838
--- /dev/null
+++ b/app/interactors/domain/force_delete/notify_by_email.rb
@@ -0,0 +1,31 @@
+class Domain
+ module ForceDelete
+ class NotifyByEmail
+ include Interactor
+
+ def call
+ return unless notify_by_email?
+
+ if context.type == :fast_track
+ send_email
+ context.domain.update(contact_notification_sent_date: Time.zone.today)
+ else
+ context.domain.update(template_name: context.domain.notification_template)
+ end
+ end
+
+ private
+
+ def notify_by_email?
+ ActiveRecord::Type::Boolean.new.cast(params[:notify_by_email])
+ end
+
+ def send_email
+ DomainDeleteMailer.forced(domain: context.domain,
+ registrar: context.domain.registrar,
+ registrant: context.domain.registrant,
+ template_name: context.domain.notification_template).deliver_now
+ end
+ end
+ end
+end
diff --git a/app/interactors/domain/force_delete/notify_registrar.rb b/app/interactors/domain/force_delete/notify_registrar.rb
new file mode 100644
index 000000000..345f4d7eb
--- /dev/null
+++ b/app/interactors/domain/force_delete/notify_registrar.rb
@@ -0,0 +1,16 @@
+class Domain
+ module ForceDelete
+ class NotifyRegistrar
+ include Interactor
+
+ def call
+ domain = context.domain
+
+ domain.registrar.notifications.create!(text: 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/interactors/domain/force_delete/prepare_domain.rb b/app/interactors/domain/force_delete/prepare_domain.rb
index 4b3b83064..3bc764dc8 100644
--- a/app/interactors/domain/force_delete/prepare_domain.rb
+++ b/app/interactors/domain/force_delete/prepare_domain.rb
@@ -3,10 +3,14 @@ class Domain
class PrepareDomain
include Interactor
+ STATUSES_TO_SET = [DomainStatus::FORCE_DELETE,
+ DomainStatus::SERVER_RENEW_PROHIBITED,
+ DomainStatus::SERVER_TRANSFER_PROHIBITED].freeze
+
def call
domain = context.domain
domain.statuses_before_force_delete = domain.statuses
- domain.statuses |= domain.class.STATUSES_TO_SET
+ domain.statuses |= STATUSES_TO_SET
domain.save(validate: false)
end
end
diff --git a/app/interactors/domain/force_delete/set_status.rb b/app/interactors/domain/force_delete/set_status.rb
index 7ce481623..2a6c49daa 100644
--- a/app/interactors/domain/force_delete/set_status.rb
+++ b/app/interactors/domain/force_delete/set_status.rb
@@ -16,7 +16,10 @@ class Domain
end
def force_delete_fast_track
- domain.force_delete_date = force_delete_fast_track_start_date + 1.day
+ domain.force_delete_date = Time.zone.today +
+ Setting.expire_warning_period.days +
+ Setting.redemption_grace_period.days +
+ 1.day
domain.force_delete_start = Time.zone.today + 1.day
end
diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index c6f9b598f..768b1d11b 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -7,10 +7,6 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
:contact_notification_sent_date,
:template_name
- STATUSES_TO_SET = [DomainStatus::FORCE_DELETE,
- DomainStatus::SERVER_RENEW_PROHIBITED,
- DomainStatus::SERVER_TRANSFER_PROHIBITED].freeze
-
scope :notification_not_sent,
lambda {
where("(force_delete_data->>'contact_notification_sent_date') is null")
@@ -57,6 +53,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def schedule_force_delete(type: :fast_track)
+ # added to interactor
if discarded?
raise StandardError, 'Force delete procedure cannot be scheduled while a domain is discarded'
end
@@ -72,8 +69,8 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
preserve_current_statuses_for_force_delete
add_force_delete_statuses
add_force_delete_type(:fast)
- self.force_delete_date = force_delete_fast_track_start_date + 1.day
- self.force_delete_start = Time.zone.today + 1.day
+ self.force_delete_date = force_delete_fast_track_start_date + 1.day # added to interactor
+ self.force_delete_start = Time.zone.today + 1.day # added to interactor
stop_all_pending_actions
allow_deletion
save(validate: false)
@@ -120,12 +117,14 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def soft_delete_dates(years)
+ # added to interactor
self.force_delete_start = valid_to - years.years
self.force_delete_date = force_delete_start + Setting.expire_warning_period.days +
Setting.redemption_grace_period.days
end
def stop_all_pending_actions
+ # added to interactor
statuses.delete(DomainStatus::PENDING_UPDATE)
statuses.delete(DomainStatus::PENDING_TRANSFER)
statuses.delete(DomainStatus::PENDING_RENEW)
@@ -133,6 +132,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def preserve_current_statuses_for_force_delete
+ # added to interactor
update(statuses_before_force_delete: statuses)
end
@@ -142,6 +142,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def add_force_delete_statuses
+ # added to interactor
self.statuses |= [DomainStatus::FORCE_DELETE,
DomainStatus::SERVER_RENEW_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED]
@@ -155,11 +156,13 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def allow_deletion
+ # added to interactor
statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
end
def force_delete_fast_track_start_date
+ # added to interactor
Time.zone.today + Setting.expire_warning_period.days + Setting.redemption_grace_period.days
end
end
From f97dff60029b953a946ba05074416abfc1a1a721 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 10 Nov 2020 14:06:37 +0500
Subject: [PATCH 102/172] Fix tests & interactor process
---
.../admin/domains/force_delete_controller.rb | 28 +------
app/interactors/domain/force_delete/base.rb | 16 ----
.../domain/force_delete/notify_by_email.rb | 31 --------
.../domain/force_delete/notify_registrar.rb | 16 ----
.../domain/force_delete_interactor/base.rb | 16 ++++
.../check_discarded.rb | 4 +-
.../notify_by_email.rb | 31 ++++++++
.../notify_registrar.rb | 16 ++++
.../post_set_process.rb | 2 +-
.../prepare_domain.rb | 2 +-
.../set_status.rb | 25 +++---
app/models/concerns/domain/force_delete.rb | 79 +------------------
test/models/domain/force_delete_test.rb | 7 +-
test/models/domain_test.rb | 2 +-
14 files changed, 93 insertions(+), 182 deletions(-)
delete mode 100644 app/interactors/domain/force_delete/base.rb
delete mode 100644 app/interactors/domain/force_delete/notify_by_email.rb
delete mode 100644 app/interactors/domain/force_delete/notify_registrar.rb
create mode 100644 app/interactors/domain/force_delete_interactor/base.rb
rename app/interactors/domain/{force_delete => force_delete_interactor}/check_discarded.rb (77%)
create mode 100644 app/interactors/domain/force_delete_interactor/notify_by_email.rb
create mode 100644 app/interactors/domain/force_delete_interactor/notify_registrar.rb
rename app/interactors/domain/{force_delete => force_delete_interactor}/post_set_process.rb (95%)
rename app/interactors/domain/{force_delete => force_delete_interactor}/prepare_domain.rb (93%)
rename app/interactors/domain/{force_delete => force_delete_interactor}/set_status.rb (61%)
diff --git a/app/controllers/admin/domains/force_delete_controller.rb b/app/controllers/admin/domains/force_delete_controller.rb
index ca5588964..9f660ed71 100644
--- a/app/controllers/admin/domains/force_delete_controller.rb
+++ b/app/controllers/admin/domains/force_delete_controller.rb
@@ -5,29 +5,12 @@ module Admin
authorize! :manage, domain
domain.transaction do
- # domain.schedule_force_delete(type: force_delete_type)
- # domain.registrar.notifications.create!(text: t('force_delete_set_on_domain',
- # domain_name: domain.name,
- # outzone_date: domain.outzone_date,
- # purge_date: domain.purge_date)) # added to interactor
- #
- # notify_by_email if notify_by_email? # added to interactor
- Domain::ForceDelete::Base.call(domain: domain, type: force_delete_type)
+ domain.schedule_force_delete(type: force_delete_type, notify_by_email: notify_by_email?)
end
redirect_to edit_admin_domain_url(domain), notice: t('.scheduled')
end
- def notify_by_email
- # added to interactor
- if force_delete_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 destroy
authorize! :manage, domain
domain.cancel_force_delete
@@ -41,18 +24,9 @@ module Admin
end
def notify_by_email?
- # added to interactor
ActiveRecord::Type::Boolean.new.cast(params[:notify_by_email])
end
- def send_email
- # added to interactor
- DomainDeleteMailer.forced(domain: domain,
- registrar: domain.registrar,
- registrant: domain.registrant,
- template_name: domain.notification_template).deliver_now
- end
-
def force_delete_type
soft_delete? ? :soft : :fast_track
end
diff --git a/app/interactors/domain/force_delete/base.rb b/app/interactors/domain/force_delete/base.rb
deleted file mode 100644
index 79de3cf2f..000000000
--- a/app/interactors/domain/force_delete/base.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class Domain
- module ForceDelete
- class Base
- include Interactor::Organizer
-
- # As per https://github.com/collectiveidea/interactor#organizers
-
- organize Domain::ForceDelete::CheckDiscarded,
- Domain::ForceDelete::PrepareDomain,
- Domain::ForceDelete::SetStatus,
- Domain::ForceDelete::PostSetProcess,
- Domain::ForceDelete::NotifyRegistrar,
- Domain::ForceDelete::NotifyByEmail
- end
- end
-end
diff --git a/app/interactors/domain/force_delete/notify_by_email.rb b/app/interactors/domain/force_delete/notify_by_email.rb
deleted file mode 100644
index 949dd5838..000000000
--- a/app/interactors/domain/force_delete/notify_by_email.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-class Domain
- module ForceDelete
- class NotifyByEmail
- include Interactor
-
- def call
- return unless notify_by_email?
-
- if context.type == :fast_track
- send_email
- context.domain.update(contact_notification_sent_date: Time.zone.today)
- else
- context.domain.update(template_name: context.domain.notification_template)
- end
- end
-
- private
-
- def notify_by_email?
- ActiveRecord::Type::Boolean.new.cast(params[:notify_by_email])
- end
-
- def send_email
- DomainDeleteMailer.forced(domain: context.domain,
- registrar: context.domain.registrar,
- registrant: context.domain.registrant,
- template_name: context.domain.notification_template).deliver_now
- end
- end
- end
-end
diff --git a/app/interactors/domain/force_delete/notify_registrar.rb b/app/interactors/domain/force_delete/notify_registrar.rb
deleted file mode 100644
index 345f4d7eb..000000000
--- a/app/interactors/domain/force_delete/notify_registrar.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class Domain
- module ForceDelete
- class NotifyRegistrar
- include Interactor
-
- def call
- domain = context.domain
-
- domain.registrar.notifications.create!(text: 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/interactors/domain/force_delete_interactor/base.rb b/app/interactors/domain/force_delete_interactor/base.rb
new file mode 100644
index 000000000..d10edcaef
--- /dev/null
+++ b/app/interactors/domain/force_delete_interactor/base.rb
@@ -0,0 +1,16 @@
+class Domain
+ module ForceDeleteInteractor
+ class Base
+ include Interactor::Organizer
+
+ # As per https://github.com/collectiveidea/interactor#organizers
+
+ organize Domain::ForceDeleteInteractor::CheckDiscarded,
+ Domain::ForceDeleteInteractor::PrepareDomain,
+ Domain::ForceDeleteInteractor::SetStatus,
+ Domain::ForceDeleteInteractor::PostSetProcess,
+ Domain::ForceDeleteInteractor::NotifyRegistrar,
+ Domain::ForceDeleteInteractor::NotifyByEmail
+ end
+ end
+end
diff --git a/app/interactors/domain/force_delete/check_discarded.rb b/app/interactors/domain/force_delete_interactor/check_discarded.rb
similarity index 77%
rename from app/interactors/domain/force_delete/check_discarded.rb
rename to app/interactors/domain/force_delete_interactor/check_discarded.rb
index ac2cd31b6..c340f9f43 100644
--- a/app/interactors/domain/force_delete/check_discarded.rb
+++ b/app/interactors/domain/force_delete_interactor/check_discarded.rb
@@ -1,5 +1,5 @@
class Domain
- module ForceDelete
+ module ForceDeleteInteractor
class CheckDiscarded
include Interactor
@@ -7,7 +7,7 @@ class Domain
return unless context.domain.discarded?
message = 'Force delete procedure cannot be scheduled while a domain is discarded'
- context.fail!( message: message )
+ context.fail!(message: message)
end
end
end
diff --git a/app/interactors/domain/force_delete_interactor/notify_by_email.rb b/app/interactors/domain/force_delete_interactor/notify_by_email.rb
new file mode 100644
index 000000000..91855b839
--- /dev/null
+++ b/app/interactors/domain/force_delete_interactor/notify_by_email.rb
@@ -0,0 +1,31 @@
+class Domain
+ module ForceDeleteInteractor
+ class NotifyByEmail
+ include Interactor
+
+ def call
+ return unless context.notify_by_email
+
+ if context.type == :fast_track
+ send_email
+ domain.update(contact_notification_sent_date: Time.zone.today)
+ else
+ domain.update(template_name: context.domain.notification_template)
+ end
+ end
+
+ private
+
+ def domain
+ @domain ||= context.domain
+ 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/interactors/domain/force_delete_interactor/notify_registrar.rb b/app/interactors/domain/force_delete_interactor/notify_registrar.rb
new file mode 100644
index 000000000..bfe35d29a
--- /dev/null
+++ b/app/interactors/domain/force_delete_interactor/notify_registrar.rb
@@ -0,0 +1,16 @@
+class Domain
+ module ForceDeleteInteractor
+ class NotifyRegistrar
+ include Interactor
+
+ def call
+ domain = context.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
+ end
+ end
+end
diff --git a/app/interactors/domain/force_delete/post_set_process.rb b/app/interactors/domain/force_delete_interactor/post_set_process.rb
similarity index 95%
rename from app/interactors/domain/force_delete/post_set_process.rb
rename to app/interactors/domain/force_delete_interactor/post_set_process.rb
index a2fc531b2..78a039d43 100644
--- a/app/interactors/domain/force_delete/post_set_process.rb
+++ b/app/interactors/domain/force_delete_interactor/post_set_process.rb
@@ -1,5 +1,5 @@
class Domain
- module ForceDelete
+ module ForceDeleteInteractor
class PostSetProcess
include Interactor
diff --git a/app/interactors/domain/force_delete/prepare_domain.rb b/app/interactors/domain/force_delete_interactor/prepare_domain.rb
similarity index 93%
rename from app/interactors/domain/force_delete/prepare_domain.rb
rename to app/interactors/domain/force_delete_interactor/prepare_domain.rb
index 3bc764dc8..c214a6b88 100644
--- a/app/interactors/domain/force_delete/prepare_domain.rb
+++ b/app/interactors/domain/force_delete_interactor/prepare_domain.rb
@@ -1,5 +1,5 @@
class Domain
- module ForceDelete
+ module ForceDeleteInteractor
class PrepareDomain
include Interactor
diff --git a/app/interactors/domain/force_delete/set_status.rb b/app/interactors/domain/force_delete_interactor/set_status.rb
similarity index 61%
rename from app/interactors/domain/force_delete/set_status.rb
rename to app/interactors/domain/force_delete_interactor/set_status.rb
index 2a6c49daa..a15b67ce2 100644
--- a/app/interactors/domain/force_delete/set_status.rb
+++ b/app/interactors/domain/force_delete_interactor/set_status.rb
@@ -1,5 +1,5 @@
class Domain
- module ForceDelete
+ module ForceDeleteInteractor
class SetStatus
include Interactor
@@ -9,23 +9,20 @@ class Domain
domain.save(validate: false)
end
- private
-
def domain
- @domain |= context.domain
+ @domain ||= context.domain
end
def force_delete_fast_track
domain.force_delete_date = Time.zone.today +
- Setting.expire_warning_period.days +
- Setting.redemption_grace_period.days +
- 1.day
+ expire_warning_period_days +
+ redemption_grace_period_days
domain.force_delete_start = Time.zone.today + 1.day
end
def force_delete_soft
- years = (valid_to.to_date - Time.zone.today).to_i / 365
- soft_forcedelete_dates(years)
+ years = (domain.valid_to.to_date - Time.zone.today).to_i / 365
+ soft_forcedelete_dates(years) if years.positive?
end
def soft_forcedelete_dates(years)
@@ -34,6 +31,16 @@ class Domain
Setting.expire_warning_period.days +
Setting.redemption_grace_period.days
end
+
+ private
+
+ 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/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index 768b1d11b..26dc62413 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -52,38 +52,10 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
force_delete_start + Setting.expire_warning_period.days <= valid_to
end
- def schedule_force_delete(type: :fast_track)
- # added to interactor
- if discarded?
- raise StandardError, 'Force delete procedure cannot be scheduled while a domain is discarded'
- end
-
- type == :fast_track ? force_delete_fast_track : force_delete_soft
- end
-
- def add_force_delete_type(force_delete_type)
- self.force_delete_type = force_delete_type
- end
-
- def force_delete_fast_track
- preserve_current_statuses_for_force_delete
- add_force_delete_statuses
- add_force_delete_type(:fast)
- self.force_delete_date = force_delete_fast_track_start_date + 1.day # added to interactor
- self.force_delete_start = Time.zone.today + 1.day # added to interactor
- stop_all_pending_actions
- allow_deletion
- save(validate: false)
- end
-
- def force_delete_soft
- preserve_current_statuses_for_force_delete
- add_force_delete_statuses
- add_force_delete_type(:soft)
- calculate_soft_delete_date
- stop_all_pending_actions
- allow_deletion
- save(validate: false)
+ def schedule_force_delete(type: :fast_track, notify_by_email: false)
+ Domain::ForceDeleteInteractor::Base.call(domain: self,
+ type: type,
+ notify_by_email: notify_by_email)
end
def clear_force_delete_data
@@ -111,58 +83,15 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
private
- def calculate_soft_delete_date
- years = (valid_to.to_date - Time.zone.today).to_i / 365
- soft_delete_dates(years) if years.positive?
- end
-
- def soft_delete_dates(years)
- # added to interactor
- self.force_delete_start = valid_to - years.years
- self.force_delete_date = force_delete_start + Setting.expire_warning_period.days +
- Setting.redemption_grace_period.days
- end
-
- def stop_all_pending_actions
- # added to interactor
- statuses.delete(DomainStatus::PENDING_UPDATE)
- statuses.delete(DomainStatus::PENDING_TRANSFER)
- statuses.delete(DomainStatus::PENDING_RENEW)
- statuses.delete(DomainStatus::PENDING_CREATE)
- end
-
- def preserve_current_statuses_for_force_delete
- # added to interactor
- update(statuses_before_force_delete: statuses)
- end
-
def restore_statuses_before_force_delete
self.statuses = statuses_before_force_delete
self.statuses_before_force_delete = nil
end
- def add_force_delete_statuses
- # added to interactor
- self.statuses |= [DomainStatus::FORCE_DELETE,
- DomainStatus::SERVER_RENEW_PROHIBITED,
- DomainStatus::SERVER_TRANSFER_PROHIBITED]
- end
-
def remove_force_delete_statuses
statuses.delete(DomainStatus::FORCE_DELETE)
statuses.delete(DomainStatus::SERVER_RENEW_PROHIBITED)
statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED)
statuses.delete(DomainStatus::CLIENT_HOLD)
end
-
- def allow_deletion
- # added to interactor
- statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED)
- statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
- end
-
- def force_delete_fast_track_start_date
- # added to interactor
- Time.zone.today + Setting.expire_warning_period.days + Setting.redemption_grace_period.days
- end
end
diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb
index f0723c326..f5c7e7b06 100644
--- a/test/models/domain/force_delete_test.rb
+++ b/test/models/domain/force_delete_test.rb
@@ -111,9 +111,10 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase
def test_force_delete_cannot_be_scheduled_when_a_domain_is_discarded
@domain.update!(statuses: [DomainStatus::DELETE_CANDIDATE])
- assert_raises StandardError do
- @domain.schedule_force_delete(type: :fast_track)
- end
+ context = Domain::ForceDeleteInteractor::Base.call(domain: @domain, type: :fast_track)
+
+ assert_not context.success?
+ assert_equal 'Force delete procedure cannot be scheduled while a domain is discarded', context.message
end
def test_cancels_force_delete
diff --git a/test/models/domain_test.rb b/test/models/domain_test.rb
index 4a9240f57..bb4dd37cf 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')
- @domain.schedule_force_delete(type: :fast_track)
+ Domain::ForceDeleteInteractor::Base.call(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 3c7fa8846357c797d51fab1b2cfb6bd099877cdb Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 10 Nov 2020 15:06:32 +0500
Subject: [PATCH 103/172] Inherit all the interactors from base one
---
.../domain/force_delete_interactor/base.rb | 13 +++++--------
.../force_delete_interactor/check_discarded.rb | 6 ++----
.../force_delete_interactor/notify_by_email.rb | 10 +---------
.../force_delete_interactor/notify_registrar.rb | 6 +-----
.../force_delete_interactor/post_set_process.rb | 8 +++-----
.../force_delete_interactor/prepare_domain.rb | 5 +----
.../force_delete_interactor/set_force_delete.rb | 16 ++++++++++++++++
.../domain/force_delete_interactor/set_status.rb | 8 +-------
app/models/concerns/domain/force_delete.rb | 6 +++---
test/models/domain/force_delete_test.rb | 2 +-
test/models/domain_test.rb | 2 +-
11 files changed, 35 insertions(+), 47 deletions(-)
create mode 100644 app/interactors/domain/force_delete_interactor/set_force_delete.rb
diff --git a/app/interactors/domain/force_delete_interactor/base.rb b/app/interactors/domain/force_delete_interactor/base.rb
index d10edcaef..6724d53e3 100644
--- a/app/interactors/domain/force_delete_interactor/base.rb
+++ b/app/interactors/domain/force_delete_interactor/base.rb
@@ -1,16 +1,13 @@
class Domain
module ForceDeleteInteractor
class Base
- include Interactor::Organizer
+ include Interactor
- # As per https://github.com/collectiveidea/interactor#organizers
+ private
- organize Domain::ForceDeleteInteractor::CheckDiscarded,
- Domain::ForceDeleteInteractor::PrepareDomain,
- Domain::ForceDeleteInteractor::SetStatus,
- Domain::ForceDeleteInteractor::PostSetProcess,
- Domain::ForceDeleteInteractor::NotifyRegistrar,
- Domain::ForceDeleteInteractor::NotifyByEmail
+ def domain
+ @domain ||= context.domain
+ end
end
end
end
diff --git a/app/interactors/domain/force_delete_interactor/check_discarded.rb b/app/interactors/domain/force_delete_interactor/check_discarded.rb
index c340f9f43..b63828f49 100644
--- a/app/interactors/domain/force_delete_interactor/check_discarded.rb
+++ b/app/interactors/domain/force_delete_interactor/check_discarded.rb
@@ -1,10 +1,8 @@
class Domain
module ForceDeleteInteractor
- class CheckDiscarded
- include Interactor
-
+ class CheckDiscarded < Base
def call
- return unless context.domain.discarded?
+ return unless domain.discarded?
message = 'Force delete procedure cannot be scheduled while a domain is discarded'
context.fail!(message: message)
diff --git a/app/interactors/domain/force_delete_interactor/notify_by_email.rb b/app/interactors/domain/force_delete_interactor/notify_by_email.rb
index 91855b839..5263fdd7a 100644
--- a/app/interactors/domain/force_delete_interactor/notify_by_email.rb
+++ b/app/interactors/domain/force_delete_interactor/notify_by_email.rb
@@ -1,8 +1,6 @@
class Domain
module ForceDeleteInteractor
- class NotifyByEmail
- include Interactor
-
+ class NotifyByEmail < Base
def call
return unless context.notify_by_email
@@ -14,12 +12,6 @@ class Domain
end
end
- private
-
- def domain
- @domain ||= context.domain
- end
-
def send_email
DomainDeleteMailer.forced(domain: domain,
registrar: domain.registrar,
diff --git a/app/interactors/domain/force_delete_interactor/notify_registrar.rb b/app/interactors/domain/force_delete_interactor/notify_registrar.rb
index bfe35d29a..bd891d5dc 100644
--- a/app/interactors/domain/force_delete_interactor/notify_registrar.rb
+++ b/app/interactors/domain/force_delete_interactor/notify_registrar.rb
@@ -1,11 +1,7 @@
class Domain
module ForceDeleteInteractor
- class NotifyRegistrar
- include Interactor
-
+ class NotifyRegistrar < Base
def call
- domain = context.domain
-
domain.registrar.notifications.create!(text: I18n.t('force_delete_set_on_domain',
domain_name: domain.name,
outzone_date: domain.outzone_date,
diff --git a/app/interactors/domain/force_delete_interactor/post_set_process.rb b/app/interactors/domain/force_delete_interactor/post_set_process.rb
index 78a039d43..4017eb459 100644
--- a/app/interactors/domain/force_delete_interactor/post_set_process.rb
+++ b/app/interactors/domain/force_delete_interactor/post_set_process.rb
@@ -1,10 +1,8 @@
class Domain
module ForceDeleteInteractor
- class PostSetProcess
- include Interactor
-
+ class PostSetProcess < Base
def call
- statuses = context.domain.statuses
+ statuses = domain.statuses
# Stop all pending actions
statuses.delete(DomainStatus::PENDING_UPDATE)
statuses.delete(DomainStatus::PENDING_TRANSFER)
@@ -14,7 +12,7 @@ class Domain
# Allow deletion
statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
- context.domain.save(validate: false)
+ domain.save(validate: false)
end
end
end
diff --git a/app/interactors/domain/force_delete_interactor/prepare_domain.rb b/app/interactors/domain/force_delete_interactor/prepare_domain.rb
index c214a6b88..6317bbaf1 100644
--- a/app/interactors/domain/force_delete_interactor/prepare_domain.rb
+++ b/app/interactors/domain/force_delete_interactor/prepare_domain.rb
@@ -1,14 +1,11 @@
class Domain
module ForceDeleteInteractor
- class PrepareDomain
- include Interactor
-
+ class PrepareDomain < Base
STATUSES_TO_SET = [DomainStatus::FORCE_DELETE,
DomainStatus::SERVER_RENEW_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED].freeze
def call
- domain = context.domain
domain.statuses_before_force_delete = domain.statuses
domain.statuses |= STATUSES_TO_SET
domain.save(validate: false)
diff --git a/app/interactors/domain/force_delete_interactor/set_force_delete.rb b/app/interactors/domain/force_delete_interactor/set_force_delete.rb
new file mode 100644
index 000000000..4435b8f8c
--- /dev/null
+++ b/app/interactors/domain/force_delete_interactor/set_force_delete.rb
@@ -0,0 +1,16 @@
+class Domain
+ module ForceDeleteInteractor
+ class SetForceDelete
+ include Interactor::Organizer
+
+ # As per https://github.com/collectiveidea/interactor#organizers
+
+ organize Domain::ForceDeleteInteractor::CheckDiscarded,
+ Domain::ForceDeleteInteractor::PrepareDomain,
+ Domain::ForceDeleteInteractor::SetStatus,
+ Domain::ForceDeleteInteractor::PostSetProcess,
+ Domain::ForceDeleteInteractor::NotifyRegistrar,
+ Domain::ForceDeleteInteractor::NotifyByEmail
+ end
+ end
+end
diff --git a/app/interactors/domain/force_delete_interactor/set_status.rb b/app/interactors/domain/force_delete_interactor/set_status.rb
index a15b67ce2..418952f51 100644
--- a/app/interactors/domain/force_delete_interactor/set_status.rb
+++ b/app/interactors/domain/force_delete_interactor/set_status.rb
@@ -1,18 +1,12 @@
class Domain
module ForceDeleteInteractor
- class SetStatus
- include Interactor
-
+ class SetStatus < Base
def call
domain.force_delete_type = context.type
context.type == :fast_track ? force_delete_fast_track : force_delete_soft
domain.save(validate: false)
end
- def domain
- @domain ||= context.domain
- end
-
def force_delete_fast_track
domain.force_delete_date = Time.zone.today +
expire_warning_period_days +
diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index 26dc62413..4a032ab36 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -53,9 +53,9 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def schedule_force_delete(type: :fast_track, notify_by_email: false)
- Domain::ForceDeleteInteractor::Base.call(domain: self,
- type: type,
- notify_by_email: notify_by_email)
+ Domain::ForceDeleteInteractor::SetForceDelete.call(domain: self,
+ type: type,
+ notify_by_email: notify_by_email)
end
def clear_force_delete_data
diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb
index f5c7e7b06..ddd330f47 100644
--- a/test/models/domain/force_delete_test.rb
+++ b/test/models/domain/force_delete_test.rb
@@ -111,7 +111,7 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase
def test_force_delete_cannot_be_scheduled_when_a_domain_is_discarded
@domain.update!(statuses: [DomainStatus::DELETE_CANDIDATE])
- context = Domain::ForceDeleteInteractor::Base.call(domain: @domain, type: :fast_track)
+ context = Domain::ForceDeleteInteractor::SetForceDelete.call(domain: @domain, type: :fast_track)
assert_not context.success?
assert_equal 'Force delete procedure cannot be scheduled while a domain is discarded', context.message
diff --git a/test/models/domain_test.rb b/test/models/domain_test.rb
index bb4dd37cf..2b01c795f 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')
- Domain::ForceDeleteInteractor::Base.call(domain: @domain, type: :fast_track)
+ Domain::ForceDeleteInteractor::SetForceDelete.call(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 377a95cc76713b40fd9b2890811bdcb2190a39db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Wed, 11 Nov 2020 13:09:32 +0200
Subject: [PATCH 104/172] Add experimental registrant change accept/deny API
endpoint
---
.../api/v1/registrant/confirms_controller.rb | 13 +++++++++++++
app/services/registrant_change.rb | 1 +
2 files changed, 14 insertions(+)
diff --git a/app/controllers/api/v1/registrant/confirms_controller.rb b/app/controllers/api/v1/registrant/confirms_controller.rb
index cbc8c5413..390753fd3 100644
--- a/app/controllers/api/v1/registrant/confirms_controller.rb
+++ b/app/controllers/api/v1/registrant/confirms_controller.rb
@@ -17,10 +17,23 @@ module Api
end
def update
+ verification = RegistrantVerification.new(domain_id: @domain.id,
+ verification_token: confirmation_params[:token])
+
+ head(update_action(verification) ? :ok : :bad_request)
end
private
+ def update_action(verification)
+ initiator = "email link, #{t(:user_not_authenticated)}"
+ if params[:confirm].present?
+ verification.domain_registrant_change_confirm!(initiator)
+ else
+ verification.domain_registrant_change_reject!(initiator)
+ end
+ end
+
def serialized_registrant(registrant)
{
name: registrant.try(:name),
diff --git a/app/services/registrant_change.rb b/app/services/registrant_change.rb
index 35b631fb6..fdee7654a 100644
--- a/app/services/registrant_change.rb
+++ b/app/services/registrant_change.rb
@@ -5,6 +5,7 @@ class RegistrantChange
end
def confirm
+ Dispute.close_by_domain(@domain.name) if @domain.disputed?
notify_registrant
end
From 55e66724cf2ae6be3394a0074b469d4adc8578e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Wed, 11 Nov 2020 16:21:32 +0200
Subject: [PATCH 105/172] Clean up verifications controller
---
.../api/v1/registrant/confirms_controller.rb | 39 ++++++++++++++-----
config/routes.rb | 3 +-
2 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/app/controllers/api/v1/registrant/confirms_controller.rb b/app/controllers/api/v1/registrant/confirms_controller.rb
index 390753fd3..7d3dd5552 100644
--- a/app/controllers/api/v1/registrant/confirms_controller.rb
+++ b/app/controllers/api/v1/registrant/confirms_controller.rb
@@ -7,6 +7,7 @@ module Api
skip_before_action :authenticate, :set_paper_trail_whodunnit
before_action :set_domain, only: %i[index update]
before_action :verify_updateable, only: %i[index update]
+ before_action :verify_decision, only: %i[update]
def index
render json: {
@@ -18,16 +19,30 @@ module Api
def update
verification = RegistrantVerification.new(domain_id: @domain.id,
- verification_token: confirmation_params[:token])
+ verification_token: verify_params[:token])
- head(update_action(verification) ? :ok : :bad_request)
+ head(:bad_request) and return unless update_action(verification)
+
+ render json: {
+ domain_name: @domain.name,
+ current_registrant: serialized_registrant(current_registrant),
+ status: params[:decision]
+ }
end
private
+ def current_registrant
+ changes_registrant? ? @domain.registrant : @domain.pending_registrant
+ end
+
+ def changes_registrant?
+ params[:decision] == 'confirmed'
+ end
+
def update_action(verification)
- initiator = "email link, #{t(:user_not_authenticated)}"
- if params[:confirm].present?
+ initiator = "email link, #{I18n.t(:user_not_authenticated)}"
+ if changes_registrant?
verification.domain_registrant_change_confirm!(initiator)
else
verification.domain_registrant_change_reject!(initiator)
@@ -42,25 +57,31 @@ module Api
}
end
- def confirmation_params
+ def verify_params
params do |p|
p.require(:name)
p.require(:token)
end
end
+ def verify_decision
+ return if %w[confirmed rejected].include?(params[:decision])
+
+ head :bad_request
+ end
+
def set_domain
- @domain = Domain.find_by(name: confirmation_params[:name])
+ @domain = Domain.find_by(name: verify_params[:name])
+ @domain ||= Domain.find_by(name_puny: verify_params[:name])
return if @domain
render json: { error: 'Domain not found' }, status: :not_found
end
def verify_updateable
- return if @domain.registrant_update_confirmable?(confirmation_params[:token])
+ return if @domain.registrant_update_confirmable?(verify_params[:token])
- render json: { error: 'Application expired or not found' },
- status: :unauthorized
+ render json: { error: 'Application expired or not found' }, status: :unauthorized
end
end
end
diff --git a/config/routes.rb b/config/routes.rb
index 0b74a2b97..107484f6e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -57,7 +57,8 @@ Rails.application.routes.draw do
namespace :registrant do
post 'auth/eid', to: 'auth#eid'
get 'confirms/:name/:token', to: 'confirms#index', constraints: { name: /[^\/]+/ }
- post 'confirms/:name/:token', to: 'confirms#update', constraints: { name: /[^\/]+/ }
+ post 'confirms/:name/:token/:decision', to: 'confirms#update', constraints: { name: /[^\/]+/ }
+
resources :domains, only: %i[index show], param: :uuid do
resource :registry_lock, only: %i[create destroy]
end
From 6e1a836c97e72a3fd0183835178362766246903d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Wed, 11 Nov 2020 16:23:01 +0200
Subject: [PATCH 106/172] Fix CC issues
---
app/controllers/api/v1/registrant/confirms_controller.rb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/controllers/api/v1/registrant/confirms_controller.rb b/app/controllers/api/v1/registrant/confirms_controller.rb
index 7d3dd5552..712df6bc1 100644
--- a/app/controllers/api/v1/registrant/confirms_controller.rb
+++ b/app/controllers/api/v1/registrant/confirms_controller.rb
@@ -13,7 +13,7 @@ module Api
render json: {
domain_name: @domain.name,
current_registrant: serialized_registrant(@domain.registrant),
- new_registrant: serialized_registrant(@domain.pending_registrant)
+ new_registrant: serialized_registrant(@domain.pending_registrant),
}
end
@@ -26,7 +26,7 @@ module Api
render json: {
domain_name: @domain.name,
current_registrant: serialized_registrant(current_registrant),
- status: params[:decision]
+ status: params[:decision],
}
end
@@ -53,7 +53,7 @@ module Api
{
name: registrant.try(:name),
ident: registrant.try(:ident),
- country: registrant.try(:ident_country_code)
+ country: registrant.try(:ident_country_code),
}
end
From bce39e3404535535ce2097f2b46069e5872b092e Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Wed, 11 Nov 2020 15:44:00 +0500
Subject: [PATCH 107/172] Move interactor from Interactor gem to
ActiveInteraction
---
Gemfile | 3 +--
Gemfile.lock | 9 +++------
.../admin/domains/force_delete_controller.rb | 8 ++++++--
.../domain/force_delete_interaction/base.rb | 17 +++++++++++++++++
.../check_discarded.rb | 8 ++++----
.../notify_by_email.rb | 10 +++++-----
.../notify_registrar.rb | 4 ++--
.../post_set_process.rb | 4 ++--
.../force_delete_interaction}/prepare_domain.rb | 4 ++--
.../set_force_delete.rb | 14 ++++++++++++++
.../force_delete_interaction}/set_status.rb | 12 ++++++------
.../domain/force_delete_interactor/base.rb | 13 -------------
.../force_delete_interactor/set_force_delete.rb | 16 ----------------
app/models/concerns/domain/force_delete.rb | 2 +-
config/application.rb | 1 +
test/models/domain/force_delete_test.rb | 8 +++++---
test/models/domain_test.rb | 2 +-
17 files changed, 70 insertions(+), 65 deletions(-)
create mode 100644 app/interactions/domain/force_delete_interaction/base.rb
rename app/{interactors/domain/force_delete_interactor => interactions/domain/force_delete_interaction}/check_discarded.rb (55%)
rename app/{interactors/domain/force_delete_interactor => interactions/domain/force_delete_interaction}/notify_by_email.rb (70%)
rename app/{interactors/domain/force_delete_interactor => interactions/domain/force_delete_interaction}/notify_registrar.rb (89%)
rename app/{interactors/domain/force_delete_interactor => interactions/domain/force_delete_interaction}/post_set_process.rb (91%)
rename app/{interactors/domain/force_delete_interactor => interactions/domain/force_delete_interaction}/prepare_domain.rb (89%)
create mode 100644 app/interactions/domain/force_delete_interaction/set_force_delete.rb
rename app/{interactors/domain/force_delete_interactor => interactions/domain/force_delete_interaction}/set_status.rb (86%)
delete mode 100644 app/interactors/domain/force_delete_interactor/base.rb
delete mode 100644 app/interactors/domain/force_delete_interactor/set_force_delete.rb
diff --git a/Gemfile b/Gemfile
index c4f5a7cf8..d35238fc0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,9 +1,8 @@
source 'https://rubygems.org'
# core
+gem 'active_interaction', '~> 3.8'
gem 'bootsnap', '>= 1.1.0', require: false
-gem 'interactor', '~> 3.0'
-gem 'interactor-rails', '~> 2.0'
gem 'iso8601', '0.12.1' # for dates and times
gem 'rails', '~> 6.0'
gem 'rest-client'
diff --git a/Gemfile.lock b/Gemfile.lock
index cc59a8f41..14970c2c9 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -112,6 +112,8 @@ GEM
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
+ active_interaction (3.8.3)
+ activemodel (>= 4, < 7)
activejob (6.0.3.3)
activesupport (= 6.0.3.3)
globalid (>= 0.3.6)
@@ -251,10 +253,6 @@ GEM
i18n (1.8.5)
concurrent-ruby (~> 1.0)
i18n_data (0.10.0)
- interactor (3.1.2)
- interactor-rails (2.2.1)
- interactor (~> 3.0)
- rails (>= 4.2)
isikukood (0.1.2)
iso8601 (0.12.1)
jquery-rails (4.4.0)
@@ -525,6 +523,7 @@ PLATFORMS
ruby
DEPENDENCIES
+ active_interaction (~> 3.8)
activerecord-import
airbrake
bootsnap (>= 1.1.0)
@@ -548,8 +547,6 @@ DEPENDENCIES
figaro (= 1.1.1)
grape
haml (~> 5.0)
- interactor (~> 3.0)
- interactor-rails (~> 2.0)
isikukood
iso8601 (= 0.12.1)
jquery-rails
diff --git a/app/controllers/admin/domains/force_delete_controller.rb b/app/controllers/admin/domains/force_delete_controller.rb
index 9f660ed71..4fe85fa3b 100644
--- a/app/controllers/admin/domains/force_delete_controller.rb
+++ b/app/controllers/admin/domains/force_delete_controller.rb
@@ -4,11 +4,15 @@ module Admin
def create
authorize! :manage, domain
+ notice = t('.scheduled')
+
domain.transaction do
- domain.schedule_force_delete(type: force_delete_type, notify_by_email: notify_by_email?)
+ result = domain.schedule_force_delete(type: force_delete_type,
+ notify_by_email: notify_by_email?)
+ notice = result.errors.messages[:domain].first unless result.valid?
end
- redirect_to edit_admin_domain_url(domain), notice: t('.scheduled')
+ redirect_to edit_admin_domain_url(domain), notice: notice
end
def destroy
diff --git a/app/interactions/domain/force_delete_interaction/base.rb b/app/interactions/domain/force_delete_interaction/base.rb
new file mode 100644
index 000000000..e8079982b
--- /dev/null
+++ b/app/interactions/domain/force_delete_interaction/base.rb
@@ -0,0 +1,17 @@
+class Domain
+ 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
+end
diff --git a/app/interactors/domain/force_delete_interactor/check_discarded.rb b/app/interactions/domain/force_delete_interaction/check_discarded.rb
similarity index 55%
rename from app/interactors/domain/force_delete_interactor/check_discarded.rb
rename to app/interactions/domain/force_delete_interaction/check_discarded.rb
index b63828f49..d2b54641a 100644
--- a/app/interactors/domain/force_delete_interactor/check_discarded.rb
+++ b/app/interactions/domain/force_delete_interaction/check_discarded.rb
@@ -1,11 +1,11 @@
class Domain
- module ForceDeleteInteractor
+ module ForceDeleteInteraction
class CheckDiscarded < Base
- def call
- return unless domain.discarded?
+ def execute
+ return true unless domain.discarded?
message = 'Force delete procedure cannot be scheduled while a domain is discarded'
- context.fail!(message: message)
+ errors.add(:domain, message)
end
end
end
diff --git a/app/interactors/domain/force_delete_interactor/notify_by_email.rb b/app/interactions/domain/force_delete_interaction/notify_by_email.rb
similarity index 70%
rename from app/interactors/domain/force_delete_interactor/notify_by_email.rb
rename to app/interactions/domain/force_delete_interaction/notify_by_email.rb
index 5263fdd7a..97abc8e5c 100644
--- a/app/interactors/domain/force_delete_interactor/notify_by_email.rb
+++ b/app/interactions/domain/force_delete_interaction/notify_by_email.rb
@@ -1,14 +1,14 @@
class Domain
- module ForceDeleteInteractor
+ module ForceDeleteInteraction
class NotifyByEmail < Base
- def call
- return unless context.notify_by_email
+ def execute
+ return unless notify_by_email
- if context.type == :fast_track
+ if type == :fast_track
send_email
domain.update(contact_notification_sent_date: Time.zone.today)
else
- domain.update(template_name: context.domain.notification_template)
+ domain.update(template_name: domain.notification_template)
end
end
diff --git a/app/interactors/domain/force_delete_interactor/notify_registrar.rb b/app/interactions/domain/force_delete_interaction/notify_registrar.rb
similarity index 89%
rename from app/interactors/domain/force_delete_interactor/notify_registrar.rb
rename to app/interactions/domain/force_delete_interaction/notify_registrar.rb
index bd891d5dc..da3e400cc 100644
--- a/app/interactors/domain/force_delete_interactor/notify_registrar.rb
+++ b/app/interactions/domain/force_delete_interaction/notify_registrar.rb
@@ -1,7 +1,7 @@
class Domain
- module ForceDeleteInteractor
+ module ForceDeleteInteraction
class NotifyRegistrar < Base
- def call
+ def execute
domain.registrar.notifications.create!(text: I18n.t('force_delete_set_on_domain',
domain_name: domain.name,
outzone_date: domain.outzone_date,
diff --git a/app/interactors/domain/force_delete_interactor/post_set_process.rb b/app/interactions/domain/force_delete_interaction/post_set_process.rb
similarity index 91%
rename from app/interactors/domain/force_delete_interactor/post_set_process.rb
rename to app/interactions/domain/force_delete_interaction/post_set_process.rb
index 4017eb459..68eb59bf9 100644
--- a/app/interactors/domain/force_delete_interactor/post_set_process.rb
+++ b/app/interactions/domain/force_delete_interaction/post_set_process.rb
@@ -1,7 +1,7 @@
class Domain
- module ForceDeleteInteractor
+ module ForceDeleteInteraction
class PostSetProcess < Base
- def call
+ def execute
statuses = domain.statuses
# Stop all pending actions
statuses.delete(DomainStatus::PENDING_UPDATE)
diff --git a/app/interactors/domain/force_delete_interactor/prepare_domain.rb b/app/interactions/domain/force_delete_interaction/prepare_domain.rb
similarity index 89%
rename from app/interactors/domain/force_delete_interactor/prepare_domain.rb
rename to app/interactions/domain/force_delete_interaction/prepare_domain.rb
index 6317bbaf1..fddfeb75a 100644
--- a/app/interactors/domain/force_delete_interactor/prepare_domain.rb
+++ b/app/interactions/domain/force_delete_interaction/prepare_domain.rb
@@ -1,11 +1,11 @@
class Domain
- module ForceDeleteInteractor
+ module ForceDeleteInteraction
class PrepareDomain < Base
STATUSES_TO_SET = [DomainStatus::FORCE_DELETE,
DomainStatus::SERVER_RENEW_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED].freeze
- def call
+ def execute
domain.statuses_before_force_delete = domain.statuses
domain.statuses |= STATUSES_TO_SET
domain.save(validate: false)
diff --git a/app/interactions/domain/force_delete_interaction/set_force_delete.rb b/app/interactions/domain/force_delete_interaction/set_force_delete.rb
new file mode 100644
index 000000000..6bbd8ef20
--- /dev/null
+++ b/app/interactions/domain/force_delete_interaction/set_force_delete.rb
@@ -0,0 +1,14 @@
+class Domain
+ 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
+end
diff --git a/app/interactors/domain/force_delete_interactor/set_status.rb b/app/interactions/domain/force_delete_interaction/set_status.rb
similarity index 86%
rename from app/interactors/domain/force_delete_interactor/set_status.rb
rename to app/interactions/domain/force_delete_interaction/set_status.rb
index 418952f51..a56069fcc 100644
--- a/app/interactors/domain/force_delete_interactor/set_status.rb
+++ b/app/interactions/domain/force_delete_interaction/set_status.rb
@@ -1,9 +1,9 @@
class Domain
- module ForceDeleteInteractor
+ module ForceDeleteInteraction
class SetStatus < Base
- def call
- domain.force_delete_type = context.type
- context.type == :fast_track ? force_delete_fast_track : force_delete_soft
+ def execute
+ domain.force_delete_type = type
+ type == :fast_track ? force_delete_fast_track : force_delete_soft
domain.save(validate: false)
end
@@ -19,6 +19,8 @@ class Domain
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 +
@@ -26,8 +28,6 @@ class Domain
Setting.redemption_grace_period.days
end
- private
-
def redemption_grace_period_days
Setting.redemption_grace_period.days + 1.day
end
diff --git a/app/interactors/domain/force_delete_interactor/base.rb b/app/interactors/domain/force_delete_interactor/base.rb
deleted file mode 100644
index 6724d53e3..000000000
--- a/app/interactors/domain/force_delete_interactor/base.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class Domain
- module ForceDeleteInteractor
- class Base
- include Interactor
-
- private
-
- def domain
- @domain ||= context.domain
- end
- end
- end
-end
diff --git a/app/interactors/domain/force_delete_interactor/set_force_delete.rb b/app/interactors/domain/force_delete_interactor/set_force_delete.rb
deleted file mode 100644
index 4435b8f8c..000000000
--- a/app/interactors/domain/force_delete_interactor/set_force_delete.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class Domain
- module ForceDeleteInteractor
- class SetForceDelete
- include Interactor::Organizer
-
- # As per https://github.com/collectiveidea/interactor#organizers
-
- organize Domain::ForceDeleteInteractor::CheckDiscarded,
- Domain::ForceDeleteInteractor::PrepareDomain,
- Domain::ForceDeleteInteractor::SetStatus,
- Domain::ForceDeleteInteractor::PostSetProcess,
- Domain::ForceDeleteInteractor::NotifyRegistrar,
- Domain::ForceDeleteInteractor::NotifyByEmail
- end
- end
-end
diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index 4a032ab36..f81669c74 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -53,7 +53,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def schedule_force_delete(type: :fast_track, notify_by_email: false)
- Domain::ForceDeleteInteractor::SetForceDelete.call(domain: self,
+ Domain::ForceDeleteInteraction::SetForceDelete.run(domain: self,
type: type,
notify_by_email: notify_by_email)
end
diff --git a/config/application.rb b/config/application.rb
index 5f4481512..a5fb17c9d 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -36,6 +36,7 @@ module DomainNameRegistry
# Autoload all model subdirs
config.autoload_paths += Dir[Rails.root.join('app', 'models', '**/')]
+ config.autoload_paths += Dir[Rails.root.join('app', 'interactions', '**/')]
config.eager_load_paths << config.root.join('lib', 'validators')
config.watchable_dirs['lib'] = %i[rb]
diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb
index ddd330f47..b57763342 100644
--- a/test/models/domain/force_delete_test.rb
+++ b/test/models/domain/force_delete_test.rb
@@ -111,10 +111,12 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase
def test_force_delete_cannot_be_scheduled_when_a_domain_is_discarded
@domain.update!(statuses: [DomainStatus::DELETE_CANDIDATE])
- context = Domain::ForceDeleteInteractor::SetForceDelete.call(domain: @domain, type: :fast_track)
+ result = Domain::ForceDeleteInteraction::SetForceDelete.run(domain: @domain, type: :fast_track)
- assert_not context.success?
- assert_equal 'Force delete procedure cannot be scheduled while a domain is discarded', context.message
+ assert_not result.valid?
+ assert_not @domain.force_delete_scheduled?
+ message = ["Force delete procedure cannot be scheduled while a domain is discarded"]
+ assert_equal message, result.errors.messages[:domain]
end
def test_cancels_force_delete
diff --git a/test/models/domain_test.rb b/test/models/domain_test.rb
index 2b01c795f..514efaf14 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')
- Domain::ForceDeleteInteractor::SetForceDelete.call(domain: @domain, type: :fast_track)
+ Domain::ForceDeleteInteraction::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 e62f0a077abda210a76866e1184d0e420391aa34 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Wed, 11 Nov 2020 21:16:27 +0500
Subject: [PATCH 108/172] Remove domain namespace
---
.../domain/force_delete_interaction/base.rb | 17 --------
.../check_discarded.rb | 12 ------
.../notify_by_email.rb | 23 -----------
.../notify_registrar.rb | 12 ------
.../post_set_process.rb | 19 ---------
.../prepare_domain.rb | 15 -------
.../set_force_delete.rb | 14 -------
.../force_delete_interaction/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 | 6 +--
test/models/domain/force_delete_test.rb | 2 +-
test/models/domain_test.rb | 2 +-
19 files changed, 143 insertions(+), 157 deletions(-)
delete mode 100644 app/interactions/domain/force_delete_interaction/base.rb
delete mode 100644 app/interactions/domain/force_delete_interaction/check_discarded.rb
delete mode 100644 app/interactions/domain/force_delete_interaction/notify_by_email.rb
delete mode 100644 app/interactions/domain/force_delete_interaction/notify_registrar.rb
delete mode 100644 app/interactions/domain/force_delete_interaction/post_set_process.rb
delete mode 100644 app/interactions/domain/force_delete_interaction/prepare_domain.rb
delete mode 100644 app/interactions/domain/force_delete_interaction/set_force_delete.rb
delete mode 100644 app/interactions/domain/force_delete_interaction/set_status.rb
create mode 100644 app/interactions/force_delete_interaction/base.rb
create mode 100644 app/interactions/force_delete_interaction/check_discarded.rb
create mode 100644 app/interactions/force_delete_interaction/notify_by_email.rb
create mode 100644 app/interactions/force_delete_interaction/notify_registrar.rb
create mode 100644 app/interactions/force_delete_interaction/post_set_process.rb
create mode 100644 app/interactions/force_delete_interaction/prepare_domain.rb
create mode 100644 app/interactions/force_delete_interaction/set_force_delete.rb
create mode 100644 app/interactions/force_delete_interaction/set_status.rb
diff --git a/app/interactions/domain/force_delete_interaction/base.rb b/app/interactions/domain/force_delete_interaction/base.rb
deleted file mode 100644
index e8079982b..000000000
--- a/app/interactions/domain/force_delete_interaction/base.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class Domain
- 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
-end
diff --git a/app/interactions/domain/force_delete_interaction/check_discarded.rb b/app/interactions/domain/force_delete_interaction/check_discarded.rb
deleted file mode 100644
index d2b54641a..000000000
--- a/app/interactions/domain/force_delete_interaction/check_discarded.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class Domain
- 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
-end
diff --git a/app/interactions/domain/force_delete_interaction/notify_by_email.rb b/app/interactions/domain/force_delete_interaction/notify_by_email.rb
deleted file mode 100644
index 97abc8e5c..000000000
--- a/app/interactions/domain/force_delete_interaction/notify_by_email.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-class Domain
- 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
-end
diff --git a/app/interactions/domain/force_delete_interaction/notify_registrar.rb b/app/interactions/domain/force_delete_interaction/notify_registrar.rb
deleted file mode 100644
index da3e400cc..000000000
--- a/app/interactions/domain/force_delete_interaction/notify_registrar.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class Domain
- 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
-end
diff --git a/app/interactions/domain/force_delete_interaction/post_set_process.rb b/app/interactions/domain/force_delete_interaction/post_set_process.rb
deleted file mode 100644
index 68eb59bf9..000000000
--- a/app/interactions/domain/force_delete_interaction/post_set_process.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-class Domain
- 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
-end
diff --git a/app/interactions/domain/force_delete_interaction/prepare_domain.rb b/app/interactions/domain/force_delete_interaction/prepare_domain.rb
deleted file mode 100644
index fddfeb75a..000000000
--- a/app/interactions/domain/force_delete_interaction/prepare_domain.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class Domain
- 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
-end
diff --git a/app/interactions/domain/force_delete_interaction/set_force_delete.rb b/app/interactions/domain/force_delete_interaction/set_force_delete.rb
deleted file mode 100644
index 6bbd8ef20..000000000
--- a/app/interactions/domain/force_delete_interaction/set_force_delete.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class Domain
- 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
-end
diff --git a/app/interactions/domain/force_delete_interaction/set_status.rb b/app/interactions/domain/force_delete_interaction/set_status.rb
deleted file mode 100644
index a56069fcc..000000000
--- a/app/interactions/domain/force_delete_interaction/set_status.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-class Domain
- 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
-end
diff --git a/app/interactions/force_delete_interaction/base.rb b/app/interactions/force_delete_interaction/base.rb
new file mode 100644
index 000000000..4764ce8fe
--- /dev/null
+++ b/app/interactions/force_delete_interaction/base.rb
@@ -0,0 +1,16 @@
+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
new file mode 100644
index 000000000..e0c893294
--- /dev/null
+++ b/app/interactions/force_delete_interaction/check_discarded.rb
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 000000000..541df258d
--- /dev/null
+++ b/app/interactions/force_delete_interaction/notify_by_email.rb
@@ -0,0 +1,21 @@
+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
new file mode 100644
index 000000000..691e54f7e
--- /dev/null
+++ b/app/interactions/force_delete_interaction/notify_registrar.rb
@@ -0,0 +1,10 @@
+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
new file mode 100644
index 000000000..e51acf9b7
--- /dev/null
+++ b/app/interactions/force_delete_interaction/post_set_process.rb
@@ -0,0 +1,17 @@
+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
new file mode 100644
index 000000000..97f364145
--- /dev/null
+++ b/app/interactions/force_delete_interaction/prepare_domain.rb
@@ -0,0 +1,13 @@
+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
new file mode 100644
index 000000000..4608b5127
--- /dev/null
+++ b/app/interactions/force_delete_interaction/set_force_delete.rb
@@ -0,0 +1,12 @@
+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
new file mode 100644
index 000000000..7d104aeee
--- /dev/null
+++ b/app/interactions/force_delete_interaction/set_status.rb
@@ -0,0 +1,38 @@
+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 f81669c74..b119b0ce0 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -53,9 +53,9 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def schedule_force_delete(type: :fast_track, notify_by_email: false)
- Domain::ForceDeleteInteraction::SetForceDelete.run(domain: self,
- type: type,
- notify_by_email: notify_by_email)
+ ForceDeleteInteraction::SetForceDelete.run(domain: self,
+ type: type,
+ notify_by_email: notify_by_email)
end
def clear_force_delete_data
diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb
index b57763342..2c264d916 100644
--- a/test/models/domain/force_delete_test.rb
+++ b/test/models/domain/force_delete_test.rb
@@ -111,7 +111,7 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase
def test_force_delete_cannot_be_scheduled_when_a_domain_is_discarded
@domain.update!(statuses: [DomainStatus::DELETE_CANDIDATE])
- result = Domain::ForceDeleteInteraction::SetForceDelete.run(domain: @domain, type: :fast_track)
+ result = ForceDeleteInteraction::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 514efaf14..cc88cf35f 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')
- Domain::ForceDeleteInteraction::SetForceDelete.run!(domain: @domain, type: :fast_track)
+ ForceDeleteInteraction::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 4eaa8065ba3efbb5cb6890ef8215ef3c4b055b22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Wed, 11 Nov 2020 16:49:26 +0200
Subject: [PATCH 109/172] Mailer: Enable registrant confirm actions via REST
---
app/mailers/domain_delete_mailer.rb | 7 ++++++-
config/application.yml.sample | 3 +++
config/routes.rb | 1 +
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/app/mailers/domain_delete_mailer.rb b/app/mailers/domain_delete_mailer.rb
index 1f08204bf..c4190fe14 100644
--- a/app/mailers/domain_delete_mailer.rb
+++ b/app/mailers/domain_delete_mailer.rb
@@ -53,7 +53,12 @@ class DomainDeleteMailer < ApplicationMailer
private
def confirmation_url(domain)
- registrant_domain_delete_confirm_url(domain, token: domain.registrant_verification_token)
+ base_url = ENV['registrant_portal_verifications_base_url']
+ if base_url.blank?
+ registrant_domain_delete_confirm_url(domain, token: domain.registrant_verification_token)
+ else
+ "#{base_url}/confirmation/#{domain.name_puny}/#{domain.registrant_verification_token}"
+ end
end
def forced_email_from
diff --git a/config/application.yml.sample b/config/application.yml.sample
index ab64ed35e..acaa536dd 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
+# Base URL (inc. https://) of REST registrant portal
+# Leave blank to use internal registrant portal
+registrant_portal_verifications_base_url: ''
#
# MISC
diff --git a/config/routes.rb b/config/routes.rb
index 107484f6e..7061f125f 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -63,6 +63,7 @@ Rails.application.routes.draw do
resource :registry_lock, only: %i[create destroy]
end
resources :contacts, only: %i[index show update], param: :uuid
+ resources :companies, only: %i[index]
end
resources :auctions, only: %i[index show update], param: :uuid
From 64d35a864f840ea4db72f5e9af047c1b4a4b3fbd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 12 Nov 2020 11:19:16 +0200
Subject: [PATCH 110/172] Add delete action to confirmations API endpoint
---
.../api/v1/registrant/confirms_controller.rb | 49 +++++++++++++------
app/mailers/domain_delete_mailer.rb | 2 +-
app/mailers/registrant_change_mailer.rb | 7 ++-
config/routes.rb | 4 +-
4 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/app/controllers/api/v1/registrant/confirms_controller.rb b/app/controllers/api/v1/registrant/confirms_controller.rb
index 712df6bc1..b04a72449 100644
--- a/app/controllers/api/v1/registrant/confirms_controller.rb
+++ b/app/controllers/api/v1/registrant/confirms_controller.rb
@@ -6,7 +6,7 @@ module Api
class ConfirmsController < ::Api::V1::Registrant::BaseController
skip_before_action :authenticate, :set_paper_trail_whodunnit
before_action :set_domain, only: %i[index update]
- before_action :verify_updateable, only: %i[index update]
+ before_action :verify_action, only: %i[index update]
before_action :verify_decision, only: %i[update]
def index
@@ -21,7 +21,10 @@ module Api
verification = RegistrantVerification.new(domain_id: @domain.id,
verification_token: verify_params[:token])
- head(:bad_request) and return unless update_action(verification)
+ unless delete_action? ? delete_action(verification) : change_action(verification)
+ head :bad_request
+ return
+ end
render json: {
domain_name: @domain.name,
@@ -32,21 +35,28 @@ module Api
private
- def current_registrant
- changes_registrant? ? @domain.registrant : @domain.pending_registrant
+ def initiator
+ "email link, #{I18n.t(:user_not_authenticated)}"
end
- def changes_registrant?
+ def current_registrant
+ approved? ? @domain.registrant : @domain.pending_registrant
+ end
+
+ def approved?
params[:decision] == 'confirmed'
end
- def update_action(verification)
- initiator = "email link, #{I18n.t(:user_not_authenticated)}"
- if changes_registrant?
- verification.domain_registrant_change_confirm!(initiator)
- else
- verification.domain_registrant_change_reject!(initiator)
- end
+ def change_action(verification)
+ return verification.domain_registrant_change_confirm!(initiator) if approved?
+
+ verification.domain_registrant_change_reject!(initiator)
+ end
+
+ def delete_action(verification)
+ return verification.domain_registrant_delete_confirm!(initiator) if approved?
+
+ verification.domain_registrant_delete_reject!(initiator)
end
def serialized_registrant(registrant)
@@ -59,11 +69,18 @@ module Api
def verify_params
params do |p|
+ p.require(:template)
p.require(:name)
p.require(:token)
end
end
+ def delete_action?
+ return true if params[:template] == 'delete'
+
+ false
+ end
+
def verify_decision
return if %w[confirmed rejected].include?(params[:decision])
@@ -78,8 +95,12 @@ module Api
render json: { error: 'Domain not found' }, status: :not_found
end
- def verify_updateable
- return if @domain.registrant_update_confirmable?(verify_params[:token])
+ def verify_action
+ if params[:template] == 'change'
+ return true if @domain.registrant_update_confirmable?(verify_params[:token])
+ elsif params[:template] == 'delete'
+ return true if @domain.registrant_delete_confirmable?(verify_params[:token])
+ end
render json: { error: 'Application expired or not found' }, status: :unauthorized
end
diff --git a/app/mailers/domain_delete_mailer.rb b/app/mailers/domain_delete_mailer.rb
index c4190fe14..8e2b1a341 100644
--- a/app/mailers/domain_delete_mailer.rb
+++ b/app/mailers/domain_delete_mailer.rb
@@ -57,7 +57,7 @@ class DomainDeleteMailer < ApplicationMailer
if base_url.blank?
registrant_domain_delete_confirm_url(domain, token: domain.registrant_verification_token)
else
- "#{base_url}/confirmation/#{domain.name_puny}/#{domain.registrant_verification_token}"
+ "#{base_url}/confirmation/#{domain.name_puny}/delete/#{domain.registrant_verification_token}"
end
end
diff --git a/app/mailers/registrant_change_mailer.rb b/app/mailers/registrant_change_mailer.rb
index ff3cfa18e..3e97f4b86 100644
--- a/app/mailers/registrant_change_mailer.rb
+++ b/app/mailers/registrant_change_mailer.rb
@@ -50,7 +50,12 @@ class RegistrantChangeMailer < ApplicationMailer
private
def confirmation_url(domain)
- registrant_domain_update_confirm_url(domain, token: domain.registrant_verification_token)
+ base_url = ENV['registrant_portal_verifications_base_url']
+ if base_url.blank?
+ registrant_domain_update_confirm_url(domain, token: domain.registrant_verification_token)
+ else
+ "#{base_url}/confirmation/#{domain.name_puny}/change/#{domain.registrant_verification_token}"
+ end
end
def address_processing
diff --git a/config/routes.rb b/config/routes.rb
index 7061f125f..440c9c05e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -56,8 +56,8 @@ Rails.application.routes.draw do
namespace :v1 do
namespace :registrant do
post 'auth/eid', to: 'auth#eid'
- get 'confirms/:name/:token', to: 'confirms#index', constraints: { name: /[^\/]+/ }
- post 'confirms/:name/:token/:decision', to: 'confirms#update', constraints: { name: /[^\/]+/ }
+ get 'confirms/:name/:template/:token', to: 'confirms#index', constraints: { name: /[^\/]+/ }
+ post 'confirms/:name/:template/:token/:decision', to: 'confirms#update', constraints: { name: /[^\/]+/ }
resources :domains, only: %i[index show], param: :uuid do
resource :registry_lock, only: %i[create destroy]
From c42c482d64f61ca27af202dce82ef7e1e3a6d9c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 12 Nov 2020 13:38:09 +0200
Subject: [PATCH 111/172] Fix CC issues
---
.../api/v1/registrant/confirms_controller.rb | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/app/controllers/api/v1/registrant/confirms_controller.rb b/app/controllers/api/v1/registrant/confirms_controller.rb
index b04a72449..d03e7ab93 100644
--- a/app/controllers/api/v1/registrant/confirms_controller.rb
+++ b/app/controllers/api/v1/registrant/confirms_controller.rb
@@ -26,11 +26,9 @@ module Api
return
end
- render json: {
- domain_name: @domain.name,
- current_registrant: serialized_registrant(current_registrant),
- status: params[:decision],
- }
+ render json: { domain_name: @domain.name,
+ current_registrant: serialized_registrant(current_registrant),
+ status: params[:decision] }
end
private
@@ -96,11 +94,13 @@ module Api
end
def verify_action
- if params[:template] == 'change'
- return true if @domain.registrant_update_confirmable?(verify_params[:token])
- elsif params[:template] == 'delete'
- return true if @domain.registrant_delete_confirmable?(verify_params[:token])
- end
+ action = if params[:template] == 'change'
+ @domain.registrant_update_confirmable?(verify_params[:token])
+ elsif params[:template] == 'delete'
+ @domain.registrant_delete_confirmable?(verify_params[:token])
+ end
+
+ return unless action
render json: { error: 'Application expired or not found' }, status: :unauthorized
end
From 60a66bc540d30487e58886576e7d1e283c8ae2a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 12 Nov 2020 15:46:55 +0200
Subject: [PATCH 112/172] Registrant confirms API: Add tests
---
.../api/v1/registrant/confirms_controller.rb | 39 ++-
.../registrant_api_verifications_test.rb | 259 ++++++++++++++++++
2 files changed, 283 insertions(+), 15 deletions(-)
create mode 100644 test/integration/api/registrant/registrant_api_verifications_test.rb
diff --git a/app/controllers/api/v1/registrant/confirms_controller.rb b/app/controllers/api/v1/registrant/confirms_controller.rb
index d03e7ab93..057400c8e 100644
--- a/app/controllers/api/v1/registrant/confirms_controller.rb
+++ b/app/controllers/api/v1/registrant/confirms_controller.rb
@@ -10,11 +10,16 @@ module Api
before_action :verify_decision, only: %i[update]
def index
- render json: {
+ res = {
domain_name: @domain.name,
current_registrant: serialized_registrant(@domain.registrant),
- new_registrant: serialized_registrant(@domain.pending_registrant),
}
+
+ unless delete_action?
+ res[:new_registrant] = serialized_registrant(@domain.pending_registrant)
+ end
+
+ render json: res, status: :ok
end
def update
@@ -28,7 +33,7 @@ module Api
render json: { domain_name: @domain.name,
current_registrant: serialized_registrant(current_registrant),
- status: params[:decision] }
+ status: params[:decision] }, status: :ok
end
private
@@ -38,23 +43,27 @@ module Api
end
def current_registrant
- approved? ? @domain.registrant : @domain.pending_registrant
+ confirmed? && !delete_action? ? @domain.pending_registrant : @domain.registrant
end
- def approved?
- params[:decision] == 'confirmed'
+ def confirmed?
+ verify_params[:decision] == 'confirmed'
end
def change_action(verification)
- return verification.domain_registrant_change_confirm!(initiator) if approved?
-
- verification.domain_registrant_change_reject!(initiator)
+ if confirmed?
+ verification.domain_registrant_change_confirm!(initiator)
+ else
+ verification.domain_registrant_change_reject!(initiator)
+ end
end
def delete_action(verification)
- return verification.domain_registrant_delete_confirm!(initiator) if approved?
-
- verification.domain_registrant_delete_reject!(initiator)
+ if confirmed?
+ verification.domain_registrant_delete_confirm!(initiator)
+ else
+ verification.domain_registrant_delete_reject!(initiator)
+ end
end
def serialized_registrant(registrant)
@@ -67,9 +76,9 @@ module Api
def verify_params
params do |p|
- p.require(:template)
p.require(:name)
p.require(:token)
+ p.permit(:decision)
end
end
@@ -82,7 +91,7 @@ module Api
def verify_decision
return if %w[confirmed rejected].include?(params[:decision])
- head :bad_request
+ head :not_found
end
def set_domain
@@ -100,7 +109,7 @@ module Api
@domain.registrant_delete_confirmable?(verify_params[:token])
end
- return unless action
+ return if action
render json: { error: 'Application expired or not found' }, status: :unauthorized
end
diff --git a/test/integration/api/registrant/registrant_api_verifications_test.rb b/test/integration/api/registrant/registrant_api_verifications_test.rb
new file mode 100644
index 000000000..b2333e560
--- /dev/null
+++ b/test/integration/api/registrant/registrant_api_verifications_test.rb
@@ -0,0 +1,259 @@
+require 'test_helper'
+require 'auth_token/auth_token_creator'
+
+class RegistrantApiVerificationsTest < ApplicationIntegrationTest
+ def setup
+ super
+
+ @domain = domains(:hospital)
+ @registrant = @domain.registrant
+ @new_registrant = contacts(:jack)
+
+ @token = 'verysecrettoken'
+
+ @domain.update(statuses: [DomainStatus::PENDING_UPDATE],
+ registrant_verification_asked_at: Time.zone.now - 1.day,
+ registrant_verification_token: @token)
+
+ end
+
+ def test_fetches_registrant_change_request
+ pending_json = { new_registrant_id: @new_registrant.id }
+ @domain.update(pending_json: pending_json)
+ @domain.reload
+
+ assert @domain.registrant_update_confirmable?(@token)
+
+ get "/api/v1/registrant/confirms/#{@domain.name_puny}/change/#{@token}"
+ assert_equal(200, response.status)
+
+ res = JSON.parse(response.body, symbolize_names: true)
+ expected_body = {
+ domain_name: "hospital.test",
+ current_registrant: {
+ name: @registrant.name,
+ ident: @registrant.ident,
+ country: @registrant.ident_country_code
+ },
+ new_registrant: {
+ name: @new_registrant.name,
+ ident: @new_registrant.ident,
+ country: @new_registrant.ident_country_code
+ }
+ }
+
+ assert_equal expected_body, res
+ end
+
+ def test_approves_registrant_change_request
+ pending_json = { new_registrant_id: @new_registrant.id }
+ @domain.update(pending_json: pending_json)
+ @domain.reload
+
+ assert @domain.registrant_update_confirmable?(@token)
+
+ post "/api/v1/registrant/confirms/#{@domain.name_puny}/change/#{@token}/confirmed"
+ assert_equal(200, response.status)
+
+ res = JSON.parse(response.body, symbolize_names: true)
+ expected_body = {
+ domain_name: @domain.name,
+ current_registrant: {
+ name: @new_registrant.name,
+ ident: @new_registrant.ident,
+ country: @new_registrant.ident_country_code
+ },
+ status: 'confirmed'
+ }
+
+ assert_equal expected_body, res
+ end
+
+ def test_rejects_registrant_change_request
+ pending_json = { new_registrant_id: @new_registrant.id }
+ @domain.update(pending_json: pending_json)
+ @domain.reload
+
+ assert @domain.registrant_update_confirmable?(@token)
+
+ post "/api/v1/registrant/confirms/#{@domain.name_puny}/change/#{@token}/rejected"
+ assert_equal(200, response.status)
+
+ res = JSON.parse(response.body, symbolize_names: true)
+ expected_body = {
+ domain_name: @domain.name,
+ current_registrant: {
+ name: @registrant.name,
+ ident: @registrant.ident,
+ country: @registrant.ident_country_code
+ },
+ status: 'rejected'
+ }
+
+ assert_equal expected_body, res
+ end
+
+ def test_registrant_change_requires_valid_attributes
+ pending_json = { new_registrant_id: @new_registrant.id }
+ @domain.update(pending_json: pending_json)
+ @domain.reload
+
+ get "/api/v1/registrant/confirms/#{@domain.name_puny}/change/123"
+ assert_equal 401, response.status
+
+ get "/api/v1/registrant/confirms/aohldfjg.ee/change/123"
+ assert_equal 404, response.status
+
+ post "/api/v1/registrant/confirms/#{@domain.name_puny}/change/#{@token}/invalidaction"
+ assert_equal 404, response.status
+ end
+
+ def test_fetches_domain_delete_request
+ @domain.update(statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
+ @domain.reload
+
+ assert @domain.registrant_delete_confirmable?(@token)
+
+ get "/api/v1/registrant/confirms/#{@domain.name_puny}/delete/#{@token}"
+ assert_equal(200, response.status)
+
+ res = JSON.parse(response.body, symbolize_names: true)
+ expected_body = {
+ domain_name: "hospital.test",
+ current_registrant: {
+ name: @registrant.name,
+ ident: @registrant.ident,
+ country: @registrant.ident_country_code
+ }
+ }
+
+ assert_equal expected_body, res
+ end
+
+ def test_approves_domain_delete_request
+ @domain.update(statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
+ @domain.reload
+
+ assert @domain.registrant_delete_confirmable?(@token)
+
+ post "/api/v1/registrant/confirms/#{@domain.name_puny}/delete/#{@token}/confirmed"
+ assert_equal(200, response.status)
+
+ res = JSON.parse(response.body, symbolize_names: true)
+ expected_body = {
+ domain_name: @domain.name,
+ current_registrant: {
+ name: @registrant.name,
+ ident: @registrant.ident,
+ country: @registrant.ident_country_code
+ },
+ status: 'confirmed'
+ }
+
+ assert_equal expected_body, res
+ end
+
+ def test_rejects_domain_delete_request
+ @domain.update(statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
+ @domain.reload
+
+ assert @domain.registrant_delete_confirmable?(@token)
+
+ post "/api/v1/registrant/confirms/#{@domain.name_puny}/delete/#{@token}/rejected"
+ assert_equal(200, response.status)
+
+ res = JSON.parse(response.body, symbolize_names: true)
+ expected_body = {
+ domain_name: @domain.name,
+ current_registrant: {
+ name: @registrant.name,
+ ident: @registrant.ident,
+ country: @registrant.ident_country_code
+ },
+ status: 'rejected'
+ }
+
+ assert_equal expected_body, res
+ end
+
+ def test_domain_delete_requires_valid_attributes
+ @domain.update(statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION, DomainStatus::PENDING_DELETE])
+ @domain.reload
+
+ get "/api/v1/registrant/confirms/#{@domain.name_puny}/delete/123"
+ assert_equal 401, response.status
+
+ get "/api/v1/registrant/confirms/aohldfjg.ee/delete/123"
+ assert_equal 404, response.status
+
+ post "/api/v1/registrant/confirms/#{@domain.name_puny}/delete/#{@token}/invalidaction"
+ assert_equal 404, response.status
+ end
+ #def test_get_non_existent_domain_details_by_uuid
+ # get '/api/v1/registrant/domains/random-uuid', headers: @auth_headers
+ # assert_equal(404, response.status)
+
+ # response_json = JSON.parse(response.body, symbolize_names: true)
+ # assert_equal({ errors: [base: ['Domain not found']] }, response_json)
+ #end
+
+ #def test_root_returns_domain_list
+ # get '/api/v1/registrant/domains', headers: @auth_headers
+ # assert_equal(200, response.status)
+
+ # response_json = JSON.parse(response.body, symbolize_names: true)
+ # array_of_domain_names = response_json.map { |x| x[:name] }
+ # assert(array_of_domain_names.include?('hospital.test'))
+
+ # array_of_domain_registrars = response_json.map { |x| x[:registrar] }
+ # assert(array_of_domain_registrars.include?({name: 'Good Names', website: nil}))
+ #end
+
+ #def test_root_accepts_limit_and_offset_parameters
+ # get '/api/v1/registrant/domains', params: { 'limit' => 2, 'offset' => 0 },
+ # headers: @auth_headers
+ # response_json = JSON.parse(response.body, symbolize_names: true)
+
+ # assert_equal(200, response.status)
+ # assert_equal(2, response_json.count)
+
+ # get '/api/v1/registrant/domains', headers: @auth_headers
+ # response_json = JSON.parse(response.body, symbolize_names: true)
+
+ # assert_equal(4, response_json.count)
+ #end
+
+ #def test_root_does_not_accept_limit_higher_than_200
+ # get '/api/v1/registrant/domains', params: { 'limit' => 400, 'offset' => 0 },
+ # headers: @auth_headers
+
+ # assert_equal(400, response.status)
+ # response_json = JSON.parse(response.body, symbolize_names: true)
+ # assert_equal({ errors: [{ limit: ['parameter is out of range'] }] }, response_json)
+ #end
+
+ #def test_root_does_not_accept_offset_lower_than_0
+ # get '/api/v1/registrant/domains', params: { 'limit' => 200, 'offset' => "-10" },
+ # headers: @auth_headers
+
+ # assert_equal(400, response.status)
+ # response_json = JSON.parse(response.body, symbolize_names: true)
+ # assert_equal({ errors: [{ offset: ['parameter is out of range'] }] }, response_json)
+ #end
+
+ #def test_root_returns_401_without_authorization
+ # get '/api/v1/registrant/domains'
+ # assert_equal(401, response.status)
+ # json_body = JSON.parse(response.body, symbolize_names: true)
+
+ # assert_equal({ errors: [base: ['Not authorized']] }, json_body)
+ #end
+
+ #def test_details_returns_401_without_authorization
+ # get '/api/v1/registrant/domains/5edda1a5-3548-41ee-8b65-6d60daf85a37'
+ # assert_equal(401, response.status)
+ # json_body = JSON.parse(response.body, symbolize_names: true)
+
+ # assert_equal({ errors: [base: ['Not authorized']] }, json_body)
+ #end
+end
From 26ec7e3f12a3d88294b8631c57ed2c1c95b60a5e Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Fri, 13 Sep 2019 16:55:40 +0300
Subject: [PATCH 113/172] Combine tests
---
.../integration/epp/login/credentials_test.rb | 64 -------
.../epp/login/password_change_test.rb | 32 ----
.../epp/login/session_limit_test.rb | 61 -------
test/integration/epp/login_test.rb | 167 ++++++++++++++++++
4 files changed, 167 insertions(+), 157 deletions(-)
delete mode 100644 test/integration/epp/login/credentials_test.rb
delete mode 100644 test/integration/epp/login/password_change_test.rb
delete mode 100644 test/integration/epp/login/session_limit_test.rb
create mode 100644 test/integration/epp/login_test.rb
diff --git a/test/integration/epp/login/credentials_test.rb b/test/integration/epp/login/credentials_test.rb
deleted file mode 100644
index 0f7dac97c..000000000
--- a/test/integration/epp/login/credentials_test.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-require 'test_helper'
-
-class EppLoginCredentialsTest < EppTestCase
- def test_correct_credentials
- request_xml = <<-XML
-
-
-
-
- test_bestnames
- testtest
-
- 1.0
- en
-
-
- https://epp.tld.ee/schema/domain-eis-1.0.xsd
- https://epp.tld.ee/schema/contact-ee-1.1.xsd
- urn:ietf:params:xml:ns:host-1.0
-
-
-
-
- XML
-
- post epp_login_path, params: { frame: request_xml },
- headers: { 'HTTP_COOKIE' => 'session=new_session_id' }
- assert EppSession.find_by(session_id: 'new_session_id')
- assert_equal users(:api_bestnames), EppSession.find_by(session_id: 'new_session_id').user
- assert_epp_response :completed_successfully
- end
-
- def test_already_logged_in
- assert true # Handled by EPP proxy
- end
-
- def test_wrong_credentials
- request_xml = <<-XML
-
-
-
-
- non-existent
- valid-but-wrong
-
- 1.0
- en
-
-
- https://epp.tld.ee/schema/domain-eis-1.0.xsd
- https://epp.tld.ee/schema/contact-ee-1.1.xsd
- urn:ietf:params:xml:ns:host-1.0
-
-
-
-
- XML
-
- post epp_login_path, params: { frame: request_xml },
- headers: { 'HTTP_COOKIE' => 'session=any_random_string' }
-
- assert_epp_response :authentication_error_server_closing_connection
- end
-end
diff --git a/test/integration/epp/login/password_change_test.rb b/test/integration/epp/login/password_change_test.rb
deleted file mode 100644
index 3b1834406..000000000
--- a/test/integration/epp/login/password_change_test.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-require 'test_helper'
-
-class EppLoginPasswordChangeTest < EppTestCase
- def test_password_change
- request_xml = <<-XML
-
-
-
-
- test_bestnames
- testtest
- new-password
-
- 1.0
- en
-
-
- https://epp.tld.ee/schema/domain-eis-1.0.xsd
- https://epp.tld.ee/schema/contact-ee-1.1.xsd
- urn:ietf:params:xml:ns:host-1.0
-
-
-
-
- XML
-
- post epp_login_path, params: { frame: request_xml },
- headers: { 'HTTP_COOKIE' => 'session=new_session_id' }
- assert_equal 'new-password', users(:api_bestnames).plain_text_password
- assert_epp_response :completed_successfully
- end
-end
\ No newline at end of file
diff --git a/test/integration/epp/login/session_limit_test.rb b/test/integration/epp/login/session_limit_test.rb
deleted file mode 100644
index f1d83fe7b..000000000
--- a/test/integration/epp/login/session_limit_test.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-require 'test_helper'
-
-class EppLoginSessionLimitTest < EppTestCase
- setup do
- travel_to Time.zone.parse('2010-07-05')
- EppSession.delete_all
- end
-
- def test_not_reached
- (EppSession.limit_per_registrar - 1).times do
- EppSession.create!(session_id: SecureRandom.hex,
- user: users(:api_bestnames),
- updated_at: Time.zone.parse('2010-07-05'))
- end
-
- assert_difference 'EppSession.count' do
- post epp_login_path, params: { frame: request_xml },
- headers: { 'HTTP_COOKIE' => 'session=new_session_id' }
- end
- assert_epp_response :completed_successfully
- end
-
- def test_reached
- EppSession.limit_per_registrar.times do
- EppSession.create!(session_id: SecureRandom.hex,
- user: users(:api_bestnames),
- updated_at: Time.zone.parse('2010-07-05'))
- end
-
- assert_no_difference 'EppSession.count' do
- post epp_login_path, params: { frame: request_xml },
- headers: { 'HTTP_COOKIE' => 'session=new_session_id' }
- end
- assert_epp_response :authentication_error_server_closing_connection
- end
-
- private
-
- def request_xml
- <<-XML
-
-
-
-
- test_bestnames
- testtest
-
- 1.0
- en
-
-
- https://epp.tld.ee/schema/domain-eis-1.0.xsd
- https://epp.tld.ee/schema/contact-ee-1.1.xsd
- urn:ietf:params:xml:ns:host-1.0
-
-
-
-
- XML
- end
-end
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
new file mode 100644
index 000000000..d3ef22ec1
--- /dev/null
+++ b/test/integration/epp/login_test.rb
@@ -0,0 +1,167 @@
+require 'test_helper'
+
+class EppLoginTest < EppTestCase
+ def test_correct_credentials
+ request_xml = <<-XML
+
+
+
+
+ test_bestnames
+ testtest
+
+ 1.0
+ en
+
+
+ https://epp.tld.ee/schema/domain-eis-1.0.xsd
+ https://epp.tld.ee/schema/contact-ee-1.1.xsd
+ urn:ietf:params:xml:ns:host-1.0
+ urn:ietf:params:xml:ns:keyrelay-1.0
+
+
+
+
+ XML
+
+ post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' }
+ assert EppSession.find_by(session_id: 'new_session_id')
+ assert_equal users(:api_bestnames), EppSession.find_by(session_id: 'new_session_id').user
+ assert_epp_response :completed_successfully
+ end
+
+ def test_already_logged_in
+ assert true # Handled by mod_epp
+ end
+
+ def test_wrong_credentials
+ request_xml = <<-XML
+
+
+
+
+ non-existent
+ valid-but-wrong
+
+ 1.0
+ en
+
+
+ https://epp.tld.ee/schema/domain-eis-1.0.xsd
+ https://epp.tld.ee/schema/contact-ee-1.1.xsd
+ urn:ietf:params:xml:ns:host-1.0
+ urn:ietf:params:xml:ns:keyrelay-1.0
+
+
+
+
+ XML
+
+ post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=any_random_string'
+
+ assert_epp_response :authentication_error_server_closing_connection
+ end
+
+ def test_password_change
+ request_xml = <<-XML
+
+
+
+
+ test_bestnames
+ testtest
+ new-password
+
+ 1.0
+ en
+
+
+ https://epp.tld.ee/schema/domain-eis-1.0.xsd
+ https://epp.tld.ee/schema/contact-ee-1.1.xsd
+ urn:ietf:params:xml:ns:host-1.0
+ urn:ietf:params:xml:ns:keyrelay-1.0
+
+
+
+
+ XML
+
+ post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' }
+ assert_equal 'new-password', users(:api_bestnames).plain_text_password
+ assert_epp_response :completed_successfully
+ end
+
+ def test_not_reached
+ travel_to Time.zone.parse('2010-07-05')
+ EppSession.delete_all
+ request_xml = <<-XML
+
+
+
+
+ test_bestnames
+ testtest
+
+ 1.0
+ en
+
+
+ https://epp.tld.ee/schema/domain-eis-1.0.xsd
+ https://epp.tld.ee/schema/contact-ee-1.1.xsd
+ urn:ietf:params:xml:ns:host-1.0
+ urn:ietf:params:xml:ns:keyrelay-1.0
+
+
+
+
+ XML
+
+ (EppSession.limit_per_registrar - 1).times do
+ EppSession.create!(session_id: SecureRandom.hex,
+ user: users(:api_bestnames),
+ updated_at: Time.zone.parse('2010-07-05'))
+ end
+
+ assert_difference 'EppSession.count' do
+ post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' }
+ end
+ assert_epp_response :completed_successfully
+ end
+
+ def test_reached
+ travel_to Time.zone.parse('2010-07-05')
+ EppSession.delete_all
+ request_xml = <<-XML
+
+
+
+
+ test_bestnames
+ testtest
+
+ 1.0
+ en
+
+
+ https://epp.tld.ee/schema/domain-eis-1.0.xsd
+ https://epp.tld.ee/schema/contact-ee-1.1.xsd
+ urn:ietf:params:xml:ns:host-1.0
+ urn:ietf:params:xml:ns:keyrelay-1.0
+
+
+
+
+ XML
+
+ EppSession.limit_per_registrar.times do
+ EppSession.create!(session_id: SecureRandom.hex,
+ user: users(:api_bestnames),
+ updated_at: Time.zone.parse('2010-07-05'))
+ end
+
+ assert_no_difference 'EppSession.count' do
+ post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' }
+ end
+ assert_epp_response :authentication_error_server_closing_connection
+ end
+end
From 087300ff9d440e9c18759288184ee8337490223b Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Fri, 13 Sep 2019 17:01:29 +0300
Subject: [PATCH 114/172] Reformat
---
app/controllers/epp/sessions_controller.rb | 6 +++---
test/integration/epp/login_test.rb | 11 +++++------
2 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/app/controllers/epp/sessions_controller.rb b/app/controllers/epp/sessions_controller.rb
index b1c7fbbfb..e84659c86 100644
--- a/app/controllers/epp/sessions_controller.rb
+++ b/app/controllers/epp/sessions_controller.rb
@@ -90,8 +90,8 @@ module Epp
if params[:parsed_frame].css('newPW').first
unless @api_user.update(plain_text_password: params[:parsed_frame].css('newPW').first.text)
handle_errors(@api_user) and return
+ end
end
- end
epp_session = EppSession.new
epp_session.session_id = epp_session_id
@@ -100,8 +100,8 @@ module Epp
render_epp_response('login_success')
else
handle_errors
+ end
end
- end
def ip_white?
webclient_request = ENV['webclient_ips'].split(',').map(&:strip).include?(request.ip)
@@ -125,7 +125,7 @@ module Epp
@api_user = current_user # cache current_user for logging
epp_session.destroy
render_epp_response('logout')
- end
+ end
### HELPER METHODS ###
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
index d3ef22ec1..2c69dcf49 100644
--- a/test/integration/epp/login_test.rb
+++ b/test/integration/epp/login_test.rb
@@ -23,11 +23,11 @@ class EppLoginTest < EppTestCase
XML
+ post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new_session_id'
- post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' }
+ assert_epp_response :completed_successfully
assert EppSession.find_by(session_id: 'new_session_id')
assert_equal users(:api_bestnames), EppSession.find_by(session_id: 'new_session_id').user
- assert_epp_response :completed_successfully
end
def test_already_logged_in
@@ -56,7 +56,6 @@ class EppLoginTest < EppTestCase
XML
-
post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=any_random_string'
assert_epp_response :authentication_error_server_closing_connection
@@ -85,8 +84,8 @@ class EppLoginTest < EppTestCase
XML
+ post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new_session_id'
- post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' }
assert_equal 'new-password', users(:api_bestnames).plain_text_password
assert_epp_response :completed_successfully
end
@@ -123,7 +122,7 @@ class EppLoginTest < EppTestCase
end
assert_difference 'EppSession.count' do
- post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' }
+ post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new_session_id'
end
assert_epp_response :completed_successfully
end
@@ -160,7 +159,7 @@ class EppLoginTest < EppTestCase
end
assert_no_difference 'EppSession.count' do
- post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' }
+ post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new_session_id'
end
assert_epp_response :authentication_error_server_closing_connection
end
From 7ba5b3b2ae74992aa1a4112848c37911d40d27b5 Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Fri, 13 Sep 2019 17:10:08 +0300
Subject: [PATCH 115/172] Refactor EPP login password change
---
app/controllers/epp/sessions_controller.rb | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/app/controllers/epp/sessions_controller.rb b/app/controllers/epp/sessions_controller.rb
index e84659c86..6c3509786 100644
--- a/app/controllers/epp/sessions_controller.rb
+++ b/app/controllers/epp/sessions_controller.rb
@@ -87,10 +87,11 @@ module Epp
end
if success
- if params[:parsed_frame].css('newPW').first
- unless @api_user.update(plain_text_password: params[:parsed_frame].css('newPW').first.text)
- handle_errors(@api_user) and return
- end
+ new_password = params[:parsed_frame].at_css('newPW')&.text
+
+ if new_password.present?
+ @api_user.plain_text_password = new_password
+ @api_user.save!
end
epp_session = EppSession.new
From 3a5779782a111442b8cf6610e02a0f842106cc5d Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Fri, 13 Sep 2019 17:53:32 +0300
Subject: [PATCH 116/172] Prohibit authenticated EPP user from logging in again
Fixes #1313
---
app/controllers/epp/sessions_controller.rb | 14 +++++++++-
test/integration/epp/login_test.rb | 30 ++++++++++++++++++++--
2 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/app/controllers/epp/sessions_controller.rb b/app/controllers/epp/sessions_controller.rb
index 6c3509786..df706b55d 100644
--- a/app/controllers/epp/sessions_controller.rb
+++ b/app/controllers/epp/sessions_controller.rb
@@ -88,12 +88,24 @@ module Epp
if success
new_password = params[:parsed_frame].at_css('newPW')&.text
+ password_change = new_password.present?
- if new_password.present?
+ if password_change
@api_user.plain_text_password = new_password
@api_user.save!
end
+ already_authenticated = EppSession.exists?(session_id: epp_session_id)
+
+ if already_authenticated
+ epp_errors << {
+ msg: 'Command use error; Already authenticated',
+ code: 2002,
+ }
+ handle_errors
+ return
+ end
+
epp_session = EppSession.new
epp_session.session_id = epp_session_id
epp_session.user = @api_user
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
index 2c69dcf49..c44ac1eee 100644
--- a/test/integration/epp/login_test.rb
+++ b/test/integration/epp/login_test.rb
@@ -30,8 +30,34 @@ class EppLoginTest < EppTestCase
assert_equal users(:api_bestnames), EppSession.find_by(session_id: 'new_session_id').user
end
- def test_already_logged_in
- assert true # Handled by mod_epp
+ def test_user_cannot_login_again
+ session = epp_sessions(:api_bestnames)
+ user = session.user
+
+ request_xml = <<-XML
+
+
+
+
+ #{user.username}
+ #{user.plain_text_password}
+
+ 1.0
+ en
+
+
+ https://epp.tld.ee/schema/domain-eis-1.0.xsd
+ https://epp.tld.ee/schema/contact-ee-1.1.xsd
+ urn:ietf:params:xml:ns:host-1.0
+ urn:ietf:params:xml:ns:keyrelay-1.0
+
+
+
+
+ XML
+ post '/epp/session/login', { frame: request_xml }, HTTP_COOKIE: "session=#{session.session_id}"
+
+ assert_epp_response :use_error
end
def test_wrong_credentials
From 370b37cff6f479a49e3d8e21d3931817b6db4775 Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Fri, 13 Sep 2019 18:22:30 +0300
Subject: [PATCH 117/172] Improve readability
---
test/integration/epp/login_test.rb | 65 +++++++++++++++++++-----------
1 file changed, 42 insertions(+), 23 deletions(-)
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
index c44ac1eee..83e41cc27 100644
--- a/test/integration/epp/login_test.rb
+++ b/test/integration/epp/login_test.rb
@@ -1,14 +1,17 @@
require 'test_helper'
class EppLoginTest < EppTestCase
- def test_correct_credentials
+ def test_logging_in_with_correct_credentials_creates_new_session
+ user = users(:api_bestnames)
+ new_session_id = 'new-session-id'
+
request_xml = <<-XML
- test_bestnames
- testtest
+ #{user.username}
+ #{user.plain_text_password}1.0en
@@ -23,11 +26,13 @@ class EppLoginTest < EppTestCase
XML
- post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new_session_id'
-
+ assert_difference 'EppSession.count' do
+ post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{new_session_id}"
+ end
assert_epp_response :completed_successfully
- assert EppSession.find_by(session_id: 'new_session_id')
- assert_equal users(:api_bestnames), EppSession.find_by(session_id: 'new_session_id').user
+ session = EppSession.last
+ assert_equal new_session_id, session.session_id
+ assert_equal user, session.user
end
def test_user_cannot_login_again
@@ -55,19 +60,25 @@ class EppLoginTest < EppTestCase
XML
- post '/epp/session/login', { frame: request_xml }, HTTP_COOKIE: "session=#{session.session_id}"
+ assert_no_difference 'EppSession.count' do
+ post '/epp/session/login', { frame: request_xml }, HTTP_COOKIE: "session=#{session.session_id}"
+ end
assert_epp_response :use_error
end
- def test_wrong_credentials
+ def test_user_cannot_login_with_wrong_credentials
+ user = users(:api_bestnames)
+ wrong_password = 'a' * ApiUser.min_password_length
+ assert_not_equal wrong_password, user.plain_text_password
+
request_xml = <<-XML
- non-existent
- valid-but-wrong
+ #{user.username}
+ #{wrong_password}1.0en
@@ -82,20 +93,26 @@ class EppLoginTest < EppTestCase
XML
- post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=any_random_string'
+ assert_no_difference 'EppSession.count' do
+ post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new-session-id'
+ end
assert_epp_response :authentication_error_server_closing_connection
end
def test_password_change
+ user = users(:api_bestnames)
+ new_password = 'a' * ApiUser.min_password_length
+ assert_not_equal new_password, user.plain_text_password
+
request_xml = <<-XML
- test_bestnames
- testtest
- new-password
+ #{user.username}
+ #{user.plain_text_password}
+ #{new_password}1.0en
@@ -110,10 +127,11 @@ class EppLoginTest < EppTestCase
XML
- post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new_session_id'
+ post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new-session-id'
+ user.reload
- assert_equal 'new-password', users(:api_bestnames).plain_text_password
assert_epp_response :completed_successfully
+ assert_equal new_password, user.plain_text_password
end
def test_not_reached
@@ -148,12 +166,13 @@ class EppLoginTest < EppTestCase
end
assert_difference 'EppSession.count' do
- post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new_session_id'
+ post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=non-existent'
end
assert_epp_response :completed_successfully
end
- def test_reached
+ def test_user_cannot_login_when_session_limit_reached
+ user = users(:api_bestnames)
travel_to Time.zone.parse('2010-07-05')
EppSession.delete_all
request_xml = <<-XML
@@ -161,8 +180,8 @@ class EppLoginTest < EppTestCase
- test_bestnames
- testtest
+ #{user.username}
+ #{user.plain_text_password}1.0en
@@ -180,12 +199,12 @@ class EppLoginTest < EppTestCase
EppSession.limit_per_registrar.times do
EppSession.create!(session_id: SecureRandom.hex,
- user: users(:api_bestnames),
+ user: user,
updated_at: Time.zone.parse('2010-07-05'))
end
assert_no_difference 'EppSession.count' do
- post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new_session_id'
+ post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new-session-id'
end
assert_epp_response :authentication_error_server_closing_connection
end
From 744d6a2b537b4e3f70d429f886f1fd382d44f644 Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Fri, 13 Sep 2019 18:23:18 +0300
Subject: [PATCH 118/172] Remove unnecessary test
---
test/integration/epp/login_test.rb | 37 ------------------------------
1 file changed, 37 deletions(-)
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
index 83e41cc27..fe8ef2cf8 100644
--- a/test/integration/epp/login_test.rb
+++ b/test/integration/epp/login_test.rb
@@ -134,43 +134,6 @@ class EppLoginTest < EppTestCase
assert_equal new_password, user.plain_text_password
end
- def test_not_reached
- travel_to Time.zone.parse('2010-07-05')
- EppSession.delete_all
- request_xml = <<-XML
-
-
-
-
- test_bestnames
- testtest
-
- 1.0
- en
-
-
- https://epp.tld.ee/schema/domain-eis-1.0.xsd
- https://epp.tld.ee/schema/contact-ee-1.1.xsd
- urn:ietf:params:xml:ns:host-1.0
- urn:ietf:params:xml:ns:keyrelay-1.0
-
-
-
-
- XML
-
- (EppSession.limit_per_registrar - 1).times do
- EppSession.create!(session_id: SecureRandom.hex,
- user: users(:api_bestnames),
- updated_at: Time.zone.parse('2010-07-05'))
- end
-
- assert_difference 'EppSession.count' do
- post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=non-existent'
- end
- assert_epp_response :completed_successfully
- end
-
def test_user_cannot_login_when_session_limit_reached
user = users(:api_bestnames)
travel_to Time.zone.parse('2010-07-05')
From daeb00ebe7719689703cee1ad5d469e01cef4ffe Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Fri, 13 Sep 2019 21:06:23 +0300
Subject: [PATCH 119/172] Change EPP response code according to its
specification
Fixes #587
---
app/controllers/epp/sessions_controller.rb | 4 ++--
app/models/epp/response/result/code.rb | 2 ++
test/integration/epp/login_test.rb | 2 +-
test/models/epp/response/result/code_test.rb | 2 ++
4 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/app/controllers/epp/sessions_controller.rb b/app/controllers/epp/sessions_controller.rb
index df706b55d..04603dbe7 100644
--- a/app/controllers/epp/sessions_controller.rb
+++ b/app/controllers/epp/sessions_controller.rb
@@ -79,8 +79,8 @@ module Epp
if success && EppSession.limit_reached?(@api_user.registrar)
epp_errors << {
- msg: 'Authentication error; server closing connection (connection limit reached)',
- code: '2501'
+ msg: 'Session limit exceeded; server closing connection (connection limit reached)',
+ code: '2502',
}
success = false
diff --git a/app/models/epp/response/result/code.rb b/app/models/epp/response/result/code.rb
index 1be4a3f7c..10edf0a35 100644
--- a/app/models/epp/response/result/code.rb
+++ b/app/models/epp/response/result/code.rb
@@ -30,6 +30,7 @@ module Epp
data_management_policy_violation: 2308,
command_failed: 2400,
authentication_error_server_closing_connection: 2501,
+ session_limit_exceeded_server_closing_connection: 2502,
}.freeze
private_constant :KEY_TO_VALUE
@@ -59,6 +60,7 @@ module Epp
2308 => 'Data management policy violation',
2400 => 'Command failed',
2501 => 'Authentication error; server closing connection',
+ 2502 => 'Session limit exceeded; server closing connection',
}.freeze
private_constant :DEFAULT_DESCRIPTIONS
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
index fe8ef2cf8..7442728a0 100644
--- a/test/integration/epp/login_test.rb
+++ b/test/integration/epp/login_test.rb
@@ -169,6 +169,6 @@ class EppLoginTest < EppTestCase
assert_no_difference 'EppSession.count' do
post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new-session-id'
end
- assert_epp_response :authentication_error_server_closing_connection
+ assert_epp_response :session_limit_exceeded_server_closing_connection
end
end
diff --git a/test/models/epp/response/result/code_test.rb b/test/models/epp/response/result/code_test.rb
index f16013180..184a18438 100644
--- a/test/models/epp/response/result/code_test.rb
+++ b/test/models/epp/response/result/code_test.rb
@@ -51,6 +51,7 @@ class EppResponseResultCodeTest < ActiveSupport::TestCase
data_management_policy_violation: 2308,
command_failed: 2400,
authentication_error_server_closing_connection: 2501,
+ session_limit_exceeded_server_closing_connection: 2502,
}
assert_equal codes, Epp::Response::Result::Code.codes
end
@@ -82,6 +83,7 @@ class EppResponseResultCodeTest < ActiveSupport::TestCase
2308 => 'Data management policy violation',
2400 => 'Command failed',
2501 => 'Authentication error; server closing connection',
+ 2502 => 'Session limit exceeded; server closing connection',
}
assert_equal descriptions, Epp::Response::Result::Code.default_descriptions
end
From 59fbcde4ca6356e334ec5b36823d4dd84060dfdd Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Tue, 17 Sep 2019 17:17:51 +0300
Subject: [PATCH 120/172] Remove hardcoded value
---
app/models/epp_session.rb | 7 +++----
config/application.yml.sample | 2 ++
test/models/epp_session_test.rb | 4 ----
3 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/app/models/epp_session.rb b/app/models/epp_session.rb
index f1b641aa0..1336be39e 100644
--- a/app/models/epp_session.rb
+++ b/app/models/epp_session.rb
@@ -6,11 +6,10 @@ class EppSession < ApplicationRecord
class_attribute :timeout
self.timeout = (ENV['epp_session_timeout_seconds'] || 300).to_i.seconds
- alias_attribute :last_access, :updated_at
+ class_attribute :limit_per_registrar
+ self.limit_per_registrar = (ENV['epp_session_limit_per_registrar'] || 4).to_i
- def self.limit_per_registrar
- 4
- end
+ alias_attribute :last_access, :updated_at
def self.limit_reached?(registrar)
count = where(user_id: registrar.api_users.ids).where('updated_at >= ?', Time.zone.now - 1.second).count
diff --git a/config/application.yml.sample b/config/application.yml.sample
index ab64ed35e..65e83b603 100644
--- a/config/application.yml.sample
+++ b/config/application.yml.sample
@@ -170,6 +170,8 @@ tara_rant_redirect_uri: 'redirect_uri'
default_email_validation_type: 'regex'
+epp_session_limit_per_registrar: '4'
+
# Since the keys for staging are absent from the repo, we need to supply them separate for testing.
test:
payments_seb_bank_certificate: 'test/fixtures/files/seb_bank_cert.pem'
diff --git a/test/models/epp_session_test.rb b/test/models/epp_session_test.rb
index 8ed63f6ab..398753bd1 100644
--- a/test/models/epp_session_test.rb
+++ b/test/models/epp_session_test.rb
@@ -49,10 +49,6 @@ class EppSessionTest < ActiveSupport::TestCase
end
end
- def test_limit_per_registrar
- assert_equal 4, EppSession.limit_per_registrar
- end
-
def test_limit_is_per_registrar
travel_to Time.zone.parse('2010-07-05')
EppSession.delete_all
From 2d1e11ac6d7d93ba31f119640c7fd0810203c79c Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Tue, 17 Sep 2019 17:39:58 +0300
Subject: [PATCH 121/172] Improve readability
---
test/integration/epp/login_test.rb | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
index 7442728a0..bd49f591d 100644
--- a/test/integration/epp/login_test.rb
+++ b/test/integration/epp/login_test.rb
@@ -134,10 +134,16 @@ class EppLoginTest < EppTestCase
assert_equal new_password, user.plain_text_password
end
- def test_user_cannot_login_when_session_limit_reached
+ def test_user_cannot_login_when_session_limit_is_exceeded
user = users(:api_bestnames)
travel_to Time.zone.parse('2010-07-05')
- EppSession.delete_all
+ eliminate_effect_of_existing_epp_sessions
+ EppSession.limit_per_registrar.times do
+ EppSession.create!(session_id: SecureRandom.hex,
+ user: user,
+ updated_at: Time.zone.parse('2010-07-05'))
+ end
+
request_xml = <<-XML
@@ -160,15 +166,15 @@ class EppLoginTest < EppTestCase
XML
- EppSession.limit_per_registrar.times do
- EppSession.create!(session_id: SecureRandom.hex,
- user: user,
- updated_at: Time.zone.parse('2010-07-05'))
- end
-
assert_no_difference 'EppSession.count' do
post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new-session-id'
end
assert_epp_response :session_limit_exceeded_server_closing_connection
end
+
+ private
+
+ def eliminate_effect_of_existing_epp_sessions
+ EppSession.delete_all
+ end
end
From 1e997ad5b1ff39f05eb1ab3f61e5868851fd9bd1 Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Tue, 17 Sep 2019 17:50:02 +0300
Subject: [PATCH 122/172] Simplify test
---
test/integration/epp/login_test.rb | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
index bd49f591d..ada2ff0c3 100644
--- a/test/integration/epp/login_test.rb
+++ b/test/integration/epp/login_test.rb
@@ -1,6 +1,14 @@
require 'test_helper'
class EppLoginTest < EppTestCase
+ setup do
+ @original_session_limit_per_registrar = EppSession.limit_per_registrar
+ end
+
+ teardown do
+ EppSession.limit_per_registrar = @original_session_limit_per_registrar
+ end
+
def test_logging_in_with_correct_credentials_creates_new_session
user = users(:api_bestnames)
new_session_id = 'new-session-id'
@@ -138,11 +146,10 @@ class EppLoginTest < EppTestCase
user = users(:api_bestnames)
travel_to Time.zone.parse('2010-07-05')
eliminate_effect_of_existing_epp_sessions
- EppSession.limit_per_registrar.times do
- EppSession.create!(session_id: SecureRandom.hex,
- user: user,
- updated_at: Time.zone.parse('2010-07-05'))
- end
+ EppSession.limit_per_registrar = 1
+ EppSession.create!(session_id: 'any',
+ user: user,
+ updated_at: Time.zone.parse('2010-07-05'))
request_xml = <<-XML
From 9eb7d3527b8bbc9175cbd53e9889eb6d99ffe611 Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Tue, 17 Sep 2019 17:55:24 +0300
Subject: [PATCH 123/172] Do not take time into account when checking EPP
session limit
---
app/models/epp_session.rb | 2 +-
test/integration/epp/login_test.rb | 5 +----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/app/models/epp_session.rb b/app/models/epp_session.rb
index 1336be39e..657f76973 100644
--- a/app/models/epp_session.rb
+++ b/app/models/epp_session.rb
@@ -12,7 +12,7 @@ class EppSession < ApplicationRecord
alias_attribute :last_access, :updated_at
def self.limit_reached?(registrar)
- count = where(user_id: registrar.api_users.ids).where('updated_at >= ?', Time.zone.now - 1.second).count
+ count = where(user_id: registrar.api_users.ids).count
count >= limit_per_registrar
end
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
index ada2ff0c3..fe62f9afe 100644
--- a/test/integration/epp/login_test.rb
+++ b/test/integration/epp/login_test.rb
@@ -144,12 +144,9 @@ class EppLoginTest < EppTestCase
def test_user_cannot_login_when_session_limit_is_exceeded
user = users(:api_bestnames)
- travel_to Time.zone.parse('2010-07-05')
eliminate_effect_of_existing_epp_sessions
EppSession.limit_per_registrar = 1
- EppSession.create!(session_id: 'any',
- user: user,
- updated_at: Time.zone.parse('2010-07-05'))
+ EppSession.create!(session_id: 'any', user: user)
request_xml = <<-XML
From cbb3c0d5ef706c63102cd9e1e311d24aab162621 Mon Sep 17 00:00:00 2001
From: Artur Beljajev
Date: Tue, 17 Sep 2019 18:03:49 +0300
Subject: [PATCH 124/172] Improve readability
---
app/models/epp_session.rb | 6 +++---
config/application.yml.sample | 2 +-
test/integration/epp/login_test.rb | 8 ++++----
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/app/models/epp_session.rb b/app/models/epp_session.rb
index 657f76973..7567bf3d2 100644
--- a/app/models/epp_session.rb
+++ b/app/models/epp_session.rb
@@ -6,14 +6,14 @@ class EppSession < ApplicationRecord
class_attribute :timeout
self.timeout = (ENV['epp_session_timeout_seconds'] || 300).to_i.seconds
- class_attribute :limit_per_registrar
- self.limit_per_registrar = (ENV['epp_session_limit_per_registrar'] || 4).to_i
+ class_attribute :sessions_per_registrar
+ self.sessions_per_registrar = (ENV['epp_session_limit_per_registrar'] || 4).to_i
alias_attribute :last_access, :updated_at
def self.limit_reached?(registrar)
count = where(user_id: registrar.api_users.ids).count
- count >= limit_per_registrar
+ count >= sessions_per_registrar
end
def self.expired
diff --git a/config/application.yml.sample b/config/application.yml.sample
index 65e83b603..e979e772a 100644
--- a/config/application.yml.sample
+++ b/config/application.yml.sample
@@ -170,7 +170,7 @@ tara_rant_redirect_uri: 'redirect_uri'
default_email_validation_type: 'regex'
-epp_session_limit_per_registrar: '4'
+epp_sessions_per_registrar: '4'
# Since the keys for staging are absent from the repo, we need to supply them separate for testing.
test:
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
index fe62f9afe..d82ba8891 100644
--- a/test/integration/epp/login_test.rb
+++ b/test/integration/epp/login_test.rb
@@ -2,11 +2,11 @@ require 'test_helper'
class EppLoginTest < EppTestCase
setup do
- @original_session_limit_per_registrar = EppSession.limit_per_registrar
+ @original_sessions_per_registrar_setting = EppSession.sessions_per_registrar
end
teardown do
- EppSession.limit_per_registrar = @original_session_limit_per_registrar
+ EppSession.sessions_per_registrar = @original_sessions_per_registrar_setting
end
def test_logging_in_with_correct_credentials_creates_new_session
@@ -142,10 +142,10 @@ class EppLoginTest < EppTestCase
assert_equal new_password, user.plain_text_password
end
- def test_user_cannot_login_when_session_limit_is_exceeded
+ def test_user_cannot_login_when_max_allowed_sessions_per_registrar_is_exceeded
user = users(:api_bestnames)
eliminate_effect_of_existing_epp_sessions
- EppSession.limit_per_registrar = 1
+ EppSession.sessions_per_registrar = 1
EppSession.create!(session_id: 'any', user: user)
request_xml = <<-XML
From 26c8fe6a3e8e68a75ba3076e1d329d50f5ea0d4a Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Fri, 4 Sep 2020 15:06:40 +0500
Subject: [PATCH 125/172] Fix tests
---
test/integration/epp/login_test.rb | 15 ++++++++++-----
test/models/epp_session_test.rb | 2 +-
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/test/integration/epp/login_test.rb b/test/integration/epp/login_test.rb
index d82ba8891..dd7a750c9 100644
--- a/test/integration/epp/login_test.rb
+++ b/test/integration/epp/login_test.rb
@@ -35,7 +35,8 @@ class EppLoginTest < EppTestCase
XML
assert_difference 'EppSession.count' do
- post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{new_session_id}"
+ post '/epp/session/login', params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => "session=#{new_session_id}" }
end
assert_epp_response :completed_successfully
session = EppSession.last
@@ -70,7 +71,8 @@ class EppLoginTest < EppTestCase
XML
assert_no_difference 'EppSession.count' do
- post '/epp/session/login', { frame: request_xml }, HTTP_COOKIE: "session=#{session.session_id}"
+ post '/epp/session/login', params: { frame: request_xml },
+ headers: { HTTP_COOKIE: "session=#{session.session_id}" }
end
assert_epp_response :use_error
end
@@ -103,7 +105,8 @@ class EppLoginTest < EppTestCase
XML
assert_no_difference 'EppSession.count' do
- post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new-session-id'
+ post '/epp/session/login', params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=new-session-id' }
end
assert_epp_response :authentication_error_server_closing_connection
end
@@ -135,7 +138,8 @@ class EppLoginTest < EppTestCase
XML
- post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new-session-id'
+ post '/epp/session/login', params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=new-session-id' }
user.reload
assert_epp_response :completed_successfully
@@ -171,7 +175,8 @@ class EppLoginTest < EppTestCase
XML
assert_no_difference 'EppSession.count' do
- post '/epp/session/login', { frame: request_xml }, 'HTTP_COOKIE' => 'session=new-session-id'
+ post '/epp/session/login', params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=new-session-id' }
end
assert_epp_response :session_limit_exceeded_server_closing_connection
end
diff --git a/test/models/epp_session_test.rb b/test/models/epp_session_test.rb
index 398753bd1..3fd184e0b 100644
--- a/test/models/epp_session_test.rb
+++ b/test/models/epp_session_test.rb
@@ -53,7 +53,7 @@ class EppSessionTest < ActiveSupport::TestCase
travel_to Time.zone.parse('2010-07-05')
EppSession.delete_all
- EppSession.limit_per_registrar.times do
+ EppSession.sessions_per_registrar.times do
EppSession.create!(session_id: SecureRandom.hex,
user: users(:api_goodnames),
updated_at: Time.zone.parse('2010-07-05'))
From 495e1a4ae169a7f200b63e49087cbd3ce0448e71 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Fri, 13 Nov 2020 13:36:53 +0500
Subject: [PATCH 126/172] Fix env usage in EppSession model
---
app/models/epp_session.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/models/epp_session.rb b/app/models/epp_session.rb
index 7567bf3d2..6bec39ee3 100644
--- a/app/models/epp_session.rb
+++ b/app/models/epp_session.rb
@@ -7,7 +7,7 @@ class EppSession < ApplicationRecord
self.timeout = (ENV['epp_session_timeout_seconds'] || 300).to_i.seconds
class_attribute :sessions_per_registrar
- self.sessions_per_registrar = (ENV['epp_session_limit_per_registrar'] || 4).to_i
+ self.sessions_per_registrar = (ENV['epp_sessions_per_registrar'] || 4).to_i
alias_attribute :last_access, :updated_at
From 13b0d45e255ff44834407b00e77f7ffac0057ae0 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Fri, 13 Nov 2020 14:38:24 +0500
Subject: [PATCH 127/172] Check for 4 sessions only in inexpired ones
---
app/models/epp_session.rb | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/app/models/epp_session.rb b/app/models/epp_session.rb
index 6bec39ee3..a6fb97ed2 100644
--- a/app/models/epp_session.rb
+++ b/app/models/epp_session.rb
@@ -11,13 +11,21 @@ class EppSession < ApplicationRecord
alias_attribute :last_access, :updated_at
+ scope :not_expired,
+ lambda {
+ where(':now <= (updated_at + interval :interval)', now: Time.zone.now, interval: interval)
+ }
+
def self.limit_reached?(registrar)
- count = where(user_id: registrar.api_users.ids).count
+ count = where(user_id: registrar.api_users.ids).not_expired.count
count >= sessions_per_registrar
end
+ def self.interval
+ "#{timeout.parts.first.second} #{timeout.parts.first.first}"
+ end
+
def self.expired
- interval = "#{timeout.parts.first.second} #{timeout.parts.first.first}"
where(':now > (updated_at + interval :interval)', now: Time.zone.now, interval: interval)
end
From 54eb1e91decdc65d880ae1f44d0ca6ab135f1f5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Thu, 12 Nov 2020 17:05:13 +0200
Subject: [PATCH 128/172] Fix CC issues
---
app/mailers/application_mailer.rb | 13 ++-
app/mailers/domain_delete_mailer.rb | 11 +--
app/mailers/registrant_change_mailer.rb | 11 +--
.../registrant_api_verifications_test.rb | 90 +++++++++++++------
4 files changed, 78 insertions(+), 47 deletions(-)
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
index 9269a1102..9366174ef 100644
--- a/app/mailers/application_mailer.rb
+++ b/app/mailers/application_mailer.rb
@@ -1,4 +1,15 @@
class ApplicationMailer < ActionMailer::Base
append_view_path Rails.root.join('app', 'views', 'mailers')
layout 'mailer'
-end
\ No newline at end of file
+
+ def registrant_confirm_url(domain:, method:)
+ token = domain.registrant_verification_token
+ base_url = ENV['registrant_portal_verifications_base_url']
+
+ url = registrant_domain_delete_confirm_url(domain, token: token) if method == 'delete'
+ url ||= registrant_domain_update_confirm_url(domain, token: token)
+ return url if base_url.blank?
+
+ "#{base_url}/confirms/#{domain.name_puny}/#{method}/#{token}"
+ end
+end
diff --git a/app/mailers/domain_delete_mailer.rb b/app/mailers/domain_delete_mailer.rb
index 8e2b1a341..8c0e830b1 100644
--- a/app/mailers/domain_delete_mailer.rb
+++ b/app/mailers/domain_delete_mailer.rb
@@ -6,7 +6,7 @@ class DomainDeleteMailer < ApplicationMailer
def confirmation_request(domain:, registrar:, registrant:)
@domain = DomainPresenter.new(domain: domain, view: view_context)
@registrar = RegistrarPresenter.new(registrar: registrar, view: view_context)
- @confirmation_url = confirmation_url(domain)
+ @confirmation_url = registrant_confirm_url(domain: domain, method: 'delete')
subject = default_i18n_subject(domain_name: domain.name)
mail(to: registrant.email, subject: subject)
@@ -52,15 +52,6 @@ class DomainDeleteMailer < ApplicationMailer
private
- def confirmation_url(domain)
- base_url = ENV['registrant_portal_verifications_base_url']
- if base_url.blank?
- registrant_domain_delete_confirm_url(domain, token: domain.registrant_verification_token)
- else
- "#{base_url}/confirmation/#{domain.name_puny}/delete/#{domain.registrant_verification_token}"
- end
- end
-
def forced_email_from
ENV['action_mailer_force_delete_from'] || self.class.default[:from]
end
diff --git a/app/mailers/registrant_change_mailer.rb b/app/mailers/registrant_change_mailer.rb
index 3e97f4b86..8f43f4ab5 100644
--- a/app/mailers/registrant_change_mailer.rb
+++ b/app/mailers/registrant_change_mailer.rb
@@ -5,7 +5,7 @@ class RegistrantChangeMailer < ApplicationMailer
@domain = DomainPresenter.new(domain: domain, view: view_context)
@registrar = RegistrarPresenter.new(registrar: registrar, view: view_context)
@new_registrant = RegistrantPresenter.new(registrant: new_registrant, view: view_context)
- @confirmation_url = confirmation_url(domain)
+ @confirmation_url = registrant_confirm_url(domain: domain, method: 'change')
subject = default_i18n_subject(domain_name: domain.name)
mail(to: current_registrant.email, subject: subject)
@@ -49,15 +49,6 @@ class RegistrantChangeMailer < ApplicationMailer
private
- def confirmation_url(domain)
- base_url = ENV['registrant_portal_verifications_base_url']
- if base_url.blank?
- registrant_domain_update_confirm_url(domain, token: domain.registrant_verification_token)
- else
- "#{base_url}/confirmation/#{domain.name_puny}/change/#{domain.registrant_verification_token}"
- end
- end
-
def address_processing
Contact.address_processing?
end
diff --git a/test/integration/api/registrant/registrant_api_verifications_test.rb b/test/integration/api/registrant/registrant_api_verifications_test.rb
index b2333e560..821d0dee0 100644
--- a/test/integration/api/registrant/registrant_api_verifications_test.rb
+++ b/test/integration/api/registrant/registrant_api_verifications_test.rb
@@ -8,17 +8,22 @@ class RegistrantApiVerificationsTest < ApplicationIntegrationTest
@domain = domains(:hospital)
@registrant = @domain.registrant
@new_registrant = contacts(:jack)
+ @user = users(:api_bestnames)
@token = 'verysecrettoken'
- @domain.update(statuses: [DomainStatus::PENDING_UPDATE],
+ @domain.update!(statuses: [DomainStatus::PENDING_UPDATE],
registrant_verification_asked_at: Time.zone.now - 1.day,
registrant_verification_token: @token)
end
def test_fetches_registrant_change_request
- pending_json = { new_registrant_id: @new_registrant.id }
+ pending_json = { new_registrant_id: @new_registrant.id,
+ new_registrant_name: @new_registrant.name,
+ new_registrant_email: @new_registrant.email,
+ current_user_id: @user.id }
+
@domain.update(pending_json: pending_json)
@domain.reload
@@ -46,31 +51,40 @@ class RegistrantApiVerificationsTest < ApplicationIntegrationTest
end
def test_approves_registrant_change_request
- pending_json = { new_registrant_id: @new_registrant.id }
- @domain.update(pending_json: pending_json)
+ pending_json = { new_registrant_id: @new_registrant.id,
+ new_registrant_name: @new_registrant.name,
+ new_registrant_email: @new_registrant.email,
+ current_user_id: @user.id }
+
+ @domain.update!(pending_json: pending_json)
@domain.reload
assert @domain.registrant_update_confirmable?(@token)
- post "/api/v1/registrant/confirms/#{@domain.name_puny}/change/#{@token}/confirmed"
- assert_equal(200, response.status)
+ perform_enqueued_jobs do
+ post "/api/v1/registrant/confirms/#{@domain.name_puny}/change/#{@token}/confirmed"
+ assert_equal(200, response.status)
- res = JSON.parse(response.body, symbolize_names: true)
- expected_body = {
- domain_name: @domain.name,
- current_registrant: {
- name: @new_registrant.name,
- ident: @new_registrant.ident,
- country: @new_registrant.ident_country_code
- },
- status: 'confirmed'
- }
-
- assert_equal expected_body, res
+ res = JSON.parse(response.body, symbolize_names: true)
+ expected_body = {
+ domain_name: @domain.name,
+ current_registrant: {
+ name: @new_registrant.name,
+ ident: @new_registrant.ident,
+ country: @new_registrant.ident_country_code
+ },
+ status: 'confirmed'
+ }
+ assert_equal expected_body, res
+ end
end
def test_rejects_registrant_change_request
- pending_json = { new_registrant_id: @new_registrant.id }
+ pending_json = { new_registrant_id: @new_registrant.id,
+ new_registrant_name: @new_registrant.name,
+ new_registrant_email: @new_registrant.email,
+ current_user_id: @user.id }
+
@domain.update(pending_json: pending_json)
@domain.reload
@@ -94,7 +108,11 @@ class RegistrantApiVerificationsTest < ApplicationIntegrationTest
end
def test_registrant_change_requires_valid_attributes
- pending_json = { new_registrant_id: @new_registrant.id }
+ pending_json = { new_registrant_id: @new_registrant.id,
+ new_registrant_name: @new_registrant.name,
+ new_registrant_email: @new_registrant.email,
+ current_user_id: @user.id }
+
@domain.update(pending_json: pending_json)
@domain.reload
@@ -109,7 +127,12 @@ class RegistrantApiVerificationsTest < ApplicationIntegrationTest
end
def test_fetches_domain_delete_request
- @domain.update(statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
+ pending_json = { new_registrant_id: @new_registrant.id,
+ new_registrant_name: @new_registrant.name,
+ new_registrant_email: @new_registrant.email,
+ current_user_id: @user.id }
+
+ @domain.update(pending_json: pending_json, statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
@domain.reload
assert @domain.registrant_delete_confirmable?(@token)
@@ -131,8 +154,13 @@ class RegistrantApiVerificationsTest < ApplicationIntegrationTest
end
def test_approves_domain_delete_request
- @domain.update(statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
- @domain.reload
+ pending_json = { new_registrant_id: @new_registrant.id,
+ new_registrant_name: @new_registrant.name,
+ new_registrant_email: @new_registrant.email,
+ current_user_id: @user.id }
+
+ @domain.update(pending_json: pending_json, statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
+ @domain.reload
assert @domain.registrant_delete_confirmable?(@token)
@@ -154,8 +182,13 @@ class RegistrantApiVerificationsTest < ApplicationIntegrationTest
end
def test_rejects_domain_delete_request
- @domain.update(statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
- @domain.reload
+ pending_json = { new_registrant_id: @new_registrant.id,
+ new_registrant_name: @new_registrant.name,
+ new_registrant_email: @new_registrant.email,
+ current_user_id: @user.id }
+
+ @domain.update(pending_json: pending_json, statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
+ @domain.reload
assert @domain.registrant_delete_confirmable?(@token)
@@ -177,7 +210,12 @@ class RegistrantApiVerificationsTest < ApplicationIntegrationTest
end
def test_domain_delete_requires_valid_attributes
- @domain.update(statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION, DomainStatus::PENDING_DELETE])
+ pending_json = { new_registrant_id: @new_registrant.id,
+ new_registrant_name: @new_registrant.name,
+ new_registrant_email: @new_registrant.email,
+ current_user_id: @user.id }
+
+ @domain.update(pending_json: pending_json, statuses: [DomainStatus::PENDING_DELETE_CONFIRMATION])
@domain.reload
get "/api/v1/registrant/confirms/#{@domain.name_puny}/delete/123"
From fc816ad67ba143804764ddaeca8721d6e4accbea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Fri, 13 Nov 2020 16:38:39 +0200
Subject: [PATCH 129/172] REPP: Check for ident hash presence before contact
update
---
app/controllers/repp/v1/contacts_controller.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/controllers/repp/v1/contacts_controller.rb b/app/controllers/repp/v1/contacts_controller.rb
index a6cd7d07d..504948ed9 100644
--- a/app/controllers/repp/v1/contacts_controller.rb
+++ b/app/controllers/repp/v1/contacts_controller.rb
@@ -108,7 +108,7 @@ module Repp
end
def contact_ident_params(required: true)
- if required
+ if required || !params[:contact][:ident].nil?
params.require(:contact).require(:ident).require(%i[ident ident_type ident_country_code])
params.require(:contact).require(:ident).permit(:ident, :ident_type, :ident_country_code)
else
From 331ade988c2e891d8addc634e105bf68318defc3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Fri, 13 Nov 2020 17:00:44 +0200
Subject: [PATCH 130/172] Update CHANGELOG.md
---
CHANGELOG.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 21f710645..58ae259b2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+13.11.2020
+* Fixed per registrar epp session limit [#729](https://github.com/internetee/registry/issues/729)
+* Correct error code is returned on reaching session limit [#587](https://github.com/internetee/registry/issues/587)
+* No logins within active session [#1313](https://github.com/internetee/registry/issues/1313)
+
06.11.2020
* Csv option to limit list of domains for bulk nameserver change in registrar portal [#1737](https://github.com/internetee/registry/issues/1737)
* New forceDelete email template for invalid contact data [#1178](https://github.com/internetee/registry/issues/1178)
From 3d0150076c83eba56d474f89557750f8879ba9ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 16 Nov 2020 14:46:37 +0200
Subject: [PATCH 131/172] REPP: Hide contact internal ID
---
.../repp/v1/contacts_controller.rb | 16 ++++---
app/models/epp/contact.rb | 2 +-
lib/serializers/repp/contact.rb | 42 +++++++++++++++++++
3 files changed, 53 insertions(+), 7 deletions(-)
create mode 100644 lib/serializers/repp/contact.rb
diff --git a/app/controllers/repp/v1/contacts_controller.rb b/app/controllers/repp/v1/contacts_controller.rb
index 504948ed9..69d4ecc96 100644
--- a/app/controllers/repp/v1/contacts_controller.rb
+++ b/app/controllers/repp/v1/contacts_controller.rb
@@ -1,3 +1,4 @@
+require 'serializers/repp/contact'
module Repp
module V1
class ContactsController < BaseController
@@ -14,7 +15,8 @@ module Repp
## GET /repp/v1/contacts/1
def show
- render_success(data: @contact.as_json)
+ serializer = ::Serializers::Repp::Contact.new(@contact, show_address: Contact.address_processing?)
+ render_success(data: serializer.to_json)
end
## GET /repp/v1/contacts/check/1
@@ -76,11 +78,13 @@ module Repp
def showable_contacts(details, limit, offset)
contacts = current_user.registrar.contacts.limit(limit).offset(offset)
- unless Contact.address_processing? && params[:details] == 'true'
- contacts = contacts.select(Contact.attribute_names - Contact.address_attribute_names)
- end
- contacts = contacts.pluck(:code) unless details
+ return contacts.pluck(:code) unless details
+
+ contacts = contacts.map do |contact|
+ serializer = ::Serializers::Repp::Contact.new(contact, show_address: Contact.address_processing?)
+ serializer.to_json
+ end
contacts
end
@@ -104,7 +108,7 @@ module Repp
def contact_create_params(required: true)
params.require(:contact).require(%i[name email phone]) if required
- params.require(:contact).permit(:name, :email, :phone, :code)
+ params.require(:contact).permit(:name, :email, :phone, :id)
end
def contact_ident_params(required: true)
diff --git a/app/models/epp/contact.rb b/app/models/epp/contact.rb
index 3f0f3e8ab..50ebac065 100644
--- a/app/models/epp/contact.rb
+++ b/app/models/epp/contact.rb
@@ -36,7 +36,7 @@ class Epp::Contact < Contact
attrs = epp ? attrs_from(frame, new_record: true) : frame
super(
attrs.merge(
- code: epp ? frame.css('id').text : frame[:code],
+ code: epp ? frame.css('id').text : frame[:id],
registrar: registrar
)
)
diff --git a/lib/serializers/repp/contact.rb b/lib/serializers/repp/contact.rb
new file mode 100644
index 000000000..fe08a6f7d
--- /dev/null
+++ b/lib/serializers/repp/contact.rb
@@ -0,0 +1,42 @@
+module Serializers
+ module Repp
+ class Contact
+ attr_reader :contact
+
+ def initialize(contact, show_address:)
+ @contact = contact
+ @show_address = show_address
+ end
+
+ def to_json
+ json = {
+ id: contact.code,
+ name: contact.name,
+ ident: {
+ code: contact.ident,
+ type: contact.ident_type,
+ country_code: contact.ident_country_code,
+ },
+ email: contact.email,
+ phone: contact.phone,
+ fax: contact.fax,
+ auth_info: contact.auth_info,
+ statuses: contact.statuses,
+ disclosed_attributes: contact.disclosed_attributes,
+ }
+
+ return json unless @show_address
+
+ json[:address] = {
+ street: contact.street,
+ zip: contact.zip,
+ city: contact.city,
+ state: contact.state,
+ country_code: contact.country_code,
+ }
+
+ json
+ end
+ end
+ end
+end
From 03db562c77f9020dad4b61a3bba80b6baa0fa93c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Mon, 16 Nov 2020 16:26:59 +0200
Subject: [PATCH 132/172] REPP: Show error when invalid ident format submitted
---
app/controllers/repp/v1/base_controller.rb | 1 +
app/controllers/repp/v1/contacts_controller.rb | 2 +-
app/models/actions/contact_update.rb | 8 ++++++--
test/integration/repp/v1/contacts/show_test.rb | 2 +-
4 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/app/controllers/repp/v1/base_controller.rb b/app/controllers/repp/v1/base_controller.rb
index 678ae0a22..70b189fc1 100644
--- a/app/controllers/repp/v1/base_controller.rb
+++ b/app/controllers/repp/v1/base_controller.rb
@@ -4,6 +4,7 @@ module Repp
rescue_from ActiveRecord::RecordNotFound, with: :not_found_error
before_action :authenticate_user
before_action :check_ip_restriction
+ before_action :set_paper_trail_whodunnit
attr_reader :current_user
rescue_from ActionController::ParameterMissing do |exception|
diff --git a/app/controllers/repp/v1/contacts_controller.rb b/app/controllers/repp/v1/contacts_controller.rb
index 69d4ecc96..959d4f6c7 100644
--- a/app/controllers/repp/v1/contacts_controller.rb
+++ b/app/controllers/repp/v1/contacts_controller.rb
@@ -112,7 +112,7 @@ module Repp
end
def contact_ident_params(required: true)
- if required || !params[:contact][:ident].nil?
+ if required
params.require(:contact).require(:ident).require(%i[ident ident_type ident_country_code])
params.require(:contact).require(:ident).permit(:ident, :ident_type, :ident_country_code)
else
diff --git a/app/models/actions/contact_update.rb b/app/models/actions/contact_update.rb
index 6400526c5..7ca7b6b04 100644
--- a/app/models/actions/contact_update.rb
+++ b/app/models/actions/contact_update.rb
@@ -17,7 +17,7 @@ module Actions
def call
maybe_remove_address
maybe_update_statuses
- maybe_update_ident if ident
+ maybe_update_ident if ident.present?
maybe_attach_legal_doc
commit
end
@@ -53,7 +53,11 @@ module Actions
end
def maybe_update_ident
- return unless ident[:ident]
+ unless ident.is_a?(Hash)
+ contact.add_epp_error('2308', nil, nil, I18n.t('epp.contacts.errors.valid_ident'))
+ @error = true
+ return
+ end
if contact.identifier.valid?
submitted_ident = ::Contact::Ident.new(code: ident[:ident],
diff --git a/test/integration/repp/v1/contacts/show_test.rb b/test/integration/repp/v1/contacts/show_test.rb
index 3fd782cca..4a6f5b615 100644
--- a/test/integration/repp/v1/contacts/show_test.rb
+++ b/test/integration/repp/v1/contacts/show_test.rb
@@ -28,7 +28,7 @@ class ReppV1ContactsShowTest < ActionDispatch::IntegrationTest
assert_equal 1000, json[:code]
assert_equal 'Command completed successfully', json[:message]
- assert_equal contact.code, json[:data][:code]
+ assert_equal contact.code, json[:data][:id]
end
def test_can_not_access_out_of_scope_contacts
From 7edf48c885e6bced344f125c8e8304a04866f0b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Tue, 17 Nov 2020 11:51:45 +0200
Subject: [PATCH 133/172] Fix some CC issues
---
.../repp/v1/contacts_controller.rb | 6 ++-
.../v1/registrar/nameservers_controller.rb | 2 +-
lib/serializers/registrant_api/.DS_Store | Bin 0 -> 6148 bytes
lib/serializers/repp/contact.rb | 44 ++++++++----------
4 files changed, 24 insertions(+), 28 deletions(-)
create mode 100644 lib/serializers/registrant_api/.DS_Store
diff --git a/app/controllers/repp/v1/contacts_controller.rb b/app/controllers/repp/v1/contacts_controller.rb
index 959d4f6c7..144be01c6 100644
--- a/app/controllers/repp/v1/contacts_controller.rb
+++ b/app/controllers/repp/v1/contacts_controller.rb
@@ -15,7 +15,8 @@ module Repp
## GET /repp/v1/contacts/1
def show
- serializer = ::Serializers::Repp::Contact.new(@contact, show_address: Contact.address_processing?)
+ serializer = ::Serializers::Repp::Contact.new(@contact,
+ show_address: Contact.address_processing?)
render_success(data: serializer.to_json)
end
@@ -82,7 +83,8 @@ module Repp
return contacts.pluck(:code) unless details
contacts = contacts.map do |contact|
- serializer = ::Serializers::Repp::Contact.new(contact, show_address: Contact.address_processing?)
+ serializer = ::Serializers::Repp::Contact.new(contact,
+ show_address: Contact.address_processing?)
serializer.to_json
end
diff --git a/app/controllers/repp/v1/registrar/nameservers_controller.rb b/app/controllers/repp/v1/registrar/nameservers_controller.rb
index fb00d92c0..47004d97b 100644
--- a/app/controllers/repp/v1/registrar/nameservers_controller.rb
+++ b/app/controllers/repp/v1/registrar/nameservers_controller.rb
@@ -34,7 +34,7 @@ module Repp
params.permit(data: [
:type, :id,
{ domains: [],
- attributes: [:hostname, { ipv4: [], ipv6: [] }] },
+ attributes: [:hostname, { ipv4: [], ipv6: [] }] }
])
end
diff --git a/lib/serializers/registrant_api/.DS_Store b/lib/serializers/registrant_api/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6
GIT binary patch
literal 6148
zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3
zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ
zLs35+`xjp>T0
Date: Tue, 17 Nov 2020 13:00:47 +0200
Subject: [PATCH 134/172] Add response to REPP log
---
.../repp/v1/auctions_controller.rb | 4 +--
app/controllers/repp/v1/base_controller.rb | 29 +++++++------------
.../repp/v1/contacts_controller.rb | 4 +--
.../repp/v1/domains/contacts_controller.rb | 4 +--
.../repp/v1/retained_domains_controller.rb | 3 +-
lib/serializers/repp/contact.rb | 10 +++----
6 files changed, 24 insertions(+), 30 deletions(-)
diff --git a/app/controllers/repp/v1/auctions_controller.rb b/app/controllers/repp/v1/auctions_controller.rb
index 4a5265d13..676dac266 100644
--- a/app/controllers/repp/v1/auctions_controller.rb
+++ b/app/controllers/repp/v1/auctions_controller.rb
@@ -3,9 +3,9 @@ module Repp
class AuctionsController < ActionController::API
def index
auctions = Auction.started
+ @response = { count: auctions.count, auctions: auctions_to_json(auctions) }
- render json: { count: auctions.count,
- auctions: auctions_to_json(auctions) }
+ render json: @response
end
private
diff --git a/app/controllers/repp/v1/base_controller.rb b/app/controllers/repp/v1/base_controller.rb
index 70b189fc1..73d8c400a 100644
--- a/app/controllers/repp/v1/base_controller.rb
+++ b/app/controllers/repp/v1/base_controller.rb
@@ -24,10 +24,10 @@ module Repp
private
def render_success(code: nil, message: nil, data: nil)
- resp = { code: code || 1000, message: message || 'Command completed successfully',
+ @response = { code: code || 1000, message: message || 'Command completed successfully',
data: data || {} }
- render(json: resp, status: :ok)
+ render(json: @response, status: :ok)
end
def epp_errors
@@ -64,10 +64,8 @@ module Repp
@epp_errors ||= []
@epp_errors << { code: 2304, msg: 'Command failed' } if data != {}
- render(
- json: { code: @epp_errors[0][:code].to_i, message: @epp_errors[0][:msg], data: data },
- status: status
- )
+ @response = { code: @epp_errors[0][:code].to_i, message: @epp_errors[0][:msg], data: data }
+ render(json: @response, status: status)
end
def basic_token
@@ -85,10 +83,8 @@ module Repp
raise(ArgumentError)
rescue NoMethodError, ArgumentError
- render(
- json: { code: 2202, message: 'Invalid authorization information' },
- status: :unauthorized
- )
+ @response = { code: 2202, message: 'Invalid authorization information' }
+ render(json: @response, status: :unauthorized)
end
def check_ip_restriction
@@ -96,17 +92,14 @@ module Repp
return if allowed
- render(
- json: {
- code: 2202,
- message: I18n.t('registrar.authorization.ip_not_allowed', ip: request.ip),
- },
- status: :unauthorized
- )
+ @response = { code: 2202,
+ message: I18n.t('registrar.authorization.ip_not_allowed', ip: request.ip) }
+ render(json: @response, status: :unauthorized)
end
def not_found_error
- render(json: { code: 2303, message: 'Object does not exist' }, status: :not_found)
+ @response = { code: 2303, message: 'Object does not exist' }
+ render(json: @response, status: :not_found)
end
end
end
diff --git a/app/controllers/repp/v1/contacts_controller.rb b/app/controllers/repp/v1/contacts_controller.rb
index 144be01c6..acf275c47 100644
--- a/app/controllers/repp/v1/contacts_controller.rb
+++ b/app/controllers/repp/v1/contacts_controller.rb
@@ -9,8 +9,8 @@ module Repp
record_count = current_user.registrar.contacts.count
contacts = showable_contacts(params[:details], params[:limit] || 200,
params[:offset] || 0)
-
- render(json: { contacts: contacts, total_number_of_records: record_count }, status: :ok)
+ @response = { contacts: contacts, total_number_of_records: record_count }
+ render(json: @response, status: :ok)
end
## GET /repp/v1/contacts/1
diff --git a/app/controllers/repp/v1/domains/contacts_controller.rb b/app/controllers/repp/v1/domains/contacts_controller.rb
index fb5dfb567..75404e0c6 100644
--- a/app/controllers/repp/v1/domains/contacts_controller.rb
+++ b/app/controllers/repp/v1/domains/contacts_controller.rb
@@ -26,8 +26,8 @@ module Repp
return handle_errors if @epp_errors.any?
affected, skipped = TechDomainContact.replace(@current_contact, @new_contact)
- data = { affected_domains: affected, skipped_domains: skipped }
- render_success(data: data)
+ @response = { affected_domains: affected, skipped_domains: skipped }
+ render_success(data: @response)
end
private
diff --git a/app/controllers/repp/v1/retained_domains_controller.rb b/app/controllers/repp/v1/retained_domains_controller.rb
index c1bb458e9..8edc32f5b 100644
--- a/app/controllers/repp/v1/retained_domains_controller.rb
+++ b/app/controllers/repp/v1/retained_domains_controller.rb
@@ -3,8 +3,9 @@ module Repp
class RetainedDomainsController < ActionController::API
def index
domains = RetainedDomains.new(query_params)
+ @response = { count: domains.count, domains: domains.to_jsonable }
- render json: { count: domains.count, domains: domains.to_jsonable }
+ render json: @response
end
def query_params
diff --git a/lib/serializers/repp/contact.rb b/lib/serializers/repp/contact.rb
index 8a3cad616..834402359 100644
--- a/lib/serializers/repp/contact.rb
+++ b/lib/serializers/repp/contact.rb
@@ -8,11 +8,11 @@ module Serializers
@show_address = show_address
end
- def to_json(_obj)
- json = { id: contact.code, name: contact.name, ident: ident,
- email: contact.email, phone: contact.phone, fax: contact.fax,
- auth_info: contact.auth_info, statuses: contact.statuses,
- disclosed_attributes: contact.disclosed_attributes }
+ def to_json(obj = contact)
+ json = { id: obj.code, name: obj.name, ident: ident,
+ email: obj.email, phone: obj.phone, fax: obj.fax,
+ auth_info: obj.auth_info, statuses: obj.statuses,
+ disclosed_attributes: obj.disclosed_attributes }
json[:address] = address if @show_address
From e40737408f9fec6eaf1400f31a530936e457247c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Tue, 17 Nov 2020 14:33:12 +0200
Subject: [PATCH 135/172] History: Show last state of contact on contact
destroy event
---
app/helpers/object_versions_helper.rb | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/helpers/object_versions_helper.rb b/app/helpers/object_versions_helper.rb
index d8e00abbe..8e394b29a 100644
--- a/app/helpers/object_versions_helper.rb
+++ b/app/helpers/object_versions_helper.rb
@@ -3,7 +3,8 @@ module ObjectVersionsHelper
version.object_changes.to_h.each do |key, value|
method_name = "#{key}=".to_sym
if new_object.respond_to?(method_name)
- new_object.public_send(method_name, value.last)
+ delete_action = version.event == 'destroy'
+ new_object.public_send(method_name, delete_action ? value.first : value.last)
end
end
end
From c9ebdbeb40e1f4377e30ee5ca0cdf733ead11554 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Tue, 17 Nov 2020 14:40:18 +0200
Subject: [PATCH 136/172] EPP: Hide name from contactInfo if no auth provided
---
app/views/epp/contacts/info.xml.builder | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/app/views/epp/contacts/info.xml.builder b/app/views/epp/contacts/info.xml.builder
index 1945e7def..4874080e8 100644
--- a/app/views/epp/contacts/info.xml.builder
+++ b/app/views/epp/contacts/info.xml.builder
@@ -14,7 +14,11 @@ xml.epp_head do
end
xml.tag!('contact:postalInfo', type: 'int') do
- xml.tag!('contact:name', @contact.name)
+ if can? :view_full_info, @contact, @password
+ xml.tag!('contact:name', @contact.name)
+ else
+ xml.tag!('contact:name', 'No access')
+ end
if can? :view_full_info, @contact, @password
xml.tag!('contact:org', @contact.org_name) if @contact.org_name.present?
From a747464f3d8d076aaebce2246111c4d47e370c3b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Tue, 17 Nov 2020 16:16:27 +0200
Subject: [PATCH 137/172] Don't show contact name if not viewed by sponsoring
registrar
---
app/views/registrar/domains/partials/_contacts.haml | 2 +-
app/views/registrar/domains/partials/_general.html.erb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/registrar/domains/partials/_contacts.haml b/app/views/registrar/domains/partials/_contacts.haml
index 48d1ac21f..e6ef9aa8f 100644
--- a/app/views/registrar/domains/partials/_contacts.haml
+++ b/app/views/registrar/domains/partials/_contacts.haml
@@ -13,5 +13,5 @@
- registrant = Contact.find_by_code(x.text)
%tr
%td= x['type']
- %td= registrant.name
+ %td= registrant.registrar == current_registrar_user.registrar ? registrant.name : 'N/A'
%td= x.text
diff --git a/app/views/registrar/domains/partials/_general.html.erb b/app/views/registrar/domains/partials/_general.html.erb
index 3fb3a5df8..ff064857c 100644
--- a/app/views/registrar/domains/partials/_general.html.erb
+++ b/app/views/registrar/domains/partials/_general.html.erb
@@ -23,7 +23,7 @@
<% registrant = Contact.find_by_code(@data.css('registrant').text) %>
Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Domeeniga on seotud puudulike kontakti objekte, milles tulenevalt on Eesti Interneti SA blokeerinud domeeni pikendamise ja registripidaja vahetuse, kuniks kontaktandmed korrastatakse. Andmete korrastamiseks ja registreeringu pikendamiseks pöörduge palun oma registripidaja poole.
+
Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Domeeniga on seotud puudulikke kontakti objekte, millest tulenevalt on Eesti Interneti SA blokeerinud domeeni pikendamise ja registripidaja vahetuse, kuniks kontaktandmed korrastatakse. Andmete korrastamiseks ja registreeringu pikendamiseks pöörduge palun oma registripidaja poole.
<%= @domain.name %> pikendamata jätmisel domeen kustub ja läheb <%= @domain.delete_date %> oksjonile .ee oksjonikeskkonda. Domeenioksjonite kohta loe lähemalt siit.
From 6a6265e3a5b97918558ae4218119061ce665679c Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Wed, 18 Nov 2020 18:09:31 +0500
Subject: [PATCH 149/172] Move CancelForceDelete to interactor
---
.../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 +++++++
app/models/concerns/domain/force_delete.rb | 26 +------------------
7 files changed, 56 insertions(+), 25 deletions(-)
create mode 100644 app/interactions/cancel_force_delete_interaction/base.rb
create mode 100644 app/interactions/cancel_force_delete_interaction/cancel_force_delete.rb
create mode 100644 app/interactions/cancel_force_delete_interaction/clear_force_delete_data.rb
create mode 100644 app/interactions/cancel_force_delete_interaction/notify_registrar.rb
create mode 100644 app/interactions/cancel_force_delete_interaction/remove_force_delete_statuses.rb
create mode 100644 app/interactions/cancel_force_delete_interaction/restore_statuses_before_force_delete.rb
diff --git a/app/interactions/cancel_force_delete_interaction/base.rb b/app/interactions/cancel_force_delete_interaction/base.rb
new file mode 100644
index 000000000..595279d87
--- /dev/null
+++ b/app/interactions/cancel_force_delete_interaction/base.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 000000000..2f45bf0e4
--- /dev/null
+++ b/app/interactions/cancel_force_delete_interaction/cancel_force_delete.rb
@@ -0,0 +1,10 @@
+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
new file mode 100644
index 000000000..ccc0714f7
--- /dev/null
+++ b/app/interactions/cancel_force_delete_interaction/clear_force_delete_data.rb
@@ -0,0 +1,10 @@
+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
new file mode 100644
index 000000000..3ded4c489
--- /dev/null
+++ b/app/interactions/cancel_force_delete_interaction/notify_registrar.rb
@@ -0,0 +1,8 @@
+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
new file mode 100644
index 000000000..1cc4989e5
--- /dev/null
+++ b/app/interactions/cancel_force_delete_interaction/remove_force_delete_statuses.rb
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 000000000..06b6bbd18
--- /dev/null
+++ b/app/interactions/cancel_force_delete_interaction/restore_statuses_before_force_delete.rb
@@ -0,0 +1,9 @@
+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/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index b119b0ce0..ff869fc0a 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -58,18 +58,8 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
notify_by_email: notify_by_email)
end
- def clear_force_delete_data
- self.force_delete_data = nil
- end
-
def cancel_force_delete
- remove_force_delete_statuses
- restore_statuses_before_force_delete
- clear_force_delete_data
- self.force_delete_date = nil
- self.force_delete_start = nil
- save(validate: false)
- registrar.notifications.create!(text: I18n.t('force_delete_cancelled', domain_name: name))
+ CancelForceDeleteInteraction::CancelForceDelete.run(domain: self)
end
def outzone_date
@@ -80,18 +70,4 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
(force_delete_date&.beginning_of_day || valid_to + Setting.expire_warning_period.days +
Setting.redemption_grace_period.days)
end
-
- private
-
- def restore_statuses_before_force_delete
- self.statuses = statuses_before_force_delete
- self.statuses_before_force_delete = nil
- end
-
- def remove_force_delete_statuses
- statuses.delete(DomainStatus::FORCE_DELETE)
- statuses.delete(DomainStatus::SERVER_RENEW_PROHIBITED)
- statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED)
- statuses.delete(DomainStatus::CLIENT_HOLD)
- end
end
From 822f19a676f02561419aa5e0d99dc5b7de794a99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Fri, 20 Nov 2020 13:48:07 +0200
Subject: [PATCH 150/172] Update CHANGELOG.md
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 913d3cc21..52408c420 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+20.11.2020
+* Registrant confirmation over Registrant API [#1742](https://github.com/internetee/registry/pull/1742)
+
19.11.2020
* Only sponsoring registrar has access to private contact's details [#1745](https://github.com/internetee/registry/issues/1745)
* Refactor ForceDelete [#1740](https://github.com/internetee/registry/issues/1740)
From fce16f924d02e5f6cd89c0845efd2794e6db65f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Fri, 20 Nov 2020 17:28:40 +0200
Subject: [PATCH 151/172] Update CHANGELOG.md
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52408c420..28810c8d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
20.11.2020
* Registrant confirmation over Registrant API [#1742](https://github.com/internetee/registry/pull/1742)
+* Refactored forceDelete cancellation for interactors [#1743](https://github.com/internetee/registry/issues/1743)
19.11.2020
* Only sponsoring registrar has access to private contact's details [#1745](https://github.com/internetee/registry/issues/1745)
From a40116e05e5e80378ef99f861ec824c020ffd276 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Fri, 20 Nov 2020 16:51:05 +0500
Subject: [PATCH 152/172] 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 153/172] 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 154/172] 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 5a82d7c2c01cacdc91d30ec6ff7f62cacaf10809 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 23 Nov 2020 16:36:30 +0500
Subject: [PATCH 155/172] Fix error handling in processing request IP
---
app/models/white_ip.rb | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb
index c2fb51cd1..a5041095e 100644
--- a/app/models/white_ip.rb
+++ b/app/models/white_ip.rb
@@ -41,10 +41,15 @@ class WhiteIp < ApplicationRecord
class << self
# rubocop:disable Style/CaseEquality
def include_ip?(ip)
- ipv4 = select { |white_ip| IPAddr.new(white_ip.ipv4, Socket::AF_INET) === IPAddr.new(ip) }
- ipv6 = select { |white_ip| IPAddr.new(white_ip.ipv6, Socket::AF_INET6) === IPAddr.new(ip) }
- ids = (ipv4 + ipv6).pluck(:id).flatten.uniq
+ new_ip4 = IPAddr.new(ip, Socket::AF_INET)
+ new_ip6 = IPAddr.new(ip, Socket::AF_INET6)
+
+ result = self.all.select { |white_ip| IPAddr.new(white_ip.ipv4, Socket::AF_INET) === new_ip4 ||
+ IPAddr.new(white_ip.ipv6, Socket::AF_INET6) === new_ip6 }
+ ids = result.pluck(:id).flatten.uniq
where(id: ids).any?
+ rescue IPAddr::InvalidAddressError => _e
+ false
end
# rubocop:enable Style/CaseEquality
end
From bace495f575a73a0b55e2542853c31f8f746b707 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 23 Nov 2020 17:24:52 +0500
Subject: [PATCH 156/172] Revert "Fix error handling in processing request IP"
This reverts commit 5a82d7c2c01cacdc91d30ec6ff7f62cacaf10809.
---
app/models/white_ip.rb | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb
index a5041095e..c2fb51cd1 100644
--- a/app/models/white_ip.rb
+++ b/app/models/white_ip.rb
@@ -41,15 +41,10 @@ class WhiteIp < ApplicationRecord
class << self
# rubocop:disable Style/CaseEquality
def include_ip?(ip)
- new_ip4 = IPAddr.new(ip, Socket::AF_INET)
- new_ip6 = IPAddr.new(ip, Socket::AF_INET6)
-
- result = self.all.select { |white_ip| IPAddr.new(white_ip.ipv4, Socket::AF_INET) === new_ip4 ||
- IPAddr.new(white_ip.ipv6, Socket::AF_INET6) === new_ip6 }
- ids = result.pluck(:id).flatten.uniq
+ ipv4 = select { |white_ip| IPAddr.new(white_ip.ipv4, Socket::AF_INET) === IPAddr.new(ip) }
+ ipv6 = select { |white_ip| IPAddr.new(white_ip.ipv6, Socket::AF_INET6) === IPAddr.new(ip) }
+ ids = (ipv4 + ipv6).pluck(:id).flatten.uniq
where(id: ids).any?
- rescue IPAddr::InvalidAddressError => _e
- false
end
# rubocop:enable Style/CaseEquality
end
From f01e59d95aaa965664216a9bda4346894cd205d9 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 23 Nov 2020 17:29:59 +0500
Subject: [PATCH 157/172] Some white ip check fixes
---
app/models/white_ip.rb | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb
index c2fb51cd1..7198c225f 100644
--- a/app/models/white_ip.rb
+++ b/app/models/white_ip.rb
@@ -41,11 +41,35 @@ class WhiteIp < ApplicationRecord
class << self
# rubocop:disable Style/CaseEquality
def include_ip?(ip)
- ipv4 = select { |white_ip| IPAddr.new(white_ip.ipv4, Socket::AF_INET) === IPAddr.new(ip) }
- ipv6 = select { |white_ip| IPAddr.new(white_ip.ipv6, Socket::AF_INET6) === IPAddr.new(ip) }
- ids = (ipv4 + ipv6).pluck(:id).flatten.uniq
- where(id: ids).any?
+ Rails.logger.info "Checking if whitelist includes ip:#{ip}"
+ return false if ip.blank?
+
+ where(id: ids_including(ip)).any?
+ end
+
+ def ids_including(ip)
+ ipv4 = ipv6 = []
+ if check_ip4(ip).present?
+ ipv4 = select { |white_ip| IPAddr.new(white_ip.ipv4, Socket::AF_INET) === check_ip4(ip) }
+ end
+ if check_ip6(ip).present?
+ ipv6 = select { |white_ip| IPAddr.new(white_ip.ipv6, Socket::AF_INET6) === check_ip6 }
+ end
+ (ipv4 + ipv6).pluck(:id).flatten.uniq
end
# rubocop:enable Style/CaseEquality
+
+ def check_ip4(ip)
+ IPAddr.new(ip, Socket::AF_INET)
+ rescue StandardError => _e
+ nil
+ end
+
+ def check_ip6(ip)
+ IPAddr.new(ip, Socket::AF_INET6)
+ rescue StandardError => _e
+ nil
+ end
+
end
end
From 3943628716d97f4d043c3ffb35dece36b903fabe Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 23 Nov 2020 18:07:01 +0500
Subject: [PATCH 158/172] Add some debug messages
---
app/models/authorization/restricted_ip.rb | 2 ++
app/models/registrar.rb | 3 ++-
app/models/white_ip.rb | 13 +++++++++----
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/app/models/authorization/restricted_ip.rb b/app/models/authorization/restricted_ip.rb
index b3c7b7cdb..0149814d5 100644
--- a/app/models/authorization/restricted_ip.rb
+++ b/app/models/authorization/restricted_ip.rb
@@ -14,7 +14,9 @@ module Authorization
end
def can_access_registrar_area_sign_in_page?
+ Rails.logger.info "Checking if Auth::RestrictedIp.enabled: #{self.class.enabled?}"
return true unless self.class.enabled?
+ Rails.logger.info "Checking if registrar area accessible, result: #{WhiteIp.registrar_area.include_ip?(ip)}"
WhiteIp.registrar_area.include_ip?(ip)
end
diff --git a/app/models/registrar.rb b/app/models/registrar.rb
index 040c7886b..4503bedd0 100644
--- a/app/models/registrar.rb
+++ b/app/models/registrar.rb
@@ -137,7 +137,8 @@ class Registrar < ApplicationRecord
def api_ip_white?(ip)
return true unless Setting.api_ip_whitelist_enabled
- white_ips.api.pluck(:ipv4, :ipv6).flatten.include?(ip)
+ # white_ips.api.pluck(:ipv4, :ipv6).flatten.include?(ip)
+ white_ips.api.include_ip?(ip)
end
# Audit log is needed, therefore no raw SQL
diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb
index 7198c225f..1d3379de5 100644
--- a/app/models/white_ip.rb
+++ b/app/models/white_ip.rb
@@ -41,21 +41,26 @@ class WhiteIp < ApplicationRecord
class << self
# rubocop:disable Style/CaseEquality
def include_ip?(ip)
- Rails.logger.info "Checking if whitelist includes ip:#{ip}"
+ Rails.logger.info "Checking if whitelist includes ip: #{ip}"
return false if ip.blank?
- where(id: ids_including(ip)).any?
+ result = where(id: ids_including(ip)).any?
+ Rails.logger.info "Result is: #{result}"
+ result
end
def ids_including(ip)
+ Rails.logger.info "Checking ip #{ip}"
ipv4 = ipv6 = []
if check_ip4(ip).present?
ipv4 = select { |white_ip| IPAddr.new(white_ip.ipv4, Socket::AF_INET) === check_ip4(ip) }
end
if check_ip6(ip).present?
- ipv6 = select { |white_ip| IPAddr.new(white_ip.ipv6, Socket::AF_INET6) === check_ip6 }
+ ipv6 = select { |white_ip| IPAddr.new(white_ip.ipv6, Socket::AF_INET6) === check_ip6(ip) }
end
- (ipv4 + ipv6).pluck(:id).flatten.uniq
+ result = (ipv4 + ipv6).pluck(:id).flatten.uniq
+ Rails.logger.info "Result is #{result}"
+ result
end
# rubocop:enable Style/CaseEquality
From 708e87f5a7946488bac621b5f4381fbefc5d1322 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 24 Nov 2020 13:19:08 +0500
Subject: [PATCH 159/172] CC fixes
---
app/models/authorization/restricted_ip.rb | 2 --
app/models/registrar.rb | 2 +-
app/models/white_ip.rb | 13 ++++---------
3 files changed, 5 insertions(+), 12 deletions(-)
diff --git a/app/models/authorization/restricted_ip.rb b/app/models/authorization/restricted_ip.rb
index 0149814d5..b3c7b7cdb 100644
--- a/app/models/authorization/restricted_ip.rb
+++ b/app/models/authorization/restricted_ip.rb
@@ -14,9 +14,7 @@ module Authorization
end
def can_access_registrar_area_sign_in_page?
- Rails.logger.info "Checking if Auth::RestrictedIp.enabled: #{self.class.enabled?}"
return true unless self.class.enabled?
- Rails.logger.info "Checking if registrar area accessible, result: #{WhiteIp.registrar_area.include_ip?(ip)}"
WhiteIp.registrar_area.include_ip?(ip)
end
diff --git a/app/models/registrar.rb b/app/models/registrar.rb
index 4503bedd0..149bb7541 100644
--- a/app/models/registrar.rb
+++ b/app/models/registrar.rb
@@ -137,7 +137,7 @@ class Registrar < ApplicationRecord
def api_ip_white?(ip)
return true unless Setting.api_ip_whitelist_enabled
- # white_ips.api.pluck(:ipv4, :ipv6).flatten.include?(ip)
+
white_ips.api.include_ip?(ip)
end
diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb
index 1d3379de5..417633b12 100644
--- a/app/models/white_ip.rb
+++ b/app/models/white_ip.rb
@@ -40,17 +40,14 @@ class WhiteIp < ApplicationRecord
class << self
# rubocop:disable Style/CaseEquality
+ # rubocop:disable Metrics/AbcSize
def include_ip?(ip)
- Rails.logger.info "Checking if whitelist includes ip: #{ip}"
return false if ip.blank?
- result = where(id: ids_including(ip)).any?
- Rails.logger.info "Result is: #{result}"
- result
+ where(id: ids_including(ip)).any?
end
def ids_including(ip)
- Rails.logger.info "Checking ip #{ip}"
ipv4 = ipv6 = []
if check_ip4(ip).present?
ipv4 = select { |white_ip| IPAddr.new(white_ip.ipv4, Socket::AF_INET) === check_ip4(ip) }
@@ -58,11 +55,10 @@ class WhiteIp < ApplicationRecord
if check_ip6(ip).present?
ipv6 = select { |white_ip| IPAddr.new(white_ip.ipv6, Socket::AF_INET6) === check_ip6(ip) }
end
- result = (ipv4 + ipv6).pluck(:id).flatten.uniq
- Rails.logger.info "Result is #{result}"
- result
+ (ipv4 + ipv6).pluck(:id).flatten.uniq
end
# rubocop:enable Style/CaseEquality
+ # rubocop:enable Metrics/AbcSize
def check_ip4(ip)
IPAddr.new(ip, Socket::AF_INET)
@@ -75,6 +71,5 @@ class WhiteIp < ApplicationRecord
rescue StandardError => _e
nil
end
-
end
end
From 89c5413fc702c8399474ff18f6f245af531deeba Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Tue, 24 Nov 2020 13:26:38 +0500
Subject: [PATCH 160/172] 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 283bf8cd1adaf6d8a6ed13aac1c980d210769159 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?=
Date: Tue, 24 Nov 2020 14:25:52 +0200
Subject: [PATCH 161/172] Fix contact version view
---
app/helpers/object_versions_helper.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/helpers/object_versions_helper.rb b/app/helpers/object_versions_helper.rb
index dccf03017..be8ef1217 100644
--- a/app/helpers/object_versions_helper.rb
+++ b/app/helpers/object_versions_helper.rb
@@ -3,7 +3,7 @@ module ObjectVersionsHelper
version.object_changes.to_h.each do |key, value|
method_name = "#{key}=".to_sym
if new_object.respond_to?(method_name)
- new_object.public_send(method_name, event_value(event, value))
+ new_object.public_send(method_name, event_value(version, value))
end
end
end
From ee92807139cc5f5c0c5ee20531a5ab84b41991c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Tue, 24 Nov 2020 15:03:06 +0200
Subject: [PATCH 162/172] Update CHANGELOG.md
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 28810c8d8..22b3d7d02 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+24.11.2020
+* Added subnet support for list of allowed IPs [#983](https://github.com/internetee/registry/issues/983)
+
20.11.2020
* Registrant confirmation over Registrant API [#1742](https://github.com/internetee/registry/pull/1742)
* Refactored forceDelete cancellation for interactors [#1743](https://github.com/internetee/registry/issues/1743)
From b39de0885a4dd88ce95d111da6196705df2db252 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20V=C3=B5hmar?=
Date: Tue, 24 Nov 2020 15:29:50 +0200
Subject: [PATCH 163/172] Update CHANGELOG.md
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 22b3d7d02..ebbc3d905 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
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)
20.11.2020
* Registrant confirmation over Registrant API [#1742](https://github.com/internetee/registry/pull/1742)
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 164/172] 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 5363c546a598ecfe8460a43c6bb2c105ea764ab0 Mon Sep 17 00:00:00 2001
From: Alex Sherman
Date: Mon, 30 Nov 2020 13:46:53 +0500
Subject: [PATCH 165/172] 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 166/172] 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 167/172] 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 168/172] 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 169/172] 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 170/172] 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 171/172] 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 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 172/172] 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)