diff --git a/Gemfile b/Gemfile index 10c680786..d29fa223b 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,7 @@ gem 'rails', '4.2.4' # when update, all initializers eis_custom files nee gem 'iso8601', '0.8.6' # for dates and times gem 'hashie-forbidden_attributes', '0.1.1' gem 'SyslogLogger', '2.0', require: 'syslog/logger' +gem 'rest-client' # load env gem 'figaro', '1.1.1' diff --git a/Gemfile.lock b/Gemfile.lock index b92d6dc1b..45eb09943 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -188,6 +188,8 @@ GEM nokogiri (>= 1.4.0) savon (>= 2.4.0) docile (1.1.5) + domain_name (0.5.25) + unf (>= 0.0.5, < 1.0.0) epp-xml (1.0.4) activesupport (~> 4.1) builder (~> 3.2) @@ -261,6 +263,8 @@ GEM nokogiri (~> 1.6.0) ruby_parser (~> 3.5) html5_validators (1.2.2) + http-cookie (1.0.2) + domain_name (~> 0.5) httpclient (2.6.0.1) httpi (2.4.1) rack @@ -320,6 +324,7 @@ GEM multi_json (1.11.2) multi_xml (0.5.5) nenv (0.2.0) + netrc (0.11.0) newrelic_rpm (3.12.0.288) nokogiri (1.6.6.2) mini_portile (~> 0.6.0) @@ -412,6 +417,10 @@ GEM request_store (1.1.0) responders (2.1.0) railties (>= 4.2.0, < 5) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) rspec (3.3.0) rspec-core (~> 3.3.0) rspec-expectations (~> 3.3.0) @@ -515,6 +524,9 @@ GEM uglifier (2.7.1) execjs (>= 0.3.0) json (>= 1.8.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.1) unicorn (4.9.0) kgio (~> 2.6) rack @@ -617,6 +629,7 @@ DEPENDENCIES rails-settings-cached (= 0.4.1) rake ransack (= 1.5.1) + rest-client rspec-rails (= 3.3.2) rubocop (= 0.32.1) rubycritic (= 1.4.0) diff --git a/app/controllers/admin/contacts_controller.rb b/app/controllers/admin/contacts_controller.rb index a1df165d2..960d74002 100644 --- a/app/controllers/admin/contacts_controller.rb +++ b/app/controllers/admin/contacts_controller.rb @@ -4,8 +4,14 @@ class Admin::ContactsController < AdminController def index params[:q] ||= {} - @q = Contact.includes(:registrar).search(params[:q]) - @contacts = @q.result.page(params[:page]) + search_params = params[:q].deep_dup + + if search_params[:domain_contacts_type_in].is_a?(Array) && search_params[:domain_contacts_type_in].delete('registrant') + search_params[:registrant_domains_id_not_null] = 1 + end + + @q = Contact.includes(:registrar).search(search_params) + @contacts = @q.result(distinct: :true).page(params[:page]) if params[:statuses_contains] contacts = Contact.includes(:registrar).where( @@ -16,8 +22,8 @@ class Admin::ContactsController < AdminController end normalize_search_parameters do - @q = contacts.search(params[:q]) - @contacts = @q.result.page(params[:page]) + @q = contacts.search(search_params) + @contacts = @q.result(distinct: :true).page(params[:page]) end @contacts = @contacts.per(params[:results_per_page]) if params[:results_per_page].to_i > 0 diff --git a/app/controllers/registrar/contacts_controller.rb b/app/controllers/registrar/contacts_controller.rb index 878e29cd2..0581a3cfc 100644 --- a/app/controllers/registrar/contacts_controller.rb +++ b/app/controllers/registrar/contacts_controller.rb @@ -6,8 +6,15 @@ class Registrar::ContactsController < Registrar::DeppController # EPP controller params[:q] ||= {} params[:q].delete_if { |_k, v| v.blank? } - if params[:q].length == 1 && params[:q][:name_matches].present? - @contacts = Contact.find_by(name: params[:q][:name_matches]) + + search_params = params[:q].deep_dup + + if search_params[:domain_contacts_type_in].is_a?(Array) && search_params[:domain_contacts_type_in].delete('registrant') + search_params[:registrant_domains_id_not_null] = 1 + end + + if search_params.length == 1 && search_params[:name_matches].present? + @contacts = Contact.find_by(name: search_params[:name_matches]) end if params[:statuses_contains] @@ -19,8 +26,8 @@ class Registrar::ContactsController < Registrar::DeppController # EPP controller end normalize_search_parameters do - @q = contacts.search(params[:q]) - @contacts = @q.result.page(params[:page]) + @q = contacts.search(search_params) + @contacts = @q.result(distinct: :true).page(params[:page]) end @contacts = @contacts.per(params[:results_per_page]) if params[:results_per_page].to_i > 0 diff --git a/app/jobs/update_whois_record_job.rb b/app/jobs/update_whois_record_job.rb new file mode 100644 index 000000000..b7edb1fdd --- /dev/null +++ b/app/jobs/update_whois_record_job.rb @@ -0,0 +1,16 @@ +class UpdateWhoisRecordJob < Que::Job + + def run(ids, type) + klass = case type + when 'reserved'then ReservedDomain + when 'blocked' then BlockedDomain + else Domain + end + + ids.each do |id| + record = klass.find_by(id: id) + next unless record + record.update_whois_record + end + end +end \ No newline at end of file diff --git a/app/models/bank_link.rb b/app/models/bank_link.rb index 31be3e222..29857951f 100644 --- a/app/models/bank_link.rb +++ b/app/models/bank_link.rb @@ -32,7 +32,7 @@ class BankLink hash["VK_AMOUNT"] = number_with_precision(invoice.sum_cache, :precision => 2, :separator => ".") hash["VK_CURR"] = invoice.currency hash["VK_REF"] = "" - hash["VK_MSG"] = "Order nr. #{invoice.number}" + hash["VK_MSG"] = invoice.description hash["VK_RETURN"] = controller.registrar_return_payment_with_url(type) hash["VK_CANCEL"] = controller.registrar_return_payment_with_url(type) hash["VK_DATETIME"] = Time.now.strftime("%Y-%m-%dT%H:%M:%S%z") @@ -101,6 +101,7 @@ class BankLink transaction.buyer_iban = params["VK_SND_ACC"] transaction.buyer_name = params["VK_SND_NAME"] transaction.paid_at = Time.parse(params["VK_T_DATETIME"]) + transaction.save! transaction.autobind_invoice end diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index 2e5b90a2e..1a34965bf 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -2,6 +2,7 @@ class BankTransaction < ActiveRecord::Base include Versions belongs_to :bank_statement has_one :account_activity + has_many :directo_records, as: :item, class_name: 'Directo'# Deprecated scope :unbinded, lambda { where('id NOT IN (SELECT bank_transaction_id FROM account_activities where bank_transaction_id IS NOT NULL)') @@ -16,21 +17,32 @@ class BankTransaction < ActiveRecord::Base account_activity.invoice end + + def invoice_num + return @invoice_no if defined?(@invoice_no) + + match = description.match(/^[^\d]*(\d+)/) + return unless match + + @invoice_no = match[1].try(:to_i) + end + + def invoice + @invoice ||= registrar.invoices.find_by(number: invoice_num) if registrar + end + + def registrar + @registrar ||= Registrar.find_by(reference_no: reference_no) + end + + # For successful binding, reference number, invoice id and sum must match with the invoice # rubocop: disable Metrics/PerceivedComplexity # rubocop: disable Metrics/CyclomaticComplexity def autobind_invoice return if binded? - registrar = Registrar.find_by(reference_no: reference_no) return unless registrar - - match = description.match(/^[^\d]*(\d+)/) - return unless match - - invoice_no = match[1].to_i - return unless invoice_no - - invoice = registrar.invoices.find_by(number: invoice_no) + return unless invoice_num return unless invoice return if invoice.binded? diff --git a/app/models/blocked_domain.rb b/app/models/blocked_domain.rb index e433aae85..252539e17 100644 --- a/app/models/blocked_domain.rb +++ b/app/models/blocked_domain.rb @@ -1,6 +1,56 @@ class BlockedDomain < ActiveRecord::Base include Versions + before_save :generate_data + before_destroy :remove_data validates :name, domain_name: true, uniqueness: true - after_initialize -> { self.names = [] if names.nil? } + + class << self + def by_domain name + where(name: name) + end + + def any_of_domains names + where(name: names) + end + end + + def name= val + super SimpleIDN.to_unicode(val) + end + + def generate_data + return if Domain.where(name: name).any? + + @json = generate_json + @body = generate_body + update_whois_server + end + + alias_method :update_whois_record, :generate_data + + def update_whois_server + wr = Whois::Record.find_or_initialize_by(name: name) + wr.body = @body + wr.json = @json + wr.save + end + + def generate_body + template = Rails.root.join("app/views/for_models/whois_other.erb".freeze) + ERB.new(template.read, nil, "-").result(binding) + end + + def generate_json + h = HashWithIndifferentAccess.new + h[:name] = self.name + h[:status] = 'Blocked' + h + end + + def remove_data + return if Domain.where(name: name).any? + + Whois::Record.where(name: name).delete_all + end end diff --git a/app/models/contact.rb b/app/models/contact.rb index ccc44851d..99a41a6a4 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -29,7 +29,7 @@ class Contact < ActiveRecord::Base uniqueness: { message: :epp_id_taken }, format: { with: /\A[\w\-\:\.\_]*\z/i, message: :invalid }, length: { maximum: 100, message: :too_long_contact_code } - validate :ident_valid_format? + validate :val_ident_valid_format? validate :uniq_statuses? validate :validate_html @@ -235,16 +235,17 @@ class Contact < ActiveRecord::Base name || '[no name]' end - def ident_valid_format? + def val_ident_valid_format? case ident_country_code when 'EE'.freeze + err_msg = "invalid_EE_identity_format#{"_update" if id}".to_sym case ident_type when 'priv'.freeze - errors.add(:ident, :invalid_EE_identity_format) unless Isikukood.new(ident).valid? + errors.add(:ident, err_msg) unless Isikukood.new(ident).valid? when 'org'.freeze # !%w(1 7 8 9).freeze.include?(ident.first) || if ident.size != 8 || !(ident =~/\A[0-9]{8}\z/) - errors.add(:ident, :invalid_EE_identity_format) + errors.add(:ident, err_msg) end end end diff --git a/app/models/directo.rb b/app/models/directo.rb new file mode 100644 index 000000000..5a719d0a7 --- /dev/null +++ b/app/models/directo.rb @@ -0,0 +1,49 @@ +class Directo < ActiveRecord::Base + belongs_to :item, polymorphic: true + + def self.send_receipts + new_trans = Invoice.where(invoice_type: "DEB", in_directo: false).where.not(cancelled_at: nil) + new_trans.find_in_batches(batch_size: 10).each do |group| + mappers = {} # need them as no direct connection between invoice + builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| + xml.invoices { + group.each do |invoice| + next if invoice.account_activity.nil? || invoice.account_activity.bank_transaction.nil? + # next if invoice.account_activity.bank_transaction.sum.nil? || invoice.account_activity.bank_transaction.sum != invoice.sum_cache + + num = invoice.number + mappers[num] = invoice + xml.invoice( + "SalesAgent" => Setting.directo_sales_agent, + "Number" => num, + "InvoiceDate" => invoice.created_at.strftime("%Y-%m-%dT%H:%M:%S"), + "PaymentTerm" => Setting.directo_receipt_payment_term, + "Currency" => invoice.currency, + "CustomerCode"=> invoice.buyer.try(:directo_handle) + ){ + xml.line( + "ProductID" => Setting.directo_receipt_product_name, + "Quantity" => 1, + "UnitPriceWoVAT" => ActionController::Base.helpers.number_with_precision(invoice.sum_cache/(1+invoice.vat_prc), precision: 2, separator: "."), + "ProductName" => invoice.description + ) + } + end + } + end + + data = builder.to_xml.gsub("\n",'') + response = RestClient::Request.execute(url: ENV['directo_invoice_url'], method: :post, payload: {put: "1", what: "invoice", xmldata: data}, verify_ssl: false).to_s + dump_result_to_db(mappers, response) + end + end + + def self.dump_result_to_db mappers, xml + Nokogiri::XML(xml).css("Result").each do |res| + obj = mappers[res.attributes["docid"].value.to_i] + obj.directo_records.create!(response: res.as_json.to_h) + obj.update_columns(in_directo: true) + Rails.logger.info("[DIRECTO] Invoice #{res.attributes["docid"].value} was pushed and return is #{res.as_json.to_h.inspect}") + end + end +end diff --git a/app/models/domain.rb b/app/models/domain.rb index e4882473a..9da57e27a 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -93,7 +93,7 @@ class Domain < ActiveRecord::Base def update_reserved_domains return unless in_reserved_list? rd = ReservedDomain.by_domain(name).first - rd.names[name] = SecureRandom.hex + rd.password = SecureRandom.hex rd.save end @@ -264,9 +264,9 @@ class Domain < ActiveRecord::Base domains.each do |domain| next unless domain.expirable? domain.set_graceful_expired - DomainMailer.expiration_reminder(domain.id).deliver_in(Setting.expiration_reminder_mail.days) + DomainMailer.expiration_reminder(domain.id).deliver_in(Setting.expiration_reminder_mail.to_i.days) STDOUT << "#{Time.zone.now.utc} Domain.start_expire_period: ##{domain.id} (#{domain.name}) #{domain.changes}\n" unless Rails.env.test? - domain.save + domain.save(validate: false) end STDOUT << "#{Time.zone.now.utc} - Successfully expired #{domains.count} domains\n" unless Rails.env.test? @@ -280,7 +280,7 @@ class Domain < ActiveRecord::Base next unless domain.server_holdable? domain.statuses << DomainStatus::SERVER_HOLD STDOUT << "#{Time.zone.now.utc} Domain.start_redemption_grace_period: ##{domain.id} (#{domain.name}) #{domain.changes}\n" unless Rails.env.test? - domain.save + domain.save(validate: false) end STDOUT << "#{Time.zone.now.utc} - Successfully set server_hold to #{d.count} domains\n" unless Rails.env.test? @@ -294,7 +294,7 @@ class Domain < ActiveRecord::Base next unless domain.delete_candidateable? domain.statuses << DomainStatus::DELETE_CANDIDATE STDOUT << "#{Time.zone.now.utc} Domain.start_delete_period: ##{domain.id} (#{domain.name}) #{domain.changes}\n" unless Rails.env.test? - domain.save + domain.save(validate: false) end return if Rails.env.test? @@ -408,8 +408,7 @@ class Domain < ActiveRecord::Base end end - return false if statuses.include_any?(DomainStatus::DELETE_CANDIDATE, DomainStatus::SERVER_RENEW_PROHIBITED, - DomainStatus::CLIENT_RENEW_PROHIBITED, DomainStatus::PENDING_RENEW, + return false if statuses.include_any?(DomainStatus::DELETE_CANDIDATE, DomainStatus::PENDING_RENEW, DomainStatus::PENDING_TRANSFER, DomainStatus::PENDING_DELETE, DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_DELETE_CONFIRMATION) true diff --git a/app/models/epp/contact.rb b/app/models/epp/contact.rb index f4773f732..54806b88d 100644 --- a/app/models/epp/contact.rb +++ b/app/models/epp/contact.rb @@ -123,6 +123,7 @@ class Epp::Contact < Contact [:email, :invalid], [:ident, :invalid], [:ident, :invalid_EE_identity_format], + [:ident, :invalid_EE_identity_format_update], [:ident, :invalid_birthday_format], [:ident, :invalid_country_code], [:ident_type, :missing], @@ -164,7 +165,7 @@ class Epp::Contact < Contact org_priv = %w(org priv).freeze if ident_country_code.blank? && org_priv.include?(ident_type) && org_priv.include?(ident_frame.attr('type')) at.merge!(ident_country_code: ident_frame.attr('cc'), ident_type: ident_frame.attr('type')) - elsif ident_type == "birthday" && ident !=~ /\d{4}-\d{2}-\d{2}/ && (Date.parse(ident) rescue false) + elsif ident_type == "birthday" && !ident[/\A\d{4}-\d{2}-\d{2}\z/] && (Date.parse(ident) rescue false) at.merge!(ident: ident_frame.text) at.merge!(ident_country_code: ident_frame.attr('cc')) if ident_frame.attr('cc').present? elsif ident_type.blank? && ident_country_code.blank? diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 15e16163a..3f32ce6d5 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -8,7 +8,7 @@ class Epp::Domain < Domain before_validation :manage_permissions def manage_permissions return if is_admin # this bad hack for 109086524, refactor later - return true if is_transfer + return true if is_transfer || is_renewal return unless update_prohibited? || delete_prohibited? add_epp_error('2304', nil, nil, I18n.t(:object_status_prohibits_operation)) false @@ -590,6 +590,7 @@ class Epp::Domain < Domain statuses.delete(DomainStatus::SERVER_HOLD) statuses.delete(DomainStatus::EXPIRED) + statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED) save end diff --git a/app/models/invoice.rb b/app/models/invoice.rb index fdcb3cf61..5c7dafe85 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -2,8 +2,9 @@ class Invoice < ActiveRecord::Base include Versions belongs_to :seller, class_name: 'Registrar' belongs_to :buyer, class_name: 'Registrar' + has_one :account_activity has_many :invoice_items - has_one :account_activity + has_many :directo_records, as: :item, class_name: 'Directo' accepts_nested_attributes_for :invoice_items @@ -99,6 +100,10 @@ class Invoice < ActiveRecord::Base kit.to_pdf end + def description + "Order nr. #{number}" + end + def pdf_name "invoice-#{number}.pdf" end diff --git a/app/models/reserved_domain.rb b/app/models/reserved_domain.rb index 718d90bcf..8b2cb49e6 100644 --- a/app/models/reserved_domain.rb +++ b/app/models/reserved_domain.rb @@ -38,11 +38,15 @@ class ReservedDomain < ActiveRecord::Base end def generate_data + return if Domain.where(name: name).any? + @json = generate_json @body = generate_body update_whois_server end + alias_method :update_whois_record, :generate_data + def update_whois_server wr = Whois::Record.find_or_initialize_by(name: name) wr.body = @body @@ -63,6 +67,8 @@ class ReservedDomain < ActiveRecord::Base end def remove_data + return if Domain.where(name: name).any? + Whois::Record.where(name: name).delete_all end diff --git a/app/models/whois_record.rb b/app/models/whois_record.rb index 08d1cdf14..c16e5ce73 100644 --- a/app/models/whois_record.rb +++ b/app/models/whois_record.rb @@ -106,7 +106,7 @@ class WhoisRecord < ActiveRecord::Base self.json = generated_json self.body = generated_body self.name = json['name'] - self.registrar_id = domain.registrar_id # for faster registrar updates + self.registrar_id = domain.registrar_id if domain # for faster registrar updates end def update_whois_server diff --git a/app/validators/domain_name_validator.rb b/app/validators/domain_name_validator.rb index e39437f2b..be83f0835 100644 --- a/app/validators/domain_name_validator.rb +++ b/app/validators/domain_name_validator.rb @@ -38,7 +38,7 @@ class DomainNameValidator < ActiveModel::EachValidator def validate_blocked(value) return true unless value - return false if BlockedDomain.where("names @> ?::varchar[]", "{#{value}}").count > 0 + return false if BlockedDomain.where(name: value).count > 0 ZonefileSetting.where(origin: value).count == 0 end end diff --git a/app/views/admin/contacts/index.haml b/app/views/admin/contacts/index.haml index b8e7850e6..715b87eb6 100644 --- a/app/views/admin/contacts/index.haml +++ b/app/views/admin/contacts/index.haml @@ -29,15 +29,10 @@ .form-group = label_tag t(:country) = select_tag '[q][country_code_eq]', SortedCountry.all_options(params[:q][:country_code_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' } - .col-md-3 - .form-group - = f.label t(:is_registrant) - %div - = f.check_box :registrant_domains_id_not_null - .col-md-3 + .col-md-6 .form-group = label_tag t(:contact_type) - = select_tag '[q][domain_contacts_type_in]', options_for_select([['admin', 'AdminDomainContact'], ['tech', 'TechDomainContact']], params[:q][:domain_contacts_type_in]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' } + = select_tag '[q][domain_contacts_type_in]', options_for_select([['admin', 'AdminDomainContact'], ['tech', 'TechDomainContact'], ['registrant', 'registrant']], params[:q][:domain_contacts_type_in]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' } .row .col-md-3 .form-group diff --git a/app/views/admin/domain_versions/_version.haml b/app/views/admin/domain_versions/_version.haml index fd449b4b0..321e9abda 100644 --- a/app/views/admin/domain_versions/_version.haml +++ b/app/views/admin/domain_versions/_version.haml @@ -55,43 +55,47 @@ = "#{l(domain.valid_to, format: :date)}" %td - - registrant.each do |r| - %p - = r[:name] - = r[:phone] - = r[:email] - %p - = r[:code] + - if registrant + - registrant.each do |r| + %p + = r[:name] + = r[:phone] + = r[:email] + %p + = r[:code] %td - - admin_contacts.each do |ac| - %p - = ac[:name] - = ac[:phone] - = ac[:email] - %p - = ac[:code] + - if admin_contacts + - admin_contacts.each do |ac| + %p + = ac[:name] + = ac[:phone] + = ac[:email] + %p + = ac[:code] %td - - tech_contacts.each do |tc| - %p - = tc[:name] - = tc[:phone] - = tc[:email] - %p - = tc[:code] + - if tech_contacts + - tech_contacts.each do |tc| + %p + = tc[:name] + = tc[:phone] + = tc[:email] + %p + = tc[:code] %td %p - - nameservers.each do |ns| - = ns[:hostname] - %br - = ns[:ipv4] - = ns[:ipv6] + - if nameservers + - nameservers.each do |ns| + = ns[:hostname] + %br + = ns[:ipv4] + = ns[:ipv6] %td %p - = domain.registrar.name + = domain.registrar.name if domain.registrar - if domain.pending_json.present? %tr.js-pending{ style: 'display: none;' } diff --git a/app/views/admin/settings/index.haml b/app/views/admin/settings/index.haml index f03ca66bc..e09e48396 100644 --- a/app/views/admin/settings/index.haml +++ b/app/views/admin/settings/index.haml @@ -71,6 +71,9 @@ = render 'setting_row', var: :days_to_keep_invoices_active = render 'setting_row', var: :days_to_keep_overdue_invoices_active = render 'setting_row', var: :minimum_deposit + = render 'setting_row', var: :directo_receipt_payment_term + = render 'setting_row', var: :directo_receipt_product_name + = render 'setting_row', var: :directo_sales_agent = render 'setting_row', var: :registry_billing_email = render 'setting_row', var: :registry_invoice_contact = render 'setting_row', var: :registry_vat_no diff --git a/app/views/epp/contacts/info.xml.builder b/app/views/epp/contacts/info.xml.builder index 39aa91b39..fe851a6d9 100644 --- a/app/views/epp/contacts/info.xml.builder +++ b/app/views/epp/contacts/info.xml.builder @@ -51,7 +51,7 @@ xml.epp_head do xml.tag!('contact:crID', @contact.cr_id) xml.tag!('contact:crDate', @contact.created_at.try(:iso8601)) - if @contact.updated_at != @contact.created_at + if @contact.updated_at > @contact.created_at upID = @contact.updator.try(:registrar) upID = upID.code if upID.present? # Did updator return a kind of User that has a registrar? xml.tag!('contact:upID', upID) if upID.present? # optional upID diff --git a/app/views/epp/domains/info.xml.builder b/app/views/epp/domains/info.xml.builder index ec5947b13..ef283ab07 100644 --- a/app/views/epp/domains/info.xml.builder +++ b/app/views/epp/domains/info.xml.builder @@ -41,7 +41,7 @@ xml.epp_head do xml.tag!('domain:crID', @domain.cr_id) xml.tag!('domain:crDate', @domain.created_at.try(:iso8601)) - if @domain.updated_at != @domain.created_at + if @domain.updated_at > @domain.created_at upID = @domain.updator.try(:registrar) upID = upID.code if upID.present? # Did updator return a kind of User that has a registrar? xml.tag!('domain:upID', upID) if upID.present? # optional upID diff --git a/app/views/for_models/whois_other.erb b/app/views/for_models/whois_other.erb index 50cf0b2dc..33ee735e7 100644 --- a/app/views/for_models/whois_other.erb +++ b/app/views/for_models/whois_other.erb @@ -2,7 +2,7 @@ Estonia .ee Top Level Domain WHOIS server Domain: name: <%= @json['name'] %> -status: <%= @json['status'] %> +status: <%= @json['status'] %> Estonia .ee Top Level Domain WHOIS server More information at http://internet.ee diff --git a/app/views/mailers/domain_mailer/expiration_reminder.html.erb b/app/views/mailers/domain_mailer/expiration_reminder.html.erb index 59f02c510..e29ca826e 100644 --- a/app/views/mailers/domain_mailer/expiration_reminder.html.erb +++ b/app/views/mailers/domain_mailer/expiration_reminder.html.erb @@ -1,7 +1,7 @@ Domeen <%= @domain.name %> on aegunud
Lugupeetud .ee domeeni kasutaja

-Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= l(@domain.outzone_at, format: :short) %> internetis kättesaadav. Alates <%= l(@domain.delete_at, format: :short) %> on domeen <%= @domain.name %> avatud registreerimiseks kõigile huvilistele. +Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= l(@domain.outzone_at, format: :date) %> internetis kättesaadav. Alates <%= l(@domain.delete_at, format: :date) %> on domeen <%= @domain.name %> avatud registreerimiseks kõigile huvilistele.

Domeeni registreeringu pikendamiseks pöörduge palun oma registripidaja <%= @domain.registrar.name %> poole. Registripidajate kontaktid leiate aadressilt www.internet.ee/registripidajad.

@@ -27,7 +27,7 @@ Tel: +372 727 1000
The <%= @domain.name %> domain has expired
Dear user of .ee domain,

-The domain name <%= @domain.name %> has expired and will not be available on the Internet from <%= l(@domain.outzone_at, format: :short) %>. From <%= l(@domain.delete_at, format: :short) %>, the <%= @domain.name %> domain will be available for registration on a first come first served basis. +The domain name <%= @domain.name %> has expired and will not be available on the Internet from <%= l(@domain.outzone_at, format: :date) %>. From <%= l(@domain.delete_at, format: :date) %>, the <%= @domain.name %> domain will be available for registration on a first come first served basis.

To renew the domain registration, please contact your registrar <%= @domain.registrar.name %>. You can find the registrar's contacts at http://www.internet.ee/en/registripidajad/.

@@ -53,7 +53,7 @@ Phone: +372 727 1000
Домен <%= @domain.name %> устарел
Уважаемый пользователь домена .ee

-Доменное имя <%= @domain.name %> устарело и с <%= l(@domain.outzone_at, format: :short) %> недоступно в Интернете. С <%= l(@domain.delete_at, format: :short) %> домен <%= @domain.name %> доступен для регистрации всем желающим по принципу "first come, first served". +Доменное имя <%= @domain.name %> устарело и с <%= l(@domain.outzone_at, format: :date) %> недоступно в Интернете. С <%= l(@domain.delete_at, format: :date) %> домен <%= @domain.name %> доступен для регистрации всем желающим по принципу "first come, first served".

Для продления регистрации домена просим обратиться к своему регистратору <%= @domain.registrar.name %>. Контактные данные регистраторов можно найти по адресу http://www.internet.ee/ru/p/.

diff --git a/app/views/mailers/domain_mailer/expiration_reminder.text.erb b/app/views/mailers/domain_mailer/expiration_reminder.text.erb index 988ae5e10..d16682ea5 100644 --- a/app/views/mailers/domain_mailer/expiration_reminder.text.erb +++ b/app/views/mailers/domain_mailer/expiration_reminder.text.erb @@ -1,7 +1,7 @@ Domeen <%= @domain.name %> on aegunud Lugupeetud .ee domeeni kasutaja -Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= l(@domain.outzone_at, format: :short) %> internetis kättesaadav. Alates <%= l(@domain.delete_at, format: :short) %> on domeen <%= @domain.name %> avatud registreerimiseks kõigile huvilistele. +Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= l(@domain.outzone_at, format: :date) %> internetis kättesaadav. Alates <%= l(@domain.delete_at, format: :date) %> on domeen <%= @domain.name %> avatud registreerimiseks kõigile huvilistele. Domeeni registreeringu pikendamiseks pöörduge palun oma registripidaja <%= @domain.registrar.name %> poole. Registripidajate kontaktid leiate aadressilt www.internet.ee/registripidajad. @@ -27,7 +27,7 @@ Tel: +372 727 1000 The <%= @domain.name %> domain has expired Dear user of .ee domain, -The domain name <%= @domain.name %> has expired and will not be available on the Internet from <%= l(@domain.outzone_at, format: :short) %>. From <%= l(@domain.delete_at, format: :short) %>, the <%= @domain.name %> domain will be available for registration on a first come first served basis. +The domain name <%= @domain.name %> has expired and will not be available on the Internet from <%= l(@domain.outzone_at, format: :date) %>. From <%= l(@domain.delete_at, format: :date) %>, the <%= @domain.name %> domain will be available for registration on a first come first served basis. To renew the domain registration, please contact your registrar <%= @domain.registrar.name %>. You can find the registrar's contacts at http://www.internet.ee/en/registripidajad/. @@ -53,7 +53,7 @@ Phone: +372 727 1000 Домен <%= @domain.name %> устарел Уважаемый пользователь домена .ee -Доменное имя <%= @domain.name %> устарело и с <%= l(@domain.outzone_at, format: :short) %> недоступно в Интернете. С <%= l(@domain.delete_at, format: :short) %> домен <%= @domain.name %> доступен для регистрации всем желающим по принципу "first come, first served". +Доменное имя <%= @domain.name %> устарело и с <%= l(@domain.outzone_at, format: :date) %> недоступно в Интернете. С <%= l(@domain.delete_at, format: :date) %> домен <%= @domain.name %> доступен для регистрации всем желающим по принципу "first come, first served". Для продления регистрации домена просим обратиться к своему регистратору <%= @domain.registrar.name %>. Контактные данные регистраторов можно найти по адресу http://www.internet.ee/ru/p/. diff --git a/app/views/mailers/domain_mailer/force_delete.html.erb b/app/views/mailers/domain_mailer/force_delete.html.erb index 82bdee156..6f4f4cb27 100644 --- a/app/views/mailers/domain_mailer/force_delete.html.erb +++ b/app/views/mailers/domain_mailer/force_delete.html.erb @@ -20,7 +20,7 @@ Registrikood: <%= @domain.registrant.try(:ident) %>

Domeenireeglite punktist 6.4 tulenevalt on domeeni suhtes õigust omaval registreerijal võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @domain.registrar %> domeeni üleandmise taotlus Domeenireeglite p 5.3.6.2 kohaselt. Taotlusele tuleb lisada domeeni omandamist tõendavad dokumendid, mis asendavad Domeenireeglite punktis 5.3.6.3 sätestatud üleandva registreerija nõusolekut. Vastav dokumentatsioon tuleks esitada Registripidajale esimesel võimalusel.

-

Kui üleandmine ei ole 30 päeva jooksul toimunud, kustub domeen <%= @domain.name %> 24 tunni jooksul <%= l(@domain.force_delete_at, format: :short) %> möödumisest juhuslikult valitud ajahetkel. Soovi korral on võimalik domeen pärast selle kustumist registrist “kes ees, see mees” põhimõttel uuesti registreerida.

+

Kui üleandmine ei ole 30 päeva jooksul toimunud, kustub domeen <%= @domain.name %> 24 tunni jooksul <%= l(@domain.force_delete_at, format: :date) %> möödumisest juhuslikult valitud ajahetkel. Soovi korral on võimalik domeen pärast selle kustumist registrist “kes ees, see mees” põhimõttel uuesti registreerida.

Lisaküsimuste korral võtke palun ühendust oma registripidajaga <%= @domain.registrar %>, kelle kontaktandmed leiate lingilt http://www.internet.ee/registripidajad



@@ -39,7 +39,7 @@ Registry code: <%= @domain.registrant.try(:ident) %>

According to paragraph 6.4 of the Domain Regulation, the registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @domain.registrar %> in accordance with paragraph 5.3.6.2 of the Domain Regulation. The application must be submitted together with documents certifying the acquisition of the domain that will replace the consent of the surrendering registrant as laid down in paragraph 5.3.6.3 of the Domain Regulation. The relevant documents should be submitted to the registrar as soon as possible.

-

If the transfer has not been made in 30 days, the domain <%= @domain.name %> will be deleted at a randomly chosen moment within 24 hours after <%= l(@domain.force_delete_at, format: :short) %>. After deletion it is possible to reregister the domain on a "first come, first served" basis.

+

If the transfer has not been made in 30 days, the domain <%= @domain.name %> will be deleted at a randomly chosen moment within 24 hours after <%= l(@domain.force_delete_at, format: :date) %>. After deletion it is possible to reregister the domain on a "first come, first served" basis.

Should you have additional questions, please contact your registrar <%= @domain.registrar %>, whose contact information can be found at http://www.internet.ee/registrars/



@@ -58,7 +58,7 @@ Registry code: <%= @domain.registrant.try(:ident) %>

Согласно пункту 6.4 Правил домена регистрант, имеющий право на домен, может подать регистратору <%= @domain.registrar %> домена <%= @domain.name %> ходатайство о передаче домена в соответствии с п. 5.3.6.2 Правил домена. К ходатайству следует приложить подтверждающие приобретение домена документы, заменяющие в соответствии с пунктом 5.3.6.3 Правил домена согласие передающего доменное имя регистранта. EIS предлагает представить соответствующую документацию Регистратору при первой возможности, начиная с инициирования процедуры удаления.

-

Если в течение 30 дней передача не произошла, домен <%= @domain.name %> удаляется по истечении 24 часов <%= l(@domain.force_delete_at, format: :short) %> в случайный момент времени. По желанию после удаления из регистра домен можно снова зарегистрировать по принципу "кто успел, тот и съел".

+

Если в течение 30 дней передача не произошла, домен <%= @domain.name %> удаляется по истечении 24 часов <%= l(@domain.force_delete_at, format: :date) %> в случайный момент времени. По желанию после удаления из регистра домен можно снова зарегистрировать по принципу "кто успел, тот и съел".

Просим обратиться к своему регистратору <%= @domain.registrar %>. Контактные данные регистраторов можно найти по адресу http://www.internet.ee/registratory/



diff --git a/app/views/mailers/domain_mailer/force_delete.text.erb b/app/views/mailers/domain_mailer/force_delete.text.erb index 527288686..d6369c8cb 100644 --- a/app/views/mailers/domain_mailer/force_delete.text.erb +++ b/app/views/mailers/domain_mailer/force_delete.text.erb @@ -11,7 +11,7 @@ Kuivõrd äriregistrist kustutatud juriidiline isik ei saa olla domeeni registre Domeenireeglite punktist 6.4 tulenevalt on domeeni suhtes õigust omaval registreerijal võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @domain.registrar %> domeeni üleandmise taotlus Domeenireeglite p 5.3.6.2 kohaselt. Taotlusele tuleb lisada domeeni omandamist tõendavad dokumendid, mis asendavad Domeenireeglite punktis 5.3.6.3 sätestatud üleandva registreerija nõusolekut. Vastav dokumentatsioon tuleks esitada Registripidajale esimesel võimalusel. -Kui üleandmine ei ole 30 päeva jooksul toimunud, kustub domeen <%= @domain.name %> 24 tunni jooksul <%= l(@domain.force_delete_at, format: :short) %> möödumisest juhuslikult valitud ajahetkel. Soovi korral on võimalik domeen pärast selle kustumist registrist "kes ees, see mees" põhimõttel uuesti registreerida. +Kui üleandmine ei ole 30 päeva jooksul toimunud, kustub domeen <%= @domain.name %> 24 tunni jooksul <%= l(@domain.force_delete_at, format: :date) %> möödumisest juhuslikult valitud ajahetkel. Soovi korral on võimalik domeen pärast selle kustumist registrist "kes ees, see mees" põhimõttel uuesti registreerida. Lisaküsimuste korral võtke palun ühendust oma registripidajaga <%= @domain.registrar %>, kelle kontaktandmed leiate lingilt http://www.internet.ee/registripidajad/ @@ -30,7 +30,7 @@ As a terminated legal person cannot be the registrant of a domain, the EIF start According to paragraph 6.4 of the Domain Regulation, the registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @domain.registrar %> in accordance with paragraph 5.3.6.2 of the Domain Regulation. The application must be submitted together with documents certifying the acquisition of the domain that will replace the consent of the surrendering registrant as laid down in paragraph 5.3.6.3 of the Domain Regulation. The relevant documents should be submitted to the registrar as soon as possible. -If the transfer has not been made in 30 days, the domain <%= @domain.name %> will be deleted at a randomly chosen moment within 24 hours after <%= l(@domain.force_delete_at, format: :short) %>. After deletion it is possible to reregister the domain on a "first come, first served" basis. +If the transfer has not been made in 30 days, the domain <%= @domain.name %> will be deleted at a randomly chosen moment within 24 hours after <%= l(@domain.force_delete_at, format: :date) %>. After deletion it is possible to reregister the domain on a "first come, first served" basis. Should you have additional questions, please contact your registrar <%= @domain.registrar %>, whose contact information can be found at http://www.internet.ee/registrars/ @@ -49,7 +49,7 @@ EIS стало известно, что юридическое лицо с ре Согласно пункту 6.4 Правил домена регистрант, имеющий право на домен, может подать регистратору <%= @domain.registrar %> домена <%= @domain.name %> ходатайство о передаче домена в соответствии с п. 5.3.6.2 Правил домена. К ходатайству следует приложить подтверждающие приобретение домена документы, заменяющие в соответствии с пунктом 5.3.6.3 Правил домена согласие передающего доменное имя регистранта. EIS предлагает представить соответствующую документацию Регистратору при первой возможности, начиная с инициирования процедуры удаления. -Если в течение 30 дней передача не произошла, домен <%= @domain.name %> удаляется по истечении 24 часов <%= l(@domain.force_delete_at, format: :short) %> в случайный момент времени. По желанию после удаления из регистра домен можно снова зарегистрировать по принципу "кто успел, тот и съел". +Если в течение 30 дней передача не произошла, домен <%= @domain.name %> удаляется по истечении 24 часов <%= l(@domain.force_delete_at, format: :date) %> в случайный момент времени. По желанию после удаления из регистра домен можно снова зарегистрировать по принципу "кто успел, тот и съел". Просим обратиться к своему регистратору <%= @domain.registrar %>. Контактные данные регистраторов можно найти по адресу http://www.internet.ee/registratory diff --git a/app/views/registrar/contacts/index.haml b/app/views/registrar/contacts/index.haml index ae93a82fd..2226f7c6a 100644 --- a/app/views/registrar/contacts/index.haml +++ b/app/views/registrar/contacts/index.haml @@ -31,15 +31,10 @@ .form-group = label_tag t(:country) = select_tag '[q][country_code_eq]', SortedCountry.all_options(params[:q][:country_code_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' } - .col-md-3 - .form-group - = f.label t(:is_registrant) - %div - = f.check_box :registrant_domains_id_not_null - .col-md-3 + .col-md-6 .form-group = label_tag t(:contact_type) - = select_tag '[q][domain_contacts_type_in]', options_for_select([['admin', 'AdminDomainContact'], ['tech', 'TechDomainContact']], params[:q][:domain_contacts_type_in]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' } + = select_tag '[q][domain_contacts_type_in]', options_for_select([['admin', 'AdminDomainContact'], ['tech', 'TechDomainContact'], ['registrant', 'registrant']], params[:q][:domain_contacts_type_in]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' } .row .col-md-3 .form-group diff --git a/config/application-example.yml b/config/application-example.yml index b08a1b007..cf6e26357 100644 --- a/config/application-example.yml +++ b/config/application-example.yml @@ -45,6 +45,8 @@ ca_cert_path: '/home/registry/registry/shared/ca/certs/ca.crt.pem' ca_key_path: '/home/registry/registry/shared/ca/private/ca.key.pem' ca_key_password: 'your-root-key-password' +directo_invoice_url: 'https://domain/ddddd.asp' + # # EPP diff --git a/config/initializers/initial_settings.rb b/config/initializers/initial_settings.rb index 193d179b0..1b25ddeb3 100644 --- a/config/initializers/initial_settings.rb +++ b/config/initializers/initial_settings.rb @@ -33,6 +33,9 @@ if con.present? && con.table_exists?('settings') Setting.save_default(:days_to_keep_invoices_active, 30) Setting.save_default(:days_to_keep_overdue_invoices_active, 30) Setting.save_default(:minimum_deposit, 0.0) + Setting.save_default(:directo_receipt_payment_term, "R") + Setting.save_default(:directo_receipt_product_name, "ETTEM06") + Setting.save_default(:directo_sales_agent, "JAANA") Setting.save_default(:days_to_renew_domain_before_expire, 90) Setting.save_default(:expire_warning_period, 15) diff --git a/config/locales/en.yml b/config/locales/en.yml index 2e36ec69d..08c70737f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -49,6 +49,7 @@ en: ident: blank: "Required parameter missing - ident" invalid_EE_identity_format: "Ident not in valid Estonian identity format." + invalid_EE_identity_format_update: "Ident not in valid Estonian identity format. Please create new contact" invalid_birthday_format: "Ident not in valid birthady format, should be YYYY-MM-DD" invalid_country_code: "Ident country code is not valid, should be in ISO_3166-1 alpha 2 format" domains: diff --git a/config/schedule.rb b/config/schedule.rb index 5524f10ab..f3bbad764 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -53,6 +53,10 @@ if @cron_group == 'registry' every 52.minutes do runner 'Domain.start_redemption_grace_period' end + + every :day, at: '19:00pm' do + runner 'Directo.send_receipts' + end if @environment == 'production' end every 10.minutes do diff --git a/db/migrate/20160108135436_name_and_password_for_blocked_domain.rb b/db/migrate/20160108135436_name_and_password_for_blocked_domain.rb new file mode 100644 index 000000000..efd46ac88 --- /dev/null +++ b/db/migrate/20160108135436_name_and_password_for_blocked_domain.rb @@ -0,0 +1,11 @@ +class NameAndPasswordForBlockedDomain < ActiveRecord::Migration + def up + add_column :blocked_domains, :name, :string + add_index :blocked_domains, :name + remove_column :blocked_domains, :names + end + + def down + + end +end diff --git a/db/migrate/20160113143447_create_directos.rb b/db/migrate/20160113143447_create_directos.rb new file mode 100644 index 000000000..2fb6f85f8 --- /dev/null +++ b/db/migrate/20160113143447_create_directos.rb @@ -0,0 +1,10 @@ +class CreateDirectos < ActiveRecord::Migration + def change + create_table :directos do |t| + t.belongs_to :item, index: true, polymorphic: true + t.json :response + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20160118092454_add_in_directo_to_invoice.rb b/db/migrate/20160118092454_add_in_directo_to_invoice.rb new file mode 100644 index 000000000..0e93c3835 --- /dev/null +++ b/db/migrate/20160118092454_add_in_directo_to_invoice.rb @@ -0,0 +1,5 @@ +class AddInDirectoToInvoice < ActiveRecord::Migration + def change + add_column :invoices, :in_directo, :boolean, default: false + end +end diff --git a/db/schema-read-only.rb b/db/schema-read-only.rb index b362619b0..78722223a 100644 --- a/db/schema-read-only.rb +++ b/db/schema-read-only.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151029152638) do +ActiveRecord::Schema.define(version: 20160108135436) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -135,13 +135,15 @@ ActiveRecord::Schema.define(version: 20151029152638) do end create_table "blocked_domains", force: :cascade do |t| - t.string "names", array: true t.datetime "created_at" t.datetime "updated_at" t.string "creator_str" t.string "updator_str" + t.string "name" end + add_index "blocked_domains", ["name"], name: "index_blocked_domains_on_name", using: :btree + create_table "cached_nameservers", id: false, force: :cascade do |t| t.string "hostname", limit: 255 t.string "ipv4", limit: 255 @@ -240,19 +242,20 @@ ActiveRecord::Schema.define(version: 20151029152638) do end create_table "dnskeys", force: :cascade do |t| - t.integer "domain_id" - t.integer "flags" - t.integer "protocol" - t.integer "alg" - t.text "public_key" - t.integer "delegation_signer_id" - t.string "ds_key_tag" - t.integer "ds_alg" - t.integer "ds_digest_type" - t.string "ds_digest" - t.string "creator_str" - t.string "updator_str" - t.integer "legacy_domain_id" + t.integer "domain_id" + t.integer "flags" + t.integer "protocol" + t.integer "alg" + t.text "public_key" + t.integer "delegation_signer_id" + t.string "ds_key_tag" + t.integer "ds_alg" + t.integer "ds_digest_type" + t.string "ds_digest" + t.string "creator_str" + t.string "updator_str" + t.integer "legacy_domain_id" + t.datetime "updated_at" end add_index "dnskeys", ["delegation_signer_id"], name: "index_dnskeys_on_delegation_signer_id", using: :btree @@ -336,6 +339,7 @@ ActiveRecord::Schema.define(version: 20151029152638) do end add_index "domains", ["delete_at"], name: "index_domains_on_delete_at", using: :btree + add_index "domains", ["name"], name: "index_domains_on_name", unique: true, using: :btree add_index "domains", ["outzone_at"], name: "index_domains_on_outzone_at", using: :btree add_index "domains", ["registrant_id"], name: "index_domains_on_registrant_id", using: :btree add_index "domains", ["registrant_verification_asked_at"], name: "index_domains_on_registrant_verification_asked_at", using: :btree @@ -442,9 +446,7 @@ ActiveRecord::Schema.define(version: 20151029152638) do t.integer "documentable_id" t.string "documentable_type" t.datetime "created_at" - t.datetime "updated_at" t.string "creator_str" - t.string "updator_str" t.string "path" end @@ -739,21 +741,6 @@ ActiveRecord::Schema.define(version: 20151029152638) do add_index "log_keyrelays", ["item_type", "item_id"], name: "index_log_keyrelays_on_item_type_and_item_id", using: :btree add_index "log_keyrelays", ["whodunnit"], name: "index_log_keyrelays_on_whodunnit", using: :btree - create_table "log_legal_documents", force: :cascade do |t| - t.string "item_type", null: false - t.integer "item_id", null: false - t.string "event", null: false - t.string "whodunnit" - t.json "object" - t.json "object_changes" - t.datetime "created_at" - t.string "session" - t.json "children" - end - - add_index "log_legal_documents", ["item_type", "item_id"], name: "index_log_legal_documents_on_item_type_and_item_id", using: :btree - add_index "log_legal_documents", ["whodunnit"], name: "index_log_legal_documents_on_whodunnit", using: :btree - create_table "log_messages", force: :cascade do |t| t.string "item_type", null: false t.integer "item_id", null: false @@ -910,10 +897,10 @@ ActiveRecord::Schema.define(version: 20151029152638) do create_table "nameservers", force: :cascade do |t| t.string "hostname" - t.string "ipv4" + t.string "ipv4", default: [], array: true t.datetime "created_at" t.datetime "updated_at" - t.string "ipv6" + t.string "ipv6", default: [], array: true t.integer "domain_id" t.string "creator_str" t.string "updator_str" @@ -1011,9 +998,13 @@ ActiveRecord::Schema.define(version: 20151029152638) do t.datetime "updated_at" t.string "creator_str" t.string "updator_str" - t.hstore "names" + t.integer "legacy_id" + t.string "name" + t.string "password" end + add_index "reserved_domains", ["name"], name: "index_reserved_domains_on_name", using: :btree + create_table "settings", force: :cascade do |t| t.string "var", null: false t.text "value" diff --git a/db/structure.sql b/db/structure.sql index b2480a04e..cf413eff1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -39,6 +39,242 @@ COMMENT ON EXTENSION hstore IS 'data type for storing sets of (key, value) pairs SET search_path = public, pg_catalog; +-- +-- Name: change_ident_country(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION change_ident_country() RETURNS boolean + LANGUAGE plpgsql + AS $_$ +DECLARE + changed BOOLEAN; + multiplier INT []; + multiplier2 INT []; + multiplier3 INT []; + multiplier4 INT []; + r RECORD; + control TEXT; + total INT; + i INT; + mod INT; + counter INT; +BEGIN + + multiplier := ARRAY [1, 2, 3, 4, 5, 6, 7, 8, 9, 1]; + + multiplier2 := ARRAY [3, 4, 5, 6, 7, 8, 9, 1, 2, 3]; + + multiplier3 := ARRAY [1, 2, 3, 4, 5, 6, 7]; + + multiplier4 := ARRAY [3, 4, 5, 6, 7, 8, 9]; + + FOR r IN SELECT id, ident FROM contacts WHERE ident_type = 'priv' /*AND ident_country_code IS NULL*/ + LOOP + IF (length(r.ident) = 11 AND (r.ident ~ '^[0-9]+$') AND (substring(r.ident, 1, 1) = '3' OR substring(r.ident, 1, 1) = '4' OR substring(r.ident, 1, 1) = '5' OR substring(r.ident, 1, 1) = '6')) + THEN + total := 0; + counter := 1; + FOREACH i IN ARRAY multiplier + LOOP + total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); + counter := (counter + 1); + END LOOP; + mod := (total % 11); + counter := 1; + + IF (mod >= 10) + THEN + total = 0; + FOREACH i IN ARRAY multiplier2 + LOOP + total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); + counter := (counter + 1); + END LOOP; + mod := (total % 11); + END IF; + + IF (mod < 10 AND substring(r.ident, 11, 1) = to_char(mod, 'FM999MI')) + THEN + UPDATE contacts SET ident_country_code = 'EE' WHERE id = r.id; + END IF; + total = 0; + END IF; + END LOOP; + + FOR r IN SELECT id, ident FROM contacts WHERE ident_type = 'org' + LOOP + IF (length(r.ident) = 8 AND (r.ident ~ '^[0-9]+$') AND (substring(r.ident, 1, 1) = '1' OR substring(r.ident, 1, 1) = '8' OR substring(r.ident, 1, 1) = '9')) + THEN + total := 0; + counter := 1; + FOREACH i IN ARRAY multiplier3 + LOOP + total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); + counter := (counter + 1); + END LOOP; + mod := total % 11; + total = 0; + counter := 1; + + IF (mod >= 10) + THEN + total = 0; + FOREACH i IN ARRAY multiplier4 + LOOP + total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); + counter := (counter + 1); + END LOOP; + mod := (total % 11); + END IF; + + IF (mod < 10 AND (substring(r.ident, 8, 1) = to_char(mod, 'FM999MI'))) + THEN + UPDATE contacts SET ident_country_code = 'EE' WHERE id = r.id; + END IF; + END IF; + END LOOP; + + + + RETURN changed; +END; +$_$; + + +-- +-- Name: change_ident_country(integer, text); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION change_ident_country(id integer, type text) RETURNS boolean + LANGUAGE plpgsql + AS $_$ +DECLARE + changed BOOLEAN; + multiplier int[]; + multiplier2 int[]; + code int; +BEGIN + + multiplier := ARRAY[1, 2, 3, 4, 5, 6, 7, 8, 9, 1]; + + multiplier2 := ARRAY[3, 4, 5, 6, 7, 8, 9, 1, 2, 3]; + + code := (SELECT code FROM contacts WHERE id = 208 AND ident_country_code = 'EE'); + + + + UPDATE contacts + SET ident = '' + WHERE id = $1 and ident_type = $2 AND ident_country_code = 'EE' + AND ident = ''; + + RETURN changed; +END; +$_$; + + +-- +-- Name: fill_ident_country(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION fill_ident_country() RETURNS boolean + LANGUAGE plpgsql + AS $_$ + DECLARE + changed BOOLEAN; + multiplier INT []; + multiplier2 INT []; + multiplier3 INT []; + multiplier4 INT []; + r RECORD; + control TEXT; + total INT; + i INT; + mod INT; + counter INT; + BEGIN + + multiplier := ARRAY [1, 2, 3, 4, 5, 6, 7, 8, 9, 1]; + multiplier2 := ARRAY [3, 4, 5, 6, 7, 8, 9, 1, 2, 3]; + multiplier3 := ARRAY [1, 2, 3, 4, 5, 6, 7]; + multiplier4 := ARRAY [3, 4, 5, 6, 7, 8, 9]; + + FOR r IN SELECT id, ident FROM contacts WHERE ident_type = 'priv' AND ident_country_code IS NULL + LOOP + IF (length(r.ident) = 11 AND (r.ident ~ '^[0-9]+$') AND (substring(r.ident, 1, 1) = '3' OR substring(r.ident, 1, 1) = '4' OR substring(r.ident, 1, 1) = '5' OR substring(r.ident, 1, 1) = '6')) + THEN + total := 0; + counter := 1; + FOREACH i IN ARRAY multiplier + LOOP + total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); + counter := (counter + 1); + END LOOP; + mod := (total % 11); + counter := 1; + IF (mod >= 10) + THEN + total = 0; + FOREACH i IN ARRAY multiplier2 + LOOP + total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); + counter := (counter + 1); + END LOOP; + mod := (total % 11); + END IF; + + IF (mod = 10) + THEN + mod := 0; + END IF; + + IF (substring(r.ident, 11, 1) = to_char(mod, 'FM999MI')) + THEN + UPDATE contacts SET ident_country_code = 'EE' WHERE id = r.id; + END IF; + total := 0; + END IF; + END LOOP; + + FOR r IN SELECT id, ident FROM contacts WHERE ident_type = 'org' AND ident_country_code IS NULL + LOOP + IF (length(r.ident) = 8 AND (r.ident ~ '^[0-9]+$') AND (substring(r.ident, 1, 1) = '1' OR substring(r.ident, 1, 1) = '8' OR substring(r.ident, 1, 1) = '9')) + THEN + total := 0; + counter := 1; + FOREACH i IN ARRAY multiplier3 + LOOP + total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); + counter := (counter + 1); + END LOOP; + mod := total % 11; + total := 0; + counter := 1; + IF (mod >= 10) + THEN + total = 0; + FOREACH i IN ARRAY multiplier4 + LOOP + total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); + counter := (counter + 1); + END LOOP; + mod := (total % 11); + END IF; + IF (mod = 10) + THEN + mod := 0; + END IF; + IF (substring(r.ident, 8, 1) = to_char(mod, 'FM999MI')) + THEN + UPDATE contacts SET ident_country_code = 'EE' WHERE id = r.id; + END IF; + END IF; + END LOOP; + RETURN changed; + END; + $_$; + + -- -- Name: generate_zonefile(character varying); Type: FUNCTION; Schema: public; Owner: - -- @@ -55,7 +291,7 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text ret text; BEGIN -- define filters - include_filter = '%.' || i_origin; + include_filter = '%' || i_origin; -- for %.%.% IF i_origin ~ '\.' THEN @@ -82,10 +318,6 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text ret = concat(tmp_var, chr(10), chr(10)); - -- origin ns records - SELECT ns_records FROM zonefile_settings zf WHERE i_origin = zf.origin INTO tmp_var; - ret := concat(ret, '; Zone NS Records', chr(10), tmp_var, chr(10)); - -- ns records SELECT array_to_string( array( @@ -93,17 +325,26 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text FROM domains d JOIN nameservers ns ON ns.domain_id = d.id WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter - AND NOT ('{serverHold,clientHold}' && d.statuses) ORDER BY d.name ), chr(10) ) INTO tmp_var; - ret := concat(ret, tmp_var, chr(10), chr(10)); + ret := concat(ret, '; Zone NS Records', chr(10), tmp_var, chr(10), chr(10)); - -- origin a glue records - SELECT a_records FROM zonefile_settings zf WHERE i_origin = zf.origin INTO tmp_var; - ret := concat(ret, '; Zone A Records', chr(10), tmp_var, chr(10)); + -- a glue records for origin nameservers + SELECT array_to_string( + array( + SELECT concat(ns.hostname, '. IN A ', ns.ipv4) + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + WHERE d.name = i_origin + AND ns.hostname LIKE '%.' || d.name + AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '' + ), chr(10) + ) INTO tmp_var; + + ret := concat(ret, '; Zone A Records', chr(10), tmp_var); -- a glue records for other nameservers SELECT array_to_string( @@ -115,15 +356,43 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text AND ns.hostname LIKE '%.' || d.name AND d.name <> i_origin AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '' - AND NOT ('{serverHold,clientHold}' && d.statuses) + AND NOT EXISTS ( -- filter out glue records that already appeared in origin glue recrods + SELECT 1 FROM nameservers nsi + JOIN domains di ON nsi.domain_id = di.id + WHERE di.name = i_origin + AND nsi.hostname = ns.hostname + ) ), chr(10) ) INTO tmp_var; - ret := concat(ret, tmp_var, chr(10), chr(10)); + -- TODO This is a possible subtitition to the previous query, stress testing is needed to see which is faster - -- origin aaaa glue records - SELECT a4_records FROM zonefile_settings zf WHERE i_origin = zf.origin INTO tmp_var; - ret := concat(ret, '; Zone AAAA Records', chr(10), tmp_var, chr(10)); + -- SELECT ns.* + -- FROM nameservers ns + -- JOIN domains d ON d.id = ns.domain_id + -- WHERE d.name LIKE '%ee' AND d.name NOT LIKE '%pri.ee' + -- AND ns.hostname LIKE '%.' || d.name + -- AND d.name <> 'ee' + -- AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '' + -- AND ns.hostname NOT IN ( + -- SELECT ns.hostname FROM domains d JOIN nameservers ns ON d.id = ns.domain_id WHERE d.name = 'ee' + -- ) + + ret := concat(ret, chr(10), tmp_var, chr(10), chr(10)); + + -- aaaa glue records for origin nameservers + SELECT array_to_string( + array( + SELECT concat(ns.hostname, '. IN AAAA ', ns.ipv6) + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + WHERE d.name = i_origin + AND ns.hostname LIKE '%.' || d.name + AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '' + ), chr(10) + ) INTO tmp_var; + + ret := concat(ret, '; Zone AAAA Records', chr(10), tmp_var); -- aaaa glue records for other nameservers SELECT array_to_string( @@ -135,23 +404,27 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text AND ns.hostname LIKE '%.' || d.name AND d.name <> i_origin AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '' - AND NOT ('{serverHold,clientHold}' && d.statuses) + AND NOT EXISTS ( -- filter out glue records that already appeared in origin glue recrods + SELECT 1 FROM nameservers nsi + JOIN domains di ON nsi.domain_id = di.id + WHERE di.name = i_origin + AND nsi.hostname = ns.hostname + ) ), chr(10) ) INTO tmp_var; - ret := concat(ret, tmp_var, chr(10), chr(10)); + ret := concat(ret, chr(10), tmp_var, chr(10), chr(10)); -- ds records SELECT array_to_string( array( SELECT concat( - d.name_puny, '. IN DS ', dk.ds_key_tag, ' ', - dk.ds_alg, ' ', dk.ds_digest_type, ' ( ', dk.ds_digest, ' )' + d.name_puny, '. 3600 IN DS ', dk.ds_key_tag, ' ', + dk.ds_alg, ' ', dk.ds_digest_type, ' ', dk.ds_digest ) FROM domains d JOIN dnskeys dk ON dk.domain_id = d.id - WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter AND dk.flags = 257 - AND NOT ('{serverHold,clientHold}' && d.statuses) + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter ), chr(10) ) INTO tmp_var; @@ -457,11 +730,11 @@ ALTER SEQUENCE banklink_transactions_id_seq OWNED BY banklink_transactions.id; CREATE TABLE blocked_domains ( id integer NOT NULL, - names character varying[], created_at timestamp without time zone, updated_at timestamp without time zone, creator_str character varying, - updator_str character varying + updator_str character varying, + name character varying ); @@ -745,7 +1018,8 @@ CREATE TABLE dnskeys ( ds_digest character varying, creator_str character varying, updator_str character varying, - legacy_domain_id integer + legacy_domain_id integer, + updated_at timestamp without time zone ); @@ -1130,9 +1404,7 @@ CREATE TABLE legal_documents ( documentable_id integer, documentable_type character varying, created_at timestamp without time zone, - updated_at timestamp without time zone, creator_str character varying, - updator_str character varying, path character varying ); @@ -1863,43 +2135,6 @@ CREATE SEQUENCE log_keyrelays_id_seq ALTER SEQUENCE log_keyrelays_id_seq OWNED BY log_keyrelays.id; --- --- Name: log_legal_documents; Type: TABLE; Schema: public; Owner: -; Tablespace: --- - -CREATE TABLE log_legal_documents ( - 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 -); - - --- --- Name: log_legal_documents_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE log_legal_documents_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: log_legal_documents_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE log_legal_documents_id_seq OWNED BY log_legal_documents.id; - - -- -- Name: log_messages; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -2313,10 +2548,10 @@ ALTER SEQUENCE messages_id_seq OWNED BY messages.id; CREATE TABLE nameservers ( id integer NOT NULL, hostname character varying, - ipv4 character varying, + ipv4 character varying[] DEFAULT '{}'::character varying[], created_at timestamp without time zone, updated_at timestamp without time zone, - ipv6 character varying, + ipv6 character varying[] DEFAULT '{}'::character varying[], domain_id integer, creator_str character varying, updator_str character varying, @@ -2560,7 +2795,9 @@ CREATE TABLE reserved_domains ( updated_at timestamp without time zone, creator_str character varying, updator_str character varying, - names hstore + legacy_id integer, + name character varying, + password character varying ); @@ -3126,13 +3363,6 @@ ALTER TABLE ONLY log_invoices ALTER COLUMN id SET DEFAULT nextval('log_invoices_ ALTER TABLE ONLY log_keyrelays ALTER COLUMN id SET DEFAULT nextval('log_keyrelays_id_seq'::regclass); --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY log_legal_documents ALTER COLUMN id SET DEFAULT nextval('log_legal_documents_id_seq'::regclass); - - -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3645,14 +3875,6 @@ ALTER TABLE ONLY log_keyrelays ADD CONSTRAINT log_keyrelays_pkey PRIMARY KEY (id); --- --- Name: log_legal_documents_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: --- - -ALTER TABLE ONLY log_legal_documents - ADD CONSTRAINT log_legal_documents_pkey PRIMARY KEY (id); - - -- -- Name: log_messages_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3880,6 +4102,13 @@ CREATE INDEX index_accounts_on_registrar_id ON accounts USING btree (registrar_i CREATE INDEX index_api_users_on_registrar_id ON api_users USING btree (registrar_id); +-- +-- Name: index_blocked_domains_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_blocked_domains_on_name ON blocked_domains USING btree (name); + + -- -- Name: index_cached_nameservers_on_hostname_and_ipv4_and_ipv6; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -3985,6 +4214,13 @@ CREATE INDEX index_domain_transfers_on_domain_id ON domain_transfers USING btree CREATE INDEX index_domains_on_delete_at ON domains USING btree (delete_at); +-- +-- Name: index_domains_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_domains_on_name ON domains USING btree (name); + + -- -- Name: index_domains_on_outzone_at; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -4349,20 +4585,6 @@ CREATE INDEX index_log_keyrelays_on_item_type_and_item_id ON log_keyrelays USING CREATE INDEX index_log_keyrelays_on_whodunnit ON log_keyrelays USING btree (whodunnit); --- --- Name: index_log_legal_documents_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: --- - -CREATE INDEX index_log_legal_documents_on_item_type_and_item_id ON log_legal_documents USING btree (item_type, item_id); - - --- --- Name: index_log_legal_documents_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: --- - -CREATE INDEX index_log_legal_documents_on_whodunnit ON log_legal_documents USING btree (whodunnit); - - -- -- Name: index_log_messages_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -4510,6 +4732,13 @@ CREATE INDEX index_registrant_verifications_on_domain_id ON registrant_verificat CREATE INDEX index_registrars_on_code ON registrars USING btree (code); +-- +-- Name: index_reserved_domains_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_reserved_domains_on_name ON reserved_domains USING btree (name); + + -- -- Name: index_settings_on_thing_type_and_thing_id_and_var; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -4947,5 +5176,27 @@ INSERT INTO schema_migrations (version) VALUES ('20150921110152'); INSERT INTO schema_migrations (version) VALUES ('20150921111842'); +INSERT INTO schema_migrations (version) VALUES ('20151028183132'); + INSERT INTO schema_migrations (version) VALUES ('20151029152638'); +INSERT INTO schema_migrations (version) VALUES ('20151112160452'); + +INSERT INTO schema_migrations (version) VALUES ('20151117081204'); + +INSERT INTO schema_migrations (version) VALUES ('20151120090455'); + +INSERT INTO schema_migrations (version) VALUES ('20151124200353'); + +INSERT INTO schema_migrations (version) VALUES ('20151125155601'); + +INSERT INTO schema_migrations (version) VALUES ('20151127091716'); + +INSERT INTO schema_migrations (version) VALUES ('20151130175654'); + +INSERT INTO schema_migrations (version) VALUES ('20151202123506'); + +INSERT INTO schema_migrations (version) VALUES ('20160106092052'); + +INSERT INTO schema_migrations (version) VALUES ('20160108135436'); + diff --git a/lib/tasks/whois.rake b/lib/tasks/whois.rake index fd905e383..c8c3ba2a1 100644 --- a/lib/tasks/whois.rake +++ b/lib/tasks/whois.rake @@ -3,15 +3,24 @@ namespace :whois do task regenerate: :environment do start = Time.zone.now.to_f - @i = 0 print "-----> Regenerate Registry whois_records table and sync with whois server..." ActiveRecord::Base.uncached do - puts "\n#{@i}" - Domain.included.find_in_batches(batch_size: 10000) do |batch| - batch.map(&:update_whois_record) - puts(@i += 10000) - GC.start + + print "\n-----> Update domains whois_records" + Domain.find_in_batches.each do |group| + UpdateWhoisRecordJob.enqueue group.map(&:id), 'domain' end + + print "\n-----> Update blocked domains whois_records" + BlockedDomain.find_in_batches.each do |group| + UpdateWhoisRecordJob.enqueue group.map(&:id), 'blocked' + end + + print "\n-----> Update reserved domains whois_records" + ReservedDomain.find_in_batches.each do |group| + UpdateWhoisRecordJob.enqueue group.map(&:id), 'reserved' + end + end puts "\n-----> all done in #{(Time.zone.now.to_f - start).round(2)} seconds" end diff --git a/spec/models/directo_spec.rb b/spec/models/directo_spec.rb new file mode 100644 index 000000000..bf187d2bf --- /dev/null +++ b/spec/models/directo_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Directo, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end