diff --git a/app/models/concerns/domain/disputable.rb b/app/models/concerns/domain/disputable.rb new file mode 100644 index 000000000..757f10fd3 --- /dev/null +++ b/app/models/concerns/domain/disputable.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Concerns + module Domain + module Disputable + extend ActiveSupport::Concern + + included do + validate :validate_disputed + end + + def mark_as_disputed + statuses.push(DomainStatus::DISPUTED) unless statuses.include?(DomainStatus::DISPUTED) + save + end + + def unmark_as_disputed + statuses.delete_if { |status| status == DomainStatus::DISPUTED } + save + end + + def in_disputed_list? + @in_disputed_list ||= Dispute.active.find_by(domain_name: name).present? + end + + def disputed? + Dispute.active.where(domain_name: name).any? + end + + def validate_disputed + return if persisted? || !in_disputed_list? + + if reserved_pw.blank? + errors.add(:base, :required_parameter_missing_reserved) + return false + end + + return if Dispute.valid_auth?(name, reserved_pw) + + errors.add(:base, :invalid_auth_information_reserved) + end + end + end +end diff --git a/app/models/dispute.rb b/app/models/dispute.rb index 031e15855..279475e23 100644 --- a/app/models/dispute.rb +++ b/app/models/dispute.rb @@ -12,16 +12,24 @@ class Dispute < ApplicationRecord after_destroy :remove_data scope :expired, -> { where('expires_at < ?', Time.zone.today) } - scope :active, -> { where('expires_at >= ? AND closed = false', Time.zone.today) } + scope :active, lambda { + where('starts_at <= ? AND expires_at >= ? AND closed = false', Time.zone.today, Time.zone.today) + } scope :closed, -> { where(closed: true) } attr_readonly :domain_name alias_attribute :name, :domain_name + def domain + Domain.find_by(name: domain_name) + end + def self.close_by_domain(domain_name) dispute = Dispute.active.find_by(domain_name: domain_name) - dispute.update(closed: true) if dispute.present? + return false unless dispute + + dispute.close end def self.valid_auth?(domain_name, password) @@ -40,6 +48,12 @@ class Dispute < ApplicationRecord def generate_data return if starts_at > Time.zone.today + return if expires_at < Time.zone.today + + domain = Domain.find_by_idn(domain_name) + domain&.mark_as_disputed + + return if domain wr = Whois::Record.find_or_initialize_by(name: domain_name) wr.json = generate_json(wr) @@ -52,6 +66,8 @@ class Dispute < ApplicationRecord return false unless update(closed: true) return if Dispute.active.where(domain_name: domain_name).any? + Domain.find_by_idn(domain_name)&.unmark_as_disputed + domain = DNS::DomainName.new(domain_name) if domain.available? && domain.auctionable? domain.sell_at_auction diff --git a/app/models/domain.rb b/app/models/domain.rb index d3296ab0c..805b58309 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -9,6 +9,7 @@ class Domain < ApplicationRecord include Concerns::Domain::Transferable include Concerns::Domain::RegistryLockable include Concerns::Domain::Releasable + include Concerns::Domain::Disputable attr_accessor :roles @@ -88,9 +89,8 @@ class Domain < ApplicationRecord validates :puny_label, length: { maximum: 63 } validates :period, presence: true, numericality: { only_integer: true } validates :transfer_code, presence: true - validate :validate_reservation - validate :validate_disputed + def validate_reservation return if persisted? || !in_reserved_list? @@ -104,19 +104,6 @@ class Domain < ApplicationRecord errors.add(:base, :invalid_auth_information_reserved) end - def validate_disputed - return if persisted? || !in_disputed_list? - - if reserved_pw.blank? - errors.add(:base, :required_parameter_missing_reserved) - return false - end - - return if Dispute.valid_auth?(name, reserved_pw) - - errors.add(:base, :invalid_auth_information_reserved) - end - validate :status_is_consistant def status_is_consistant has_error = (statuses.include?(DomainStatus::SERVER_HOLD) && statuses.include?(DomainStatus::SERVER_MANUAL_INZONE)) @@ -290,14 +277,6 @@ class Domain < ApplicationRecord @in_reserved_list ||= ReservedDomain.by_domain(name).any? end - def in_disputed_list? - @in_disputed_list ||= Dispute.active.find_by(domain_name: name).present? - end - - def disputed? - Dispute.active.where(domain_name: name).any? - end - def pending_transfer transfers.find_by(status: DomainTransfer::PENDING) end @@ -318,8 +297,8 @@ class Domain < ApplicationRecord return false if statuses.include_any?(DomainStatus::DELETE_CANDIDATE, DomainStatus::PENDING_RENEW, DomainStatus::PENDING_TRANSFER, DomainStatus::PENDING_DELETE, - DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_DELETE_CONFIRMATION) - return false if disputed? + DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_DELETE_CONFIRMATION, + DomainStatus::DISPUTED) true end diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index 4b1c49916..7a2f9d020 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -70,6 +70,7 @@ class DomainStatus < ApplicationRecord FORCE_DELETE = 'serverForceDelete' DELETE_CANDIDATE = 'deleteCandidate' EXPIRED = 'expired' + DISPUTED = 'disputed' STATUSES = [ CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED, CLIENT_HOLD, SERVER_HOLD, @@ -78,7 +79,7 @@ class DomainStatus < ApplicationRecord INACTIVE, OK, PENDING_CREATE, PENDING_DELETE, PENDING_DELETE_CONFIRMATION, PENDING_RENEW, PENDING_TRANSFER, PENDING_UPDATE, SERVER_MANUAL_INZONE, SERVER_REGISTRANT_CHANGE_PROHIBITED, SERVER_ADMIN_CHANGE_PROHIBITED, SERVER_TECH_CHANGE_PROHIBITED, FORCE_DELETE, - DELETE_CANDIDATE, EXPIRED + DELETE_CANDIDATE, EXPIRED, DISPUTED ] CLIENT_STATUSES = [ diff --git a/app/models/whois_record.rb b/app/models/whois_record.rb index cace829fa..4994283c9 100644 --- a/app/models/whois_record.rb +++ b/app/models/whois_record.rb @@ -84,6 +84,7 @@ class WhoisRecord < ApplicationRecord def populate return if domain_id.blank? + self.json = generated_json self.name = json['name'] self.registrar_id = domain.registrar_id if domain # for faster registrar updates diff --git a/test/integration/admin_area/disputes_test.rb b/test/integration/admin_area/disputes_test.rb index 1806eaea4..cfda9d23d 100644 --- a/test/integration/admin_area/disputes_test.rb +++ b/test/integration/admin_area/disputes_test.rb @@ -60,7 +60,7 @@ class AdminDisputesSystemTest < ApplicationSystemTestCase def test_deletes_dispute visit delete_admin_dispute_path(@dispute) - assert_text 'Dispute was successfully destroyed.' + assert_text 'Dispute was successfully closed.' end def test_can_not_create_overlapping_dispute