Merge branch 'master' into registry-623

# Conflicts:
#	db/structure.sql
This commit is contained in:
Artur Beljajev 2018-03-08 13:04:11 +02:00
commit ffc32b66de
72 changed files with 1004 additions and 932 deletions

7
.reek
View file

@ -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

View file

@ -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)

View file

@ -58,5 +58,6 @@ module Repp
mount Repp::ContactV1
mount Repp::AccountV1
mount Repp::DomainTransfersV1
mount Repp::NameserversV1
end
end

View file

@ -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

View file

@ -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

View file

@ -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;
});

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -1,5 +0,0 @@
class DepricatedContactStatus < ActiveRecord::Base
self.table_name = :contact_statuses
self.sequence_name = :contact_statuses_id_seq
belongs_to :contact
end

View file

@ -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

View file

@ -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?

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,5 +0,0 @@
class CountryVersion < PaperTrail::Version
include VersionSession
self.table_name = :log_countries
self.sequence_name = :log_countries_id_seq
end

View file

@ -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

View file

@ -8,7 +8,7 @@ class RegistrantPresenter
:reg_no,
:street, :city, :state, :zip, :country,
:ident_country,
:used?,
:in_use?,
to: :registrant
def initialize(registrant:, view:)

View file

@ -10,7 +10,7 @@ uus aadress: <%= contact.email %>
<br><br>
E-posti aadressile saadetakse domeeni toimingutega seotud infot, sealhulgas kinnitustaotlused omanikuvahetuse ja domeeni kustutamise korral.
<br><br>
<% if contact.used? %>
<% if contact.in_use? %>
Muudatusega seotud domeenid:<br>
<%= contact.domain_names_with_roles(locale: :et, line_break: '<br>') %>
<% end %>
@ -34,7 +34,7 @@ new address: <%= contact.email %>
<br><br>
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.
<br><br>
<% if contact.used? %>
<% if contact.in_use? %>
Domains affected by this update:<br>
<%= contact.domain_names_with_roles(line_break: '<br>') %>
<% end %>

View file

@ -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 %>

View file

@ -1,12 +1,14 @@
<div class="page-header">
<div class="row">
<div class="col-sm-9">
<div class="col-sm-7">
<h1><%= t '.header' %></h1>
</div>
<div class="col-sm-3 text-right">
<div class="col-sm-5 text-right">
<%= link_to t('.new_btn'), new_registrar_domain_path, class: 'btn btn-primary' %>
<%= link_to t('.transfer_btn'), new_registrar_domain_transfer_path, class: 'btn btn-default' %>
<%= link_to t('.replace_nameserver_btn'), registrar_edit_registrar_nameserver_path,
class: 'btn btn-default' %>
</div>
</div>
</div>

View file

@ -0,0 +1,55 @@
<%= form_tag registrar_update_registrar_nameserver_path, method: :put, class: 'form-horizontal' do %>
<div class="form-group">
<div class="col-md-2 control-label">
<%= label_tag :old_hostname %>
</div>
<div class="col-md-5">
<%= text_field_tag :old_hostname, params[:old_hostname], autofocus: true,
required: true,
spellcheck: false,
class: 'form-control' %>
</div>
</div>
<div class="form-group">
<div class="col-md-2 control-label">
<%= label_tag :new_hostname %>
</div>
<div class="col-md-5">
<%= text_field_tag :new_hostname, params[:new_hostname], required: true,
spellcheck: false,
class: 'form-control' %>
</div>
</div>
<div class="form-group">
<div class="col-md-2 control-label">
<%= label_tag :ipv4 %>
</div>
<div class="col-md-3">
<%= text_area_tag :ipv4, params[:ipv4], spellcheck: false, class: 'form-control' %>
</div>
</div>
<div class="form-group">
<div class="col-md-2 control-label">
<%= label_tag :ipv6 %>
</div>
<div class="col-md-3">
<%= text_area_tag :ipv6, params[:ipv6], spellcheck: false, class: 'form-control' %>
<span class="help-block"><%= t '.ip_hint' %></span>
</div>
</div>
<div class="form-group">
<div class="col-md-5 col-md-offset-2 text-right">
<button class="btn btn-warning">
<%= t '.replace_btn' %>
</button>
</div>
</div>
<% end %>

View file

@ -0,0 +1,11 @@
<ol class="breadcrumb">
<li><%= link_to t('registrar.domains.index.header'), registrar_domains_path %></li>
</ol>
<div class="page-header">
<h1><%= t '.header' %></h1>
</div>
<%= render 'registrar/domain_transfers/form/api_errors' %>
<%= render 'form' %>

View file

@ -25,4 +25,4 @@ en:
statuses:
not_uniq: 'not uniq'
country_code:
invalid: Country code is not valid, should be in ISO_3166-1 alpha 2 format
invalid: Country code is not valid, should be in ISO_3166-1 alpha 2 format (%{value})

View file

@ -459,8 +459,6 @@ en:
name: 'Name'
type: 'Type'
code: 'Code'
nameservers: 'Nameservers'
hostname: 'Hostname'
dnskeys: 'DNS Keys'
flag: 'Flag'
protocol: 'Protocol'

View file

@ -0,0 +1,8 @@
en:
activerecord:
errors:
models:
nameserver:
attributes:
base:
ip_required: Either IPv4 or IPv6 is required for glue record generation

View file

@ -8,7 +8,7 @@ en:
create:
header: Domain transfer
transferred: Domains have been successfully transferred
transferred: "%{count} domains have been successfully transferred"
form:
single:

View file

@ -5,6 +5,7 @@ en:
header: Domains
new_btn: New domain
transfer_btn: Transfer
replace_nameserver_btn: Replace nameserver
csv:
domain_name: Domain
transfer_code: Transfer code

View file

@ -0,0 +1,13 @@
en:
registrar:
registrar_nameservers:
edit:
header: Replace nameserver
replace_btn: Replace
form:
ip_hint: One IP per line
replace_btn: Replace nameserver
update:
replaced: Nameserver have been successfully replaced

View file

@ -62,6 +62,8 @@ Rails.application.routes.draw do
end
end
resources :domain_transfers, only: %i[new create]
get 'registrar/nameservers', to: 'registrar_nameservers#edit', as: :edit_registrar_nameserver
put 'registrar/nameservers', to: 'registrar_nameservers#update', as: :update_registrar_nameserver
resources :contacts, constraints: {:id => /[^\/]+(?=#{ ActionController::Renderers::RENDERERS.map{|e| "\\.#{e}\\z"}.join("|") })|[^\/]+/} do
member do

View file

@ -0,0 +1,5 @@
class AddNameserversDomainIdFk < ActiveRecord::Migration
def change
add_foreign_key :nameservers, :domains, name: 'nameservers_domain_id_fk'
end
end

View file

@ -0,0 +1,5 @@
class ChangeNameserversDomainIdToNotNull < ActiveRecord::Migration
def change
change_column_null :nameservers, :domain_id, false
end
end

View file

@ -0,0 +1,5 @@
class ChangeNameserversHostnameToNotNull < ActiveRecord::Migration
def change
change_column_null :nameservers, :hostname, false
end
end

View file

@ -0,0 +1,5 @@
class RemovePeople < ActiveRecord::Migration
def change
drop_table :people
end
end

View file

@ -0,0 +1,5 @@
class RemoveCountries < ActiveRecord::Migration
def change
drop_table :countries
end
end

View file

@ -0,0 +1,5 @@
class RemoveLogCountries < ActiveRecord::Migration
def change
drop_table :log_countries
end
end

View file

@ -0,0 +1,5 @@
class RemoveDataMigrations < ActiveRecord::Migration
def change
drop_table :data_migrations
end
end

View file

@ -0,0 +1,5 @@
class RemoveCachedNameservers < ActiveRecord::Migration
def change
drop_table :cached_nameservers
end
end

View file

@ -0,0 +1,5 @@
class RemoveContactStatuses < ActiveRecord::Migration
def change
drop_table :contact_statuses
end
end

View file

@ -0,0 +1,5 @@
class RemoveLogContactStatuses < ActiveRecord::Migration
def change
drop_table :log_contact_statuses
end
end

View file

@ -0,0 +1,5 @@
class RemoveDomainStatuses < ActiveRecord::Migration
def change
drop_table :domain_statuses
end
end

View file

@ -0,0 +1,5 @@
class RemoveLogDomainStatuses < ActiveRecord::Migration
def change
drop_table :log_domain_statuses
end
end

View file

@ -554,17 +554,6 @@ CREATE SEQUENCE business_registry_caches_id_seq
ALTER SEQUENCE business_registry_caches_id_seq OWNED BY business_registry_caches.id;
--
-- Name: cached_nameservers; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE cached_nameservers (
hostname character varying(255),
ipv4 character varying(255),
ipv6 character varying(255)
);
--
-- Name: certificates; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@ -603,41 +592,6 @@ CREATE SEQUENCE certificates_id_seq
ALTER SEQUENCE certificates_id_seq OWNED BY certificates.id;
--
-- Name: contact_statuses; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE contact_statuses (
id integer NOT NULL,
value character varying,
description character varying,
contact_id integer,
created_at timestamp without time zone,
updated_at timestamp without time zone,
creator_str character varying,
updator_str character varying
);
--
-- Name: contact_statuses_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE contact_statuses_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: contact_statuses_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE contact_statuses_id_seq OWNED BY contact_statuses.id;
--
-- Name: contacts; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@ -694,49 +648,6 @@ CREATE SEQUENCE contacts_id_seq
ALTER SEQUENCE contacts_id_seq OWNED BY contacts.id;
--
-- Name: countries; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE countries (
id integer NOT NULL,
iso character varying,
name character varying,
created_at timestamp without time zone,
updated_at timestamp without time zone,
creator_str character varying,
updator_str character varying
);
--
-- Name: countries_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE countries_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: countries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE countries_id_seq OWNED BY countries.id;
--
-- Name: data_migrations; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE data_migrations (
version character varying NOT NULL
);
--
-- Name: delegation_signers; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@ -914,40 +825,6 @@ CREATE SEQUENCE domain_contacts_id_seq
ALTER SEQUENCE domain_contacts_id_seq OWNED BY domain_contacts.id;
--
-- Name: domain_statuses; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE domain_statuses (
id integer NOT NULL,
domain_id integer,
description character varying,
value character varying,
creator_str character varying,
updator_str character varying,
legacy_domain_id integer
);
--
-- Name: domain_statuses_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE domain_statuses_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: domain_statuses_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE domain_statuses_id_seq OWNED BY domain_statuses.id;
--
-- Name: domain_transfers; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@ -1490,44 +1367,6 @@ CREATE SEQUENCE log_certificates_id_seq
ALTER SEQUENCE log_certificates_id_seq OWNED BY log_certificates.id;
--
-- Name: log_contact_statuses; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE log_contact_statuses (
id integer NOT NULL,
item_type character varying NOT NULL,
item_id integer NOT NULL,
event character varying NOT NULL,
whodunnit character varying,
object json,
object_changes json,
created_at timestamp without time zone,
session character varying,
children json,
uuid character varying
);
--
-- Name: log_contact_statuses_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE log_contact_statuses_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: log_contact_statuses_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE log_contact_statuses_id_seq OWNED BY log_contact_statuses.id;
--
-- Name: log_contacts; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@ -1567,44 +1406,6 @@ CREATE SEQUENCE log_contacts_id_seq
ALTER SEQUENCE log_contacts_id_seq OWNED BY log_contacts.id;
--
-- Name: log_countries; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE log_countries (
id integer NOT NULL,
item_type character varying NOT NULL,
item_id integer NOT NULL,
event character varying NOT NULL,
whodunnit character varying,
object json,
object_changes json,
created_at timestamp without time zone,
session character varying,
children json,
uuid character varying
);
--
-- Name: log_countries_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE log_countries_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: log_countries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE log_countries_id_seq OWNED BY log_countries.id;
--
-- Name: log_dnskeys; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@ -1681,44 +1482,6 @@ CREATE SEQUENCE log_domain_contacts_id_seq
ALTER SEQUENCE log_domain_contacts_id_seq OWNED BY log_domain_contacts.id;
--
-- Name: log_domain_statuses; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE log_domain_statuses (
id integer NOT NULL,
item_type character varying NOT NULL,
item_id integer NOT NULL,
event character varying NOT NULL,
whodunnit character varying,
object json,
object_changes json,
created_at timestamp without time zone,
session character varying,
children json,
uuid character varying
);
--
-- Name: log_domain_statuses_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE log_domain_statuses_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: log_domain_statuses_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE log_domain_statuses_id_seq OWNED BY log_domain_statuses.id;
--
-- Name: log_domains; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@ -2220,12 +1983,12 @@ ALTER SEQUENCE messages_id_seq OWNED BY messages.id;
CREATE TABLE nameservers (
id integer NOT NULL,
hostname character varying,
hostname character varying NOT NULL,
ipv4 character varying[] DEFAULT '{}'::character varying[],
created_at timestamp without time zone,
updated_at timestamp without time zone,
ipv6 character varying[] DEFAULT '{}'::character varying[],
domain_id integer,
domain_id integer NOT NULL,
creator_str character varying,
updator_str character varying,
legacy_domain_id integer,
@ -2252,46 +2015,6 @@ CREATE SEQUENCE nameservers_id_seq
ALTER SEQUENCE nameservers_id_seq OWNED BY nameservers.id;
--
-- Name: people; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE people (
id integer NOT NULL,
email character varying DEFAULT ''::character varying NOT NULL,
encrypted_password character varying DEFAULT ''::character varying NOT NULL,
reset_password_token character varying,
reset_password_sent_at timestamp without time zone,
remember_created_at timestamp without time zone,
sign_in_count integer DEFAULT 0 NOT NULL,
current_sign_in_at timestamp without time zone,
last_sign_in_at timestamp without time zone,
current_sign_in_ip inet,
last_sign_in_ip inet,
created_at timestamp without time zone,
updated_at timestamp without time zone
);
--
-- Name: people_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE people_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: people_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE people_id_seq OWNED BY people.id;
--
-- Name: prices; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@ -2792,13 +2515,6 @@ ALTER TABLE ONLY business_registry_caches ALTER COLUMN id SET DEFAULT nextval('b
ALTER TABLE ONLY certificates ALTER COLUMN id SET DEFAULT nextval('certificates_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY contact_statuses ALTER COLUMN id SET DEFAULT nextval('contact_statuses_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@ -2806,13 +2522,6 @@ ALTER TABLE ONLY contact_statuses ALTER COLUMN id SET DEFAULT nextval('contact_s
ALTER TABLE ONLY contacts ALTER COLUMN id SET DEFAULT nextval('contacts_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY countries ALTER COLUMN id SET DEFAULT nextval('countries_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@ -2848,13 +2557,6 @@ ALTER TABLE ONLY dnskeys ALTER COLUMN id SET DEFAULT nextval('dnskeys_id_seq'::r
ALTER TABLE ONLY domain_contacts ALTER COLUMN id SET DEFAULT nextval('domain_contacts_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY domain_statuses ALTER COLUMN id SET DEFAULT nextval('domain_statuses_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@ -2946,13 +2648,6 @@ ALTER TABLE ONLY log_blocked_domains ALTER COLUMN id SET DEFAULT nextval('log_bl
ALTER TABLE ONLY log_certificates ALTER COLUMN id SET DEFAULT nextval('log_certificates_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY log_contact_statuses ALTER COLUMN id SET DEFAULT nextval('log_contact_statuses_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@ -2960,13 +2655,6 @@ ALTER TABLE ONLY log_contact_statuses ALTER COLUMN id SET DEFAULT nextval('log_c
ALTER TABLE ONLY log_contacts ALTER COLUMN id SET DEFAULT nextval('log_contacts_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY log_countries ALTER COLUMN id SET DEFAULT nextval('log_countries_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@ -2981,13 +2669,6 @@ ALTER TABLE ONLY log_dnskeys ALTER COLUMN id SET DEFAULT nextval('log_dnskeys_id
ALTER TABLE ONLY log_domain_contacts ALTER COLUMN id SET DEFAULT nextval('log_domain_contacts_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY log_domain_statuses ALTER COLUMN id SET DEFAULT nextval('log_domain_statuses_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@ -3086,13 +2767,6 @@ ALTER TABLE ONLY messages ALTER COLUMN id SET DEFAULT nextval('messages_id_seq':
ALTER TABLE ONLY nameservers ALTER COLUMN id SET DEFAULT nextval('nameservers_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY people ALTER COLUMN id SET DEFAULT nextval('people_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@ -3234,14 +2908,6 @@ ALTER TABLE ONLY certificates
ADD CONSTRAINT certificates_pkey PRIMARY KEY (id);
--
-- Name: contact_statuses_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY contact_statuses
ADD CONSTRAINT contact_statuses_pkey PRIMARY KEY (id);
--
-- Name: contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@ -3250,14 +2916,6 @@ ALTER TABLE ONLY contacts
ADD CONSTRAINT contacts_pkey PRIMARY KEY (id);
--
-- Name: countries_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY countries
ADD CONSTRAINT countries_pkey PRIMARY KEY (id);
--
-- Name: delegation_signers_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@ -3298,14 +2956,6 @@ ALTER TABLE ONLY domain_contacts
ADD CONSTRAINT domain_contacts_pkey PRIMARY KEY (id);
--
-- Name: domain_statuses_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY domain_statuses
ADD CONSTRAINT domain_statuses_pkey PRIMARY KEY (id);
--
-- Name: domain_transfers_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@ -3410,14 +3060,6 @@ ALTER TABLE ONLY log_certificates
ADD CONSTRAINT log_certificates_pkey PRIMARY KEY (id);
--
-- Name: log_contact_statuses_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY log_contact_statuses
ADD CONSTRAINT log_contact_statuses_pkey PRIMARY KEY (id);
--
-- Name: log_contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@ -3426,14 +3068,6 @@ ALTER TABLE ONLY log_contacts
ADD CONSTRAINT log_contacts_pkey PRIMARY KEY (id);
--
-- Name: log_countries_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY log_countries
ADD CONSTRAINT log_countries_pkey PRIMARY KEY (id);
--
-- Name: log_dnskeys_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@ -3450,14 +3084,6 @@ ALTER TABLE ONLY log_domain_contacts
ADD CONSTRAINT log_domain_contacts_pkey PRIMARY KEY (id);
--
-- Name: log_domain_statuses_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY log_domain_statuses
ADD CONSTRAINT log_domain_statuses_pkey PRIMARY KEY (id);
--
-- Name: log_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@ -3570,14 +3196,6 @@ ALTER TABLE ONLY nameservers
ADD CONSTRAINT nameservers_pkey PRIMARY KEY (id);
--
-- Name: people_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY people
ADD CONSTRAINT people_pkey PRIMARY KEY (id);
--
-- Name: prices_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@ -3732,13 +3350,6 @@ CREATE INDEX index_blocked_domains_on_name ON blocked_domains USING btree (name)
CREATE INDEX index_business_registry_caches_on_ident ON business_registry_caches USING btree (ident);
--
-- Name: index_cached_nameservers_on_hostname_and_ipv4_and_ipv6; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE UNIQUE INDEX index_cached_nameservers_on_hostname_and_ipv4_and_ipv6 ON cached_nameservers USING btree (hostname, ipv4, ipv6);
--
-- Name: index_certificates_on_api_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@ -3746,13 +3357,6 @@ CREATE UNIQUE INDEX index_cached_nameservers_on_hostname_and_ipv4_and_ipv6 ON ca
CREATE INDEX index_certificates_on_api_user_id ON certificates USING btree (api_user_id);
--
-- Name: index_contact_statuses_on_contact_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_contact_statuses_on_contact_id ON contact_statuses USING btree (contact_id);
--
-- Name: index_contacts_on_code; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@ -3823,13 +3427,6 @@ CREATE INDEX index_domain_contacts_on_contact_id ON domain_contacts USING btree
CREATE INDEX index_domain_contacts_on_domain_id ON domain_contacts USING btree (domain_id);
--
-- Name: index_domain_statuses_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_domain_statuses_on_domain_id ON domain_statuses USING btree (domain_id);
--
-- Name: index_domain_transfers_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@ -4040,20 +3637,6 @@ CREATE INDEX index_log_certificates_on_item_type_and_item_id ON log_certificates
CREATE INDEX index_log_certificates_on_whodunnit ON log_certificates USING btree (whodunnit);
--
-- Name: index_log_contact_statuses_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_log_contact_statuses_on_item_type_and_item_id ON log_contact_statuses USING btree (item_type, item_id);
--
-- Name: index_log_contact_statuses_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_log_contact_statuses_on_whodunnit ON log_contact_statuses USING btree (whodunnit);
--
-- Name: index_log_contacts_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@ -4068,20 +3651,6 @@ CREATE INDEX index_log_contacts_on_item_type_and_item_id ON log_contacts USING b
CREATE INDEX index_log_contacts_on_whodunnit ON log_contacts USING btree (whodunnit);
--
-- Name: index_log_countries_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_log_countries_on_item_type_and_item_id ON log_countries USING btree (item_type, item_id);
--
-- Name: index_log_countries_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_log_countries_on_whodunnit ON log_countries USING btree (whodunnit);
--
-- Name: index_log_dnskeys_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@ -4110,20 +3679,6 @@ CREATE INDEX index_log_domain_contacts_on_item_type_and_item_id ON log_domain_co
CREATE INDEX index_log_domain_contacts_on_whodunnit ON log_domain_contacts USING btree (whodunnit);
--
-- Name: index_log_domain_statuses_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_log_domain_statuses_on_item_type_and_item_id ON log_domain_statuses USING btree (item_type, item_id);
--
-- Name: index_log_domain_statuses_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_log_domain_statuses_on_whodunnit ON log_domain_statuses USING btree (whodunnit);
--
-- Name: index_log_domains_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@ -4278,20 +3833,6 @@ CREATE INDEX index_messages_on_registrar_id ON messages USING btree (registrar_i
CREATE INDEX index_nameservers_on_domain_id ON nameservers USING btree (domain_id);
--
-- Name: index_people_on_email; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE UNIQUE INDEX index_people_on_email ON people USING btree (email);
--
-- Name: index_people_on_reset_password_token; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE UNIQUE INDEX index_people_on_reset_password_token ON people USING btree (reset_password_token);
--
-- Name: index_prices_on_zone_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@ -4390,13 +3931,6 @@ CREATE INDEX log_domains_object_legacy_id ON log_contacts USING btree ((((object
CREATE INDEX log_nameservers_object_legacy_id ON log_contacts USING btree ((((object ->> 'legacy_domain_id'::text))::integer));
--
-- Name: unique_data_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE UNIQUE INDEX unique_data_migrations ON data_migrations USING btree (version);
--
-- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@ -4532,6 +4066,14 @@ ALTER TABLE ONLY messages
ADD CONSTRAINT messages_registrar_id_fk FOREIGN KEY (registrar_id) REFERENCES registrars(id);
--
-- Name: nameservers_domain_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY nameservers
ADD CONSTRAINT nameservers_domain_id_fk FOREIGN KEY (domain_id) REFERENCES domains(id);
--
-- Name: user_registrar_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -5086,6 +4628,12 @@ INSERT INTO schema_migrations (version) VALUES ('20180126104536');
INSERT INTO schema_migrations (version) VALUES ('20180126104903');
INSERT INTO schema_migrations (version) VALUES ('20180129143538');
INSERT INTO schema_migrations (version) VALUES ('20180129232054');
INSERT INTO schema_migrations (version) VALUES ('20180129233223');
INSERT INTO schema_migrations (version) VALUES ('20180206213435');
INSERT INTO schema_migrations (version) VALUES ('20180206234620');
@ -5124,3 +4672,21 @@ INSERT INTO schema_migrations (version) VALUES ('20180228074442');
INSERT INTO schema_migrations (version) VALUES ('20180228084818');
INSERT INTO schema_migrations (version) VALUES ('20180306180401');
INSERT INTO schema_migrations (version) VALUES ('20180306181538');
INSERT INTO schema_migrations (version) VALUES ('20180306181554');
INSERT INTO schema_migrations (version) VALUES ('20180306181911');
INSERT INTO schema_migrations (version) VALUES ('20180306182456');
INSERT INTO schema_migrations (version) VALUES ('20180306182758');
INSERT INTO schema_migrations (version) VALUES ('20180306182941');
INSERT INTO schema_migrations (version) VALUES ('20180306183540');
INSERT INTO schema_migrations (version) VALUES ('20180306183549');

View file

@ -22,7 +22,7 @@ Domain name mapping protocol short version:
<domain:ns> 0-1
<domain:hostAttr> 2-11
<domain:hostName> 1 Hostname of the nameserver
<domain:hostAddr> 0-2 Required if nameserver is under domain zone.
<domain:hostAddr> 0-2 Required if nameserver hostname is under the same domain.
Attribute ip="v4 / v6"
<domain:registrant> 1 Contact reference to the registrant
<domain:contact> 0-n Contact reference. Admin contact is required if registrant is
@ -62,7 +62,7 @@ Domain name mapping protocol short version:
<domain:ns> 0-1
<domain:hostAttr> 1
<domain:hostName> 1 Hostname of the nameserver
<domain:hostAddr> 0-2 Required if nameserver is under domain zone.
<domain:hostAddr> 0-2 Required if nameserver hostname is under the same domain.
Attribute ip="v4 / v6"
<domain:rem> 0-1 Objects to remove
<domain:contact> 0-n Contact reference. Attribute: type="admin / tech"

View file

@ -83,28 +83,6 @@
<ellipse fill="none" stroke="#c5d409" cx="1215.62" cy="-123.741" rx="4.00002" ry="4.00002"/>
<polygon fill="#c5d409" stroke="#c5d409" points="1481.6,-23.3416 1491.87,-27.1865 1486.59,-23.0187 1491.58,-22.6959 1491.58,-22.6959 1491.58,-22.6959 1486.59,-23.0187 1491.29,-18.2053 1481.6,-23.3416 1481.6,-23.3416"/>
</g>
<!-- DomainStatusVersion -->
<g id="node7" class="node"><title>DomainStatusVersion</title>
<ellipse fill="none" stroke="black" cx="1924.99" cy="-145" rx="89.0842" ry="18"/>
<text text-anchor="middle" x="1924.99" y="-141.3" font-family="Times,serif" font-size="14.00">DomainStatusVersion</text>
</g>
<!-- DomainStatusVersion&#45;&gt;VersionAssociation -->
<g id="edge5" class="edge"><title>DomainStatusVersion&#45;&gt;VersionAssociation</title>
<path fill="none" stroke="#737845" d="M1899.78,-122.13C1880.11,-106.198 1851.45,-85.3285 1822.99,-73 1767.83,-49.1018 1701.21,-35.4483 1650.04,-27.8511"/>
<ellipse fill="none" stroke="#737845" cx="1903" cy="-124.782" rx="4.00002" ry="4.00002"/>
<polygon fill="#737845" stroke="#737845" points="1649.92,-27.8338 1640.66,-21.957 1644.97,-27.1225 1640.02,-26.4112 1640.02,-26.4112 1640.02,-26.4112 1644.97,-27.1225 1639.38,-30.8654 1649.92,-27.8338 1649.92,-27.8338"/>
</g>
<!-- ContactStatusVersion -->
<g id="node8" class="node"><title>ContactStatusVersion</title>
<ellipse fill="none" stroke="black" cx="2358.99" cy="-91" rx="87.1846" ry="18"/>
<text text-anchor="middle" x="2358.99" y="-87.3" font-family="Times,serif" font-size="14.00">ContactStatusVersion</text>
</g>
<!-- ContactStatusVersion&#45;&gt;VersionAssociation -->
<g id="edge6" class="edge"><title>ContactStatusVersion&#45;&gt;VersionAssociation</title>
<path fill="none" stroke="#bd1fad" d="M2315.43,-71.3361C2297.91,-64.6623 2277.31,-57.8466 2257.99,-54 2146,-31.6962 1818.56,-23.2001 1658.78,-20.3167"/>
<ellipse fill="none" stroke="#bd1fad" cx="2319.53" cy="-72.9297" rx="4.00001" ry="4.00001"/>
<polygon fill="#bd1fad" stroke="#bd1fad" points="1658.5,-20.3119 1648.58,-15.6355 1653.5,-20.2234 1648.5,-20.1348 1648.5,-20.1348 1648.5,-20.1348 1653.5,-20.2234 1648.42,-24.6341 1658.5,-20.3119 1658.5,-20.3119"/>
</g>
<!-- UserVersion&#45;&gt;VersionAssociation -->
<g id="edge7" class="edge"><title>UserVersion&#45;&gt;VersionAssociation</title>
<path fill="none" stroke="#81300d" d="M877.642,-295.337C892.405,-290.14 907.215,-282.43 917.994,-271 987.069,-197.756 904.062,-116.497 982.994,-54 1020.85,-24.0245 1323.82,-19.2493 1478.62,-18.7906"/>
@ -238,17 +216,6 @@
<ellipse fill="none" stroke="#cbb588" cx="2689.49" cy="-190.759" rx="4.00001" ry="4.00001"/>
<polygon fill="#cbb588" stroke="#cbb588" points="1654.04,-25.0657 1644.39,-19.8555 1649.06,-24.7047 1644.07,-24.3437 1644.07,-24.3437 1644.07,-24.3437 1649.06,-24.7047 1643.75,-28.832 1654.04,-25.0657 1654.04,-25.0657"/>
</g>
<!-- CountryVersion -->
<g id="node24" class="node"><title>CountryVersion</title>
<ellipse fill="none" stroke="black" cx="3413.99" cy="-91" rx="67.6881" ry="18"/>
<text text-anchor="middle" x="3413.99" y="-87.3" font-family="Times,serif" font-size="14.00">CountryVersion</text>
</g>
<!-- CountryVersion&#45;&gt;VersionAssociation -->
<g id="edge22" class="edge"><title>CountryVersion&#45;&gt;VersionAssociation</title>
<path fill="none" stroke="#b69a48" d="M3358.71,-76.3835C3351.77,-75.0437 3344.74,-73.8632 3337.99,-73 3094.5,-41.8509 3031.35,-61.7507 2785.99,-54 2363.93,-40.6673 1859.47,-26.8291 1658.24,-21.3938"/>
<ellipse fill="none" stroke="#b69a48" cx="3362.88" cy="-77.2265" rx="4.00001" ry="4.00001"/>
<polygon fill="#b69a48" stroke="#b69a48" points="1658.02,-21.3879 1648.14,-16.6196 1653.02,-21.2529 1648.02,-21.1179 1648.02,-21.1179 1648.02,-21.1179 1653.02,-21.2529 1647.9,-25.6163 1658.02,-21.3879 1658.02,-21.3879"/>
</g>
<!-- BankTransactionVersion -->
<g id="node26" class="node"><title>BankTransactionVersion</title>
<ellipse fill="none" stroke="black" cx="590.994" cy="-145" rx="98.5829" ry="18"/>
@ -1131,13 +1098,6 @@
<polygon fill="#21f8a2" stroke="#21f8a2" points="795.532,-330.958 805.846,-327.236 799.124,-327.481 802.717,-324.003 802.717,-324.003 802.717,-324.003 799.124,-327.481 799.587,-320.77 795.532,-330.958 795.532,-330.958"/>
<text text-anchor="middle" x="807.994" y="-357.3" font-family="Times,serif" font-size="14.00">versions</text>
</g>
<!-- ContactStatus&#45;&gt;ContactStatusVersion -->
<g id="edge73" class="edge"><title>ContactStatus&#45;&gt;ContactStatusVersion</title>
<path fill="none" stroke="#32889b" d="M2845.18,-184.569C2839.41,-183.259 2833.59,-182.035 2827.99,-181 2762.84,-168.941 2745.31,-174.168 2679.99,-163 2589.61,-147.545 2486.25,-123.526 2421.79,-107.778"/>
<ellipse fill="none" stroke="#32889b" cx="2849.11" cy="-185.487" rx="4.00001" ry="4.00001"/>
<polygon fill="#32889b" stroke="#32889b" points="2421.5,-107.707 2412.86,-100.954 2416.65,-106.516 2411.79,-105.325 2411.79,-105.325 2411.79,-105.325 2416.65,-106.516 2410.72,-109.695 2421.5,-107.707 2421.5,-107.707"/>
<text text-anchor="middle" x="2702.99" y="-141.3" font-family="Times,serif" font-size="14.00">versions</text>
</g>
<!-- RegistrantVerification -->
<g id="node48" class="node"><title>RegistrantVerification</title>
<ellipse fill="none" stroke="black" cx="4032.99" cy="-523" rx="89.0842" ry="18"/>
@ -1274,13 +1234,6 @@
<polygon fill="#77d44a" stroke="#77d44a" points="1705.57,-117.865 1714.17,-111.061 1707.88,-113.427 1710.18,-108.988 1710.18,-108.988 1710.18,-108.988 1707.88,-113.427 1706.19,-106.916 1705.57,-117.865 1705.57,-117.865"/>
<text text-anchor="middle" x="1721.99" y="-141.3" font-family="Times,serif" font-size="14.00">versions</text>
</g>
<!-- DomainStatus&#45;&gt;DomainStatusVersion -->
<g id="edge139" class="edge"><title>DomainStatus&#45;&gt;DomainStatusVersion</title>
<path fill="none" stroke="#83d992" d="M2116.06,-289.993C2103.04,-284.692 2089.13,-278.263 2076.99,-271 2027.96,-241.645 1978.11,-197.284 1949.44,-170.059"/>
<ellipse fill="none" stroke="#83d992" cx="2119.88" cy="-291.508" rx="4.00001" ry="4.00001"/>
<polygon fill="#83d992" stroke="#83d992" points="1949.16,-169.784 1945.05,-159.614 1945.55,-166.323 1941.94,-162.862 1941.94,-162.862 1941.94,-162.862 1945.55,-166.323 1938.82,-166.11 1949.16,-169.784 1949.16,-169.784"/>
<text text-anchor="middle" x="2099.99" y="-249.3" font-family="Times,serif" font-size="14.00">versions</text>
</g>
<!-- Registrant -->
<g id="node64" class="node"><title>Registrant</title>
<ellipse fill="none" stroke="black" cx="3805.99" cy="-523" rx="46.5926" ry="18"/>

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Before After
Before After

View file

@ -170,50 +170,6 @@
<ellipse fill="none" stroke="#ca4159" cx="1303.92" cy="-269.31" rx="4" ry="4"/>
<polygon fill="#ca4159" stroke="#ca4159" points="1668.38,-21.9528 1678.55,-26.0458 1673.37,-21.7511 1678.37,-21.5494 1678.37,-21.5494 1678.37,-21.5494 1673.37,-21.7511 1678.19,-17.0531 1668.38,-21.9528 1668.38,-21.9528"/>
</g>
<!-- DomainStatusVersion -->
<g id="node7" class="node"><title>DomainStatusVersion</title>
<path fill="none" stroke="black" d="M2133.5,-273.5C2133.5,-273.5 2246.5,-273.5 2246.5,-273.5 2252.5,-273.5 2258.5,-279.5 2258.5,-285.5 2258.5,-285.5 2258.5,-442.5 2258.5,-442.5 2258.5,-448.5 2252.5,-454.5 2246.5,-454.5 2246.5,-454.5 2133.5,-454.5 2133.5,-454.5 2127.5,-454.5 2121.5,-448.5 2121.5,-442.5 2121.5,-442.5 2121.5,-285.5 2121.5,-285.5 2121.5,-279.5 2127.5,-273.5 2133.5,-273.5"/>
<text text-anchor="middle" x="2190" y="-439.3" font-family="Times,serif" font-size="14.00">DomainStatusVersion</text>
<polyline fill="none" stroke="black" points="2121.5,-431.5 2258.5,-431.5 "/>
<text text-anchor="start" x="2129.5" y="-416.3" font-family="Times,serif" font-size="14.00">id :integer</text>
<text text-anchor="start" x="2129.5" y="-401.3" font-family="Times,serif" font-size="14.00">item_type :string</text>
<text text-anchor="start" x="2129.5" y="-386.3" font-family="Times,serif" font-size="14.00">item_id :integer</text>
<text text-anchor="start" x="2129.5" y="-371.3" font-family="Times,serif" font-size="14.00">event :string</text>
<text text-anchor="start" x="2129.5" y="-356.3" font-family="Times,serif" font-size="14.00">whodunnit :string</text>
<text text-anchor="start" x="2129.5" y="-341.3" font-family="Times,serif" font-size="14.00">object :json</text>
<text text-anchor="start" x="2129.5" y="-326.3" font-family="Times,serif" font-size="14.00">object_changes :json</text>
<text text-anchor="start" x="2129.5" y="-311.3" font-family="Times,serif" font-size="14.00">created_at :datetime</text>
<text text-anchor="start" x="2129.5" y="-296.3" font-family="Times,serif" font-size="14.00">session :string</text>
<text text-anchor="start" x="2129.5" y="-281.3" font-family="Times,serif" font-size="14.00">children :json</text>
</g>
<!-- DomainStatusVersion&#45;&gt;VersionAssociation -->
<g id="edge5" class="edge"><title>DomainStatusVersion&#45;&gt;VersionAssociation</title>
<path fill="none" stroke="#32384d" d="M2166.85,-265.638C2146.39,-201.12 2109.89,-119.994 2048,-73 2016.1,-48.7746 1915.11,-34.0274 1841.03,-26.1991"/>
<ellipse fill="none" stroke="#32384d" cx="2168.08" cy="-269.6" rx="4.00001" ry="4.00001"/>
<polygon fill="#32384d" stroke="#32384d" points="1840.71,-26.1664 1831.22,-20.6639 1835.74,-25.6532 1830.76,-25.1401 1830.76,-25.1401 1830.76,-25.1401 1835.74,-25.6532 1830.3,-29.6164 1840.71,-26.1664 1840.71,-26.1664"/>
</g>
<!-- ContactStatusVersion -->
<g id="node8" class="node"><title>ContactStatusVersion</title>
<path fill="none" stroke="black" d="M2518,-73.5C2518,-73.5 2628,-73.5 2628,-73.5 2634,-73.5 2640,-79.5 2640,-85.5 2640,-85.5 2640,-242.5 2640,-242.5 2640,-248.5 2634,-254.5 2628,-254.5 2628,-254.5 2518,-254.5 2518,-254.5 2512,-254.5 2506,-248.5 2506,-242.5 2506,-242.5 2506,-85.5 2506,-85.5 2506,-79.5 2512,-73.5 2518,-73.5"/>
<text text-anchor="middle" x="2573" y="-239.3" font-family="Times,serif" font-size="14.00">ContactStatusVersion</text>
<polyline fill="none" stroke="black" points="2506,-231.5 2640,-231.5 "/>
<text text-anchor="start" x="2514" y="-216.3" font-family="Times,serif" font-size="14.00">id :integer</text>
<text text-anchor="start" x="2514" y="-201.3" font-family="Times,serif" font-size="14.00">item_type :string</text>
<text text-anchor="start" x="2514" y="-186.3" font-family="Times,serif" font-size="14.00">item_id :integer</text>
<text text-anchor="start" x="2514" y="-171.3" font-family="Times,serif" font-size="14.00">event :string</text>
<text text-anchor="start" x="2514" y="-156.3" font-family="Times,serif" font-size="14.00">whodunnit :string</text>
<text text-anchor="start" x="2514" y="-141.3" font-family="Times,serif" font-size="14.00">object :json</text>
<text text-anchor="start" x="2514" y="-126.3" font-family="Times,serif" font-size="14.00">object_changes :json</text>
<text text-anchor="start" x="2514" y="-111.3" font-family="Times,serif" font-size="14.00">created_at :datetime</text>
<text text-anchor="start" x="2514" y="-96.3" font-family="Times,serif" font-size="14.00">session :string</text>
<text text-anchor="start" x="2514" y="-81.3" font-family="Times,serif" font-size="14.00">children :json</text>
</g>
<!-- ContactStatusVersion&#45;&gt;VersionAssociation -->
<g id="edge6" class="edge"><title>ContactStatusVersion&#45;&gt;VersionAssociation</title>
<path fill="none" stroke="#f74e61" d="M2511.93,-67.8212C2505.75,-62.4959 2499.1,-57.7839 2492,-54 2436.47,-24.4057 2031.05,-19.6332 1847.21,-19.0048"/>
<ellipse fill="none" stroke="#f74e61" cx="2515.02" cy="-70.6401" rx="4.00002" ry="4.00002"/>
<polygon fill="#f74e61" stroke="#f74e61" points="1847.02,-19.0044 1837.04,-14.4735 1842.02,-18.9889 1837.02,-18.9735 1837.02,-18.9735 1837.02,-18.9735 1842.02,-18.9889 1837.01,-23.4735 1847.02,-19.0044 1847.02,-19.0044"/>
</g>
<!-- UserVersion&#45;&gt;VersionAssociation -->
<g id="edge7" class="edge"><title>UserVersion&#45;&gt;VersionAssociation</title>
<path fill="none" stroke="#625c68" d="M936.508,-1172.61C943.887,-1101.26 953.553,-1002.22 960,-915 963.531,-867.232 971.034,-87.7726 1005,-54 1028.13,-30.9991 1472.68,-22.5857 1667.18,-19.997"/>
@ -468,28 +424,6 @@
<ellipse fill="none" stroke="#19ba78" cx="2999.97" cy="-500.986" rx="4.00002" ry="4.00002"/>
<polygon fill="#19ba78" stroke="#19ba78" points="1846.61,-19.8234 1836.68,-15.1884 1841.62,-19.7557 1836.62,-19.688 1836.62,-19.688 1836.62,-19.688 1841.62,-19.7557 1836.55,-24.1876 1846.61,-19.8234 1846.61,-19.8234"/>
</g>
<!-- CountryVersion -->
<g id="node24" class="node"><title>CountryVersion</title>
<path fill="none" stroke="black" d="M3454,-73.5C3454,-73.5 3560,-73.5 3560,-73.5 3566,-73.5 3572,-79.5 3572,-85.5 3572,-85.5 3572,-242.5 3572,-242.5 3572,-248.5 3566,-254.5 3560,-254.5 3560,-254.5 3454,-254.5 3454,-254.5 3448,-254.5 3442,-248.5 3442,-242.5 3442,-242.5 3442,-85.5 3442,-85.5 3442,-79.5 3448,-73.5 3454,-73.5"/>
<text text-anchor="middle" x="3507" y="-239.3" font-family="Times,serif" font-size="14.00">CountryVersion</text>
<polyline fill="none" stroke="black" points="3442,-231.5 3572,-231.5 "/>
<text text-anchor="start" x="3450" y="-216.3" font-family="Times,serif" font-size="14.00">id :integer</text>
<text text-anchor="start" x="3450" y="-201.3" font-family="Times,serif" font-size="14.00">item_type :string</text>
<text text-anchor="start" x="3450" y="-186.3" font-family="Times,serif" font-size="14.00">item_id :integer</text>
<text text-anchor="start" x="3450" y="-171.3" font-family="Times,serif" font-size="14.00">event :string</text>
<text text-anchor="start" x="3450" y="-156.3" font-family="Times,serif" font-size="14.00">whodunnit :string</text>
<text text-anchor="start" x="3450" y="-141.3" font-family="Times,serif" font-size="14.00">object :json</text>
<text text-anchor="start" x="3450" y="-126.3" font-family="Times,serif" font-size="14.00">object_changes :json</text>
<text text-anchor="start" x="3450" y="-111.3" font-family="Times,serif" font-size="14.00">created_at :datetime</text>
<text text-anchor="start" x="3450" y="-96.3" font-family="Times,serif" font-size="14.00">session :string</text>
<text text-anchor="start" x="3450" y="-81.3" font-family="Times,serif" font-size="14.00">children :json</text>
</g>
<!-- CountryVersion&#45;&gt;VersionAssociation -->
<g id="edge22" class="edge"><title>CountryVersion&#45;&gt;VersionAssociation</title>
<path fill="none" stroke="#766dfb" d="M3435.01,-74.0295C3434.34,-73.6773 3433.67,-73.334 3433,-73 3230.95,27.1176 3151.36,-61.5964 2926,-54 2523.04,-40.4174 2041.86,-26.8478 1846.26,-21.4432"/>
<ellipse fill="none" stroke="#766dfb" cx="3438.54" cy="-76.1046" rx="4.00002" ry="4.00002"/>
<polygon fill="#766dfb" stroke="#766dfb" points="1846.03,-21.437 1836.16,-16.6626 1841.03,-21.299 1836.03,-21.1609 1836.03,-21.1609 1836.03,-21.1609 1841.03,-21.299 1835.91,-25.6592 1846.03,-21.437 1846.03,-21.437"/>
</g>
<!-- BankTransactionVersion -->
<g id="node26" class="node"><title>BankTransactionVersion</title>
<path fill="none" stroke="black" d="M614,-273.5C614,-273.5 742,-273.5 742,-273.5 748,-273.5 754,-279.5 754,-285.5 754,-285.5 754,-442.5 754,-442.5 754,-448.5 748,-454.5 742,-454.5 742,-454.5 614,-454.5 614,-454.5 608,-454.5 602,-448.5 602,-442.5 602,-442.5 602,-285.5 602,-285.5 602,-279.5 608,-273.5 614,-273.5"/>
@ -1825,13 +1759,6 @@
<polygon fill="#1a881f" stroke="#1a881f" points="919.662,-1372.29 924.748,-1362.58 919.959,-1367.3 920.256,-1362.31 920.256,-1362.31 920.256,-1362.31 919.959,-1367.3 915.764,-1362.04 919.662,-1372.29 919.662,-1372.29"/>
<text text-anchor="middle" x="931" y="-1707.8" font-family="Times,serif" font-size="14.00">versions</text>
</g>
<!-- ContactStatus&#45;&gt;ContactStatusVersion -->
<g id="edge73" class="edge"><title>ContactStatus&#45;&gt;ContactStatusVersion</title>
<path fill="none" stroke="#381ba0" d="M3180.66,-511.338C3170.31,-496.263 3157.51,-482.349 3142,-473 3094.87,-444.588 2946.14,-475.346 2895,-455 2794.71,-415.096 2705.7,-328.835 2646.82,-260.709"/>
<ellipse fill="none" stroke="#381ba0" cx="3183.06" cy="-514.989" rx="4.00002" ry="4.00002"/>
<polygon fill="#381ba0" stroke="#381ba0" points="2646.65,-260.513 2643.57,-249.99 2643.4,-256.715 2640.15,-252.917 2640.15,-252.917 2640.15,-252.917 2643.4,-256.715 2636.73,-255.844 2646.65,-260.513 2646.65,-260.513"/>
<text text-anchor="middle" x="2918" y="-360.3" font-family="Times,serif" font-size="14.00">versions</text>
</g>
<!-- RegistrantVerification -->
<g id="node48" class="node"><title>RegistrantVerification</title>
<path fill="none" stroke="black" d="M4138,-2414C4138,-2414 4268,-2414 4268,-2414 4274,-2414 4280,-2420 4280,-2426 4280,-2426 4280,-2553 4280,-2553 4280,-2559 4274,-2565 4268,-2565 4268,-2565 4138,-2565 4138,-2565 4132,-2565 4126,-2559 4126,-2553 4126,-2553 4126,-2426 4126,-2426 4126,-2420 4132,-2414 4138,-2414"/>
@ -2009,13 +1936,6 @@
<polygon fill="#d7df82" stroke="#d7df82" points="1952.06,-264.413 1957.91,-255.135 1952.76,-259.462 1953.45,-254.51 1953.45,-254.51 1953.45,-254.51 1952.76,-259.462 1949,-253.885 1952.06,-264.413 1952.06,-264.413"/>
<text text-anchor="middle" x="1972" y="-360.3" font-family="Times,serif" font-size="14.00">versions</text>
</g>
<!-- DomainStatus&#45;&gt;DomainStatusVersion -->
<g id="edge139" class="edge"><title>DomainStatus&#45;&gt;DomainStatusVersion</title>
<path fill="none" stroke="#71309b" d="M2387.98,-1194.97C2349.1,-1031.98 2257.33,-647.246 2213.76,-464.595"/>
<ellipse fill="none" stroke="#71309b" cx="2389.01" cy="-1199.29" rx="4.00001" ry="4.00001"/>
<polygon fill="#71309b" stroke="#71309b" points="2213.72,-464.448 2215.78,-453.677 2212.56,-459.585 2211.4,-454.721 2211.4,-454.721 2211.4,-454.721 2212.56,-459.585 2207.03,-455.765 2213.72,-464.448 2213.72,-464.448"/>
<text text-anchor="middle" x="2343" y="-820.3" font-family="Times,serif" font-size="14.00">versions</text>
</g>
<!-- Registrant -->
<g id="node64" class="node"><title>Registrant</title>
<path fill="none" stroke="black" d="M3884,-2301.5C3884,-2301.5 4022,-2301.5 4022,-2301.5 4028,-2301.5 4034,-2307.5 4034,-2313.5 4034,-2313.5 4034,-2665.5 4034,-2665.5 4034,-2671.5 4028,-2677.5 4022,-2677.5 4022,-2677.5 3884,-2677.5 3884,-2677.5 3878,-2677.5 3872,-2671.5 3872,-2665.5 3872,-2665.5 3872,-2313.5 3872,-2313.5 3872,-2307.5 3878,-2301.5 3884,-2301.5"/>

Before

Width:  |  Height:  |  Size: 228 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Before After
Before After

View file

@ -18,4 +18,5 @@ Main communication specification through Restful EPP (REPP):
[Contact related functions](repp/v1/contact.md)
[Domain related functions](repp/v1/domain.md)
[Domain transfers](repp/v1/domain_transfers.md)
[Account related functions](repp/v1/account.md)
[Account related functions](repp/v1/account.md)
[Nameservers](repp/v1/nameservers.md)

View file

@ -0,0 +1,56 @@
# Nameservers
## PUT /repp/v1/registrar/nameservers
Replaces all name servers of current registrar domains.
#### Request
```
PUT /repp/v1/registrar/nameservers
Accept: application/json
Content-Type: application/json
Authorization: Basic dGVzdDp0ZXN0dGVzdA==
{
"data":{
"type": "nameserver",
"id": "ns1.example.com",
"attributes": {
"hostname": "new-ns1.example.com",
"ipv4": ["192.0.2.1", "192.0.2.2"],
"ipv6": ["2001:db8::1", "2001:db8::2"]
},
}
}
```
#### Response on success
```
HTTP/1.1 200
Content-Type: application/json
{
"data":{
"type": "nameserver",
"id": "new-ns1.example.com",
"attributes": {
"hostname": "new-ns1.example.com",
"ipv4": ["192.0.2.1", "192.0.2.2"],
"ipv6": ["2001:db8::1", "2001:db8::2"]
},
}
}
```
#### Response on failure
```
HTTP/1.1 400
Content-Type: application/json
{
"errors":[
{
"title":"ns1.example.com does not exist"
},
{
"title":"192.0.2.1 is not a valid IPv4 address"
}
]
}
```

View file

@ -2,5 +2,6 @@ FactoryBot.define do
factory :nameserver do
sequence(:hostname) { |n| "ns.test#{n}.ee" }
ipv4 '192.168.1.1'
domain
end
end

View file

@ -76,10 +76,6 @@ RSpec.describe Contact do
end
end
it 'should not have relation with domains' do
@contact.domains_present?.should == false
end
it 'should not overwrite code' do
old_code = @contact.code
@contact.code = 'CID:REG1:should-not-overwrite-old-code-12345'
@ -417,36 +413,6 @@ RSpec.describe Contact do
end
end
describe '#used?' do
context 'when used as registrant' do
let(:registrant) { create(:registrant) }
before :example do
create(:domain, registrant: registrant)
registrant.reload
end
specify { expect(registrant).to be_used }
end
context 'when used as contact' do
let(:contact) { create(:contact) }
before :example do
domain = create(:domain)
domain.admin_domain_contacts << create(:admin_domain_contact, contact: contact)
contact.reload
end
specify { expect(contact).to be_used }
end
context 'when not used' do
let(:contact) { create(:contact) }
specify { expect(contact).to_not be_used }
end
end
describe '#domain_names_with_roles' do
let(:contact) { create(:registrant) }
subject(:domain_names) { contact.domain_names_with_roles }

View file

@ -568,8 +568,8 @@ RSpec.describe Domain do
with_versioning do
context 'when saved' do
before(:each) do
domain = create(:domain)
domain.nameservers << create(:nameserver)
domain = create(:domain, nameservers_attributes: [attributes_for(:nameserver),
attributes_for(:nameserver)])
end
it 'creates domain version' do
@ -660,7 +660,7 @@ RSpec.describe Domain do
end
describe 'nameserver validation', db: true do
let(:domain) { described_class.new }
let(:domain) { described_class.new(name: 'whatever.test') }
it 'rejects less than min' do
Setting.ns_min_count = 2

View file

@ -1,125 +0,0 @@
require 'rails_helper'
describe Nameserver do
before :example do
Setting.ds_algorithm = 2
Setting.ds_data_allowed = true
Setting.ds_data_with_key_allowed = true
Setting.key_data_allowed = true
Setting.dnskeys_min_count = 0
Setting.dnskeys_max_count = 9
Setting.ns_min_count = 2
Setting.ns_max_count = 11
Setting.transfer_wait_time = 0
Setting.admin_contacts_min_count = 1
Setting.admin_contacts_max_count = 10
Setting.tech_contacts_min_count = 0
Setting.tech_contacts_max_count = 10
Setting.client_side_status_editing_enabled = true
create(:zone, origin: 'ee')
end
context 'with invalid attribute' do
before :example do
@nameserver = Nameserver.new
end
it 'should not have any versions' do
@nameserver.versions.should == []
end
end
context 'with valid attributes' do
before :example do
@nameserver = create(:nameserver)
end
it 'should be valid' do
@nameserver.valid?
@nameserver.errors.full_messages.should match_array([])
end
it 'should be valid twice' do
@nameserver = create(:nameserver)
@nameserver.valid?
@nameserver.errors.full_messages.should match_array([])
end
it 'should have one version' do
with_versioning do
@nameserver.versions.should == []
@nameserver.hostname = 'hostname.ee'
@nameserver.save
@nameserver.errors.full_messages.should match_array([])
@nameserver.versions.size.should == 1
end
end
context 'with many nameservers' do
before :example do
@api_user = create(:api_user)
@domain_1 = create(:domain, nameservers: [
create(:nameserver, hostname: 'ns1.ns.ee'),
create(:nameserver, hostname: 'ns2.ns.ee'),
create(:nameserver, hostname: 'ns2.test.ee')
], registrar: @api_user.registrar)
@domain_2 = create(:domain, nameservers: [
create(:nameserver, hostname: 'ns1.ns.ee'),
create(:nameserver, hostname: 'ns2.ns.ee'),
create(:nameserver, hostname: 'ns3.test.ee')
], registrar: @api_user.registrar)
@domain_3 = create(:domain, nameservers: [
create(:nameserver, hostname: 'ns1.ns.ee'),
create(:nameserver, hostname: 'ns2.ns.ee'),
create(:nameserver, hostname: 'ns3.test.ee')
])
end
it 'should replace hostname ends' do
res = Nameserver.replace_hostname_ends(@api_user.registrar.domains, 'ns.ee', 'test.ee')
res.should == 'replaced_some'
@api_user.registrar.nameservers.where("hostname LIKE '%test.ee'").count.should == 4
@domain_1.nameservers.pluck(:hostname).should include('ns1.ns.ee', 'ns2.ns.ee', 'ns2.test.ee')
@domain_2.nameservers.pluck(:hostname).should include('ns1.test.ee', 'ns2.test.ee', 'ns3.test.ee')
res = Nameserver.replace_hostname_ends(@api_user.registrar.domains, 'test.ee', 'testing.ee')
res.should == 'replaced_all'
@api_user.registrar.nameservers.where("hostname LIKE '%testing.ee'").count.should == 4
@domain_1.nameservers.pluck(:hostname).should include('ns1.ns.ee', 'ns2.ns.ee', 'ns2.testing.ee')
@domain_2.nameservers.pluck(:hostname).should include('ns1.testing.ee', 'ns2.testing.ee', 'ns3.testing.ee')
res = Nameserver.replace_hostname_ends(@api_user.registrar.domains, 'ns.ee', 'test.ee')
res.should == 'replaced_all'
@api_user.registrar.nameservers.where("hostname LIKE '%test.ee'").count.should == 2
@domain_1.nameservers.pluck(:hostname).should include('ns1.test.ee', 'ns2.test.ee', 'ns2.testing.ee')
@domain_2.nameservers.pluck(:hostname).should include('ns1.testing.ee', 'ns2.testing.ee', 'ns3.testing.ee')
@domain_3.nameservers.pluck(:hostname).should include('ns1.ns.ee', 'ns2.ns.ee', 'ns3.test.ee')
res = Nameserver.replace_hostname_ends(@api_user.registrar.domains, 'xcv.ee', 'test.ee')
res.should == 'replaced_none'
end
end
end
end
RSpec.describe Nameserver do
describe '::hostnames', db: false do
before :example do
expect(described_class).to receive(:pluck).with(:hostname).and_return('hostnames')
end
it 'returns names' do
expect(described_class.hostnames).to eq('hostnames')
end
end
end

View file

@ -67,7 +67,7 @@ RSpec.describe RegistrantPresenter do
zip
id_code
reg_no
used?
in_use?
)
registrant_delegatable_attributes.each do |attr_name|

View file

@ -9,16 +9,24 @@ john:
code: john-001
auth_info: cacb5b
william:
william: &william
name: William
email: william@inbox.test
phone: '+555.555'
fax: +555.555
ident: 1234
ident_type: priv
ident_country_code: US
registrar: bestnames
code: william-001
auth_info: 6573d0
street: Main Street
zip: 12345
city: New York
state: New York
country_code: US
statuses:
- ok
jane:
name: Jane
@ -42,6 +50,30 @@ acme_ltd:
code: acme-ltd-001
auth_info: 720b3c
jack:
name: Jack
email: jack@inbox.test
phone: '+555.555'
ident: 1234
ident_type: org
registrar: goodnames
ident_country_code: US
code: jack-001
auth_info: e2c440
identical_to_william:
<<: *william
registrar: goodnames
code: william-002
auth_info: 5ab865
not_in_use:
name: Useless
email: useless@inbox.test
registrar: bestnames
code: useless-001
auth_info: e75a2a
invalid:
name: any
code: any

View file

@ -28,6 +28,16 @@ library:
period: 1
period_unit: m
metro:
name: metro.test
name_dirty: metro.test
registrar: goodnames
registrant: jack
transfer_code: 1071ad
valid_to: 2010-07-05
period: 1
period_unit: m
invalid:
name: invalid.test
transfer_code: any

23
test/fixtures/nameservers.yml vendored Normal file
View file

@ -0,0 +1,23 @@
shop_ns1:
hostname: ns1.bestnames.test
ipv4:
- 192.0.2.1
ipv6:
- 2001:db8::1
domain: shop
shop_ns2:
hostname: ns2.bestnames.test
ipv4:
- 192.0.2.2
ipv6:
- 2001:db8::2
domain: shop
airport_ns1:
hostname: ns1.bestnames.test
domain: airport
metro_ns1:
hostname: ns1.bestnames.test
domain: metro

View file

@ -3,6 +3,7 @@ require 'test_helper'
class APIDomainTransfersTest < ActionDispatch::IntegrationTest
def setup
@domain = domains(:shop)
@new_registrar = registrars(:goodnames)
Setting.transfer_wait_time = 0 # Auto-approval
end
@ -10,7 +11,10 @@ class APIDomainTransfersTest < ActionDispatch::IntegrationTest
post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
assert_response 200
assert_equal ({ data: [{
type: 'domain_transfer'
type: 'domain_transfer',
attributes: {
domain_name: 'shop.test'
},
}] }),
JSON.parse(response.body, symbolize_names: true)
end
@ -26,10 +30,10 @@ class APIDomainTransfersTest < ActionDispatch::IntegrationTest
assert @domain.transfers.last.approved?
end
def test_changes_registrar
def test_assigns_new_registrar
post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
@domain.reload
assert_equal registrars(:goodnames), @domain.registrar
assert_equal @new_registrar, @domain.registrar
end
def test_regenerates_transfer_code
@ -49,11 +53,16 @@ class APIDomainTransfersTest < ActionDispatch::IntegrationTest
end
def test_duplicates_registrant_admin_and_tech_contacts
assert_difference 'Contact.count', 3 do
assert_difference -> { @new_registrar.contacts.size }, 2 do
post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
end
end
def test_reuses_identical_contact
post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
assert_equal 1, @new_registrar.contacts.where(name: 'William').size
end
def test_fails_if_domain_does_not_exist
request_params = { format: :json,
data: { domainTransfers: [{ domainName: 'non-existent.test', transferCode: 'any' }] } }
@ -68,7 +77,7 @@ class APIDomainTransfersTest < ActionDispatch::IntegrationTest
data: { domainTransfers: [{ domainName: 'shop.test', transferCode: 'wrong' }] } }
post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
assert_response 400
refute_equal registrars(:goodnames), @domain.registrar
refute_equal @new_registrar, @domain.registrar
assert_equal ({ errors: [{ title: 'shop.test transfer code is wrong' }] }),
JSON.parse(response.body, symbolize_names: true)
end

View file

@ -0,0 +1,97 @@
require 'test_helper'
class APINameserversPutTest < ActionDispatch::IntegrationTest
def test_replaces_registrar_nameservers
old_nameserver_ids = [nameservers(:shop_ns1).id,
nameservers(:airport_ns1).id,
nameservers(:metro_ns1).id]
request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test',
attributes: { hostname: 'ns55.bestnames.test' } } }
put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
assert_empty (old_nameserver_ids & registrars(:bestnames).nameservers(true).ids)
end
def test_saves_all_attributes
request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test',
attributes: { hostname: 'ns55.bestnames.test',
ipv4: ['192.0.2.55'],
ipv6: ['2001:db8::55'] } } }
put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
new_nameserver = domains(:shop).nameservers.find_by(hostname: 'ns55.bestnames.test')
assert_equal ['192.0.2.55'], new_nameserver.ipv4
assert_equal ['2001:DB8::55'], new_nameserver.ipv6
end
def test_keeps_other_nameserver_intact
request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test',
attributes: { hostname: 'ns55.bestnames.test' } } }
other_nameserver_hash = nameservers(:shop_ns2).attributes
put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
assert_equal other_nameserver_hash, nameservers(:shop_ns2).reload.attributes
end
def test_keeps_other_registrar_nameservers_intact
request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test',
attributes: { hostname: 'ns55.bestnames.test' } } }
nameserver_hash = nameservers(:metro_ns1).attributes
put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
assert_equal nameserver_hash, nameservers(:metro_ns1).reload.attributes
end
def test_returns_new_nameserver_record
request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test',
attributes: { hostname: 'ns55.bestnames.test',
ipv4: ['192.0.2.55'],
ipv6: ['2001:db8::55'] } } }
put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
assert_response 200
assert_equal ({ data: { type: 'nameserver',
id: 'ns55.bestnames.test',
attributes: { hostname: 'ns55.bestnames.test',
ipv4: ['192.0.2.55'],
ipv6: ['2001:db8::55'] } } }),
JSON.parse(response.body, symbolize_names: true)
end
def test_optional_params
request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test',
attributes: { hostname: 'ns55.bestnames.test' } } }
put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
assert_response 200
end
def test_non_existent_nameserver_hostname
request_params = { format: :json, data: { type: 'nameserver', id: 'non-existent.test',
attributes: { hostname: 'any.bestnames.test' } } }
put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
assert_response 404
assert_equal ({ errors: [{ title: 'Hostname non-existent.test does not exist' }] }),
JSON.parse(response.body, symbolize_names: true)
end
def test_invalid_request_params
request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test',
attributes: { hostname: '' } } }
put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key }
assert_response 400
assert_equal ({ errors: [{ title: 'Hostname is missing' }] }),
JSON.parse(response.body, symbolize_names: true)
end
def test_unauthenticated
put '/repp/v1/registrar/nameservers'
assert_response 401
end
private
def http_auth_key
ActionController::HttpAuthentication::Basic.encode_credentials('test_bestnames', 'testtest')
end
end

View file

@ -0,0 +1,35 @@
require 'test_helper'
class EppDomainCreateNameserversTest < ActionDispatch::IntegrationTest
# Glue record requirement
def test_nameserver_ip_address_is_required_if_hostname_is_under_the_same_domain
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<create>
<domain:create xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
<domain:name>new.test</domain:name>
<domain:ns>
<domain:hostAttr>
<domain:hostName>ns1.new.test</domain:hostName>
</domain:hostAttr>
</domain:ns>
<domain:registrant>john-001</domain:registrant>
</domain:create>
</create>
<extension>
<eis:extdata xmlns:eis="https://epp.tld.ee/schema/eis-1.0.xsd">
<eis:legalDocument type="pdf">test</eis:legalDocument>
</eis:extdata>
</extension>
</command>
</epp>
XML
assert_no_difference 'Domain.count' do
post '/epp/command/create', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' }
end
assert_equal '2003', Nokogiri::XML(response.body).at_css('result')[:code]
end
end

View file

@ -3,6 +3,7 @@ require 'test_helper'
class EppDomainTransferRequestTest < ActionDispatch::IntegrationTest
def setup
@domain = domains(:shop)
@new_registrar = registrars(:goodnames)
Setting.transfer_wait_time = 0
end
@ -24,10 +25,10 @@ class EppDomainTransferRequestTest < ActionDispatch::IntegrationTest
'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text
end
def test_changes_registrar
def test_assigns_new_registrar
post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' }
@domain.reload
assert_equal registrars(:goodnames), @domain.registrar
assert_equal @new_registrar, @domain.registrar
end
def test_regenerates_transfer_code
@ -48,11 +49,16 @@ class EppDomainTransferRequestTest < ActionDispatch::IntegrationTest
end
def test_duplicates_registrant_admin_and_tech_contacts
assert_difference 'Contact.count', 3 do
assert_difference -> { @new_registrar.contacts.size }, 2 do
post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' }
end
end
def test_reuses_identical_contact
post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' }
assert_equal 1, @new_registrar.contacts.where(name: 'William').size
end
def test_saves_legal_document
assert_difference -> { @domain.legal_documents(true).size } do
post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' }
@ -106,7 +112,7 @@ class EppDomainTransferRequestTest < ActionDispatch::IntegrationTest
post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' }
@domain.reload
refute_equal registrars(:goodnames), @domain.registrar
refute_equal @new_registrar, @domain.registrar
assert_equal '2201', Nokogiri::XML(response.body).at_css('result')[:code]
end

View file

@ -7,12 +7,14 @@ class RegistrarDomainTransfersTest < ActionDispatch::IntegrationTest
end
def test_batch_transfer_succeeds
body = { data: { domainTransfers: [{ domainName: 'shop.test', transferCode: '65078d5' }] } }
request_body = { data: { domainTransfers: [{ domainName: 'shop.test', transferCode: '65078d5' }] } }
headers = { 'Content-type' => 'application/json' }
request_stub = stub_request(:post, /domain_transfers/).with(body: body,
request_stub = stub_request(:post, /domain_transfers/).with(body: request_body,
headers: headers,
basic_auth: ['test_goodnames', 'testtest'])
.to_return(status: 204)
.to_return(body: { data: [{
type: 'domain_transfer'
}] }.to_json, status: 200)
visit registrar_domains_url
click_link 'Transfer'
@ -23,7 +25,7 @@ class RegistrarDomainTransfersTest < ActionDispatch::IntegrationTest
assert_requested request_stub
assert_current_path registrar_domains_path
assert_text 'Domains have been successfully transferred'
assert_text '1 domains have been successfully transferred'
end
def test_batch_transfer_fails_gracefully

View file

@ -0,0 +1,57 @@
require 'test_helper'
class RegistrarNameserverReplacementTest < ActionDispatch::IntegrationTest
def setup
WebMock.reset!
login_as users(:api_goodnames)
end
def test_replaces_current_registrar_nameservers
request_body = { data: { type: 'nameserver',
id: 'ns1.bestnames.test',
attributes: { hostname: 'new-ns.bestnames.test',
ipv4: %w[192.0.2.55 192.0.2.56],
ipv6: %w[2001:db8::55 2001:db8::56] } } }
request_stub = stub_request(:put, /registrar\/nameservers/).with(body: request_body,
headers: { 'Content-type' => 'application/json' },
basic_auth: ['test_goodnames', 'testtest'])
.to_return(body: { data: [{
type: 'nameserver',
id: 'new-ns.bestnames.test'
}] }.to_json, status: 200)
visit registrar_domains_url
click_link 'Replace nameserver'
fill_in 'Old hostname', with: 'ns1.bestnames.test'
fill_in 'New hostname', with: 'new-ns.bestnames.test'
fill_in 'ipv4', with: "192.0.2.55\n192.0.2.56"
fill_in 'ipv6', with: "2001:db8::55\n2001:db8::56"
click_on 'Replace nameserver'
assert_requested request_stub
assert_current_path registrar_domains_path
assert_text 'Nameserver have been successfully replaced'
end
def test_fails_gracefully
stub_request(:put, /registrar\/nameservers/).to_return(status: 400,
body: { errors: [{ title: 'epic fail' }] }.to_json,
headers: { 'Content-type' => 'application/json' })
visit registrar_domains_url
click_link 'Replace nameserver'
fill_in 'Old hostname', with: 'old hostname'
fill_in 'New hostname', with: 'new hostname'
fill_in 'ipv4', with: 'ipv4'
fill_in 'ipv6', with: 'ipv6'
click_on 'Replace nameserver'
assert_text 'epic fail'
assert_field 'Old hostname', with: 'old hostname'
assert_field 'New hostname', with: 'new hostname'
assert_field 'ipv4', with: 'ipv4'
assert_field 'ipv6', with: 'ipv6'
end
end

View file

@ -12,4 +12,18 @@ class ContactTest < ActiveSupport::TestCase
def test_invalid_fixture_is_invalid
assert contacts(:invalid).invalid?
end
def test_in_use_if_acts_as_a_registrant
DomainContact.delete_all
assert @contact.in_use?
end
def test_in_use_if_acts_as_a_domain_contact
Domain.update_all(registrant_id: contacts(:william))
assert @contact.in_use?
end
def test_not_in_use_if_acts_as_neither_registrant_nor_domain_contact
refute contacts(:not_in_use).in_use?
end
end

View file

@ -0,0 +1,63 @@
require 'test_helper'
class ContactIdenticalTest < ActiveSupport::TestCase
REGULAR_FILTER_ATTRIBUTES = %i[
name
email
phone
fax
ident
ident_type
ident_country_code
org_name
]
def setup
@contact = contacts(:william)
@identical = contacts(:identical_to_william)
end
def test_returns_identical
assert_equal @identical, @contact.identical(@identical.registrar)
end
def test_does_not_return_non_identical
REGULAR_FILTER_ATTRIBUTES.each do |attribute|
previous_value = @identical.public_send(attribute)
@identical.update_attribute(attribute, 'other')
assert_nil @contact.identical(@identical.registrar)
@identical.update_attribute(attribute, previous_value)
end
@identical.update!({ statuses: %w[ok linked] })
assert_nil @contact.identical(@identical.registrar)
end
def test_takes_address_into_account_when_processing_enabled
Contact.address_attribute_names.each do |attribute|
previous_value = @identical.public_send(attribute)
@identical.update_attribute(attribute, 'other')
Contact.stub :address_processing?, true do
assert_nil @contact.identical(@identical.registrar)
end
@identical.update_attribute(attribute, previous_value)
end
end
def test_ignores_address_when_processing_disabled
Setting.address_processing = false
Contact.address_attribute_names.each do |attribute|
previous_value = @identical.public_send(attribute)
@identical.update_attribute(attribute, 'other')
Contact.stub :address_processing?, false do
assert_equal @identical, @contact.identical(@identical.registrar)
end
@identical.update_attribute(attribute, previous_value)
end
end
end

View file

@ -0,0 +1,19 @@
require 'test_helper'
class ContactPostalAddressTest < ActiveSupport::TestCase
def setup
@contact = contacts(:john)
end
def test_invalid_if_country_code_is_invalid_and_address_processing_is_on
Setting.address_processing = true
@contact.country_code = 'invalid'
assert @contact.invalid?
end
def test_valid_if_country_code_is_invalid_and_address_processing_is_off
Setting.address_processing = false
@contact.country_code = 'invalid'
assert @contact.valid?
end
end

View file

@ -8,7 +8,6 @@ class ContactTransferTest < ActiveSupport::TestCase
def test_invalid_without_auth_info
@contact.auth_info = nil
@contact.validate
assert @contact.invalid?
end
@ -36,18 +35,23 @@ class ContactTransferTest < ActiveSupport::TestCase
end
def test_keeps_original_contact_untouched
original_hash = @contact.to_json
original_hash = @contact.attributes
@contact.transfer(@new_registrar)
@contact.reload
assert_equal original_hash, @contact.to_json
assert_equal original_hash, @contact.attributes
end
def test_creates_new_contact
assert_difference 'Contact.count' do
assert_difference -> { @new_registrar.contacts.count } do
@contact.transfer(@new_registrar)
end
end
def test_reuses_identical_contact
identical = contacts(:identical_to_william)
assert_equal identical, contacts(:william).transfer(@new_registrar)
end
def test_bypasses_validation
@contact = contacts(:invalid)
@ -56,12 +60,12 @@ class ContactTransferTest < ActiveSupport::TestCase
end
end
def test_changes_registrar
def test_assigns_new_registrar
new_contact = @contact.transfer(@new_registrar)
assert_equal @new_registrar, new_contact.registrar
end
def test_links_to_original
def test_links_to_original_contact
new_contact = @contact.transfer(@new_registrar)
assert_equal @contact, new_contact.original
end

View file

@ -8,7 +8,6 @@ class DomainTransferableTest < ActiveSupport::TestCase
def test_invalid_without_transfer_code
@domain.transfer_code = nil
@domain.validate
assert @domain.invalid?
end
@ -35,7 +34,7 @@ class DomainTransferableTest < ActiveSupport::TestCase
assert_equal '1bad4f', domain.transfer_code
end
def test_changes_registrar
def test_assigns_new_registrar
@domain.transfer(@new_registrar)
assert_equal @new_registrar, @domain.registrar
end

View file

@ -0,0 +1,27 @@
require 'test_helper'
class NameserverGlueRecordTest < ActiveSupport::TestCase
def setup
@nameserver = nameservers(:shop_ns1)
end
def test_invalid_without_ip_if_glue_record_is_required
@nameserver.hostname = 'ns1.shop.test'
@nameserver.ipv4 = @nameserver.ipv6 = ''
assert @nameserver.invalid?
assert_includes @nameserver.errors.full_messages, 'Either IPv4 or IPv6 is required' \
' for glue record generation'
end
def test_valid_with_ip_if_glue_record_is_required
@nameserver.hostname = 'ns1.shop.test'
@nameserver.ipv4 = ['192.0.2.1']
@nameserver.ipv6 = ''
assert @nameserver.valid?
end
def test_valid_without_ip_if_glue_record_is_not_required
@nameserver.ipv4 = @nameserver.ipv6 = ''
assert @nameserver.valid?
end
end

View file

@ -0,0 +1,81 @@
require 'test_helper'
class NameserverTest < ActiveSupport::TestCase
def setup
@nameserver = nameservers(:shop_ns1)
end
def test_valid
assert @nameserver.valid?
end
def test_invalid_without_domain
@nameserver.domain = nil
assert @nameserver.invalid?
end
def test_invalid_without_hostname
@nameserver.hostname = ''
assert @nameserver.invalid?
end
def test_hostname_format_validation
@nameserver.hostname = 'foo.bar'
assert @nameserver.valid?
@nameserver.hostname = 'äöüõšž.ÄÖÜÕŠŽ.umlauts'
assert @nameserver.valid?
@nameserver.hostname = 'foo_bar'
assert @nameserver.invalid?
end
def test_ipv4_format_validation
@nameserver.ipv4 = ['192.0.2.1']
assert @nameserver.valid?
@nameserver.ipv4 = ['0.0.0.256']
assert @nameserver.invalid?
@nameserver.ipv4 = ['192.168.0.0/24']
assert @nameserver.invalid?
end
def test_ipv6_format_validation
@nameserver.ipv6 = ['2001:db8::1']
assert @nameserver.valid?
@nameserver.ipv6 = ['3ffe:0b00:0000:0001:0000:0000:000a']
assert @nameserver.invalid?
end
def test_hostnames
assert_equal %w[ns1.bestnames.test
ns2.bestnames.test
ns1.bestnames.test
ns1.bestnames.test], Nameserver.hostnames
end
def test_normalizes_hostname
@nameserver.hostname = ' ns1.bestnameS.test.'
@nameserver.validate
assert_equal 'ns1.bestnames.test', @nameserver.hostname
end
def test_normalizes_ipv4
@nameserver.ipv4 = [' 192.0.2.1']
@nameserver.validate
assert_equal ['192.0.2.1'], @nameserver.ipv4
end
def test_normalizes_ipv6
@nameserver.ipv6 = [' 2001:db8::1']
@nameserver.validate
assert_equal ['2001:DB8::1'], @nameserver.ipv6
end
def test_encodes_hostname_to_punycode
@nameserver.hostname = 'ns1.münchen.de'
assert_equal 'ns1.xn--mnchen-3ya.de', @nameserver.hostname_puny
end
end