From d471b273f7af24caadcc6000304071e03eba70f6 Mon Sep 17 00:00:00 2001 From: Maciej Szlosarczyk Date: Tue, 2 Apr 2019 17:17:40 +0300 Subject: [PATCH 1/2] Handle IDN domains that went to auction Both ASCII and unicode should be supported to register a domain. --- app/controllers/epp/domains_controller.rb | 2 +- test/fixtures/auctions.yml | 5 + .../epp/domain/create/auction_idn_test.rb | 282 ++++++++++++++++++ 3 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 test/integration/epp/domain/create/auction_idn_test.rb diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb index acbe4082a..ecee7ae9d 100644 --- a/app/controllers/epp/domains_controller.rb +++ b/app/controllers/epp/domains_controller.rb @@ -24,7 +24,7 @@ class Epp::DomainsController < EppController if Domain.release_to_auction request_domain_name = params[:parsed_frame].css('name').text.strip.downcase - domain_name = DNS::DomainName.new(request_domain_name) + domain_name = DNS::DomainName.new(SimpleIDN.to_unicode(request_domain_name)) if domain_name.at_auction? throw :epp_error, diff --git a/test/fixtures/auctions.yml b/test/fixtures/auctions.yml index e25ae8ff5..7349f1257 100644 --- a/test/fixtures/auctions.yml +++ b/test/fixtures/auctions.yml @@ -2,3 +2,8 @@ one: domain: auction.test status: <%= Auction.statuses[:no_bids] %> uuid: 1b3ee442-e8fe-4922-9492-8fcb9dccc69c + +idn: + domain: "püramiid.test" + status: <%= Auction.statuses[:no_bids] %> + uuid: d05455cd-67c9-431e-bdbc-03487da9cbfa diff --git a/test/integration/epp/domain/create/auction_idn_test.rb b/test/integration/epp/domain/create/auction_idn_test.rb new file mode 100644 index 000000000..5fa19fd60 --- /dev/null +++ b/test/integration/epp/domain/create/auction_idn_test.rb @@ -0,0 +1,282 @@ +# encoding: UTF-8 +require 'test_helper' + +class EppDomainCreateAuctionIdnTest < ApplicationIntegrationTest + def setup + super + + @idn_auction = auctions(:idn) + Domain.release_to_auction = true + end + + def teardown + super + + Domain.release_to_auction = false + end + + def test_registers_domain_with_ascii_idn_cannot_be_registered_without_registration_code + @idn_auction.update!(status: Auction.statuses[:payment_received], + registration_code: "auction001") + + request_xml = <<-XML + + + + + + xn--pramiid-n2a.test + #{contacts(:john).code} + + + + + #{'test' * 2000} + + + + + XML + + assert_no_difference 'Domain.count' do + post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + end + + refute Domain.where(name: @idn_auction.domain).exists? + + @idn_auction.reload + refute @idn_auction.domain_registered? + + response_xml = Nokogiri::XML(response.body) + assert_equal '2003', response_xml.at_css('result')[:code] + assert_equal 'Required parameter missing; reserved>pw element is required', + response_xml.at_css('result msg').text + end + + def test_registers_domain_with_unicode_idn_cannot_be_registered_without_registration_code + @idn_auction.update!(status: Auction.statuses[:payment_received], + registration_code: "auction001") + + request_xml = <<-XML + + + + + + püramiid.test + #{contacts(:john).code} + + + + + #{'test' * 2000} + + + + + XML + + assert_no_difference 'Domain.count' do + post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + end + + refute Domain.where(name: @idn_auction.domain).exists? + + @idn_auction.reload + refute @idn_auction.domain_registered? + + response_xml = Nokogiri::XML(response.body) + assert_equal '2003', response_xml.at_css('result')[:code] + assert_equal 'Required parameter missing; reserved>pw element is required', + response_xml.at_css('result msg').text + end + + def test_registers_domain_with_ascii_idn_cannot_be_registered_without_winning_the_auction + @idn_auction.started! + + request_xml = <<-XML + + + + + + xn--pramiid-n2a.test + #{contacts(:john).code} + + + + + #{'test' * 2000} + + + + + XML + + assert_no_difference 'Domain.count' do + post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + end + + refute Domain.where(name: @idn_auction.domain).exists? + + @idn_auction.reload + refute @idn_auction.domain_registered? + + response_xml = Nokogiri::XML(response.body) + assert_equal '2306', response_xml.at_css('result')[:code] + assert_equal 'Parameter value policy error: domain is at auction', + response_xml.at_css('result msg').text + end + + def test_registers_domain_with_unicode_idn_cannot_be_registered_without_winning_the_auction + @idn_auction.started! + + request_xml = <<-XML + + + + + + püramiid.test + #{contacts(:john).code} + + + + + #{'test' * 2000} + + + + + XML + + assert_no_difference 'Domain.count' do + post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + end + + refute Domain.where(name: @idn_auction.domain).exists? + + @idn_auction.reload + refute @idn_auction.domain_registered? + + response_xml = Nokogiri::XML(response.body) + assert_equal '2306', response_xml.at_css('result')[:code] + assert_equal 'Parameter value policy error: domain is at auction', + response_xml.at_css('result msg').text + end + + def test_registers_domain_with_unicode_idn_cannot_be_registered_without_winning_the_auction + @idn_auction.started! + + request_xml = <<-XML + + + + + + püramiid.test + #{contacts(:john).code} + + + + + #{'test' * 2000} + + + + + XML + + assert_no_difference 'Domain.count' do + post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + end + + refute Domain.where(name: @idn_auction.domain).exists? + + @idn_auction.reload + refute @idn_auction.domain_registered? + + response_xml = Nokogiri::XML(response.body) + assert_equal '2306', response_xml.at_css('result')[:code] + assert_equal 'Parameter value policy error: domain is at auction', + response_xml.at_css('result msg').text + end + + def test_registers_unicode_domain_with_correct_registration_code_when_payment_is_received + @idn_auction.update!(status: Auction.statuses[:payment_received], + registration_code: 'auction001') + + request_xml = <<-XML + + + + + + püramiid.test + #{contacts(:john).code} + + + + + #{'test' * 2000} + + auction001 + + + + + + XML + + assert_difference 'Domain.count' do + post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + end + + @idn_auction.reload + assert @idn_auction.domain_registered? + assert Domain.where(name: @idn_auction.domain).exists? + + response_xml = Nokogiri::XML(response.body) + assert_equal '1000', response_xml.at_css('result')[:code] + assert_equal 1, Nokogiri::XML(response.body).css('result').size + end + + def test_registers_ascii_domain_with_correct_registration_code_when_payment_is_received + @idn_auction.update!(status: Auction.statuses[:payment_received], + registration_code: 'auction001') + + request_xml = <<-XML + + + + + + xn--pramiid-n2a.test + #{contacts(:john).code} + + + + + #{'test' * 2000} + + auction001 + + + + + + XML + + assert_difference 'Domain.count' do + post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + end + + @idn_auction.reload + assert @idn_auction.domain_registered? + assert Domain.where(name: @idn_auction.domain).exists? + + response_xml = Nokogiri::XML(response.body) + assert_equal '1000', response_xml.at_css('result')[:code] + assert_equal 1, Nokogiri::XML(response.body).css('result').size + end +end From 888e95a8c7c8c696ce9aefc5e7e7c0ccf59a3ecf Mon Sep 17 00:00:00 2001 From: Maciej Szlosarczyk Date: Tue, 2 Apr 2019 17:35:18 +0300 Subject: [PATCH 2/2] EPP should use unicode to check domain name availability --- app/models/epp/domain.rb | 2 +- .../epp/domain/check/auction_test.rb | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 4e3d20305..bd9a1d4a3 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -802,7 +802,7 @@ class Epp::Domain < Domain next end - domain_name = DNS::DomainName.new(domain_name_as_string) + domain_name = DNS::DomainName.new(SimpleIDN.to_unicode(domain_name_as_string)) if domain_name.unavailable? reason = I18n.t("errors.messages.epp_domain_#{domain_name.unavailability_reason}") diff --git a/test/integration/epp/domain/check/auction_test.rb b/test/integration/epp/domain/check/auction_test.rb index efc048f85..6a2722dc5 100644 --- a/test/integration/epp/domain/check/auction_test.rb +++ b/test/integration/epp/domain/check/auction_test.rb @@ -1,8 +1,10 @@ +# encoding: UTF-8 require 'test_helper' class EppDomainCheckAuctionTest < ApplicationIntegrationTest setup do @auction = auctions(:one) + @idn_auction = auctions(:idn) Domain.release_to_auction = true end @@ -35,6 +37,56 @@ class EppDomainCheckAuctionTest < ApplicationIntegrationTest assert_equal 'Domain is at auction', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text end + def test_idn_ascii_domain_is_unavailable_when_at_auction + @idn_auction.update!(status: Auction.statuses[:started]) + + request_xml = <<-XML + + + + + + xn--pramiid-n2a.test + + + + + XML + + post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + + response_xml = Nokogiri::XML(response.body) + assert_equal '1000', response_xml.at_css('result')[:code] + assert_equal 1, response_xml.css('result').size + assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] + assert_equal 'Domain is at auction', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text + end + + def test_idn_unicode_domain_is_unavailable_when_at_auction + @idn_auction.update!(status: Auction.statuses[:started]) + + request_xml = <<-XML + + + + + + püramiid.test + + + + + XML + + post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + + response_xml = Nokogiri::XML(response.body) + assert_equal '1000', response_xml.at_css('result')[:code] + assert_equal 1, response_xml.css('result').size + assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] + assert_equal 'Domain is at auction', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text + end + def test_domain_is_unavailable_when_awaiting_payment @auction.update!(status: Auction.statuses[:awaiting_payment])