From d35042a1be225b51887bd2918b63c6f87dcb69d6 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Mon, 4 Jan 2021 18:30:20 +0500 Subject: [PATCH 1/6] Add test to check if Whois::Record saved --- test/models/domain/releasable/auctionable_test.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/models/domain/releasable/auctionable_test.rb b/test/models/domain/releasable/auctionable_test.rb index de3ac0ff6..bb0485f7d 100644 --- a/test/models/domain/releasable/auctionable_test.rb +++ b/test/models/domain/releasable/auctionable_test.rb @@ -58,6 +58,20 @@ class DomainReleasableAuctionableTest < ActiveSupport::TestCase end end + def test_updates_whois + @domain.update!(delete_date: '2010-07-04') + travel_to Time.zone.parse('2010-07-05') + + Domain.release_domains + + whois_record = Whois::Record.find_by(name: @domain.name) + + json = { "name"=>@domain.name, + "status"=>["AtAuction"], + "disclaimer"=> Setting.registry_whois_disclaimer } + assert_equal whois_record.json, json + end + def test_notifies_registrar @domain.update!(delete_date: '2010-07-04') travel_to Time.zone.parse('2010-07-05') From 0c5ef72c7da90a02d6d4ce370e5a78cf47046b12 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 5 Jan 2021 14:58:01 +0500 Subject: [PATCH 2/6] Add logging & domain lock on release --- app/models/concerns/domain/releasable.rb | 10 +++++++++- app/models/concerns/to_stdout.rb | 8 ++++++++ app/models/dns/domain_name.rb | 5 ++++- app/models/whois/record.rb | 6 ++++++ test/models/domain/releasable/auctionable_test.rb | 4 +++- 5 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 app/models/concerns/to_stdout.rb diff --git a/app/models/concerns/domain/releasable.rb b/app/models/concerns/domain/releasable.rb index 4aa5faa58..12a182b65 100644 --- a/app/models/concerns/domain/releasable.rb +++ b/app/models/concerns/domain/releasable.rb @@ -39,9 +39,12 @@ module Concerns def release if release_to_auction - transaction do + with_lock do + to_stdout "Checking if domain_name is auctionable: #{domain_name.auctionable?}" domain_name.sell_at_auction if domain_name.auctionable? + to_stdout 'Destroying domain' destroy! + to_stdout 'Sending registrar notification' registrar.notifications.create!(text: "#{I18n.t(:domain_deleted)}: #{name}", attached_obj_id: id, attached_obj_type: self.class) @@ -50,6 +53,11 @@ module Concerns discard end end + + def to_stdout(message) + time = Time.zone.now.utc + STDOUT << "#{time} - #{message}\n" unless Rails.env.test? + end end end end diff --git a/app/models/concerns/to_stdout.rb b/app/models/concerns/to_stdout.rb new file mode 100644 index 000000000..2a01ee668 --- /dev/null +++ b/app/models/concerns/to_stdout.rb @@ -0,0 +1,8 @@ +module ToStdout + extend ActiveSupport::Concern + + def to_stdout(message) + time = Time.zone.now.utc + STDOUT << "#{time} - #{message}\n" unless Rails.env.test? + end +end diff --git a/app/models/dns/domain_name.rb b/app/models/dns/domain_name.rb index c1af4d5e7..0daa7bbae 100644 --- a/app/models/dns/domain_name.rb +++ b/app/models/dns/domain_name.rb @@ -2,6 +2,7 @@ module DNS # Namespace is needed, because a class with the same name is defined by `domain_name` gem, # a dependency of `actionmailer`, class DomainName + include ToStdout def initialize(name) @name = name end @@ -36,6 +37,7 @@ module DNS auction = Auction.new auction.domain = name auction.start + to_stdout "Created the auction: #{auction.inspect}" update_whois_from_auction(auction) end @@ -100,7 +102,8 @@ module DNS whois_record = Whois::Record.find_or_create_by!(name: name) do |record| record.json = {} end - + to_stdout "Starting to update WHOIS record #{whois_record.inspect}\n\n"\ + "from auction #{auction.inspect}" whois_record.update_from_auction(auction) end end diff --git a/app/models/whois/record.rb b/app/models/whois/record.rb index 1d827e22a..b4f70c28f 100644 --- a/app/models/whois/record.rb +++ b/app/models/whois/record.rb @@ -1,24 +1,30 @@ module Whois class Record < Whois::Server + include ToStdout self.table_name = 'whois_records' def self.disclaimer Setting.registry_whois_disclaimer end + # rubocop:disable Metrics/AbcSize def update_from_auction(auction) if auction.started? update!(json: { name: auction.domain, status: ['AtAuction'], disclaimer: self.class.disclaimer }) + to_stdout "Updated from auction WHOIS record #{inspect}" elsif auction.no_bids? + to_stdout "Destroying WHOIS record #{inspect}" destroy! elsif auction.awaiting_payment? || auction.payment_received? update!(json: { name: auction.domain, status: ['PendingRegistration'], disclaimer: self.class.disclaimer, registration_deadline: auction.whois_deadline }) + to_stdout "Updated from auction WHOIS record #{inspect}" end end + # rubocop:enable Metrics/AbcSize end end diff --git a/test/models/domain/releasable/auctionable_test.rb b/test/models/domain/releasable/auctionable_test.rb index bb0485f7d..a74f41c90 100644 --- a/test/models/domain/releasable/auctionable_test.rb +++ b/test/models/domain/releasable/auctionable_test.rb @@ -25,6 +25,7 @@ class DomainReleasableAuctionableTest < ActiveSupport::TestCase def test_skips_auction_when_domains_is_blocked assert_equal 'shop.test', @domain.name blocked_domains(:one).update!(name: 'shop.test') + @domain.save!(validate: false) @domain.release @@ -34,6 +35,7 @@ class DomainReleasableAuctionableTest < ActiveSupport::TestCase def test_skips_auction_when_domains_is_reserved assert_equal 'shop.test', @domain.name reserved_domains(:one).update!(name: 'shop.test') + @domain.save!(validate: false) @domain.release @@ -58,7 +60,7 @@ class DomainReleasableAuctionableTest < ActiveSupport::TestCase end end - def test_updates_whois + def test_updates_whois_server @domain.update!(delete_date: '2010-07-04') travel_to Time.zone.parse('2010-07-05') From b60a7e571f01ee941780af8a90a8dc426b3aa04e Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 5 Jan 2021 17:21:13 +0500 Subject: [PATCH 3/6] Delete original WhoisRecord after domain deletion --- app/models/concerns/domain/releasable.rb | 20 +++++++++---------- app/models/domain.rb | 2 +- .../domain/releasable/auctionable_test.rb | 6 +++++- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/models/concerns/domain/releasable.rb b/app/models/concerns/domain/releasable.rb index 12a182b65..b800a4aa5 100644 --- a/app/models/concerns/domain/releasable.rb +++ b/app/models/concerns/domain/releasable.rb @@ -39,16 +39,16 @@ module Concerns def release if release_to_auction - with_lock do - to_stdout "Checking if domain_name is auctionable: #{domain_name.auctionable?}" - domain_name.sell_at_auction if domain_name.auctionable? - to_stdout 'Destroying domain' - destroy! - to_stdout 'Sending registrar notification' - registrar.notifications.create!(text: "#{I18n.t(:domain_deleted)}: #{name}", - attached_obj_id: id, - attached_obj_type: self.class) - end + lock! + to_stdout 'Destroying domain' + destroy! + to_stdout "Checking if domain_name is auctionable: #{domain_name.auctionable?}" + domain_name.sell_at_auction if domain_name.auctionable? + + to_stdout 'Sending registrar notification' + registrar.notifications.create!(text: "#{I18n.t(:domain_deleted)}: #{name}", + attached_obj_id: id, + attached_obj_type: self.class) else discard end diff --git a/app/models/domain.rb b/app/models/domain.rb index 49f18d9db..589a0b661 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -78,7 +78,7 @@ class Domain < ApplicationRecord true end - after_commit :update_whois_record, unless: -> { domain_name.at_auction? } + after_commit :update_whois_record after_create :update_reserved_domains def update_reserved_domains diff --git a/test/models/domain/releasable/auctionable_test.rb b/test/models/domain/releasable/auctionable_test.rb index a74f41c90..d24f46913 100644 --- a/test/models/domain/releasable/auctionable_test.rb +++ b/test/models/domain/releasable/auctionable_test.rb @@ -63,11 +63,15 @@ class DomainReleasableAuctionableTest < ActiveSupport::TestCase def test_updates_whois_server @domain.update!(delete_date: '2010-07-04') travel_to Time.zone.parse('2010-07-05') + old_whois = @domain.whois_record Domain.release_domains - whois_record = Whois::Record.find_by(name: @domain.name) + assert_raises ActiveRecord::RecordNotFound do + old_whois.reload + end + whois_record = Whois::Record.find_by(name: @domain.name) json = { "name"=>@domain.name, "status"=>["AtAuction"], "disclaimer"=> Setting.registry_whois_disclaimer } From 217f009fa3443cfe817ea6a9f72f479ba45677b8 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 6 Jan 2021 12:09:03 +0500 Subject: [PATCH 4/6] Small logic fixes --- app/models/concerns/domain/releasable.rb | 6 ------ app/models/domain.rb | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/app/models/concerns/domain/releasable.rb b/app/models/concerns/domain/releasable.rb index b800a4aa5..51e1a6f1c 100644 --- a/app/models/concerns/domain/releasable.rb +++ b/app/models/concerns/domain/releasable.rb @@ -39,7 +39,6 @@ module Concerns def release if release_to_auction - lock! to_stdout 'Destroying domain' destroy! to_stdout "Checking if domain_name is auctionable: #{domain_name.auctionable?}" @@ -53,11 +52,6 @@ module Concerns discard end end - - def to_stdout(message) - time = Time.zone.now.utc - STDOUT << "#{time} - #{message}\n" unless Rails.env.test? - end end end end diff --git a/app/models/domain.rb b/app/models/domain.rb index 589a0b661..34a8c26ff 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -10,6 +10,7 @@ class Domain < ApplicationRecord include Concerns::Domain::RegistryLockable include Concerns::Domain::Releasable include Concerns::Domain::Disputable + include ToStdout attr_accessor :roles From 1d5c46e6a09f6ed96f9b28725de9629b01c08d99 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 6 Jan 2021 15:33:02 +0500 Subject: [PATCH 5/6] Move ToStdout to /app/lib folder and include it in app.rb --- app/{models/concerns => lib}/to_stdout.rb | 6 ++---- app/models/concerns/domain/releasable.rb | 6 +++--- app/models/dns/domain_name.rb | 7 +++---- app/models/domain.rb | 1 - app/models/whois/record.rb | 7 +++---- config/application.rb | 2 ++ 6 files changed, 13 insertions(+), 16 deletions(-) rename app/{models/concerns => lib}/to_stdout.rb (57%) diff --git a/app/models/concerns/to_stdout.rb b/app/lib/to_stdout.rb similarity index 57% rename from app/models/concerns/to_stdout.rb rename to app/lib/to_stdout.rb index 2a01ee668..eeab82c15 100644 --- a/app/models/concerns/to_stdout.rb +++ b/app/lib/to_stdout.rb @@ -1,7 +1,5 @@ -module ToStdout - extend ActiveSupport::Concern - - def to_stdout(message) +class ToStdout + def self.msg(message) time = Time.zone.now.utc STDOUT << "#{time} - #{message}\n" unless Rails.env.test? end diff --git a/app/models/concerns/domain/releasable.rb b/app/models/concerns/domain/releasable.rb index 51e1a6f1c..0a17b062a 100644 --- a/app/models/concerns/domain/releasable.rb +++ b/app/models/concerns/domain/releasable.rb @@ -39,12 +39,12 @@ module Concerns def release if release_to_auction - to_stdout 'Destroying domain' + ToStdout.msg 'Destroying domain' destroy! - to_stdout "Checking if domain_name is auctionable: #{domain_name.auctionable?}" + ToStdout.msg "Checking if domain_name is auctionable: #{domain_name.auctionable?}" domain_name.sell_at_auction if domain_name.auctionable? - to_stdout 'Sending registrar notification' + ToStdout.msg 'Sending registrar notification' registrar.notifications.create!(text: "#{I18n.t(:domain_deleted)}: #{name}", attached_obj_id: id, attached_obj_type: self.class) diff --git a/app/models/dns/domain_name.rb b/app/models/dns/domain_name.rb index 0daa7bbae..1e9cd6587 100644 --- a/app/models/dns/domain_name.rb +++ b/app/models/dns/domain_name.rb @@ -2,7 +2,6 @@ module DNS # Namespace is needed, because a class with the same name is defined by `domain_name` gem, # a dependency of `actionmailer`, class DomainName - include ToStdout def initialize(name) @name = name end @@ -37,7 +36,7 @@ module DNS auction = Auction.new auction.domain = name auction.start - to_stdout "Created the auction: #{auction.inspect}" + ToStdout.msg "Created the auction: #{auction.inspect}" update_whois_from_auction(auction) end @@ -102,8 +101,8 @@ module DNS whois_record = Whois::Record.find_or_create_by!(name: name) do |record| record.json = {} end - to_stdout "Starting to update WHOIS record #{whois_record.inspect}\n\n"\ - "from auction #{auction.inspect}" + ToStdout.msg "Starting to update WHOIS record #{whois_record.inspect}\n\n"\ + "from auction #{auction.inspect}" whois_record.update_from_auction(auction) end end diff --git a/app/models/domain.rb b/app/models/domain.rb index 34a8c26ff..589a0b661 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -10,7 +10,6 @@ class Domain < ApplicationRecord include Concerns::Domain::RegistryLockable include Concerns::Domain::Releasable include Concerns::Domain::Disputable - include ToStdout attr_accessor :roles diff --git a/app/models/whois/record.rb b/app/models/whois/record.rb index b4f70c28f..1501381a3 100644 --- a/app/models/whois/record.rb +++ b/app/models/whois/record.rb @@ -1,6 +1,5 @@ module Whois class Record < Whois::Server - include ToStdout self.table_name = 'whois_records' def self.disclaimer @@ -13,16 +12,16 @@ module Whois update!(json: { name: auction.domain, status: ['AtAuction'], disclaimer: self.class.disclaimer }) - to_stdout "Updated from auction WHOIS record #{inspect}" + ToStdout.msg "Updated from auction WHOIS record #{inspect}" elsif auction.no_bids? - to_stdout "Destroying WHOIS record #{inspect}" + ToStdout.msg "Destroying WHOIS record #{inspect}" destroy! elsif auction.awaiting_payment? || auction.payment_received? update!(json: { name: auction.domain, status: ['PendingRegistration'], disclaimer: self.class.disclaimer, registration_deadline: auction.whois_deadline }) - to_stdout "Updated from auction WHOIS record #{inspect}" + ToStdout.msg "Updated from auction WHOIS record #{inspect}" end end # rubocop:enable Metrics/AbcSize diff --git a/config/application.rb b/config/application.rb index a5fb17c9d..014c03269 100644 --- a/config/application.rb +++ b/config/application.rb @@ -36,8 +36,10 @@ module DomainNameRegistry # Autoload all model subdirs config.autoload_paths += Dir[Rails.root.join('app', 'models', '**/')] + config.autoload_paths += Dir[Rails.root.join('app', 'lib', '**/')] config.autoload_paths += Dir[Rails.root.join('app', 'interactions', '**/')] config.eager_load_paths << config.root.join('lib', 'validators') + config.eager_load_paths << config.root.join('app', 'lib') config.watchable_dirs['lib'] = %i[rb] config.active_record.schema_format = :sql From 59ddc5acce3ae10b4a7095e09334464ca79800e1 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Fri, 15 Jan 2021 15:32:40 +0500 Subject: [PATCH 6/6] Turn off removing auctioned Whois::Record --- app/models/whois/record.rb | 6 ++++++ app/models/whois_record.rb | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/whois/record.rb b/app/models/whois/record.rb index 1501381a3..dc9cc2ba0 100644 --- a/app/models/whois/record.rb +++ b/app/models/whois/record.rb @@ -2,6 +2,12 @@ module Whois class Record < Whois::Server self.table_name = 'whois_records' + def self.without_auctions + ids = Whois::Record.all.select { |record| Auction.where(domain: record.name).blank? } + .pluck(:id) + Whois::Record.where(id: ids) + end + def self.disclaimer Setting.registry_whois_disclaimer end diff --git a/app/models/whois_record.rb b/app/models/whois_record.rb index 3563b9630..19805d583 100644 --- a/app/models/whois_record.rb +++ b/app/models/whois_record.rb @@ -97,7 +97,7 @@ class WhoisRecord < ApplicationRecord end def destroy_whois_record - Whois::Record.where(name: name).delete_all + Whois::Record.without_auctions.where(name: name).delete_all end private