diff --git a/.reek b/.reek index aaf662290..0d5c66aa3 100644 --- a/.reek +++ b/.reek @@ -111,7 +111,6 @@ UncommunicativeVariableName: - Invoice#cancel_overdue_invoices - Legacy::Db - LegalDocument#save_to_filesystem - - Nameserver#replace_hostname_ends - RegistrantUser#find_or_create_by_idc_data - RegistrantUser#find_or_create_by_mid_data - Registrar @@ -318,7 +317,6 @@ DuplicateMethodCall: - Invoice#set_invoice_number - LegalDocument#save_to_filesystem - LegalDocument#self.remove_duplicates - - Nameserver#replace_hostname_ends - Setting#self.params_errors - Setting#self.reload_settings! - Soap::Arireg#associated_businesses @@ -806,7 +804,6 @@ TooManyStatements: - Invoice#set_invoice_number - LegalDocument#save_to_filesystem - LegalDocument#self.remove_duplicates - - Nameserver#replace_hostname_ends - RegistrantUser#find_or_create_by_idc_data - Registrar#generate_iso_11649_reference_no - Soap::Arireg#associated_businesses @@ -1003,7 +1000,6 @@ NestedIterators: - Domain#self.to_csv - Epp::Domain#nameservers_from - LegalDocument#self.remove_duplicates - - Nameserver#replace_hostname_ends - RegistrantPresenter#domain_names_with_roles - UniquenessMultiValidator#validate_each UnusedParameters: @@ -1070,7 +1066,6 @@ Attribute: - BankStatement#th6_file - Versions#version_loader - Contact#deliver_emails - - Contact#domains_present - Contact#legal_document_id - Counter#value - Deposit#amount @@ -1140,7 +1135,5 @@ UncommunicativeParameterName: - Dnskey#int_to_hex UncommunicativeMethodName: exclude: - - Nameserver#val_ipv4 - - Nameserver#val_ipv6 - Soap::Arireg#country_code_3 - WhiteIp#validate_ipv4_and_ipv6 diff --git a/CHANGELOG.md b/CHANGELOG.md index 1241486d3..9e76d8a12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +06.03.2018 +* BUG: Transfer poll message now returns affected domain name [#694](https://github.com/internetee/registry/issues/694) +* BUG: Successful REPP bulk transfer returns info about transfered domains [#693](https://github.com/internetee/registry/issues/693) +* BUG: Postal address data is not validated when address processing is disabled [#731](https://github.com/internetee/registry/issues/731) +* EPP: invalid country code message (code 2005) specifies invalid value [#733](https://github.com/internetee/registry/issues/733) +* REPP: new bulk nameserver change feature, also available on the portal for registars [#661](https://github.com/internetee/registry/issues/661) +* Admin: disable auto-email feature on setting force delete [#727](https://github.com/internetee/registry/issues/727) +* jQuery validation gem removed [#744](https://github.com/internetee/registry/issues/744) + 22.02.2018 * BUG: Registrar: contact list export is not limited to 75 records any more [#721](https://github.com/internetee/registry/issues/721) * BUG: EPP: domain and associated objects are not validated on domain delete [#707](https://github.com/internetee/registry/issues/707) diff --git a/app/api/repp/api.rb b/app/api/repp/api.rb index aec46c68b..9c12470a0 100644 --- a/app/api/repp/api.rb +++ b/app/api/repp/api.rb @@ -58,5 +58,6 @@ module Repp mount Repp::ContactV1 mount Repp::AccountV1 mount Repp::DomainTransfersV1 + mount Repp::NameserversV1 end end diff --git a/app/api/repp/domain_transfers_v1.rb b/app/api/repp/domain_transfers_v1.rb index ea714a731..c6a48df6d 100644 --- a/app/api/repp/domain_transfers_v1.rb +++ b/app/api/repp/domain_transfers_v1.rb @@ -26,7 +26,7 @@ module Repp if domain if domain.transfer_code == transfer_code DomainTransfer.request(domain, new_registrar) - successful_domain_transfers << { type: 'domain_transfer' } + successful_domain_transfers << { type: 'domain_transfer', attributes: { domain_name: domain.name } } else errors << { title: "#{domain_name} transfer code is wrong" } end diff --git a/app/api/repp/nameservers_v1.rb b/app/api/repp/nameservers_v1.rb new file mode 100644 index 000000000..d653adf7f --- /dev/null +++ b/app/api/repp/nameservers_v1.rb @@ -0,0 +1,44 @@ +module Repp + class NameserversV1 < Grape::API + version 'v1', using: :path + + resource 'registrar/nameservers' do + put '/' do + params do + requires :data, type: Hash, allow_blank: false do + requires :type, type: String, allow_blank: false + requires :id, type: String, allow_blank: false + requires :attributes, type: Hash, allow_blank: false do + requires :hostname, type: String, allow_blank: false + requires :ipv4, type: Array + requires :ipv6, type: Array + end + end + end + + hostname = params[:data][:id] + + unless current_user.registrar.nameservers.exists?(hostname: hostname) + error!({ errors: [{ title: "Hostname #{hostname} does not exist" }] }, 404) + end + + new_attributes = { + hostname: params[:data][:attributes][:hostname], + ipv4: params[:data][:attributes][:ipv4], + ipv6: params[:data][:attributes][:ipv6], + } + + begin + current_user.registrar.replace_nameservers(hostname, new_attributes) + rescue ActiveRecord::RecordInvalid => e + error!({ errors: e.record.errors.full_messages.map { |error| { title: error } } }, 400) + end + + status 200 + @response = { data: { type: 'nameserver', + id: params[:data][:attributes][:hostname], + attributes: params[:data][:attributes] } } + end + end + end +end diff --git a/app/assets/javascripts/admin/domains/force_delete.js b/app/assets/javascripts/admin/domains/force_delete.js index 652f798b3..54981a683 100644 --- a/app/assets/javascripts/admin/domains/force_delete.js +++ b/app/assets/javascripts/admin/domains/force_delete.js @@ -1,12 +1,13 @@ (function() { let container = document.querySelector('.domain-edit-force-delete-dialog'); - let toggle = container.querySelector('[data-dependent-content-toggle]'); - let dependentContent = container.querySelector('.email-template-row'); - if (!toggle) { + if (!container) { return; } + let toggle = container.querySelector('[data-dependent-content-toggle]'); + let dependentContent = container.querySelector('.email-template-row'); + toggle.addEventListener('change', function() { dependentContent.hidden = !this.checked; }); diff --git a/app/controllers/registrar/domain_transfers_controller.rb b/app/controllers/registrar/domain_transfers_controller.rb index 0c72b2d93..65127155e 100644 --- a/app/controllers/registrar/domain_transfers_controller.rb +++ b/app/controllers/registrar/domain_transfers_controller.rb @@ -51,11 +51,13 @@ class Registrar end end - if response.code == '204' - flash[:notice] = t '.transferred' + parsed_response = JSON.parse(response.body, symbolize_names: true) + + if response.code == '200' + flash[:notice] = t '.transferred', count: parsed_response[:data].size redirect_to registrar_domains_url else - @api_errors = JSON.parse(response.body, symbolize_names: true)[:errors] + @api_errors = parsed_response[:errors] render :new end else diff --git a/app/controllers/registrar/registrar_nameservers_controller.rb b/app/controllers/registrar/registrar_nameservers_controller.rb new file mode 100644 index 000000000..1af3cde64 --- /dev/null +++ b/app/controllers/registrar/registrar_nameservers_controller.rb @@ -0,0 +1,59 @@ +class Registrar + class RegistrarNameserversController < DeppController + def edit + authorize! :manage, :repp + end + + def update + authorize! :manage, :repp + + ipv4 = params[:ipv4].split("\r\n") + ipv6 = params[:ipv6].split("\r\n") + + uri = URI.parse("#{ENV['repp_url']}registrar/nameservers") + request = Net::HTTP::Put.new(uri, 'Content-Type' => 'application/json') + request.body = { data: { type: 'nameserver', id: params[:old_hostname], + attributes: { hostname: params[:new_hostname], + ipv4: ipv4, + ipv6: ipv6 } } }.to_json + request.basic_auth(current_user.username, current_user.password) + + if Rails.env.test? + response = Net::HTTP.start(uri.hostname, uri.port, + use_ssl: (uri.scheme == 'https'), + verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http| + http.request(request) + end + elsif Rails.env.development? + client_cert = File.read(ENV['cert_path']) + client_key = File.read(ENV['key_path']) + response = Net::HTTP.start(uri.hostname, uri.port, + use_ssl: (uri.scheme == 'https'), + verify_mode: OpenSSL::SSL::VERIFY_NONE, + cert: OpenSSL::X509::Certificate.new(client_cert), + key: OpenSSL::PKey::RSA.new(client_key)) do |http| + http.request(request) + end + else + client_cert = File.read(ENV['cert_path']) + client_key = File.read(ENV['key_path']) + response = Net::HTTP.start(uri.hostname, uri.port, + use_ssl: (uri.scheme == 'https'), + cert: OpenSSL::X509::Certificate.new(client_cert), + key: OpenSSL::PKey::RSA.new(client_key)) do |http| + http.request(request) + end + end + + parsed_response = JSON.parse(response.body, symbolize_names: true) + + if response.code == '200' + flash[:notice] = t '.replaced' + redirect_to registrar_domains_url + else + @api_errors = parsed_response[:errors] + render :edit + end + end + end +end diff --git a/app/models/concerns/contact/identical.rb b/app/models/concerns/contact/identical.rb new file mode 100644 index 000000000..f529e09ac --- /dev/null +++ b/app/models/concerns/contact/identical.rb @@ -0,0 +1,34 @@ +module Concerns::Contact::Identical + extend ActiveSupport::Concern + + IDENTIFIABLE_ATTRIBUTES = %w[ + name + email + phone + fax + ident + ident_type + ident_country_code + org_name + ] + private_constant :IDENTIFIABLE_ATTRIBUTES + + def identical(registrar) + self.class.where(identifiable_hash) + .where(["statuses = ?::character varying[]", "{#{read_attribute(:statuses).join(',')}}"]) + .where(registrar: registrar) + .where.not(id: id).take + end + + private + + def identifiable_hash + attributes = IDENTIFIABLE_ATTRIBUTES + + if self.class.address_processing? + attributes += self.class.address_attribute_names + end + + slice(*attributes) + end +end diff --git a/app/models/concerns/contact/transferable.rb b/app/models/concerns/contact/transferable.rb index 8da98fc57..14c1cac3c 100644 --- a/app/models/concerns/contact/transferable.rb +++ b/app/models/concerns/contact/transferable.rb @@ -7,6 +7,8 @@ module Concerns::Contact::Transferable end def transfer(new_registrar) + return identical(new_registrar) if identical(new_registrar) + new_contact = self.dup new_contact.registrar = new_registrar new_contact.original = self diff --git a/app/models/concerns/domain/transferable.rb b/app/models/concerns/domain/transferable.rb index f2e7736c2..56e77f34d 100644 --- a/app/models/concerns/domain/transferable.rb +++ b/app/models/concerns/domain/transferable.rb @@ -52,7 +52,7 @@ module Concerns::Domain::Transferable def transfer_registrant(new_registrar) return if registrant.registrar == new_registrar - self.registrant = registrant.transfer(new_registrar) + self.registrant = registrant.transfer(new_registrar).becomes(Registrant) end def transfer_domain_contacts(new_registrar) diff --git a/app/models/contact.rb b/app/models/contact.rb index 3024551f8..3bd8bb2ce 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -3,6 +3,7 @@ class Contact < ActiveRecord::Base include EppErrors include UserEvents include Concerns::Contact::Transferable + include Concerns::Contact::Identical belongs_to :original, class_name: self.name belongs_to :registrar, required: true @@ -11,9 +12,6 @@ class Contact < ActiveRecord::Base has_many :legal_documents, as: :documentable has_many :registrant_domains, class_name: 'Domain', foreign_key: 'registrant_id' - # TODO: remove later - has_many :depricated_statuses, class_name: 'DepricatedContactStatus', dependent: :destroy - has_paper_trail class_name: "ContactVersion", meta: { children: :children_log } attr_accessor :legal_document_id @@ -37,7 +35,7 @@ class Contact < ActiveRecord::Base validates_associated :identifier validate :validate_html - validate :validate_country_code + validate :validate_country_code, if: 'self.class.address_processing?' after_initialize do self.status_notes = {} if status_notes.nil? @@ -70,11 +68,6 @@ class Contact < ActiveRecord::Base after_save :update_related_whois_records - # for overwrite when doing children loop - attr_writer :domains_present - - scope :current_registrars, ->(id) { where(registrar_id: id) } - ORG = 'org' PRIV = 'priv' BIRTHDAY = 'birthday'.freeze @@ -206,7 +199,7 @@ class Contact < ActiveRecord::Base ver_scope << "(children->'#{type}')::jsonb <@ json_build_array(#{contact.id})::jsonb" end next if DomainVersion.where("created_at > ?", Time.now - Setting.orphans_contacts_in_months.to_i.months).where(ver_scope.join(" OR ")).any? - next if contact.domains_present? + next if contact.in_use? contact.destroy counter.next @@ -279,7 +272,7 @@ class Contact < ActiveRecord::Base calculated.delete(Contact::OK) calculated.delete(Contact::LINKED) calculated << Contact::OK if calculated.empty?# && valid? - calculated << Contact::LINKED if domains_present? + calculated << Contact::LINKED if in_use? calculated.uniq end @@ -347,7 +340,7 @@ class Contact < ActiveRecord::Base # no need separate method # should use only in transaction def destroy_and_clean frame - if domains_present? + if in_use? errors.add(:domains, :exist) return false end @@ -405,14 +398,6 @@ class Contact < ActiveRecord::Base end end - # optimization under children loop, - # otherwise bullet will not be happy - def domains_present? - return @domains_present if @domains_present - domain_contacts.present? || registrant_domains.present? - end - - def search_name "#{code} #{name}" end @@ -551,7 +536,7 @@ class Contact < ActiveRecord::Base Country.new(ident_country_code) end - def used? + def in_use? registrant_domains.any? || domain_contacts.any? end diff --git a/app/models/depricated_contact_status.rb b/app/models/depricated_contact_status.rb deleted file mode 100644 index b67722ac4..000000000 --- a/app/models/depricated_contact_status.rb +++ /dev/null @@ -1,5 +0,0 @@ -class DepricatedContactStatus < ActiveRecord::Base - self.table_name = :contact_statuses - self.sequence_name = :contact_statuses_id_seq - belongs_to :contact -end diff --git a/app/models/domain.rb b/app/models/domain.rb index 54dfe608e..9eef0f30f 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -40,15 +40,11 @@ class Domain < ActiveRecord::Base has_many :contacts, through: :domain_contacts, source: :contact has_many :admin_contacts, through: :admin_domain_contacts, source: :contact has_many :tech_contacts, through: :tech_domain_contacts, source: :contact - has_many :nameservers, dependent: :destroy + has_many :nameservers, dependent: :destroy, inverse_of: :domain accepts_nested_attributes_for :nameservers, allow_destroy: true, reject_if: proc { |attrs| attrs[:hostname].blank? } - has_many :domain_statuses, dependent: :destroy - accepts_nested_attributes_for :domain_statuses, allow_destroy: true, - reject_if: proc { |attrs| attrs[:value].blank? } - has_many :transfers, class_name: 'DomainTransfer', dependent: :destroy has_many :dnskeys, dependent: :destroy @@ -172,10 +168,6 @@ class Domain < ActiveRecord::Base attribute: 'contact_code_cache' } - validates :domain_statuses, uniqueness_multi: { - attribute: 'value' - } - validates :dnskeys, uniqueness_multi: { attribute: 'public_key' } @@ -610,7 +602,6 @@ class Domain < ActiveRecord::Base log[:tech_contacts] = tech_contact_ids log[:nameservers] = nameserver_ids log[:dnskeys] = dnskey_ids - log[:domain_statuses]= domain_status_ids log[:legal_documents]= [legal_document_id] log[:registrant] = [registrant_id] log diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 8c9e8bcc8..fb01fe38a 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -179,7 +179,6 @@ class Epp::Domain < Domain at[:nameservers_attributes] = nameservers_attrs(frame, action) at[:admin_domain_contacts_attributes] = admin_domain_contacts_attrs(frame, action) at[:tech_domain_contacts_attributes] = tech_domain_contacts_attrs(frame, action) - # at[:domain_statuses_attributes] = domain_statuses_attrs(frame, action) pw = frame.css('authInfo > pw').text at[:transfer_code] = pw if pw.present? diff --git a/app/models/nameserver.rb b/app/models/nameserver.rb index fb56f1198..d9a5f2a75 100644 --- a/app/models/nameserver.rb +++ b/app/models/nameserver.rb @@ -2,18 +2,31 @@ class Nameserver < ActiveRecord::Base include Versions # version/nameserver_version.rb include EppErrors - # belongs_to :registrar - belongs_to :domain + HOSTNAME_REGEXP = /\A(([a-zA-Z0-9]|[a-zA-ZäöüõšžÄÖÜÕŠŽ0-9][a-zA-ZäöüõšžÄÖÜÕŠŽ0-9\-] + *[a-zA-ZäöüõšžÄÖÜÕŠŽ0-9])\.) + *([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-] + *[A-Za-z0-9])\z/x - # scope :owned_by_registrar, -> (registrar) { joins(:domain).where('domains.registrar_id = ?', registrar.id) } + IPV4_REGEXP = /\A(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3} + ([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\z/x - # rubocop: disable Metrics/LineLength - validates :hostname, format: { with: /\A(([a-zA-Z0-9]|[a-zA-ZäöüõšžÄÖÜÕŠŽ0-9][a-zA-ZäöüõšžÄÖÜÕŠŽ0-9\-]*[a-zA-ZäöüõšžÄÖÜÕŠŽ0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])\z/ } - # validates :ipv4, format: { with: /\A(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\z/, allow_blank: true } - # validates :ipv6, format: { with: /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/, allow_blank: true } - validate :val_ipv4 - validate :val_ipv6 - # rubocop: enable Metrics/LineLength + IPV6_REGEXP = /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:| + ([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}| + ([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}| + ([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}| + ([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})| + :((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}| + ::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]| + 1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]| + 1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/x + + belongs_to :domain, required: true + + validates :hostname, presence: true + validates :hostname, format: { with: HOSTNAME_REGEXP }, allow_blank: true + validate :validate_ipv4_format + validate :validate_ipv6_format + validate :require_ip, if: :glue_record_required? before_validation :normalize_attributes before_validation :check_puny_symbols @@ -38,6 +51,39 @@ class Nameserver < ActiveRecord::Base } end + def to_s + hostname + end + + def hostname=(hostname) + self[:hostname] = SimpleIDN.to_unicode(hostname) + self[:hostname_puny] = SimpleIDN.to_ascii(hostname) + end + + class << self + def find_by_hash_params params + params = params.with_indifferent_access + rel = all + rel = rel.where(hostname: params[:hostname]) + rel + end + + def hostnames + pluck(:hostname) + end + end + + private + + def require_ip + errors.add(:base, :ip_required) if ipv4.blank? && ipv6.blank? + end + + def glue_record_required? + return unless hostname? && domain + hostname.end_with?(domain.name) + end + def normalize_attributes self.hostname = hostname.try(:strip).try(:downcase) self.ipv4 = Array(ipv4).reject(&:blank?).map(&:strip) @@ -45,6 +91,8 @@ class Nameserver < ActiveRecord::Base end def check_label_length + return unless hostname + hostname_puny.split('.').each do |label| errors.add(:hostname, :puny_to_long) if label.length > 63 end @@ -55,71 +103,15 @@ class Nameserver < ActiveRecord::Base errors.add(:hostname, :invalid) if hostname =~ regexp end - def to_s - hostname - end - - def hostname=(hostname) - self[:hostname] = SimpleIDN.to_unicode(hostname) - self[:hostname_puny] = SimpleIDN.to_ascii(hostname) - end - - def val_ipv4 - regexp = /\A(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\z/ + def validate_ipv4_format ipv4.to_a.each do |ip| - errors.add(:ipv4, :invalid) unless ip =~ regexp + errors.add(:ipv4, :invalid) unless ip =~ IPV4_REGEXP end end - def val_ipv6 - regexp = /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/ + + def validate_ipv6_format ipv6.to_a.each do |ip| - errors.add(:ipv6, :invalid) unless ip =~ regexp - end - end - - class << self - def replace_hostname_ends(domains, old_end, new_end) - domains = domains.where('EXISTS( - select 1 from nameservers ns where ns.domain_id = domains.id AND ns.hostname LIKE ? - )', "%#{old_end}") - - count, success_count = 0.0, 0.0 - domains.each do |d| - ns_attrs = { nameservers_attributes: [] } - - d.nameservers.each do |ns| - next unless ns.hostname.end_with?(old_end) - - hn = ns.hostname.chomp(old_end) - ns_attrs[:nameservers_attributes] << { - id: ns.id, - hostname: "#{hn}#{new_end}" - } - end - - success_count += 1 if d.update(ns_attrs) - count += 1 - end - - return 'replaced_none' if count == 0.0 - - prc = success_count / count - - return 'replaced_all' if prc == 1.0 - 'replaced_some' - end - - def find_by_hash_params params - params = params.with_indifferent_access - rel = all - rel = rel.where(hostname: params[:hostname]) - # rel = rel.where(hostname: params[:hostname]) if params[:ipv4] - # ignoring ips - rel - end - - def hostnames - pluck(:hostname) + errors.add(:ipv6, :invalid) unless ip =~ IPV6_REGEXP end end end diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 487bc513a..181ddab18 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -191,6 +191,20 @@ class Registrar < ActiveRecord::Base white_ips.api.pluck(:ipv4, :ipv6).flatten.include?(ip) end + # Audit log is needed, therefore no raw SQL + def replace_nameservers(hostname, new_attributes) + transaction do + nameservers.where(hostname: hostname).find_each do |original_nameserver| + new_nameserver = Nameserver.new + new_nameserver.domain = original_nameserver.domain + new_nameserver.attributes = new_attributes + new_nameserver.save! + + original_nameserver.destroy! + end + end + end + private def set_defaults diff --git a/app/models/version/contact_status_version.rb b/app/models/version/contact_status_version.rb deleted file mode 100644 index 0c01af564..000000000 --- a/app/models/version/contact_status_version.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ContactStatusVersion < PaperTrail::Version - include VersionSession - self.table_name = :log_contact_statuses - self.sequence_name = :log_contact_statuses_id_seq -end diff --git a/app/models/version/country_version.rb b/app/models/version/country_version.rb deleted file mode 100644 index e88c95181..000000000 --- a/app/models/version/country_version.rb +++ /dev/null @@ -1,5 +0,0 @@ -class CountryVersion < PaperTrail::Version - include VersionSession - self.table_name = :log_countries - self.sequence_name = :log_countries_id_seq -end diff --git a/app/models/version/domain_status_version.rb b/app/models/version/domain_status_version.rb deleted file mode 100644 index c85adbf93..000000000 --- a/app/models/version/domain_status_version.rb +++ /dev/null @@ -1,5 +0,0 @@ -class DomainStatusVersion < PaperTrail::Version - include VersionSession - self.table_name = :log_domain_statuses - self.sequence_name = :log_domain_statuses_id_seq -end diff --git a/app/presenters/registrant_presenter.rb b/app/presenters/registrant_presenter.rb index 148c5d219..6a78f86c5 100644 --- a/app/presenters/registrant_presenter.rb +++ b/app/presenters/registrant_presenter.rb @@ -8,7 +8,7 @@ class RegistrantPresenter :reg_no, :street, :city, :state, :zip, :country, :ident_country, - :used?, + :in_use?, to: :registrant def initialize(registrant:, view:) diff --git a/app/views/mailers/contact_mailer/email_updated.html.erb b/app/views/mailers/contact_mailer/email_updated.html.erb index a4f6d8583..c3a22b063 100644 --- a/app/views/mailers/contact_mailer/email_updated.html.erb +++ b/app/views/mailers/contact_mailer/email_updated.html.erb @@ -10,7 +10,7 @@ uus aadress: <%= contact.email %>

E-posti aadressile saadetakse domeeni toimingutega seotud infot, sealhulgas kinnitustaotlused omanikuvahetuse ja domeeni kustutamise korral.

-<% if contact.used? %> +<% if contact.in_use? %> Muudatusega seotud domeenid:
<%= contact.domain_names_with_roles(locale: :et, line_break: '
') %> <% end %> @@ -34,7 +34,7 @@ new address: <%= contact.email %>

E-mail addresses are used to send important information regarding your registered domains including applications for approval of registrant change and domain deletion. Please make sure that the update and contact information are correct.

-<% if contact.used? %> +<% if contact.in_use? %> Domains affected by this update:
<%= contact.domain_names_with_roles(line_break: '
') %> <% end %> diff --git a/app/views/mailers/contact_mailer/email_updated.text.erb b/app/views/mailers/contact_mailer/email_updated.text.erb index 97e46a5eb..d847f9f57 100644 --- a/app/views/mailers/contact_mailer/email_updated.text.erb +++ b/app/views/mailers/contact_mailer/email_updated.text.erb @@ -10,7 +10,7 @@ uus aadress: <%= contact.email %> E-posti aadressile saadetakse domeeni toimingutega seotud infot, sealhulgas kinnitustaotlused omanikuvahetuse ja domeeni kustutamise korral. -<% if contact.used? %> +<% if contact.in_use? %> Muudatusega seotud domeenid: <%= contact.domain_names_with_roles(locale: :et) %> <% end %> @@ -34,7 +34,7 @@ new address: <%= contact.email %> E-mail addresses are used to send important information regarding your registered domains including applications for approval of registrant change and domain deletion. Please make sure that the update and contact information are correct. -<% if contact.used? %> +<% if contact.in_use? %> Domains affected by this update: <%= contact.domain_names_with_roles %> <% end %> diff --git a/app/views/registrar/domains/index.html.erb b/app/views/registrar/domains/index.html.erb index a62619ca4..319f0d04f 100644 --- a/app/views/registrar/domains/index.html.erb +++ b/app/views/registrar/domains/index.html.erb @@ -1,12 +1,14 @@