Merge pull request #1065 from internetee/improve-epp-domain-check

Improve EPP domain:check
This commit is contained in:
Timo Võhmar 2019-01-16 17:35:52 +02:00 committed by GitHub
commit 9e791c0abb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 139 additions and 24 deletions

View file

@ -87,8 +87,8 @@ class Epp::DomainsController < EppController
def check def check
authorize! :check, Epp::Domain authorize! :check, Epp::Domain
names = params[:parsed_frame].css('name').map(&:text) domain_names = params[:parsed_frame].css('name').map(&:text)
@domains = Epp::Domain.check_availability(names) @domains = Epp::Domain.check_availability(domain_names)
render_epp_response '/epp/domains/check' render_epp_response '/epp/domains/check'
end end

View file

@ -0,0 +1,39 @@
module DNS
# Namespace is needed, because a class with the same name is defined by `domain_name` gem,
# a dependency of `actionmailer`,
class DomainName
def initialize(name)
@name = name
end
def unavailable?
registered? || blocked? || zone_with_same_origin?
end
def unavailability_reason
if registered?
:registered
elsif blocked?
:blocked
elsif zone_with_same_origin?
:zone_with_same_origin
end
end
private
attr_reader :name
def registered?
Domain.find_by_idn(name)
end
def blocked?
BlockedDomain.where(name: name).any?
end
def zone_with_same_origin?
DNS::Zone.where(origin: name).any?
end
end
end

View file

@ -788,31 +788,32 @@ class Epp::Domain < Domain
} }
end end
def check_availability(domains) def check_availability(domain_names)
domains = [domains] if domains.is_a?(String) domain_names = [domain_names] if domain_names.is_a?(String)
res = [] result = []
domains.each do |x|
x.strip! domain_names.each do |domain_name_as_string|
x.downcase! domain_name_as_string.strip!
unless DomainNameValidator.validate_format(x) domain_name_as_string.downcase!
res << { name: x, avail: 0, reason: 'invalid format' }
unless DomainNameValidator.validate_format(domain_name_as_string)
result << { name: domain_name_as_string, avail: 0, reason: 'invalid format' }
next next
end end
if ReservedDomain.pw_for(x).present? domain_name = DNS::DomainName.new(domain_name_as_string)
res << { name: x, avail: 0, reason: I18n.t('errors.messages.epp_domain_reserved') }
if domain_name.unavailable?
reason = I18n.t("errors.messages.epp_domain_#{domain_name.unavailability_reason}")
result << { name: domain_name_as_string, avail: 0, reason: reason }
next next
end end
if Domain.find_by_idn x result << { name: domain_name_as_string, avail: 1 }
res << { name: x, avail: 0, reason: 'in use' }
else
res << { name: x, avail: 1 }
end
end end
res result
end end
end end

View file

@ -196,7 +196,9 @@ en:
errors: errors:
messages: messages:
blank: 'is missing' blank: 'is missing'
epp_domain_reserved: 'Domain name is reserved' epp_domain_registered: in use
epp_domain_blocked: Blocked
epp_domain_zone_with_same_origin: Zone with the same origin exists
epp_obj_does_not_exist: 'Object does not exist' epp_obj_does_not_exist: 'Object does not exist'
epp_authorization_error: 'Authorization error' epp_authorization_error: 'Authorization error'
epp_id_taken: 'Contact id already exists' epp_id_taken: 'Contact id already exists'

View file

@ -23,7 +23,7 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest
assert_equal 'some.test', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text assert_equal 'some.test', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text
end end
def test_domain_is_available_when_not_registered_blocked_nor_reserved def test_domain_is_available_when_not_registered_or_blocked
request_xml = <<-XML request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd"> <epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
@ -44,6 +44,29 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest
assert_nil response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd') assert_nil response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')
end end
def test_domain_is_available_when_reserved
assert_equal 'reserved.test', reserved_domains(:one).name
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<check>
<domain:check xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
<domain:name>reserved.test</domain:name>
</domain:check>
</check>
</command>
</epp>
XML
post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames'
response_xml = Nokogiri::XML(response.body)
assert_equal '1', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail']
assert_nil response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')
end
def test_domain_is_unavailable_when_format_is_invalid def test_domain_is_unavailable_when_format_is_invalid
request_xml = <<-XML request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
@ -88,8 +111,8 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest
assert_equal 'in use', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text assert_equal 'in use', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text
end end
def test_domain_is_unavailable_when_reserved def test_domain_is_unavailable_when_blocked
assert_equal 'reserved.test', reserved_domains(:one).name assert_equal 'blocked.test', blocked_domains(:one).name
request_xml = <<-XML request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
@ -97,7 +120,7 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest
<command> <command>
<check> <check>
<domain:check xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd"> <domain:check xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
<domain:name>reserved.test</domain:name> <domain:name>blocked.test</domain:name>
</domain:check> </domain:check>
</check> </check>
</command> </command>
@ -108,7 +131,30 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest
response_xml = Nokogiri::XML(response.body) response_xml = Nokogiri::XML(response.body)
assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail']
assert_equal 'Domain name is reserved', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text assert_equal 'Blocked', 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_zone_with_the_same_origin_exists
assert_equal 'test', dns_zones(:one).origin
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<check>
<domain:check xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
<domain:name>test</domain:name>
</domain:check>
</check>
</command>
</epp>
XML
post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames'
response_xml = Nokogiri::XML(response.body)
assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail']
assert_equal 'Zone with the same origin exists', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text
end end
def test_multiple_domains def test_multiple_domains

View file

@ -0,0 +1,27 @@
require 'test_helper'
class DNS::DomainNameTest < ActiveSupport::TestCase
def test_unavailable_when_registered
domain_name = DNS::DomainName.new('shop.test')
assert_equal 'shop.test', domains(:shop).name
assert domain_name.unavailable?
assert_equal :registered, domain_name.unavailability_reason
end
def test_unavailable_when_blocked
domain_name = DNS::DomainName.new('blocked.test')
assert_equal 'blocked.test', blocked_domains(:one).name
assert domain_name.unavailable?
assert_equal :blocked, domain_name.unavailability_reason
end
def test_unavailable_when_zone_with_the_same_origin_exists
domain_name = DNS::DomainName.new('test')
assert_equal 'test', dns_zones(:one).origin
assert domain_name.unavailable?
assert_equal :zone_with_same_origin, domain_name.unavailability_reason
end
end