Merge pull request #740 from internetee/registry-661

Registry 661
This commit is contained in:
Timo Võhmar 2018-03-05 12:28:43 +02:00 committed by GitHub
commit fbbada1c37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 712 additions and 215 deletions

View file

@ -40,7 +40,7 @@ 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? }

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

@ -158,6 +158,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