diff --git a/app/services/whois/parser.rb b/app/services/whois/parser.rb index d44631a..d428ff4 100644 --- a/app/services/whois/parser.rb +++ b/app/services/whois/parser.rb @@ -7,6 +7,7 @@ module Whois Afilias, AFNIC, CIRA, + Icann, IO, Neustar, Sonic, diff --git a/app/services/whois/parser/afilias.rb b/app/services/whois/parser/afilias.rb index 56daed7..316d0a9 100644 --- a/app/services/whois/parser/afilias.rb +++ b/app/services/whois/parser/afilias.rb @@ -18,7 +18,6 @@ module Whois .mn .sc .vc - .org .aero .asia .xxx diff --git a/app/services/whois/parser/icann.rb b/app/services/whois/parser/icann.rb new file mode 100644 index 0000000..2449a68 --- /dev/null +++ b/app/services/whois/parser/icann.rb @@ -0,0 +1,43 @@ +# Copyright (C) 2022 Jérémy Lecour , 2022 Evolix +# License: GNU AGPL-3+ (see full text in LICENSE file) + +module Whois + module Parser + class Icann < Base + # https://www.icann.org/resources/pages/epp-status-codes-2014-06-16-en + SUPPORTED_TLD = %w[ + .org + ].freeze + + COMMENT_REGEX = /^(%|>)+ +(?.+)$/ + FIELD_REGEX = /^(?[^:]+)\s*:\s+(?.+)$/ + + def self.supports?(domain) + SUPPORTED_TLD.include?(tld(domain)) + end + + protected + + def do_parse + raise_not_found if text_include?("Domain not found.") + + extract_values + end + + private + + def extract_values + domain_index = get_field!("Domain Name", value: domain.downcase).index + + created_date = get_value!("Creation Date", after: domain_index) + response.created_at = parse_date(created_date) + + expire_date = get_value!("Registry Expiry Date", after: domain_index) + response.expire_at = parse_date(expire_date) + + updated_date = get_value!("Updated Date", after: domain_index) + response.updated_at = parse_date(updated_date) + end + end + end +end diff --git a/test/fixtures/files/whois/domain.org.txt b/test/fixtures/files/whois/domain.org.txt index ccbfa5b..7ea0e5d 100644 --- a/test/fixtures/files/whois/domain.org.txt +++ b/test/fixtures/files/whois/domain.org.txt @@ -1,138 +1,61 @@ -% IANA WHOIS server -% for more information on IANA, visit http://www.iana.org -% This query returned 1 object - -refer: whois.pir.org - -domain: ORG - -organisation: Public Interest Registry (PIR) -address: 1775 Wiehle Avenue -address: Suite 102A -address: Reston Virginia 20190 -address: United States - -contact: administrative -name: Director of Operations, Compliance and Customer Support -organisation: Public Interest Registry (PIR) -address: 1775 Wiehle Avenue -address: Reston Virginia 20190 -address: United States -phone: +1 919 369 4161 -fax-no: +1 703 889 5779 -e-mail: ops@pir.org - -contact: technical -name: Senior Director, DNS Infrastructure Group -organisation: Afilias -address: Building 3, Suite 105 -address: 300 Welsh Road -address: Horsham, Pennsylvania 19044 -address: United States -phone: +1 215.706.5700 -fax-no: +1 215.706.5701 -e-mail: tld-tech-poc@afilias.info - -nserver: A0.ORG.AFILIAS-NST.INFO 199.19.56.1 2001:500:e:0:0:0:0:1 -nserver: A2.ORG.AFILIAS-NST.INFO 199.249.112.1 2001:500:40:0:0:0:0:1 -nserver: B0.ORG.AFILIAS-NST.ORG 199.19.54.1 2001:500:c:0:0:0:0:1 -nserver: B2.ORG.AFILIAS-NST.ORG 199.249.120.1 2001:500:48:0:0:0:0:1 -nserver: C0.ORG.AFILIAS-NST.INFO 199.19.53.1 2001:500:b:0:0:0:0:1 -nserver: D0.ORG.AFILIAS-NST.ORG 199.19.57.1 2001:500:f:0:0:0:0:1 -ds-rdata: 9795 7 2 3922b31b6f3a4ea92b19eb7b52120f031fd8e05ff0b03bafcf9f891bfe7ff8e5 -ds-rdata: 9795 7 1 364dfab3daf254cab477b5675b10766ddaa24982 - -whois: whois.pir.org - -status: ACTIVE -remarks: Registration information: http://www.pir.org - -created: 1985-01-01 -changed: 2016-05-10 -source: IANA - -Domain Name: DOMAIN.ORG -Registry Domain ID: D1511762-LROR -Registrar WHOIS Server: whois.domain.com -Registrar URL: www.domain.com -Updated Date: 2018-04-02T03:47:23Z -Creation Date: 1995-04-30T04:00:00Z -Registry Expiry Date: 2019-05-01T04:00:00Z -Registrar Registration Expiration Date: -Registrar: Domain.com, LLC -Registrar IANA ID: 886 -Registrar Abuse Contact Email: compliance@domain-inc.net -Registrar Abuse Contact Phone: +1.6022262389 -Reseller: -Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited -Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited -Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited -Registrant Organization: Endurance International Group West, Inc -Registrant State/Province: MA -Registrant Country: US -Name Server: DNS1.DOMAINBANK.COM -Name Server: DNS2.DOMAINBANK.COM -DNSSEC: unsigned -URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/ ->>> Last update of WHOIS database: 2018-06-05T14:44:20Z <<< - -Domain Name: DOMAIN.ORG -Registry Domain ID: D1511762-LROR -Registrar WHOIS Server: whois.domain.com -Registrar URL: www.domain.com -Updated Date: 2018-04-02T03:47:23 -Creation Date: 1995-04-29T04:00:00 -Registrar Registration Expiration Date: 2019-05-01T04:00:00 -Registrar: Domain.com, LLC -Registrar IANA ID: 886 -Reseller: Domain Name Holding Company, Inc -Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited +Domain Name: domain.org +Registry Domain ID: 917361e9a4034753ad252db587e82521-LROR +Registrar WHOIS Server: whois.gandi.net +Registrar URL: http://www.gandi.net +Updated Date: 2022-06-03T22:27:15Z +Creation Date: 2002-11-18T18:08:13Z +Registry Expiry Date: 2022-11-18T18:08:13Z +Registrar: Gandi SAS +Registrar IANA ID: 81 +Registrar Abuse Contact Email: abuse@support.gandi.net +Registrar Abuse Contact Phone: +33.170377661 Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited -Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited -Registry Registrant ID: -Registrant Name: Data Protected Data Protected -Registrant Organization: Data Protected -Registrant Street: 123 Data Protected -Registrant City: Toronto -Registrant State/Province: ON -Registrant Postal Code: M6K 3M1 -Registrant Country: CA -Registrant Phone: +1.0000000000 -Registrant Phone Ext: -Registrant Fax: +1.0000000000 -Registrant Fax Ext: -Registrant Email: noreply@data-protected.net -Registry Admin ID: -Admin Name: Data Protected Data Protected -Admin Organization: Data Protected -Admin Street: 123 Data Protected -Admin City: Toronto -Admin State/Province: ON -Admin Postal Code: M6K 3M1 -Admin Country: CA -Admin Phone: +1.0000000000 -Admin Phone Ext: -Admin Fax: +1.0000000000 -Admin Fax Ext: -Admin Email: noreply@data-protected.net -Registry Tech ID: -Tech Name: Data Protected Data Protected -Tech Organization: Data Protected -Tech Street: 123 Data Protected -Tech City: Toronto -Tech State/Province: ON -Tech Postal Code: M6K 3M1 -Tech Country: CA -Tech Phone: +1.0000000000 -Tech Phone Ext: -Tech Fax: +1.0000000000 -Tech Fax Ext: -Tech Email: noreply@data-protected.net -Name Server: dns1.domainbank.com -Name Server: dns2.domainbank.com +Registry Registrant ID: REDACTED FOR PRIVACY +Registrant Name: REDACTED FOR PRIVACY +Registrant Organization: Institut Molinari +Registrant Street: REDACTED FOR PRIVACY +Registrant City: REDACTED FOR PRIVACY +Registrant State/Province: +Registrant Postal Code: REDACTED FOR PRIVACY +Registrant Country: BE +Registrant Phone: REDACTED FOR PRIVACY +Registrant Phone Ext: REDACTED FOR PRIVACY +Registrant Fax: REDACTED FOR PRIVACY +Registrant Fax Ext: REDACTED FOR PRIVACY +Registrant Email: Please query the RDDS service of the Registrar of Record identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. +Registry Admin ID: REDACTED FOR PRIVACY +Admin Name: REDACTED FOR PRIVACY +Admin Organization: REDACTED FOR PRIVACY +Admin Street: REDACTED FOR PRIVACY +Admin City: REDACTED FOR PRIVACY +Admin State/Province: REDACTED FOR PRIVACY +Admin Postal Code: REDACTED FOR PRIVACY +Admin Country: REDACTED FOR PRIVACY +Admin Phone: REDACTED FOR PRIVACY +Admin Phone Ext: REDACTED FOR PRIVACY +Admin Fax: REDACTED FOR PRIVACY +Admin Fax Ext: REDACTED FOR PRIVACY +Admin Email: Please query the RDDS service of the Registrar of Record identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. +Registry Tech ID: REDACTED FOR PRIVACY +Tech Name: REDACTED FOR PRIVACY +Tech Organization: REDACTED FOR PRIVACY +Tech Street: REDACTED FOR PRIVACY +Tech City: REDACTED FOR PRIVACY +Tech State/Province: REDACTED FOR PRIVACY +Tech Postal Code: REDACTED FOR PRIVACY +Tech Country: REDACTED FOR PRIVACY +Tech Phone: REDACTED FOR PRIVACY +Tech Phone Ext: REDACTED FOR PRIVACY +Tech Fax: REDACTED FOR PRIVACY +Tech Fax Ext: REDACTED FOR PRIVACY +Tech Email: Please query the RDDS service of the Registrar of Record identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. +Name Server: ns-155-a.gandi.net +Name Server: ns-200-b.gandi.net +Name Server: ns-89-c.gandi.net +DNSSEC: unsigned +URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/ +>>> Last update of WHOIS database: 2022-06-12T23:04:05Z <<< -Registrar Abuse Contact Email: compliance@domain-inc.net -Registrar Abuse Contact Phone: +1.6027165396 -URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/ ->>> Last update of WHOIS database: 2018-04-02T03:47:23 <<< +For more information on Whois status codes, please visit https://icann.org/epp +Terms of Use: Access to Public Interest Registry WHOIS information is provided to assist persons in determining the contents of a domain name registration record in the Public Interest Registry registry database. The data in this record is provided by Public Interest Registry for informational purposes only, and Public Interest Registry does not guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Registry Operator, a Registrar, or Donuts except as reasonably necessary to register domain names or modify existing registrations. All rights reserved. Public Interest Registry reserves the right to modify these terms at any time. By submitting this query, you agree to abide by this policy. The Registrar of Record identified in this output may have an RDDS service that can be queried for additional information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. \ No newline at end of file diff --git a/test/fixtures/files/whois/willneverexist.org.txt b/test/fixtures/files/whois/willneverexist.org.txt index 2610827..ec44c3b 100644 --- a/test/fixtures/files/whois/willneverexist.org.txt +++ b/test/fixtures/files/whois/willneverexist.org.txt @@ -1,56 +1,4 @@ -% IANA WHOIS server -% for more information on IANA, visit http://www.iana.org -% This query returned 1 object - -refer: whois.pir.org - -domain: ORG - -organisation: Public Interest Registry (PIR) -address: 1775 Wiehle Avenue -address: Suite 102A -address: Reston Virginia 20190 -address: United States - -contact: administrative -name: Director of Operations, Compliance and Customer Support -organisation: Public Interest Registry (PIR) -address: 1775 Wiehle Avenue -address: Reston Virginia 20190 -address: United States -phone: +1 919 369 4161 -fax-no: +1 703 889 5779 -e-mail: ops@pir.org - -contact: technical -name: Senior Director, DNS Infrastructure Group -organisation: Afilias -address: Building 3, Suite 105 -address: 300 Welsh Road -address: Horsham, Pennsylvania 19044 -address: United States -phone: +1 215.706.5700 -fax-no: +1 215.706.5701 -e-mail: tld-tech-poc@afilias.info - -nserver: A0.ORG.AFILIAS-NST.INFO 199.19.56.1 2001:500:e:0:0:0:0:1 -nserver: A2.ORG.AFILIAS-NST.INFO 199.249.112.1 2001:500:40:0:0:0:0:1 -nserver: B0.ORG.AFILIAS-NST.ORG 199.19.54.1 2001:500:c:0:0:0:0:1 -nserver: B2.ORG.AFILIAS-NST.ORG 199.249.120.1 2001:500:48:0:0:0:0:1 -nserver: C0.ORG.AFILIAS-NST.INFO 199.19.53.1 2001:500:b:0:0:0:0:1 -nserver: D0.ORG.AFILIAS-NST.ORG 199.19.57.1 2001:500:f:0:0:0:0:1 -ds-rdata: 9795 7 2 3922b31b6f3a4ea92b19eb7b52120f031fd8e05ff0b03bafcf9f891bfe7ff8e5 -ds-rdata: 9795 7 1 364dfab3daf254cab477b5675b10766ddaa24982 - -whois: whois.pir.org - -status: ACTIVE -remarks: Registration information: http://www.pir.org - -created: 1985-01-01 -changed: 2016-05-10 -source: IANA - -NOT FOUND ->>> Last update of WHOIS database: 2018-06-05T14:44:34Z <<< +Domain not found. +>>> Last update of WHOIS database: 2022-06-13T20:29:13Z <<< +Terms of Use: Access to Public Interest Registry WHOIS information is provided to assist persons in determining the contents of a domain name registration record in the Public Interest Registry registry database. The data in this record is provided by Public Interest Registry for informational purposes only, and Public Interest Registry does not guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Registry Operator, a Registrar, or Donuts except as reasonably necessary to register domain names or modify existing registrations. All rights reserved. Public Interest Registry reserves the right to modify these terms at any time. By submitting this query, you agree to abide by this policy. The Registrar of Record identified in this output may have an RDDS service that can be queried for additional information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. \ No newline at end of file diff --git a/test/services/whois/parser/afilias_test.rb b/test/services/whois/parser/afilias_test.rb index 6fa8946..8d1e465 100644 --- a/test/services/whois/parser/afilias_test.rb +++ b/test/services/whois/parser/afilias_test.rb @@ -36,37 +36,5 @@ module Whois parser.parse(whois_output) end end - - test "should parse a whois response for .org" do - parser = Whois::Parser::Afilias.new("domain.org") - domain_com = file_fixture("whois/domain.org.txt").read - response = parser.parse(domain_com) - assert_kind_of Whois::Response, response - - assert_equal Time.new(1995, 4, 30, 4, 0, 0, 0), response.created_at - assert response.created_at.utc? - - assert_equal Time.new(2018, 4, 2, 3, 47, 23, 0), response.updated_at - assert_equal Time.new(2019, 5, 1, 4, 0, 0, 0), response.expire_at - end - - test "should raises DomainNotFoundError for .org when domain is not registered" do - parser = Whois::Parser::Afilias.new("willneverexist.org") - not_found = file_fixture("whois/willneverexist.org.txt").read - - assert_raises DomainNotFoundError do - parser.parse(not_found) - end - end - - test "should raises InvalidDateError for .org when a date is not parsable" do - parser = Whois::Parser::Afilias.new("domain.org") - domain_com = file_fixture("whois/domain.org.txt").read - domain_com.gsub!("2018-04-02T03:47:23Z", "not a date") - - assert_raises InvalidDateError do - parser.parse(domain_com) - end - end end end diff --git a/test/services/whois/parser/icann_test.rb b/test/services/whois/parser/icann_test.rb new file mode 100644 index 0000000..639bd64 --- /dev/null +++ b/test/services/whois/parser/icann_test.rb @@ -0,0 +1,41 @@ +# Copyright (C) 2018 Colin Darie , 2018 Evolix +# License: GNU AGPL-3+ (see full text in LICENSE file) + +require "test_helper" + +module Whois + class IcannTest < ActiveSupport::TestCase + test "should parse a whois response for .org" do + parser = Whois::Parser::Icann.new("domain.org") + domain_com = file_fixture("whois/domain.org.txt").read + response = parser.parse(domain_com) + assert_kind_of Whois::Response, response + + assert_equal Time.new(2002, 11, 18, 18, 8, 13, 0), response.created_at + assert response.created_at.utc? + + assert_equal Time.new(2022, 6, 3, 22, 27, 15, 0), response.updated_at + assert_equal Time.new(2022, 11, 18, 18, 8, 13, 0), response.expire_at + end + + test "should raises DomainNotFoundError for .org when domain is not registered" do + parser = Whois::Parser::Icann.new("willneverexist.org") + not_found = file_fixture("whois/willneverexist.org.txt").read + + assert_raises DomainNotFoundError do + parser.parse(not_found) + end + end + + test "should raises InvalidDateError for .org when a date is not parsable" do + parser = Whois::Parser::Icann.new("domain.org") + domain_com = file_fixture("whois/domain.org.txt").read + # replace one of the dates with something that is not a date + domain_com.gsub!("2002-11-18T18:08:13Z", "not a date") + + assert_raises InvalidDateError do + parser.parse(domain_com) + end + end + end +end diff --git a/test/services/whois/parser_test.rb b/test/services/whois/parser_test.rb index d8f7830..4915967 100644 --- a/test/services/whois/parser_test.rb +++ b/test/services/whois/parser_test.rb @@ -18,6 +18,10 @@ module Whois assert_kind_of Parser::Afilias, Parser.for("example.info") end + test "should instanciate a parser class matching Icann tlds" do + assert_kind_of Parser::Icann, Parser.for("example.org") + end + test "should raises an exception when a domain is not supported" do assert_raises UnsupportedDomainError do Parser.for("example.xyz")