Skip to content

Commit

Permalink
Merge pull request #1109 from internetee/fix-auction-integration
Browse files Browse the repository at this point in the history
Revamp WHOIS for auctions
  • Loading branch information
vohmar authored Mar 25, 2019
2 parents 5d61cbf + 49cea70 commit 0393e7a
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 127 deletions.
11 changes: 11 additions & 0 deletions app/controllers/api/v1/auctions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ def update
raise "Invalid status #{params[:status]}"
end

if auction.payment_not_received? || auction.domain_not_registered?
update_whois_from_auction(Auction.pending(auction.domain))
else
update_whois_from_auction(auction)
end

render json: serializable_hash_for_update_action(auction)
end

Expand All @@ -44,6 +50,11 @@ def serializable_hash_for_update_action(auction)
hash[:registration_code] = auction.registration_code if auction.payment_received?
hash
end

def update_whois_from_auction(auction)
whois_record = Whois::Record.find_by!(name: auction.domain)
whois_record.update_from_auction(auction)
end
end
end
end
25 changes: 12 additions & 13 deletions app/models/auction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,17 @@ class Auction < ActiveRecord::Base
statuses[:payment_received]].freeze
private_constant :PENDING_STATUSES

def self.sell(domain_name)
create!(domain: domain_name.to_s, status: statuses[:started])
end

def self.pending(domain_name)
find_by(domain: domain_name.to_s, status: PENDING_STATUSES)
end

def start
self.status = self.class.statuses[:started]
save!
end

def mark_as_no_bids
transaction do
DNS::DomainName.new(domain).update_whois
no_bids!
end
no_bids!
end

def mark_as_payment_received
Expand Down Expand Up @@ -57,17 +55,18 @@ def domain_registrable?(registration_code = nil)
payment_received? && registration_code_matches?(registration_code)
end

def restart
new_auction = self.class.new(domain: domain)
new_auction.start
end

private

def generate_registration_code
self.registration_code = SecureRandom.hex
end

def restart
self.class.create!(domain: domain, status: self.class.statuses[:started])
end

def registration_code_matches?(code)
registration_code == code
end
end
end
15 changes: 9 additions & 6 deletions app/models/dns/domain_name.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ def unavailability_reason
end

def sell_at_auction
Auction.sell(self)
update_whois
auction = Auction.new
auction.domain = name
auction.start
update_whois_from_auction(auction)
end

def at_auction?
Expand All @@ -49,10 +51,6 @@ def pending_registration?
pending_auction&.payment_received?
end

def update_whois
Whois::Record.refresh(self)
end

def registered?
Domain.find_by_idn(name)
end
Expand Down Expand Up @@ -92,5 +90,10 @@ def zone_with_same_origin?
def pending_auction
Auction.pending(self)
end

def update_whois_from_auction(auction)
whois_record = Whois::Record.find_by!(name: name)
whois_record.update_from_auction(auction)
end
end
end
28 changes: 12 additions & 16 deletions app/models/whois/record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,18 @@ def self.disclaimer
Setting.registry_whois_disclaimer
end

def self.refresh(domain_name)
if domain_name.at_auction?
# Remove original record since `Domain#update_whois_record` callback is disabled when
# domain is at auction
find_by(name: domain_name.to_s).try(:destroy!)

create!(name: domain_name, json: { name: domain_name.to_s,
status: ['AtAuction'],
disclaimer: disclaimer })
elsif domain_name.awaiting_payment? || domain_name.pending_registration?
find_by(name: domain_name.to_s).update!(json: { name: domain_name.to_s,
status: ['PendingRegistration'],
disclaimer: disclaimer })
else
find_by(name: domain_name.to_s).destroy!
def update_from_auction(auction)
if auction.started?
update!(json: { name: auction.domain,
status: ['AtAuction'],
disclaimer: self.class.disclaimer })
elsif auction.no_bids?
destroy!
elsif auction.awaiting_payment? || auction.payment_received?
update!(json: { name: auction.domain,
status: ['PendingRegistration'],
disclaimer: self.class.disclaimer })
end
end
end
end
end
18 changes: 16 additions & 2 deletions lib/tasks/whois.rake
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ namespace :whois do
print "-----> Regenerate Registry whois_records table and sync with whois server..."
ActiveRecord::Base.uncached do

# Must be on top
print "\n-----> Update whois_records for auctions"
Auction.pluck('DISTINCT domain').each do |domain|
pending_auction = Auction.pending(domain)

if pending_auction
Whois::Record.transaction do
whois_record = Whois::Record.find_or_create_by!(name: domain)
whois_record.update_from_auction(pending_auction)
end
else
Whois::Record.find_by(name: domain)&.destroy!
end
end

print "\n-----> Update domains whois_records"
Domain.find_in_batches.each do |group|
UpdateWhoisRecordJob.enqueue group.map(&:name), 'domain'
Expand All @@ -20,7 +35,6 @@ namespace :whois do
ReservedDomain.find_in_batches.each do |group|
UpdateWhoisRecordJob.enqueue group.map(&:name), 'reserved'
end

end
puts "\n-----> all done in #{(Time.zone.now.to_f - start).round(2)} seconds"
end
Expand All @@ -32,7 +46,7 @@ namespace :whois do
puts "\n------------------------ Create #{whois_db} ---------------------------------------\n"
ActiveRecord::Base.clear_all_connections!
conf = ActiveRecord::Base.configurations

ActiveRecord::Base.connection.create_database(conf[whois_db]['database'].to_sym, conf[whois_db])
rescue => e
puts "\n#{e}"
Expand Down
32 changes: 16 additions & 16 deletions test/integration/api/v1/auctions/update_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ class ApiV1AuctionUpdateTest < ActionDispatch::IntegrationTest

setup do
@auction = auctions(:one)
@whois_record = whois_records(:one)
@whois_record.update!(name: 'auction.test')

@original_auction_api_allowed_ips_setting = ENV['auction_api_allowed_ips']
ENV['auction_api_allowed_ips'] = '127.0.0.1'
Expand Down Expand Up @@ -36,9 +38,6 @@ def test_marks_as_awaiting_payment
end

def test_marks_as_no_bids
assert_equal 'auction.test', @auction.domain
whois_records(:one).update!(name: 'auction.test')

patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:no_bids] }
.to_json, 'Content-Type' => Mime::JSON.to_s
@auction.reload
Expand All @@ -59,6 +58,13 @@ def test_marks_as_payment_not_received
assert @auction.payment_not_received?
end

def test_marks_as_domain_not_registered
patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:domain_not_registered] }
.to_json, 'Content-Type' => Mime::JSON.to_s
@auction.reload
assert @auction.domain_not_registered?
end

def test_reveals_registration_code_when_payment_is_received
@auction.update!(registration_code: 'auction-001',
status: Auction.statuses[:awaiting_payment])
Expand All @@ -80,22 +86,16 @@ def test_conceals_registration_code_when_payment_is_not_received
assert_nil response_json['registration_code']
end

def test_restarts_an_auction_when_the_payment_is_not_received
@auction.update!(domain: 'auction.test', status: Auction.statuses[:awaiting_payment])

patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:payment_not_received] }
.to_json, 'Content-Type' => Mime::JSON.to_s

assert DNS::DomainName.new('auction.test').at_auction?
end

def test_restarts_an_auction_when_domain_is_not_registered
@auction.update!(domain: 'auction.test', status: Auction.statuses[:payment_received])
def test_updates_whois
travel_to Time.zone.parse('2010-07-05 10:00')
assert_equal 'auction.test', @auction.domain
@whois_record.update!(updated_at: '2010-07-04')

patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:domain_not_registered] }
patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:payment_received] }
.to_json, 'Content-Type' => Mime::JSON.to_s
@whois_record.reload

assert DNS::DomainName.new('auction.test').at_auction?
assert_equal Time.zone.parse('2010-07-05 10:00'), @whois_record.updated_at
end

def test_inaccessible_when_ip_address_is_not_allowed
Expand Down
44 changes: 23 additions & 21 deletions test/models/auction_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ def test_statuses
'domain_not_registered' => 'domain_not_registered' }), Auction.statuses
end

def test_selling_domain_starts_new_auction
domain_name = DNS::DomainName.new('shop.test')
def test_starts_an_auction
assert_not @auction.started?

assert_difference 'Auction.count' do
Auction.sell(domain_name)
end
auction = Auction.last
assert_equal domain_name.to_s, auction.domain
assert auction.started?
@auction.start
@auction.reload

assert @auction.started?
end

def test_pending
Expand Down Expand Up @@ -84,16 +82,12 @@ def test_marking_as_payment_not_received
assert_nil @auction.registration_code
end

def test_restarts_an_auction_when_payment_is_not_received
@auction.update!(domain: 'auction.test', status: Auction.statuses[:awaiting_payment])
def test_marking_as_payment_not_received_restarts_an_auction
@auction.update!(status: Auction.statuses[:awaiting_payment])

assert_difference 'Auction.count' do
@auction.mark_as_payment_not_received
end

new_auction = Auction.last
assert_equal 'auction.test', new_auction.domain
assert new_auction.started?
end

def test_marking_as_domain_not_registered
Expand All @@ -105,16 +99,12 @@ def test_marking_as_domain_not_registered
assert @auction.domain_not_registered?
end

def test_restarts_an_auction_when_domain_is_not_registered
@auction.update!(domain: 'auction.test', status: Auction.statuses[:domain_not_registered])
def test_marking_as_domain_not_registered_restarts_an_auction
@auction.update!(status: Auction.statuses[:payment_received])

assert_difference 'Auction.count' do
@auction.mark_as_domain_not_registered
end

new_auction = Auction.last
assert_equal 'auction.test', new_auction.domain
assert new_auction.started?
end

def test_domain_registrable
Expand All @@ -140,4 +130,16 @@ def test_domain_unregistrable
assert_not @auction.domain_registrable?(nil)
assert_not @auction.domain_registrable?('')
end
end

def test_restarts_an_auction
assert_equal 'auction.test', @auction.domain

assert_difference 'Auction.count' do
@auction.restart
end

new_auction = Auction.last
assert_equal 'auction.test', new_auction.domain
assert new_auction.started?
end
end
13 changes: 8 additions & 5 deletions test/models/dns/domain_name_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ def test_unavailable_when_awaiting_payment
assert_equal :awaiting_payment, domain_name.unavailability_reason
end

def test_sell_at_auction
domain_name = DNS::DomainName.new('new-auction.test')
def test_sells_at_auction
domain_name = DNS::DomainName.new('shop.test')
assert_not domain_name.at_auction?

domain_name.sell_at_auction
Expand All @@ -81,12 +81,15 @@ def test_sell_at_auction
end

def test_selling_at_auction_updates_whois
travel_to Time.zone.parse('2010-07-05 10:00')
@whois_record = whois_records(:one)
@whois_record.update!(name: 'new-auction.test', updated_at: '2010-07-04')
domain_name = DNS::DomainName.new('new-auction.test')
assert_not domain_name.at_auction?

domain_name.sell_at_auction
@whois_record.reload

assert Whois::Record.find_by(name: 'new-auction.test')
assert_equal Time.zone.parse('2010-07-05 10:00'), @whois_record.updated_at
end

def test_at_auction
Expand Down Expand Up @@ -159,4 +162,4 @@ def test_not_auctionable_when_reserved
assert_equal 'reserved.test', reserved_domains(:one).name
assert_not DNS::DomainName.new('reserved.test').auctionable?
end
end
end
10 changes: 0 additions & 10 deletions test/models/domain/releasable/auctionable_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,6 @@ def test_deletes_registered_domain
end
end

def test_updates_whois
assert_equal 'shop.test', @domain.name
@domain.update!(delete_at: Time.zone.parse('2010-07-05 07:59'))
travel_to Time.zone.parse('2010-07-05 08:00')

Domain.release_domains

assert Whois::Record.find_by(name: 'shop.test')
end

def test_ignores_domains_with_delete_at_in_the_future_or_now
@domain.update!(delete_at: Time.zone.parse('2010-07-05 08:00'))
travel_to Time.zone.parse('2010-07-05 08:00')
Expand Down
Loading

0 comments on commit 0393e7a

Please sign in to comment.