From 7e356e369ec78f173e136848efdfe9611bc356e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lecour?= Date: Thu, 28 Feb 2019 00:15:03 +0100 Subject: [PATCH] Add support for .ca TLD --- app/services/whois/parser.rb | 3 +- app/services/whois/parser/base.rb | 7 +- app/services/whois/parser/cira.rb | 47 +++++ test/fixtures/files/whois/domain.ca.txt | 187 ++++++++++++++++++ .../files/whois/willneverexist.ca.txt | 55 ++++++ test/services/whois/parser/cira_test.rb | 43 ++++ 6 files changed, 339 insertions(+), 3 deletions(-) create mode 100644 app/services/whois/parser/cira.rb create mode 100644 test/fixtures/files/whois/domain.ca.txt create mode 100644 test/fixtures/files/whois/willneverexist.ca.txt create mode 100644 test/services/whois/parser/cira_test.rb diff --git a/app/services/whois/parser.rb b/app/services/whois/parser.rb index 2045008..cc12824 100644 --- a/app/services/whois/parser.rb +++ b/app/services/whois/parser.rb @@ -5,11 +5,12 @@ require "null_logger" require "whois/errors" require "whois/parser/afilias" require "whois/parser/afnic" +require "whois/parser/cira" require "whois/parser/verisign" module Whois module Parser - PARSERS = [AFNIC, Verisign, Afilias].freeze + PARSERS = [AFNIC, CIRA, Verisign, Afilias].freeze class << self def for(domain, logger: NullLogger.new) diff --git a/app/services/whois/parser/base.rb b/app/services/whois/parser/base.rb index e5b1742..480972d 100644 --- a/app/services/whois/parser/base.rb +++ b/app/services/whois/parser/base.rb @@ -39,12 +39,15 @@ module Whois protected - def get_field!(name, after: -1, value: nil) + def get_field(name, after: -1, value: nil) fields.detect { |field| field.index > after && field.name == name && (value.nil? || field.value == value) - } || fail(FieldNotFoundError, "Field `#{name}` not found, after index #{after}") + } + end + def get_field!(name, after: -1, value: nil) + get_field(name, after: after, value: value) || fail(FieldNotFoundError, "Field `#{name}` not found, after index #{after}") end def get_value!(name, after: -1) diff --git a/app/services/whois/parser/cira.rb b/app/services/whois/parser/cira.rb new file mode 100644 index 0000000..cb248f2 --- /dev/null +++ b/app/services/whois/parser/cira.rb @@ -0,0 +1,47 @@ +# Copyright (C) 2018 Colin Darie , 2018 Evolix +# License: GNU AGPL-3+ (see full text in LICENSE file) + +require "domain_helper" +require "whois/errors" +require_relative "base" + +module Whois + module Parser + class CIRA < Base + # https://cira.ca/ + SUPPORTED_TLD = %w[ + .ca + ].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 get_field("Not found", value: domain.downcase) + + 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.ca.txt b/test/fixtures/files/whois/domain.ca.txt new file mode 100644 index 0000000..04a625b --- /dev/null +++ b/test/fixtures/files/whois/domain.ca.txt @@ -0,0 +1,187 @@ +% IANA WHOIS server +% for more information on IANA, visit http://www.iana.org +% This query returned 1 object + +refer: whois.cira.ca + +domain: CA + +organisation: Canadian Internet Registration Authority (CIRA) Autorité Canadienne pour les enregistrements Internet (ACEI) +address: 979 Bank Street, Suite 400 +address: Ottawa, Ontario, K1S 5K5 +address: Canada + +contact: administrative +name: Chief Information Officer +organisation: CIRA +address: 979 Bank Street, Suite 400 +address: Ottawa, Ontario, K1S 5K5 +address: Canada +phone: +1 613 237 5335 +fax-no: +1 613 237 0534 +e-mail: chief.information.officer@cira.ca + +contact: technical +name: DNS Admin +organisation: CIRA +address: 979 Bank Street, Suite 400 +address: Ottawa, Ontario, K1S 5K5 +address: Canada +phone: +1 613 237 5335 +fax-no: +1 613 237 0534 +e-mail: admin-dns@cira.ca + +nserver: ANY.CA-SERVERS.CA 199.4.144.2 2001:500:a7:0:0:0:0:2 +nserver: C.CA-SERVERS.CA 185.159.196.2 2620:10a:8053:0:0:0:0:2 +nserver: J.CA-SERVERS.CA 198.182.167.1 2001:500:83:0:0:0:0:1 +nserver: X.CA-SERVERS.CA 199.253.250.68 2620:10a:80ba:0:0:0:0:68 +ds-rdata: 2134 8 2 4b8475c0c0fe2afdfee1a71a237c91059098d12fc18265b290edb238a5f63582 + +whois: whois.cira.ca + +status: ACTIVE +remarks: Registration information: http://www.cira.ca/ + +created: 1987-05-14 +changed: 2018-03-12 +source: IANA + +Domain Name: domain.ca +Registry Domain ID: 20543793-CIRA +Registrar WHOIS Server: whois.ca.fury.ca +Registrar URL: www.gandi.net +Updated Date: 2018-12-03T21:21:04Z +Creation Date: 2015-03-24T09:10:16Z +Registry Expiry Date: 2020-03-24T09:10:16Z +Registrar: Gandi Services Inc. +Registrar IANA ID: +Registrar Abuse Contact Email: +Registrar Abuse Contact Phone: +Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited +Registry Registrant ID: 20489098-CIRA +Registrant Name: DOMAIN LLC () +Registrant Organization: +Registrant Street: 12, r De la vie +Registrant City: Marseille +Registrant State/Province: Marseille +Registrant Postal Code: 13009 +Registrant Country: FR +Registrant Phone: +33.491234567 +Registrant Phone Ext: +Registrant Fax: +Registrant Fax Ext: +Registrant Email: 7487d1824de2ffea6b1ba98ba8b83342-793288@contact.gandi.net +Registry Admin ID: 20528918-CIRA +Admin Name: John Appleseeds +Admin Organization: +Admin Street: A complete street address +Admin City: cityville +Admin State/Province: cityville +Admin Postal Code: 19321 +Admin Country: FR +Admin Phone: +33.491234567 +Admin Phone Ext: +Admin Fax: +Admin Fax Ext: +Admin Email: contact@domain.fr +Registry Tech ID: 20528918-CIRA +Tech Name: John Appleseeds +Tech Organization: +Tech Street: A complete street address +Tech City: cityville +Tech State/Province: cityville +Tech Postal Code: 19321 +Tech Country: FR +Tech Phone: +33.491234567 +Tech Phone Ext: +Tech Fax: +Tech Fax Ext: +Tech Email: contact@domain.fr +Registry Billing ID: +Billing Name: +Billing Organization: +Billing Street: +Billing City: +Billing State/Province: +Billing Postal Code: +Billing Country: +Billing Phone: +Billing Phone Ext: +Billing Fax: +Billing Fax Ext: +Billing Email: +Name Server: ns1.domain.net +Name Server: ns0.domain.com +DNSSEC: unsigned +URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/ +>>> Last update of WHOIS database: 2019-02-27T22:40:02Z <<< + +Domain Name: domain.ca +Registry Domain ID: 20543793-CIRA +Registrar WHOIS Server: whois.ca.fury.ca +Registrar URL: www.gandi.net +Updated Date: 2018-12-03T21:21:04Z +Creation Date: 2015-03-24T09:10:16Z +Registry Expiry Date: 2020-03-24T09:10:16Z +Registrar: Gandi Services Inc. +Registrar IANA ID: +Registrar Abuse Contact Email: +Registrar Abuse Contact Phone: +Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited +Registry Registrant ID: 20489098-CIRA +Registrant Name: domain SARL () +Registrant Organization: +Registrant Street: 37, r Guibal +Registrant City: Marseille +Registrant State/Province: Marseille +Registrant Postal Code: 19321 +Registrant Country: FR +Registrant Phone: +33.491234567 +Registrant Phone Ext: +Registrant Fax: +Registrant Fax Ext: +Registrant Email: 7487d1824de2ffea6b1ba98ba8b83342-793288@contact.gandi.net +Registry Admin ID: 20528918-CIRA +Admin Name: John Appleseeds +Admin Organization: +Admin Street: A complete street address +Admin City: cityville +Admin State/Province: cityville +Admin Postal Code: 19321 +Admin Country: FR +Admin Phone: +33.491234567 +Admin Phone Ext: +Admin Fax: +Admin Fax Ext: +Admin Email: contact@domain.fr +Registry Tech ID: 20528918-CIRA +Tech Name: John Appleseeds +Tech Organization: +Tech Street: A complete street address +Tech City: cityville +Tech State/Province: cityville +Tech Postal Code: 19321 +Tech Country: FR +Tech Phone: +33.491234567 +Tech Phone Ext: +Tech Fax: +Tech Fax Ext: +Tech Email: contact@domain.fr +Registry Billing ID: +Billing Name: +Billing Organization: +Billing Street: +Billing City: +Billing State/Province: +Billing Postal Code: +Billing Country: +Billing Phone: +Billing Phone Ext: +Billing Fax: +Billing Fax Ext: +Billing Email: +Name Server: ns1.domain.net +Name Server: ns0.domain.com +DNSSEC: unsigned +URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/ +>>> Last update of WHOIS database: 2019-02-27T22:40:02Z <<< diff --git a/test/fixtures/files/whois/willneverexist.ca.txt b/test/fixtures/files/whois/willneverexist.ca.txt new file mode 100644 index 0000000..0436cc9 --- /dev/null +++ b/test/fixtures/files/whois/willneverexist.ca.txt @@ -0,0 +1,55 @@ +% IANA WHOIS server +% for more information on IANA, visit http://www.iana.org +% This query returned 1 object + +refer: whois.cira.ca + +domain: CA + +organisation: Canadian Internet Registration Authority (CIRA) Autorité Canadienne pour les enregistrements Internet (ACEI) +address: 979 Bank Street, Suite 400 +address: Ottawa, Ontario, K1S 5K5 +address: Canada + +contact: administrative +name: Chief Information Officer +organisation: CIRA +address: 979 Bank Street, Suite 400 +address: Ottawa, Ontario, K1S 5K5 +address: Canada +phone: +1 613 237 5335 +fax-no: +1 613 237 0534 +e-mail: chief.information.officer@cira.ca + +contact: technical +name: DNS Admin +organisation: CIRA +address: 979 Bank Street, Suite 400 +address: Ottawa, Ontario, K1S 5K5 +address: Canada +phone: +1 613 237 5335 +fax-no: +1 613 237 0534 +e-mail: admin-dns@cira.ca + +nserver: ANY.CA-SERVERS.CA 199.4.144.2 2001:500:a7:0:0:0:0:2 +nserver: C.CA-SERVERS.CA 185.159.196.2 2620:10a:8053:0:0:0:0:2 +nserver: J.CA-SERVERS.CA 198.182.167.1 2001:500:83:0:0:0:0:1 +nserver: X.CA-SERVERS.CA 199.253.250.68 2620:10a:80ba:0:0:0:0:68 +ds-rdata: 2134 8 2 4b8475c0c0fe2afdfee1a71a237c91059098d12fc18265b290edb238a5f63582 + +whois: whois.cira.ca + +status: ACTIVE +remarks: Registration information: http://www.cira.ca/ + +created: 1987-05-14 +changed: 2018-03-12 +source: IANA + +Not found: willneverexist.ca + +% +% Use of CIRA's WHOIS service is governed by the Terms of Use in its Legal +% Notice, available at http://www.cira.ca/legal-notice/?lang=en +% +% (c) 2019 Canadian Internet Registration Authority, (http://www.cira.ca/) diff --git a/test/services/whois/parser/cira_test.rb b/test/services/whois/parser/cira_test.rb new file mode 100644 index 0000000..7dc42e9 --- /dev/null +++ b/test/services/whois/parser/cira_test.rb @@ -0,0 +1,43 @@ +# Copyright (C) 2018 Colin Darie , 2018 Evolix +# License: GNU AGPL-3+ (see full text in LICENSE file) + +require "test_helper" +require "whois/parser/cira" +require "whois/response" +require "whois/errors" + +module Whois + class CIRATest < ActiveSupport::TestCase + test "should parse a whois response for .ca" do + parser = Parser::CIRA.new("domain.ca") + whois_output = file_fixture("whois/domain.ca.txt").read + response = parser.parse(whois_output) + assert_kind_of Response, response + + assert_equal Time.new(2015, 3, 24, 9, 10, 16, 0), response.created_at + assert response.created_at.utc? + + assert_equal Time.new(2018, 12, 3, 21, 21, 04, 0), response.updated_at + assert_equal Time.new(2020, 3, 24, 9, 10, 16, 0), response.expire_at + end + + test "should raises DomainNotFoundError for .ca when domain is not registered" do + parser = Parser::CIRA.new("willneverexist.ca") + not_found = file_fixture("whois/willneverexist.ca.txt").read + + assert_raises DomainNotFoundError do + parser.parse(not_found) + end + end + + test "should raises InvalidDateError for .ca when a date is not parsable" do + parser = Parser::CIRA.new("domain.ca") + whois_output = file_fixture("whois/domain.ca.txt").read + whois_output.gsub!("2015-03-24T09:10:16Z", "not a date") + + assert_raises InvalidDateError do + parser.parse(whois_output) + end + end + end +end