From a13b336f54c5fa73e3b40183a02e57e9d57b17f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Mon, 5 Oct 2020 14:44:48 +0300 Subject: [PATCH 01/56] Allow renewal regardless of pendingDelete status flag --- app/models/domain.rb | 4 ++-- app/models/epp/domain.rb | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/models/domain.rb b/app/models/domain.rb index 679669728..9a8441eb5 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -320,8 +320,8 @@ class Domain < ApplicationRecord def renew_blocking_statuses disallowed = [DomainStatus::DELETE_CANDIDATE, DomainStatus::PENDING_RENEW, DomainStatus::PENDING_TRANSFER, DomainStatus::CLIENT_RENEW_PROHIBITED, - DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_DELETE, - DomainStatus::PENDING_DELETE_CONFIRMATION, DomainStatus::SERVER_RENEW_PROHIBITED] + DomainStatus::PENDING_UPDATE, DomainStatus::SERVER_RENEW_PROHIBITED, + DomainStatus::PENDING_DELETE_CONFIRMATION] (statuses & disallowed) end diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 530e54a0f..c46732712 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -612,6 +612,7 @@ class Epp::Domain < Domain statuses.delete(DomainStatus::SERVER_HOLD) statuses.delete(DomainStatus::EXPIRED) statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED) + cancel_pending_delete save end From d81fd763e28b37e87cb523f372ae9e17b01c937b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Mon, 5 Oct 2020 15:33:38 +0300 Subject: [PATCH 02/56] Test domain is renewable if pendingDelete is set --- test/models/domain_test.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/models/domain_test.rb b/test/models/domain_test.rb index a943be6ef..4a9240f57 100644 --- a/test/models/domain_test.rb +++ b/test/models/domain_test.rb @@ -444,6 +444,20 @@ class DomainTest < ActiveSupport::TestCase assert_not @domain.renewable? end + def test_renewable_if_pending_delete + assert @domain.renewable? + @domain.statuses << DomainStatus::PENDING_DELETE + + assert @domain.renewable? + end + + def test_not_renewable_if_pending_delete_unconfirmed + assert @domain.renewable? + @domain.statuses << DomainStatus::PENDING_DELETE_CONFIRMATION + + assert_not @domain.renewable? + end + private def valid_domain From 9b3559c8b811ac1748a9bb921f173296bbccca72 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 7 Oct 2020 16:10:55 +0500 Subject: [PATCH 03/56] Add data migration to i18ze disclaimer --- ...01007104651_make_whois_disclamer_i18ned.rb | 21 +++++++++++++++++++ db/data_schema.rb | 2 +- test/fixtures/setting_entries.yml | 5 ++--- test/models/whois/record_test.rb | 12 +++++------ test/models/whois_record_test.rb | 5 +---- 5 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 db/data/20201007104651_make_whois_disclamer_i18ned.rb diff --git a/db/data/20201007104651_make_whois_disclamer_i18ned.rb b/db/data/20201007104651_make_whois_disclamer_i18ned.rb new file mode 100644 index 000000000..59bec04d8 --- /dev/null +++ b/db/data/20201007104651_make_whois_disclamer_i18ned.rb @@ -0,0 +1,21 @@ +class MakeWhoisDisclamerI18ned < ActiveRecord::Migration[6.0] + def up + entry = SettingEntry.find_by(code: 'registry_whois_disclaimer') + hash = { en: 'Search results may not be used for commercial, advertising, recompilation, repackaging, redistribution, reuse, obscuring or other similar activities.', + et: 'Otsitulemusi ei tohi kasutada ärilistel, reklaami, ümber töötlemise, edasi levitamise, taaskasutuse, muutmise ega muul sarnasel eesmärgil.', + ru: 'Результаты поиска не могут быть использованы в коммерческих целях, включая, но не ограничиваясь, рекламу, рекомпиляцию, изменение формата, перераспределение либо переиспользование.' } + string = JSON.generate(hash) + entry.format = 'hash' + entry.value = string + entry.save! + end + + def down + entry = SettingEntry.find_by(code: 'registry_whois_disclaimer') + string = 'Search results may not be used for commercial, advertising, recompilation, \ + repackaging, redistribution, reuse, obscuring or other similar activities.' + entry.format = 'string' + entry.value = string + entry.save! + end +end diff --git a/db/data_schema.rb b/db/data_schema.rb index 2968b1184..84cdf8411 100644 --- a/db/data_schema.rb +++ b/db/data_schema.rb @@ -1,2 +1,2 @@ # encoding: UTF-8 -DataMigrate::Data.define(version: 20200901131427) +DataMigrate::Data.define(version: 20201007104651) diff --git a/test/fixtures/setting_entries.yml b/test/fixtures/setting_entries.yml index 78db36465..7ac1dd611 100644 --- a/test/fixtures/setting_entries.yml +++ b/test/fixtures/setting_entries.yml @@ -448,10 +448,9 @@ dispute_period_in_months: registry_whois_disclaimer: code: registry_whois_disclaimer - value: 'Search results may not be used for commercial, advertising, recompilation, - repackaging, redistribution, reuse, obscuring or other similar activities.' + value: "{\"en\":\"111\",\"et\":\"222\",\"ru\":\"333\"}" group: contacts - format: string + format: hash created_at: <%= Time.zone.parse('2010-07-05') %> updated_at: <%= Time.zone.parse('2010-07-05') %> diff --git a/test/models/whois/record_test.rb b/test/models/whois/record_test.rb index 3e727d80a..e900a4965 100644 --- a/test/models/whois/record_test.rb +++ b/test/models/whois/record_test.rb @@ -8,7 +8,7 @@ class Whois::RecordTest < ActiveSupport::TestCase @auction = auctions(:one) @original_disclaimer = Setting.registry_whois_disclaimer - Setting.registry_whois_disclaimer = 'disclaimer' + Setting.registry_whois_disclaimer = JSON.generate({en: 'disclaimer'}) end teardown do @@ -16,8 +16,8 @@ class Whois::RecordTest < ActiveSupport::TestCase end def test_reads_disclaimer_setting - Setting.registry_whois_disclaimer = 'test disclaimer' - assert_equal 'test disclaimer', Whois::Record.disclaimer + Setting.registry_whois_disclaimer = JSON.generate({en: 'test_disclaimer'}) + assert_equal Setting.registry_whois_disclaimer, Whois::Record.disclaimer end def test_updates_whois_record_from_auction_when_started @@ -28,7 +28,7 @@ class Whois::RecordTest < ActiveSupport::TestCase assert_equal ({ 'name' => 'domain.test', 'status' => ['AtAuction'], - 'disclaimer' => 'disclaimer' }), @whois_record.json + 'disclaimer' => { 'en' => 'disclaimer' }}), @whois_record.json end def test_updates_whois_record_from_auction_when_no_bids @@ -49,7 +49,7 @@ class Whois::RecordTest < ActiveSupport::TestCase assert_equal ({ 'name' => 'domain.test', 'status' => ['PendingRegistration'], - 'disclaimer' => 'disclaimer', + 'disclaimer' => { 'en' => 'disclaimer' }, 'registration_deadline' => registration_deadline.try(:to_s, :iso8601) }), @whois_record.json end @@ -64,7 +64,7 @@ class Whois::RecordTest < ActiveSupport::TestCase assert_equal ({ 'name' => 'domain.test', 'status' => ['PendingRegistration'], - 'disclaimer' => 'disclaimer', + 'disclaimer' => { 'en' => 'disclaimer' }, 'registration_deadline' => registration_deadline.try(:to_s, :iso8601) }), @whois_record.json end diff --git a/test/models/whois_record_test.rb b/test/models/whois_record_test.rb index 63e19d2be..cacd0e0fa 100644 --- a/test/models/whois_record_test.rb +++ b/test/models/whois_record_test.rb @@ -12,10 +12,7 @@ class WhoisRecordTest < ActiveSupport::TestCase end def test_generated_json_has_expected_values - expected_disclaimer_text = <<-TEXT.squish - Search results may not be used for commercial, advertising, recompilation, - repackaging, redistribution, reuse, obscuring or other similar activities. - TEXT + expected_disclaimer_text = SettingEntry.find_by(code: 'registry_whois_disclaimer').retrieve expected_partial_hash = { disclaimer: expected_disclaimer_text, From 6e72bb03b38d395cf70138f80508c8034cc02840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Tue, 20 Oct 2020 15:48:35 +0300 Subject: [PATCH 04/56] DomainCron: Don't send force delete mail if template empty --- app/models/concerns/job/force_delete_notify.rb | 2 +- test/models/domain_cron_test.rb | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/models/concerns/job/force_delete_notify.rb b/app/models/concerns/job/force_delete_notify.rb index 658c7a315..bc291354e 100644 --- a/app/models/concerns/job/force_delete_notify.rb +++ b/app/models/concerns/job/force_delete_notify.rb @@ -15,7 +15,7 @@ module Concerns domain.registrar.notifications.create!(text: I18n.t('grace_period_started_domain', domain_name: domain.name, date: domain.force_delete_start)) - send_mail(domain) + send_mail(domain) if domain.template_name.present? domain.update(contact_notification_sent_date: Time.zone.today) end diff --git a/test/models/domain_cron_test.rb b/test/models/domain_cron_test.rb index 3bf36b9e2..0224b1a61 100644 --- a/test/models/domain_cron_test.rb +++ b/test/models/domain_cron_test.rb @@ -39,6 +39,21 @@ class DomainCronTest < ActiveSupport::TestCase assert_emails 1 end + def does_not_deliver_forced_email_if_template_empty + Setting.redemption_grace_period = 30 + + @domain.update(valid_to: Time.zone.parse('2012-08-05')) + assert_not @domain.force_delete_scheduled? + travel_to Time.zone.parse('2010-07-05') + @domain.schedule_force_delete(type: :soft) + @domain.reload + @domain.update(template_name: nil) + travel_to Time.zone.parse('2010-08-06') + DomainCron.start_client_hold + + assert_emails 0 + end + def test_does_not_sets_hold_if_already_set Setting.redemption_grace_period = 30 From a7587b9c4faf36dd540088d1b06ef66a775e8565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Tue, 20 Oct 2020 17:08:29 +0300 Subject: [PATCH 05/56] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ef45bf81..90e2523dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +20.10.2020 +* ForceDelete mailer now respects option to not notify registrant [#1719](https://github.com/internetee/registry/pull/1719) + 19.10.2020 * Improved logging for LHV-connect messages [#1712](https://github.com/internetee/registry/issues/1712) * LHV-connect gem update to handle blank descriptions [#1714](https://github.com/internetee/registry/issues/1714) From 9503850d71c0ec24f1201334715f7b9f05ea8913 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Mon, 26 Oct 2020 14:00:19 +0500 Subject: [PATCH 06/56] Remove extra day from soft delete years Closes #1720 --- app/models/concerns/domain/force_delete.rb | 2 +- test/models/domain/force_delete_test.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index af3aaa7c7..9b75d1e92 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -106,7 +106,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength end def soft_delete_dates(years) - self.force_delete_start = valid_to - years.years + 1.day + 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 diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb index ad91ccfec..0969504a4 100644 --- a/test/models/domain/force_delete_test.rb +++ b/test/models/domain/force_delete_test.rb @@ -27,8 +27,8 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase @domain.reload assert @domain.force_delete_scheduled? - assert_equal Date.parse('2010-09-20'), @domain.force_delete_date.to_date - assert_equal Date.parse('2010-08-06'), @domain.force_delete_start.to_date + assert_equal Date.parse('2010-09-19'), @domain.force_delete_date.to_date + assert_equal Date.parse('2010-08-05'), @domain.force_delete_start.to_date end def test_schedules_force_delete_soft_less_than_year_ahead From 407577cdb7924673f453af4cf3d15ccd3bb35f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Tue, 27 Oct 2020 13:00:34 +0200 Subject: [PATCH 07/56] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90e2523dc..a2609918e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +27.10.2020 +* Fixed 1 day delay in force delete for multi year registrations [#1720](https://github.com/internetee/registry/issues/1720) + 20.10.2020 * ForceDelete mailer now respects option to not notify registrant [#1719](https://github.com/internetee/registry/pull/1719) From b1903fa8d68e47fbda220a7889b8fa2d722812ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 28 Oct 2020 15:13:17 +0200 Subject: [PATCH 08/56] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2609918e..90926de81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +28.10.2020 +* domain renew now canceles pending delete process [#1664](https://github.com/internetee/registry/issues/1664) + 27.10.2020 * Fixed 1 day delay in force delete for multi year registrations [#1720](https://github.com/internetee/registry/issues/1720) From 083be0d536769993d73f0385660d61cfb8798ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 28 Oct 2020 16:20:08 +0200 Subject: [PATCH 09/56] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90926de81..4b8504cde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ 28.10.2020 -* domain renew now canceles pending delete process [#1664](https://github.com/internetee/registry/issues/1664) +* Domain renew now canceles pending delete process [#1664](https://github.com/internetee/registry/issues/1664) +* Added multi-language support to whois disclaimer [#1703](https://github.com/internetee/registry/issues/1703) 27.10.2020 * Fixed 1 day delay in force delete for multi year registrations [#1720](https://github.com/internetee/registry/issues/1720) From c1bba784d6450948c4f809bf805051b749372de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 28 Oct 2020 16:35:35 +0200 Subject: [PATCH 10/56] Update contact(s) name based on eIdentity data from Registrant API --- app/models/registrant_user.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index c0addb5cd..40f48f69c 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -2,6 +2,7 @@ class RegistrantUser < User attr_accessor :idc_data devise :trackable, :timeoutable + after_save :update_related_contacts def ability @ability ||= Ability.new(self) @@ -54,6 +55,12 @@ class RegistrantUser < User username.split.second end + def update_related_contacts + cc, idcode = registrant_ident.split('-') + contacts = Contact.where(ident: idcode, country_code: cc).where('name != ?', username) + contacts.each { |c| c.update(name: username) } + end + class << self def find_or_create_by_api_data(user_data = {}) return false unless user_data[:ident] From 7b258f8e798ada9d681177ba6e0d1c9e60abbae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 28 Oct 2020 17:05:48 +0200 Subject: [PATCH 11/56] Don't force RegistrantUser name to be uppercase --- app/models/registrant_user.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index 40f48f69c..cb8212e17 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -57,7 +57,9 @@ class RegistrantUser < User def update_related_contacts cc, idcode = registrant_ident.split('-') - contacts = Contact.where(ident: idcode, country_code: cc).where('name != ?', username) + contacts = Contact.where(ident: idcode, country_code: cc) + .where('UPPER(name) != UPPER(?)', username) + contacts.each { |c| c.update(name: username) } end @@ -67,8 +69,8 @@ class RegistrantUser < User return false unless user_data[:first_name] return false unless user_data[:last_name] - user_data.each_value { |v| v.upcase! if v.is_a?(String) } user_data[:country_code] ||= 'EE' + %i[ident country_code].each { |f| user_data[f].upcase! if user_data[f].is_a?(String) } find_or_create_by_user_data(user_data) end From e1d2fb45d57be67ae924cf47767cc31b253d7624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 29 Oct 2020 11:11:39 +0200 Subject: [PATCH 12/56] Fix tests --- app/models/registrant_user.rb | 5 ++-- .../registrant_user_creation_test.rb | 23 +++++++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index cb8212e17..420446582 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -2,7 +2,6 @@ class RegistrantUser < User attr_accessor :idc_data devise :trackable, :timeoutable - after_save :update_related_contacts def ability @ability ||= Ability.new(self) @@ -56,8 +55,7 @@ class RegistrantUser < User end def update_related_contacts - cc, idcode = registrant_ident.split('-') - contacts = Contact.where(ident: idcode, country_code: cc) + contacts = Contact.where(ident: ident, country_code: country_code) .where('UPPER(name) != UPPER(?)', username) contacts.each { |c| c.update(name: username) } @@ -100,6 +98,7 @@ class RegistrantUser < User user.username = "#{user_data[:first_name]} #{user_data[:last_name]}" user.save + user.update_related_contacts user end end diff --git a/test/models/registrant_user/registrant_user_creation_test.rb b/test/models/registrant_user/registrant_user_creation_test.rb index 5ed680795..9fff4ca02 100644 --- a/test/models/registrant_user/registrant_user_creation_test.rb +++ b/test/models/registrant_user/registrant_user_creation_test.rb @@ -14,7 +14,7 @@ class RegistrantUserCreationTest < ActiveSupport::TestCase assert_equal('JOHN SMITH', user.username) end - def test_find_or_create_by_api_data_creates_a_user_after_upcasing_input + def test_find_or_create_by_api_data_creates_a_user_with_original_name user_data = { ident: '37710100070', first_name: 'John', @@ -24,6 +24,25 @@ class RegistrantUserCreationTest < ActiveSupport::TestCase RegistrantUser.find_or_create_by_api_data(user_data) user = User.find_by(registrant_ident: 'EE-37710100070') - assert_equal('JOHN SMITH', user.username) + assert_equal('John Smith', user.username) + end + + def test_updates_related_contacts_name_if_differs_from_e_identity + contact = contacts(:john) + contact.update(ident: '39708290276', ident_country_code: 'EE') + + user_data = { + ident: '39708290276', + first_name: 'John', + last_name: 'Doe' + } + + RegistrantUser.find_or_create_by_api_data(user_data) + + user = User.find_by(registrant_ident: 'EE-39708290276') + assert_equal('John Doe', user.username) + + contact.reload + assert_equal user.username, contact.name end end From 44637b08cf46ec8ecee7cef366e4c19994f807fb Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 29 Oct 2020 16:15:12 +0500 Subject: [PATCH 13/56] Fix statuses search bug --- app/controllers/registrar/domains_controller.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/controllers/registrar/domains_controller.rb b/app/controllers/registrar/domains_controller.rb index 50ad0bd10..581b517ae 100644 --- a/app/controllers/registrar/domains_controller.rb +++ b/app/controllers/registrar/domains_controller.rb @@ -16,13 +16,14 @@ class Registrar end end - if params[:statuses_contains] - domains = current_registrar_user.registrar.domains.includes(:registrar, :registrant).where( - "statuses @> ?::varchar[]", "{#{params[:statuses_contains].join(',')}}" - ) - else - domains = current_registrar_user.registrar.domains.includes(:registrar, :registrant) - end + domains = if params[:statuses_contains] + current_registrar_user.registrar.domains + .includes(:registrar, :registrant) + .where('domains.statuses @> ?::varchar[]', + "{#{params[:statuses_contains].join(',')}}") + else + current_registrar_user.registrar.domains.includes(:registrar, :registrant) + end normalize_search_parameters do @q = domains.search(search_params) From 358a39e0fdecc410face333569c538eadbe836c2 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 29 Oct 2020 17:08:34 +0500 Subject: [PATCH 14/56] Fix search via Ransack association --- .../registrar/domains_controller.rb | 24 +++++++++++-------- .../registrar/domains/_search_form.html.erb | 3 ++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/app/controllers/registrar/domains_controller.rb b/app/controllers/registrar/domains_controller.rb index 581b517ae..1a46da463 100644 --- a/app/controllers/registrar/domains_controller.rb +++ b/app/controllers/registrar/domains_controller.rb @@ -11,27 +11,27 @@ class Registrar search_params[:name_matches].present? domain = Domain.find_by(name: search_params[:name_matches]) - if domain - redirect_to info_registrar_domains_url(domain_name: domain.name) and return - end + redirect_to info_registrar_domains_url(domain_name: domain.name) and return if domain end domains = if params[:statuses_contains] - current_registrar_user.registrar.domains - .includes(:registrar, :registrant) - .where('domains.statuses @> ?::varchar[]', - "{#{params[:statuses_contains].join(',')}}") + current_domain_scope.where('domains.statuses @> ?::varchar[]', + "{#{params[:statuses_contains].join(',')}}") else - current_registrar_user.registrar.domains.includes(:registrar, :registrant) + current_domain_scope end + if params[:contacts_ident_eq] + domains = domains.where(contacts: { ident: params[:contacts_ident_eq] }) + end + normalize_search_parameters do - @q = domains.search(search_params) + @q = domains.search(search_params.except(:contacts_ident_eq)) @domains = @q.result.page(params[:page]) # if we do not get any results, add wildcards to the name field and search again if @domains.count == 0 && search_params[:name_matches] !~ /^%.+%$/ - new_search_params = search_params.to_h + new_search_params = search_params.to_h.except(:contacts_ident_eq) new_search_params[:name_matches] = "%#{new_search_params[:name_matches]}%" @q = domains.search(new_search_params) @domains = @q.result.page(params[:page]) @@ -57,6 +57,10 @@ class Registrar end end + def current_domain_scope + current_registrar_user.registrar.domains.includes(:registrar, :registrant) + end + def info authorize! :info, Depp::Domain @data = @domain.info(params[:domain_name]) if params[:domain_name] diff --git a/app/views/registrar/domains/_search_form.html.erb b/app/views/registrar/domains/_search_form.html.erb index 08b370b76..e9e5b5e1a 100644 --- a/app/views/registrar/domains/_search_form.html.erb +++ b/app/views/registrar/domains/_search_form.html.erb @@ -18,7 +18,8 @@
<%= f.label :contact_ident, for: nil %> - <%= f.search_field :contacts_ident_eq, class: 'form-control', placeholder: t(:contact_ident) %> + <%= f.search_field :contacts_ident_eq, value: search_params[:contacts_ident_eq], + class: 'form-control', placeholder: t(:contact_ident) %>
From 2f259982da9e1d22a80305c37e80fd529bf59ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Fri, 30 Oct 2020 11:51:20 +0200 Subject: [PATCH 15/56] Find related contacts via ident and ident_country_code --- app/models/registrant_user.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index 420446582..f1e0e1c2d 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -55,7 +55,8 @@ class RegistrantUser < User end def update_related_contacts - contacts = Contact.where(ident: ident, country_code: country_code) + cc, idcode = registrant_ident.split('-') + contacts = Contact.where(ident: idcode, ident_country_code: cc) .where('UPPER(name) != UPPER(?)', username) contacts.each { |c| c.update(name: username) } From 89154c4fe200482caa1f868802b8bdf642b13cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Fri, 30 Oct 2020 11:56:07 +0200 Subject: [PATCH 16/56] Use predefined methods to determine country and ident --- app/models/registrant_user.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index f1e0e1c2d..089292917 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -55,8 +55,7 @@ class RegistrantUser < User end def update_related_contacts - cc, idcode = registrant_ident.split('-') - contacts = Contact.where(ident: idcode, ident_country_code: cc) + contacts = Contact.where(ident: ident, ident_country_code: country.alpha2) .where('UPPER(name) != UPPER(?)', username) contacts.each { |c| c.update(name: username) } From 7d6d53e4207df8e62ac390beb7a519444d578f2f Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Mon, 2 Nov 2020 15:47:00 +0500 Subject: [PATCH 17/56] Auto-select email template Chooses template based on domain registrant ident_type. Closes #442 --- .../admin/domains/force_delete_controller.rb | 8 +++++-- .../domains/_force_delete_dialog.html.erb | 6 ----- app/views/admin/domains/edit.html.erb | 2 +- .../admin_area/domains/force_delete_test.rb | 22 +++++++++++++++++++ 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/domains/force_delete_controller.rb b/app/controllers/admin/domains/force_delete_controller.rb index c61f050d2..e64012de7 100644 --- a/app/controllers/admin/domains/force_delete_controller.rb +++ b/app/controllers/admin/domains/force_delete_controller.rb @@ -22,7 +22,7 @@ module Admin send_email domain.update(contact_notification_sent_date: Time.zone.today) else - domain.update(template_name: params[:template_name]) + domain.update(template_name: template_name) end end @@ -34,6 +34,10 @@ module Admin private + def template_name + domain.registrant.org? ? 'legal_person' : 'private_person' + end + def domain @domain ||= Domain.find(params[:domain_id]) end @@ -46,7 +50,7 @@ module Admin DomainDeleteMailer.forced(domain: domain, registrar: domain.registrar, registrant: domain.registrant, - template_name: params[:template_name]).deliver_now + template_name: template_name).deliver_now end def force_delete_type diff --git a/app/views/admin/domains/_force_delete_dialog.html.erb b/app/views/admin/domains/_force_delete_dialog.html.erb index a76c14edd..932a3f75c 100644 --- a/app/views/admin/domains/_force_delete_dialog.html.erb +++ b/app/views/admin/domains/_force_delete_dialog.html.erb @@ -33,12 +33,6 @@ - <% end %> <%= render 'form' %> -<%= render 'force_delete_dialog', domain: @domain, templates: force_delete_templates %> +<%= render 'force_delete_dialog', domain: @domain %> diff --git a/test/system/admin_area/domains/force_delete_test.rb b/test/system/admin_area/domains/force_delete_test.rb index 4ccc10923..6aa53be6c 100644 --- a/test/system/admin_area/domains/force_delete_test.rb +++ b/test/system/admin_area/domains/force_delete_test.rb @@ -42,6 +42,22 @@ class AdminAreaDomainForceDeleteTest < ApplicationSystemTestCase find(:css, '#soft_delete').set(true) click_link_or_button 'Force delete domain' end + + @domain.reload + assert_equal template_name, @domain.template_name + end + + def test_uses_legal_template_if_registrant_org + @domain.registrant.update(ident_type: 'org') + + 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 template_name, @domain.template_name end def test_allows_to_skip_notifying_registrant_and_admin_contacts_by_email @@ -71,4 +87,10 @@ 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 269c5c284ff216d143b52c24fa56ee28d7657317 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Mon, 2 Nov 2020 16:05:04 +0500 Subject: [PATCH 18/56] Remove ForceDelete from statuses blocking confirmation --- app/models/domain.rb | 2 +- test/models/domain/force_delete_test.rb | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/models/domain.rb b/app/models/domain.rb index 2b3213a36..648a7b3c5 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -384,7 +384,7 @@ class Domain < ApplicationRecord end def registrant_update_confirmable?(token) - return false if (statuses & [DomainStatus::FORCE_DELETE, DomainStatus::DELETE_CANDIDATE]).any? + return false if statuses.include? DomainStatus::DELETE_CANDIDATE return false unless pending_update? return false unless registrant_verification_asked? return false unless registrant_verification_token == token diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb index 0969504a4..9743989ac 100644 --- a/test/models/domain/force_delete_test.rb +++ b/test/models/domain/force_delete_test.rb @@ -252,4 +252,16 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase assert @domain.force_delete_scheduled? assert @domain.pending_update? end + + def test_force_delete_does_not_affect_registrant_update_confirmable + @domain.schedule_force_delete(type: :soft) + @domain.registrant_verification_asked!('test', User.last.id) + @domain.save! + @domain.reload + + @domain.statuses << DomainStatus::PENDING_UPDATE + + assert @domain.force_delete_scheduled? + assert @domain.registrant_update_confirmable?(@domain.registrant_verification_token) + end end From b1488169492827fc0180942b3ec71e66023b8280 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 3 Nov 2020 14:22:12 +0500 Subject: [PATCH 19/56] Fix ForceDelete possible statuses doubling --- app/models/concerns/domain/force_delete.rb | 6 +++--- test/models/domain/force_delete_test.rb | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index 9b75d1e92..7a1ace6a7 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -128,9 +128,9 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength end def add_force_delete_statuses - statuses << DomainStatus::FORCE_DELETE - statuses << DomainStatus::SERVER_RENEW_PROHIBITED - statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED + self.statuses |= [DomainStatus::FORCE_DELETE, + DomainStatus::SERVER_RENEW_PROHIBITED, + DomainStatus::SERVER_TRANSFER_PROHIBITED] end def remove_force_delete_statuses diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb index 0969504a4..4678ed99a 100644 --- a/test/models/domain/force_delete_test.rb +++ b/test/models/domain/force_delete_test.rb @@ -137,6 +137,19 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase assert_not @domain.force_delete_scheduled? end + def test_force_delete_does_not_double_statuses + statuses = [ + DomainStatus::FORCE_DELETE, + DomainStatus::SERVER_RENEW_PROHIBITED, + DomainStatus::SERVER_TRANSFER_PROHIBITED, + ] + @domain.statuses = @domain.statuses + statuses + @domain.save! + @domain.reload + @domain.schedule_force_delete(type: :fast_track) + assert_equal @domain.statuses.size, statuses.size + end + def test_cancelling_force_delete_removes_statuses_that_were_set_on_force_delete statuses = [ DomainStatus::FORCE_DELETE, From 3444c4e021e007ad75e384f64cb5c0922ec39cbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Tue, 3 Nov 2020 16:14:01 +0200 Subject: [PATCH 20/56] Add registrar poll message after updateing registrant contact(s) names --- app/models/registrant_user.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index 089292917..aa41ccff8 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -58,7 +58,11 @@ class RegistrantUser < User contacts = Contact.where(ident: ident, ident_country_code: country.alpha2) .where('UPPER(name) != UPPER(?)', username) - contacts.each { |c| c.update(name: username) } + contacts.each do |contact| + contact.update(name: username) + action = actions.create!(contact: contact, operation: :update) + contact.registrar.notify(action) + end end class << self From 08815f58124e8439259d54b36990b4f2f9c67298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Tue, 3 Nov 2020 18:07:20 +0200 Subject: [PATCH 21/56] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b8504cde..3860062c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +03.11.2020 +* Fixed registrant confirmation while forcedelete is set on a domain [#1729](https://github.com/internetee/registry/issues/1729) + 28.10.2020 * Domain renew now canceles pending delete process [#1664](https://github.com/internetee/registry/issues/1664) * Added multi-language support to whois disclaimer [#1703](https://github.com/internetee/registry/issues/1703) From b62ffc4e7ee8079c694e166da564dc2099600958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Tue, 3 Nov 2020 18:18:47 +0200 Subject: [PATCH 22/56] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3860062c8..0d92e9339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ 03.11.2020 * Fixed registrant confirmation while forcedelete is set on a domain [#1729](https://github.com/internetee/registry/issues/1729) +* Fixed search in registrar domain view [#262](https://github.com/internetee/registry/issues/262) 28.10.2020 * Domain renew now canceles pending delete process [#1664](https://github.com/internetee/registry/issues/1664) From 433445f1ac22101cb830d96a8528f86253df344f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Tue, 3 Nov 2020 18:36:35 +0200 Subject: [PATCH 23/56] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d92e9339..2eafe8711 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ 03.11.2020 * Fixed registrant confirmation while forcedelete is set on a domain [#1729](https://github.com/internetee/registry/issues/1729) * Fixed search in registrar domain view [#262](https://github.com/internetee/registry/issues/262) +* Fixed double status issue on setting forceDelete [#1135](https://github.com/internetee/registry/issues/1135) 28.10.2020 * Domain renew now canceles pending delete process [#1664](https://github.com/internetee/registry/issues/1664) From 20d5ab9ebf1fe4fca67531e02fe46e82444af04c Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 4 Nov 2020 14:24:09 +0500 Subject: [PATCH 24/56] Fix statuses processing for ForceDelete --- app/models/concerns/domain/force_delete.rb | 4 +-- test/models/domain/force_delete_test.rb | 33 ++++++++++++++++------ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index 7a1ace6a7..7f3cb3922 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -80,8 +80,8 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength end def cancel_force_delete - restore_statuses_before_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 @@ -119,7 +119,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength end def preserve_current_statuses_for_force_delete - self.statuses_before_force_delete = statuses.clone + update(statuses_before_force_delete: statuses) end def restore_statuses_before_force_delete diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb index 8fcbfeb2b..f0723c326 100644 --- a/test/models/domain/force_delete_test.rb +++ b/test/models/domain/force_delete_test.rb @@ -150,19 +150,36 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase assert_equal @domain.statuses.size, statuses.size end - def test_cancelling_force_delete_removes_statuses_that_were_set_on_force_delete - statuses = [ - DomainStatus::FORCE_DELETE, - DomainStatus::SERVER_RENEW_PROHIBITED, - DomainStatus::SERVER_TRANSFER_PROHIBITED, - ] - @domain.statuses = @domain.statuses + statuses + def test_cancelling_force_delete_removes_force_delete_status @domain.schedule_force_delete(type: :fast_track) + assert @domain.statuses.include?(DomainStatus::FORCE_DELETE) + assert @domain.statuses.include?(DomainStatus::SERVER_RENEW_PROHIBITED) + assert @domain.statuses.include?(DomainStatus::SERVER_TRANSFER_PROHIBITED) + @domain.cancel_force_delete @domain.reload - assert_empty @domain.statuses & statuses + assert_not @domain.statuses.include?(DomainStatus::FORCE_DELETE) + assert_not @domain.statuses.include?(DomainStatus::SERVER_RENEW_PROHIBITED) + assert_not @domain.statuses.include?(DomainStatus::SERVER_TRANSFER_PROHIBITED) + end + + def test_cancelling_force_delete_keeps_previous_statuses + statuses = [ + DomainStatus::SERVER_RENEW_PROHIBITED, + DomainStatus::SERVER_TRANSFER_PROHIBITED, + ] + + @domain.statuses = statuses + @domain.save! + @domain.reload + + @domain.schedule_force_delete(type: :fast_track) + @domain.cancel_force_delete + @domain.reload + + assert_equal @domain.statuses, statuses end def test_hard_force_delete_should_have_outzone_and_purge_date_with_time From a6702267e58482dc56a812e71a2b730ecdb3fb24 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 4 Nov 2020 17:11:46 +0500 Subject: [PATCH 25/56] Move template decision method to FD concern --- app/controllers/admin/domains/force_delete_controller.rb | 8 ++------ app/models/concerns/domain/force_delete.rb | 4 ++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/domains/force_delete_controller.rb b/app/controllers/admin/domains/force_delete_controller.rb index e64012de7..6a111926f 100644 --- a/app/controllers/admin/domains/force_delete_controller.rb +++ b/app/controllers/admin/domains/force_delete_controller.rb @@ -22,7 +22,7 @@ module Admin send_email domain.update(contact_notification_sent_date: Time.zone.today) else - domain.update(template_name: template_name) + domain.update(template_name: domain.notification_template) end end @@ -34,10 +34,6 @@ module Admin private - def template_name - domain.registrant.org? ? 'legal_person' : 'private_person' - end - def domain @domain ||= Domain.find(params[:domain_id]) end @@ -50,7 +46,7 @@ module Admin DomainDeleteMailer.forced(domain: domain, registrar: domain.registrar, registrant: domain.registrant, - template_name: template_name).deliver_now + template_name: domain.notification_template).deliver_now end def force_delete_type diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index 9b75d1e92..bf619c65f 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -19,6 +19,10 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength end end + def notification_template + registrant.org? ? 'legal_person' : 'private_person' + end + def force_delete_scheduled? statuses.include?(DomainStatus::FORCE_DELETE) end From b35eb160a6ecf32c3f4735b72f7b29eb43ed29e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 4 Nov 2020 16:28:09 +0200 Subject: [PATCH 26/56] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2eafe8711..6721791d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +04.11.2020 +* Email notification templates for forceDelete are now automatically selected according to registrant type [#442](https://github.com/internetee/registry/issues/442) + 03.11.2020 * Fixed registrant confirmation while forcedelete is set on a domain [#1729](https://github.com/internetee/registry/issues/1729) * Fixed search in registrar domain view [#262](https://github.com/internetee/registry/issues/262) From c3f63ed43a80a60410e52e4e29d53af89c136008 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Fri, 30 Oct 2020 15:36:34 +0500 Subject: [PATCH 27/56] Add new mailer template for expired soft delete domains --- app/jobs/domain_expire_email_job.rb | 6 ++- app/mailers/domain_expire_mailer.rb | 37 ++++++++++---- .../expired_soft.html.erb | 48 +++++++++++++++++++ .../expired_soft.text.erb | 48 +++++++++++++++++++ test/mailers/domain_expire_mailer_test.rb | 11 ++++- .../previews/domain_expire_mailer_preview.rb | 8 +++- 6 files changed, 146 insertions(+), 12 deletions(-) create mode 100644 app/views/mailers/domain_expire_mailer/expired_soft.html.erb create mode 100644 app/views/mailers/domain_expire_mailer/expired_soft.text.erb diff --git a/app/jobs/domain_expire_email_job.rb b/app/jobs/domain_expire_email_job.rb index 9b70a54e6..94bd8670c 100644 --- a/app/jobs/domain_expire_email_job.rb +++ b/app/jobs/domain_expire_email_job.rb @@ -4,6 +4,10 @@ class DomainExpireEmailJob < Que::Job return if domain.registered? - DomainExpireMailer.expired(domain: domain, registrar: domain.registrar).deliver_now + if domain.force_delete_scheduled? + DomainExpireMailer.expired_soft(domain: domain, registrar: domain.registrar).deliver_now + else + DomainExpireMailer.expired(domain: domain, registrar: domain.registrar).deliver_now + end end end diff --git a/app/mailers/domain_expire_mailer.rb b/app/mailers/domain_expire_mailer.rb index ecbd8ee3d..e73b1fa84 100644 --- a/app/mailers/domain_expire_mailer.rb +++ b/app/mailers/domain_expire_mailer.rb @@ -1,19 +1,38 @@ class DomainExpireMailer < ApplicationMailer + attr_accessor :domain, :registrar + def expired(domain:, registrar:) - @domain = domain_presenter(domain: domain) - @registrar = registrar_presenter(registrar: registrar) + process_mail(domain: domain, registrar: registrar, method_name: __method__.to_s) + end - recipient = filter_invalid_emails(emails: domain.primary_contact_emails, domain: domain) - subject = default_i18n_subject(domain_name: domain.name) - - logger.info("Send DomainExpireMailer#expired email for domain #{domain.name} (##{domain.id})" \ - " to #{recipient.join(', ')}") - - mail(to: recipient, subject: subject) + def expired_soft(domain:, registrar:) + process_mail(domain: domain, registrar: registrar, method_name: __method__.to_s) end private + def process_mail(domain:, registrar:, method_name:) + init(domain, registrar) + + logger.info("Send DomainExpireMailer##{method_name} email for #{domain.name} (##{domain.id})" \ + " to #{recipient(domain).join(', ')}") + + mail(to: recipient(domain), subject: subject) + end + + def init(domain, registrar) + @domain = domain_presenter(domain: domain) + @registrar = registrar_presenter(registrar: registrar) + end + + def recipient(domain) + filter_invalid_emails(emails: domain.primary_contact_emails, domain: @domain) + end + + def subject + default_i18n_subject(domain_name: @domain.name) + end + def domain_presenter(domain:) DomainPresenter.new(domain: domain, view: view_context) end diff --git a/app/views/mailers/domain_expire_mailer/expired_soft.html.erb b/app/views/mailers/domain_expire_mailer/expired_soft.html.erb new file mode 100644 index 000000000..1dd661a38 --- /dev/null +++ b/app/views/mailers/domain_expire_mailer/expired_soft.html.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.

+ +

Domeeni <%= @domain.name %> registripidaja:

+<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %> + +

Ülevaate kõikidest endaga seotud domeenidest saate registreerija portaalist.

+ +<%= 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.

+ +

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.

+ +<%= render 'mailers/shared/signatures/signature.en.html' %> + +
+ +

Срок действия домена <%= @domain.name %> истек

+ +

Уважаемый регистрант/административный контакт домена .ee

+ +

Срок действия доменного имени <%= @domain.name %> истек, и с <%= @domain.on_hold_date %> оно больше не доступно в интернете. У домена указаны неверные контактные данные. Обновление и перенос к другому регистратору заблокированы до исправления контактных данных. Для исправления контактных данных и обновления регистрации вашего домена, пожалуйста, обратитесь в вашему регистратору.

+ +

Если доменное имя не продлено, домен <%= @domain.name %> будет удален и <%= @domain.delete_date %> идет на аукцион в .ee среду аукциона. О проведении доменных аукционов читайте здесь.

+ +

Pегистратор домена <%= @domain.name %>:

+<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %> + +

Обзор всех связанных с вами доменов можете получить на портале регистратора.

+ +<%= 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 28/56] 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 29/56] 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 @@ +

Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt

+ +

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:

+<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %> + +<%= render 'mailers/shared/signatures/signature.et.html' %> + +
+ +

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:

+<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %> + +<%= render 'mailers/shared/signatures/signature.en.html' %> +
+ +

Уважаемый регистрант/административный контакт домена .ee

+ +

Целевому учреждению 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 %>

+ +<%= render 'mailers/shared/signatures/signature.ru.html' %> From 3ce0fc4a5c3d035b1c9f47675dc4c8279364d562 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 5 Nov 2020 12:18:33 +0500 Subject: [PATCH 30/56] Add invalid email template --- app/models/concerns/email_verifable.rb | 4 ++ app/models/domain.rb | 4 ++ .../forced/invalid_email.html.erb | 24 +++++----- .../forced/invalid_email.text.erb | 47 +++++++++++++++++++ 4 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 app/views/mailers/domain_delete_mailer/forced/invalid_email.text.erb diff --git a/app/models/concerns/email_verifable.rb b/app/models/concerns/email_verifable.rb index dc512b2c8..2168a0754 100644 --- a/app/models/concerns/email_verifable.rb +++ b/app/models/concerns/email_verifable.rb @@ -15,6 +15,10 @@ module Concerns domain: domain(billing_email)) end + def email_verification_failed? + email_verification.failed? + end + class_methods do def domain(email) Mail::Address.new(email).domain&.downcase || 'not_found' diff --git a/app/models/domain.rb b/app/models/domain.rb index 648a7b3c5..b15bb7c55 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -642,6 +642,10 @@ class Domain < ApplicationRecord DNS::DomainName.new(name) end + def contact_emails_verification_failed + contacts.select(&:email_verification_failed?)&.map(&:email)&.uniq + end + def self.to_csv CSV.generate do |csv| csv << column_names 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 2dec52905..9e69519e4 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,12 +1,12 @@

Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt

-

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:

<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %> @@ -17,11 +17,13 @@

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:

<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %> @@ -31,15 +33,15 @@

Уважаемый регистрант/административный контакт домена .ee

-

Целевому учреждению 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 %>

+<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>

<%= render 'mailers/shared/signatures/signature.ru.html' %> diff --git a/app/views/mailers/domain_delete_mailer/forced/invalid_email.text.erb b/app/views/mailers/domain_delete_mailer/forced/invalid_email.text.erb new file mode 100644 index 000000000..8d2fc58ce --- /dev/null +++ b/app/views/mailers/domain_delete_mailer/forced/invalid_email.text.erb @@ -0,0 +1,47 @@ +

Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt

+ +

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:

+<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %> + +<%= render 'mailers/shared/signatures/signature.et.html' %> + +
+ +

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:

+<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %> + +<%= render 'mailers/shared/signatures/signature.en.html' %> +
+ +

Уважаемый регистрант/административный контакт домена .ee

+ +

Целевому учреждению 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 31/56] 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 32/56] 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 33/56] 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 @@

Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt

-

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 34/56] 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 35/56] 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 36/56] 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 37/56] 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 40/56] 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 26ec7e3f12a3d88294b8631c57ed2c1c95b60a5e Mon Sep 17 00:00:00 2001 From: Artur Beljajev Date: Fri, 13 Sep 2019 16:55:40 +0300 Subject: [PATCH 41/56] 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 42/56] 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 43/56] 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 44/56] 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 45/56] 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.0 en @@ -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.0 en @@ -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.0 en @@ -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.0 en @@ -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 46/56] 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 47/56] 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 48/56] 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 49/56] 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 50/56] 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 51/56] 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 52/56] 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 53/56] 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 54/56] 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 55/56] 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 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 56/56] 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)