Merge branch 'master' into 1795-validation-contacts-name

This commit is contained in:
Dinar Safiulin 2021-07-23 10:41:02 +03:00 committed by GitHub
commit aaedc31457
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 467 additions and 56 deletions

View file

@ -24,9 +24,8 @@ module Epp
# SELECT messages.id, domains.name, messages.body FROM messages LEFT OUTER
# JOIN domains ON attached_obj_id::INTEGER = domains.id
# WHERE attached_obj_type = 'Epp::Domain' AND name IS NULL;
Rails.logger.error 'orphan message, error ignored: ' + problem.to_s
# now we should dequeue or delete the messages avoid duplicate log alarms
message = 'orphan message, domain deleted, registrar should dequeue: '
Rails.logger.error message + problem.to_s
end
end

View file

@ -64,6 +64,7 @@ class Registrar
def info
authorize! :info, Depp::Domain
@data = @domain.info(params[:domain_name]) if params[:domain_name]
@pending_delete = domain_delete_pending(@data)
@client_holded = client_holded(@data)
if response_ok?
render 'info'
@ -131,6 +132,7 @@ class Registrar
@data = @domain.delete(params[:domain])
@results = @data.css('result')
if response_ok?
flash[:notice] = t('.deleting_request')
redirect_to info_registrar_domains_url(domain_name: params[:domain][:name])
else
params[:domain_name] = params[:domain][:name]
@ -182,6 +184,11 @@ class Registrar
&.any? { |status| status == DomainStatus::CLIENT_HOLD }
end
def domain_delete_pending(data)
data.css('status')&.map { |element| element.attribute('s').value }
&.any? { |status| status.include?(DomainStatus::PENDING_DELETE) }
end
def contacts
current_registrar_user.registrar.contacts
end

View file

@ -48,7 +48,7 @@ module Repp
api :PUT, '/repp/v1/registrar/notifications'
desc 'Mark poll message as read'
param :notification, Hash, required: true do
param :read, [true], required: true, desc: 'Set as true to mark as read'
param :read, [true, 'true'], required: true, desc: 'Set as true to mark as read'
end
def update
# rubocop:disable Style/AndOr

View file

@ -2,10 +2,12 @@ module Domains
module CancelForceDelete
class RemoveForceDeleteStatuses < Base
def execute
domain.statuses.delete(DomainStatus::FORCE_DELETE)
domain.statuses.delete(DomainStatus::SERVER_RENEW_PROHIBITED)
domain.statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED)
domain.statuses.delete(DomainStatus::CLIENT_HOLD)
domain_statuses = [DomainStatus::FORCE_DELETE,
DomainStatus::SERVER_RENEW_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED,
DomainStatus::CLIENT_HOLD]
rejected_statuses = domain.statuses.reject { |a| domain_statuses.include? a }
domain.statuses = rejected_statuses
domain.save(validate: false)
end
end

View file

@ -2,8 +2,9 @@ module Domains
module CancelForceDelete
class RestoreStatusesBeforeForceDelete < Base
def execute
domain.statuses = domain.statuses_before_force_delete
domain.statuses = domain.force_delete_domain_statuses_history || []
domain.statuses_before_force_delete = nil
domain.force_delete_domain_statuses_history = nil
domain.save(validate: false)
end
end

View file

@ -6,6 +6,7 @@ module Domains
DomainStatus::SERVER_TRANSFER_PROHIBITED].freeze
def execute
domain.force_delete_domain_statuses_history = domain.statuses
domain.statuses_before_force_delete = domain.statuses
domain.statuses |= STATUSES_TO_SET
domain.save(validate: false)

View file

@ -0,0 +1,36 @@
class MigrateBeforeForceDeleteStatusesJob < ApplicationJob
def perform
logger.info 'Ran MigrateBeforeForceDeleteStatusesJob!'
domains = Domain.where.not(statuses_before_force_delete: nil)
logger.info "Total domains are #{domains.count}"
interate_domain_in_batches(domains)
end
private
def interate_domain_in_batches(domains)
count = 0
domains.find_in_batches do |domain_batches|
count += domain_batches.count
logger.info "Proccesing #{count} domains of #{domains.count}"
domain_batches.each do |domain|
migrate_data_to_statuses_history(domain)
end
end
end
def migrate_data_to_statuses_history(domain)
domain.update(force_delete_domain_statuses_history: domain.statuses_before_force_delete)
rescue StandardError => e
logger.warn "#{domain.name} crashed!"
logger.warn e.to_s
raise e
end
def logger
@logger ||= Logger.new(Rails.root.join('log', 'migrate_before_force_delete_statuses.log'))
end
end

View file

@ -0,0 +1,36 @@
class MigrateStatusesToDomainHistoryJob < ApplicationJob
def perform
logger.info 'Ran MigrateStatusesToDomainHistoryJob!'
domains = Domain.where(locked_by_registrant_at: nil)
logger.info "Total domains are #{domains.count}"
interate_domain_in_batches(domains)
end
private
def interate_domain_in_batches(domains)
count = 0
domains.find_in_batches do |domain_batches|
count += domain_batches.count
logger.info "Proccesing #{count} domains of #{domains.count}"
domain_batches.each do |domain|
migrate_data_to_admin_store_field(domain)
end
end
end
def migrate_data_to_admin_store_field(domain)
domain.update(admin_store_statuses_history: domain.statuses)
rescue StandardError => e
logger.warn "#{domain.name} crashed!"
logger.warn e.to_s
raise e
end
def logger
@logger ||= Logger.new(Rails.root.join('log', 'migrate_statuses_to_domain_history.log'))
end
end

View file

@ -59,7 +59,6 @@ class BankTransaction < ApplicationRecord
end
invoice = Invoice.find_by(number: invoice_no)
errors.add(:base, I18n.t('invoice_was_not_found')) unless invoice
validate_invoice_data(invoice)
return if errors.any?
@ -68,6 +67,11 @@ class BankTransaction < ApplicationRecord
end
def validate_invoice_data(invoice)
unless invoice
errors.add(:base, I18n.t('invoice_was_not_found'))
return
end
if invoice.paid?
errors.add(:base, I18n.t('invoice_is_already_binded'))
return

View file

@ -1,6 +1,10 @@
module Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
module Domain::ForceDelete
extend ActiveSupport::Concern
FORCE_DELETE_STATUSES = [DomainStatus::FORCE_DELETE,
DomainStatus::SERVER_RENEW_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED].freeze
included do
store_accessor :force_delete_data,
:force_delete_type,

View file

@ -36,9 +36,10 @@ module Domain::RegistryLockable
transaction do
LOCK_STATUSES.each do |domain_status|
statuses.delete(domain_status)
statuses.delete([domain_status])
end
self.locked_by_registrant_at = nil
self.statuses = admin_store_statuses_history || []
alert_registrar_lock_changes!(lock: false)
save!

View file

@ -28,9 +28,6 @@ class Contact < ApplicationRecord
.where('success = false and verified_at IS NOT NULL')
}
NAME_REGEXP = /([\u00A1-\u00B3\u00B5-\u00BF\u0021-\u0026\u0028-\u002C\u003A-\u0040]|
[\u005B-\u005F\u007B-\u007E\u2040-\u206F\u20A0-\u20BF\u2100-\u218F])/x.freeze
validates :name, :email, presence: true
validates :name, format: { without: NAME_REGEXP, message: :invalid }, if: -> { priv? }

View file

@ -13,20 +13,22 @@ class Contact::Ident
validates :type, presence: true, inclusion: { in: proc { types } }
validates :country_code, presence: true, iso31661_alpha2: true
validates_with MismatchValidator
validates_with BirthDateValidator, if: :birthday?
def self.epp_code_map
{
'2003' => [
[:code, :blank],
[:type, :blank],
[:country_code, :blank]
%i[code blank],
%i[type blank],
%i[country_code blank],
],
'2005' => [
[:base, :mismatch],
[:code, :invalid_national_id],
[:code, :invalid_reg_no],
[:code, :invalid_iso8601_date],
[:country_code, :invalid_iso31661_alpha2]
%i[base mismatch],
%i[code invalid_national_id],
%i[code invalid_reg_no],
%i[code invalid_iso8601_date],
%i[code invalid_birth_date],
%i[country_code invalid_iso31661_alpha2],
]
}
end

View file

@ -22,6 +22,10 @@ class Domain < ApplicationRecord
alias_attribute :auth_info, :transfer_code # Old attribute name; for PaperTrail
alias_attribute :registered_at, :created_at
store_accessor :json_statuses_history,
:force_delete_domain_statuses_history,
:admin_store_statuses_history
# TODO: whois requests ip whitelist for full info for own domains and partial info for other domains
# TODO: most inputs should be trimmed before validatation, probably some global logic?
@ -549,8 +553,22 @@ class Domain < ApplicationRecord
statuses.include?(DomainStatus::FORCE_DELETE)
end
def update_unless_locked_by_registrant(update)
update(admin_store_statuses_history: update) unless locked_by_registrant?
end
def update_not_by_locked_statuses(update)
return unless locked_by_registrant?
result = update.reject { |status| RegistryLockable::LOCK_STATUSES.include? status }
update(admin_store_statuses_history: result)
end
# special handling for admin changing status
def admin_status_update(update)
update_unless_locked_by_registrant(update)
update_not_by_locked_statuses(update)
# check for deleted status
statuses.each do |s|
unless update.include? s

View file

@ -0,0 +1,26 @@
class Contact::Ident::BirthDateValidator < ActiveModel::Validator
VALID_BIRTH_DATE_FROM = Time.zone.today - 150.years
VALID_BIRTH_DATE_TO = Time.zone.tomorrow
def validate(record)
record.errors.add(:code, :invalid_birth_date) if birth_date_wrong?(record)
end
private
def birth_date_wrong?(record)
return unless record.birthday?
begin
Date.parse(record.code)
rescue ArgumentError
return true
end
contact_ident_date = Date.parse(record.code)
valid_time_range = VALID_BIRTH_DATE_FROM...VALID_BIRTH_DATE_TO
return if valid_time_range.cover?(contact_ident_date)
true
end
end

View file

@ -14,7 +14,7 @@
- opts = [[t(:choose),''], 'contact', 'domain', 'poll']
- opts += [params[:q][:request_object_cont]] if params[:q].present? && params[:q][:request_object_cont].present?
= f.label :request_object
= f.select :request_object_cont, opts, {}, class: 'form-control js-combobox', placeholder: t(:choose)
= f.select :request_object_cont, opts, {}, class: 'form-control selectize_create', placeholder: t(:choose)
.col-md-3
.form-group
= f.label :request_successful

View file

@ -15,9 +15,7 @@
= f.label :ident_country_code, t(:country) + '*'
.col-md-7
- if ident_complete && @contact.persisted? && f.object.ident_country_code.present?
.disabled-value
= Country.new(f.object.ident_country_code).try(:to_s)
= " [#{f.object.ident_country_code}]"
= f.text_field :ident_country_code, value: f.object.ident_country_code, :readonly => true
- else
= f.select(:ident_country_code, ApplicationController.helpers.all_country_options(country_selected), {},
class: 'js-ident-country-code', required: true)
@ -27,9 +25,7 @@
= f.label :ident_type, t(:type) + '*'
.col-md-7
- if ident_complete && @contact.persisted? && f.object.ident_type.present?
.disabled-value
= Depp::Contact.type_string(f.object.ident_type)
= " [#{f.object.ident_type}]"
= f.text_field :ident_type, value: f.object.ident_type, :readonly => true
- else
= f.select(:ident_type, Depp::Contact::SELECTION_TYPES, { selected: type_selected },
class: 'js-ident-type', required: true)
@ -39,8 +35,7 @@
= f.label :ident, t(:ident) + '*'
.col-md-7
- if ident_complete && @contact.persisted? && f.object.ident.present?
.disabled-value
= f.object.ident
= f.text_field :ident, value: f.object.ident, :readonly => true
- else
= f.text_field :ident, class: 'form-control', required: true
- tip_visibility = f.object.ident_type == 'birthday' ? '' : 'display: none'

View file

@ -7,7 +7,9 @@
class: 'btn btn-primary btn-xs' %>
<%= link_to t('.renew_btn'), renew_registrar_domains_path(domain_name: domain.name),
class: 'btn btn-default btn-xs' %>
<% unless (domain.statuses & %w[pendingDelete pendingDeleteConfirmation]).any? %>
<%= link_to t('.delete_btn'), delete_registrar_domains_path(domain_name: domain.name),
class: 'btn btn-default btn-xs' %>
<% end %>
</td>
</tr>

View file

@ -4,8 +4,10 @@
class: 'btn btn-default') %>
<%= link_to(t(:renew), renew_registrar_domains_path(domain_name: params[:domain_name]),
class: 'btn btn-default') %>
<% unless @pending_delete %>
<%= link_to(t(:delete), delete_registrar_domains_path(domain_name: params[:domain_name]),
class: 'btn btn-default') %>
<% end %>
<% if @client_holded %>
<%= link_to(t(:remove_client_hold), remove_hold_registrar_domains_path(domain_name: params[:domain_name]),
class: 'btn btn-default') %>