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

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