From 647d074b8b217c91211a83a0f90b1161cb479bda Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Wed, 8 Jul 2015 16:04:56 +0300 Subject: [PATCH] Check reserved domain on create #2565 --- app/models/domain.rb | 25 +++++++++++++++++++++++++ app/models/domain_status.rb | 1 + app/models/epp/domain.rb | 5 ++++- app/validators/domain_name_validator.rb | 7 ++++--- config/locales/en.yml | 1 + 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/app/models/domain.rb b/app/models/domain.rb index ae81ce474..1b1c840f6 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -78,12 +78,26 @@ class Domain < ActiveRecord::Base after_initialize -> { self.statuses = [] if statuses.nil? } + after_create :update_reserved_domains + def update_reserved_domains + return unless reserved? + rd = ReservedDomain.first + rd.names[name] = SecureRandom.hex + rd.save + end + validates :name_dirty, domain_name: true, uniqueness: true validates :puny_label, length: { maximum: 63 } validates :period, numericality: { only_integer: true } validates :registrant, :registrar, presence: true validate :validate_period + validate :validate_reservation + def validate_reservation + return if persisted? + return if !reserved? || reserved_pw == auth_info + errors.add(:base, :domain_is_reserved_and_requires_correct_auth_info) + end validates :nameservers, object_count: { min: -> { Setting.ns_min_count }, @@ -247,6 +261,14 @@ class Domain < ActiveRecord::Base @registrant_typeahead || registrant.try(:name) || nil end + def reserved? + reserved_pw.present? + end + + def reserved_pw + ReservedDomain.select("names -> '#{name}' AS pw").first.pw + end + def pending_transfer domain_transfers.find_by(status: DomainTransfer::PENDING) end @@ -452,6 +474,7 @@ class Domain < ActiveRecord::Base # rubocop:disable Lint/Loop def generate_auth_info + return if auth_info.present? begin self.auth_info = SecureRandom.hex end while self.class.exists?(auth_info: auth_info) @@ -493,6 +516,8 @@ class Domain < ActiveRecord::Base end def manage_automatic_statuses + statuses << DomainStatus::RESERVED if new_record? && reserved? + # domain_statuses.create(value: DomainStatus::DELETE_CANDIDATE) if delete_candidateable? if statuses.empty? && valid? statuses << DomainStatus::OK diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index b33b5446c..0f984b4e7 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -71,6 +71,7 @@ class DomainStatus < ActiveRecord::Base FORCE_DELETE = 'forceDelete' DELETE_CANDIDATE = 'deleteCandidate' EXPIRED = 'expired' + RESERVED = 'reserved' STATUSES = [ CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED, CLIENT_HOLD, SERVER_HOLD, diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 69072a398..b98aa83b1 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -66,7 +66,8 @@ class Epp::Domain < Domain [:name_dirty, :blocked, { value: { obj: 'name', val: name_dirty } }] ], '2304' => [ # Object status prohibits operation - [:base, :domain_status_prohibits_operation] + [:base, :domain_status_prohibits_operation], + [:base, :domain_is_reserved_and_requires_correct_auth_info] ], '2306' => [ # Parameter policy error [:period, :out_of_range, { value: { obj: 'period', val: period } }], @@ -112,6 +113,8 @@ class Epp::Domain < Domain at[:period_unit] = Epp::Domain.parse_period_unit_from_frame(frame) || 'y' + at[:auth_info] = frame.css('pw').text if new_record? + # at[:statuses] = domain_statuses_attrs(frame, action) # binding.pry at[:nameservers_attributes] = nameservers_attrs(frame, action) diff --git a/app/validators/domain_name_validator.rb b/app/validators/domain_name_validator.rb index ff6ef69f6..1ac609a5a 100644 --- a/app/validators/domain_name_validator.rb +++ b/app/validators/domain_name_validator.rb @@ -6,8 +6,8 @@ class DomainNameValidator < ActiveModel::EachValidator record.errors[attribute] << (options[:message] || record.errors.generate_message(attribute, :invalid)) elsif !self.class.validate_blocked(value) record.errors.add(attribute, (options[:message] || record.errors.generate_message(attribute, :blocked))) - elsif !self.class.validate_reservation(value) - record.errors.add(attribute, (options[:message] || record.errors.generate_message(attribute, :reserved))) + # elsif !self.class.validate_reservation(value) + # record.errors.add(attribute, (options[:message] || record.errors.generate_message(attribute, :reserved))) end end # rubocop: enable Metrics/PerceivedComplexity @@ -42,8 +42,9 @@ class DomainNameValidator < ActiveModel::EachValidator BlockedDomain.where("names @> ?::varchar[]", "{#{value}}").count == 0 end - def validate_reservation(value) + def validate_reservation(record, value) return true unless value + return true if record.reserved_pw == record.auth_info !ReservedDomain.exists?(name: value.mb_chars.downcase.strip) end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 1c9754932..943f453fd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -60,6 +60,7 @@ en: ds_data_not_allowed: 'dsData object is not allowed' ds_data_with_key_not_allowed: 'dsData object with key data is not allowed' key_data_not_allowed: 'keyData object is not allowed' + domain_is_reserved_and_requires_correct_auth_info: 'Domain is reserved and requires correct auth info' name_dirty: invalid: 'Domain name is invalid' reserved: 'Domain name is reserved'