Fix namespaces for Zeitwerk class loader

This commit is contained in:
Alex Sherman 2021-03-05 18:00:45 +05:00
parent 32634c7a8b
commit 43b3033991
78 changed files with 666 additions and 704 deletions

View file

@ -31,6 +31,9 @@ plugins:
rubocop: rubocop:
enabled: true enabled: true
channel: rubocop-0-74 channel: rubocop-0-74
checks:
Rubocop/Style/ClassAndModuleChildren:
enabled: false
checks: checks:
method-lines: method-lines:
config: config:

View file

@ -2,12 +2,12 @@ module Admin
class ContactVersionsController < BaseController class ContactVersionsController < BaseController
include ObjectVersionsHelper include ObjectVersionsHelper
load_and_authorize_resource load_and_authorize_resource class: Version::ContactVersion
def index def index
params[:q] ||= {} params[:q] ||= {}
@q = ContactVersion.search(params[:q]) @q = Version::ContactVersion.search(params[:q])
@versions = @q.result.page(params[:page]) @versions = @q.result.page(params[:page])
search_params = params[:q].deep_dup search_params = params[:q].deep_dup
@ -23,7 +23,7 @@ module Admin
end end
end end
versions = ContactVersion.includes(:item).where(whereS).order(created_at: :desc, id: :desc) versions = Version::ContactVersion.includes(:item).where(whereS).order(created_at: :desc, id: :desc)
@q = versions.search(params[:q]) @q = versions.search(params[:q])
@versions = @q.result.page(params[:page]) @versions = @q.result.page(params[:page])
@versions = @versions.per(params[:results_per_page]) if params[:results_per_page].to_i.positive? @versions = @versions.per(params[:results_per_page]) if params[:results_per_page].to_i.positive?
@ -32,8 +32,8 @@ module Admin
def show def show
per_page = 7 per_page = 7
@version = ContactVersion.find(params[:id]) @version = Version::ContactVersion.find(params[:id])
@versions = ContactVersion.where(item_id: @version.item_id).order(created_at: :desc, id: :desc) @versions = Version::ContactVersion.where(item_id: @version.item_id).order(created_at: :desc, id: :desc)
@versions_map = @versions.all.map(&:id) @versions_map = @versions.all.map(&:id)
# what we do is calc amount of results until needed version # what we do is calc amount of results until needed version
@ -49,7 +49,7 @@ module Admin
end end
def search def search
render json: ContactVersion.search_by_query(params[:q]) render json: Version::ContactVersion.search_by_query(params[:q])
end end
def create_where_string(key, value) def create_where_string(key, value)

View file

@ -2,12 +2,12 @@ module Admin
class DomainVersionsController < BaseController class DomainVersionsController < BaseController
include ObjectVersionsHelper include ObjectVersionsHelper
load_and_authorize_resource load_and_authorize_resource class: Version::DomainVersion
def index def index
params[:q] ||= {} params[:q] ||= {}
@q = DomainVersion.includes(:item).search(params[:q]) @q = Version::DomainVersion.includes(:item).search(params[:q])
@versions = @q.result.page(params[:page]) @versions = @q.result.page(params[:page])
search_params = params[:q].deep_dup search_params = params[:q].deep_dup
@ -40,7 +40,7 @@ module Admin
whereS += " AND object->>'registrar_id' IN (#{registrars.map { |r| "'#{r.id.to_s}'" }.join ','})" if registrars.present? whereS += " AND object->>'registrar_id' IN (#{registrars.map { |r| "'#{r.id.to_s}'" }.join ','})" if registrars.present?
whereS += " AND 1=0" if registrars == [] whereS += " AND 1=0" if registrars == []
versions = DomainVersion.includes(:item).where(whereS).order(created_at: :desc, id: :desc) versions = Version::DomainVersion.includes(:item).where(whereS).order(created_at: :desc, id: :desc)
@q = versions.search(params[:q]) @q = versions.search(params[:q])
@versions = @q.result.page(params[:page]) @versions = @q.result.page(params[:page])
@versions = @versions.per(params[:results_per_page]) if params[:results_per_page].to_i.positive? @versions = @versions.per(params[:results_per_page]) if params[:results_per_page].to_i.positive?
@ -50,8 +50,8 @@ module Admin
def show def show
per_page = 7 per_page = 7
@version = DomainVersion.find(params[:id]) @version = Version::DomainVersion.find(params[:id])
@versions = DomainVersion.where(item_id: @version.item_id).order(created_at: :desc, id: :desc) @versions = Version::DomainVersion.where(item_id: @version.item_id).order(created_at: :desc, id: :desc)
@versions_map = @versions.all.map(&:id) @versions_map = @versions.all.map(&:id)
# what we do is calc amount of results until needed version # what we do is calc amount of results until needed version
@ -67,7 +67,7 @@ module Admin
end end
def search def search
render json: DomainVersion.search_by_query(params[:q]) render json: Version::DomainVersion.search_by_query(params[:q])
end end
def create_where_string(key, value) def create_where_string(key, value)

View file

@ -17,7 +17,7 @@ class Registrar
private private
def check_ip_restriction def check_ip_restriction
ip_restriction = Authorization::RestrictedIP.new(request.ip) ip_restriction = Authorization::RestrictedIp.new(request.ip)
allowed = ip_restriction.can_access_registrar_area?(current_registrar_user.registrar) allowed = ip_restriction.can_access_registrar_area?(current_registrar_user.registrar)
return if allowed return if allowed

View file

@ -49,7 +49,7 @@ class Registrar
domain_presenters << ::DomainPresenter.new(domain: domain, view: view_context) domain_presenters << ::DomainPresenter.new(domain: domain, view: view_context)
end end
raw_csv = Registrar::DomainListCSVPresenter.new(domains: domain_presenters, raw_csv = Registrar::DomainListCsvPresenter.new(domains: domain_presenters,
view: view_context).to_s view: view_context).to_s
filename = "Domains_#{l(Time.zone.now, format: :filename)}.csv" filename = "Domains_#{l(Time.zone.now, format: :filename)}.csv"
send_data raw_csv, filename: filename, type: "#{Mime[:csv]}; charset=utf-8" send_data raw_csv, filename: filename, type: "#{Mime[:csv]}; charset=utf-8"

View file

@ -72,7 +72,7 @@ class Registrar
end end
def check_ip_restriction def check_ip_restriction
ip_restriction = Authorization::RestrictedIP.new(request.ip) ip_restriction = Authorization::RestrictedIp.new(request.ip)
allowed = ip_restriction.can_access_registrar_area_sign_in_page? allowed = ip_restriction.can_access_registrar_area_sign_in_page?
return if allowed return if allowed

View file

@ -1,4 +1,4 @@
class PunycodeInterceptor class Interceptors::PunycodeInterceptor
class << self class << self
def delivering_email(message) def delivering_email(message)
message.from = encode_addresses_as_punycode(message.from) message.from = encode_addresses_as_punycode(message.from)

View file

@ -89,8 +89,8 @@ class Ability
can :manage, BlockedDomain can :manage, BlockedDomain
can :manage, ReservedDomain can :manage, ReservedDomain
can :manage, DNS::Zone can :manage, DNS::Zone
can :manage, DomainVersion can :manage, Version::DomainVersion
can :manage, ContactVersion can :manage, Version::ContactVersion
can :manage, Billing::Price can :manage, Billing::Price
can :manage, User can :manage, User
can :manage, ApiUser can :manage, ApiUser

View file

@ -1,5 +1,5 @@
class Action < ApplicationRecord class Action < ApplicationRecord
has_paper_trail versions: { class_name: 'ActionVersion' } has_paper_trail versions: { class_name: 'Version::ActionVersion' }
belongs_to :user belongs_to :user
belongs_to :contact belongs_to :contact

View file

@ -1,5 +1,5 @@
module Authorization module Authorization
class RestrictedIP class RestrictedIp
def initialize(ip) def initialize(ip)
@ip = ip @ip = ip
end end

View file

@ -1,6 +1,6 @@
module Billing module Billing
class Price < ApplicationRecord class Price < ApplicationRecord
include Concerns::Billing::Price::Expirable include Billing::Price::Expirable
include Versions include Versions
belongs_to :zone, class_name: 'DNS::Zone', required: true belongs_to :zone, class_name: 'DNS::Zone', required: true

View file

@ -1,4 +1,4 @@
module Concerns::Billing::Price::Expirable module Billing::Price::Expirable
extend ActiveSupport::Concern extend ActiveSupport::Concern
class_methods do class_methods do

View file

@ -1,68 +1,64 @@
module Concerns module Contact::Archivable
module Contact extend ActiveSupport::Concern
module Archivable
extend ActiveSupport::Concern
class_methods do class_methods do
def archivable def archivable
unlinked.find_each.select(&:archivable?) unlinked.find_each.select(&:archivable?)
end
end
def archivable?(post: false)
inactive = inactive?
log("Found archivable contact id(#{id}), code (#{code})") if inactive && !post
inactive
end
def archive(verified: false, notify: true, extra_log: false)
unless verified
raise 'Contact cannot be archived' unless archivable?(post: true)
end
notify_registrar_about_archivation if notify
write_to_registrar_log if extra_log
destroy!
end
private
def notify_registrar_about_archivation
registrar.notifications.create!(
text: I18n.t('contact_has_been_archived',
contact_code: code, orphan_months: Setting.orphans_contacts_in_months)
)
end
def inactive?
if DomainVersion.contact_unlinked_more_than?(contact_id: id, period: inactivity_period)
return true
end
DomainVersion.was_contact_linked?(id) ? false : created_at <= inactivity_period.ago
end
def inactivity_period
Setting.orphans_contacts_in_months.months
end
def log(msg)
@log ||= Logger.new(STDOUT)
@log.info(msg)
end
def write_to_registrar_log
registrar_name = registrar.accounting_customer_code
archive_path = ENV['contact_archivation_log_file_dir']
registrar_log_path = "#{archive_path}/#{registrar_name}.txt"
FileUtils.mkdir_p(archive_path) unless Dir.exist?(archive_path)
f = File.new(registrar_log_path, 'a+')
f.write("#{code}\n")
f.close
end
end end
end end
def archivable?(post: false)
inactive = inactive?
log("Found archivable contact id(#{id}), code (#{code})") if inactive && !post
inactive
end
def archive(verified: false, notify: true, extra_log: false)
unless verified
raise 'Contact cannot be archived' unless archivable?(post: true)
end
notify_registrar_about_archivation if notify
write_to_registrar_log if extra_log
destroy!
end
private
def notify_registrar_about_archivation
registrar.notifications.create!(
text: I18n.t('contact_has_been_archived',
contact_code: code, orphan_months: Setting.orphans_contacts_in_months)
)
end
def inactive?
if Version::DomainVersion.contact_unlinked_more_than?(contact_id: id, period: inactivity_period)
return true
end
Version::DomainVersion.was_contact_linked?(id) ? false : created_at <= inactivity_period.ago
end
def inactivity_period
Setting.orphans_contacts_in_months.months
end
def log(msg)
@log ||= Logger.new(STDOUT)
@log.info(msg)
end
def write_to_registrar_log
registrar_name = registrar.accounting_customer_code
archive_path = ENV['contact_archivation_log_file_dir']
registrar_log_path = "#{archive_path}/#{registrar_name}.txt"
FileUtils.mkdir_p(archive_path) unless Dir.exist?(archive_path)
f = File.new(registrar_log_path, 'a+')
f.write("#{code}\n")
f.close
end
end end

View file

@ -1,26 +1,22 @@
module Concerns module Contact::Disclosable
module Contact extend ActiveSupport::Concern
module Disclosable
extend ActiveSupport::Concern
class_methods do class_methods do
attr_accessor :disclosable_attributes attr_accessor :disclosable_attributes
end end
included do included do
self.disclosable_attributes = %w[name email] self.disclosable_attributes = %w[name email]
validate :validate_disclosed_attributes validate :validate_disclosed_attributes
end end
private private
def validate_disclosed_attributes def validate_disclosed_attributes
return if disclosed_attributes.empty? return if disclosed_attributes.empty?
has_undisclosable_attributes = (disclosed_attributes - self.class.disclosable_attributes) has_undisclosable_attributes = (disclosed_attributes - self.class.disclosable_attributes)
.any? .any?
errors.add(:disclosed_attributes, :invalid) if has_undisclosable_attributes errors.add(:disclosed_attributes, :invalid) if has_undisclosable_attributes
end
end
end end
end end

View file

@ -1,4 +1,4 @@
module Concerns::Contact::Identical module Contact::Identical
extend ActiveSupport::Concern extend ActiveSupport::Concern
IDENTIFIABLE_ATTRIBUTES = %w[ IDENTIFIABLE_ATTRIBUTES = %w[

View file

@ -1,4 +1,4 @@
module Concerns::Domain::Activatable module Domain::Activatable
extend ActiveSupport::Concern extend ActiveSupport::Concern
def active? def active?

View file

@ -1,17 +1,13 @@
module Concerns module Domain::BulkUpdatable
module Domain extend ActiveSupport::Concern
module BulkUpdatable
extend ActiveSupport::Concern
def bulk_update_prohibited? def bulk_update_prohibited?
discarded? || statuses_blocks_update? discarded? || statuses_blocks_update?
end end
def statuses_blocks_update? def statuses_blocks_update?
prohibited_array = [DomainStatus::SERVER_UPDATE_PROHIBITED, prohibited_array = [DomainStatus::SERVER_UPDATE_PROHIBITED,
DomainStatus::CLIENT_UPDATE_PROHIBITED] DomainStatus::CLIENT_UPDATE_PROHIBITED]
prohibited_array.any? { |block_status| statuses.include?(block_status) } prohibited_array.any? { |block_status| statuses.include?(block_status) }
end
end
end end
end end

View file

@ -1,4 +1,4 @@
module Concerns::Domain::Deletable module Domain::Deletable
extend ActiveSupport::Concern extend ActiveSupport::Concern
DELETE_STATUSES = [ DELETE_STATUSES = [

View file

@ -1,4 +1,4 @@
module Concerns::Domain::Discardable module Domain::Discardable
extend ActiveSupport::Concern extend ActiveSupport::Concern
def keep def keep

View file

@ -1,44 +1,40 @@
# frozen_string_literal: true # frozen_string_literal: true
module Concerns module Domain::Disputable
module Domain extend ActiveSupport::Concern
module Disputable
extend ActiveSupport::Concern
included do included do
validate :validate_disputed validate :validate_disputed
end end
def mark_as_disputed def mark_as_disputed
statuses.push(DomainStatus::DISPUTED) unless statuses.include?(DomainStatus::DISPUTED) statuses.push(DomainStatus::DISPUTED) unless statuses.include?(DomainStatus::DISPUTED)
save save
end end
def unmark_as_disputed def unmark_as_disputed
statuses.delete_if { |status| status == DomainStatus::DISPUTED } statuses.delete_if { |status| status == DomainStatus::DISPUTED }
save save
end end
def in_disputed_list? def in_disputed_list?
@in_disputed_list ||= Dispute.active.find_by(domain_name: name).present? @in_disputed_list ||= Dispute.active.find_by(domain_name: name).present?
end end
def disputed? def disputed?
Dispute.active.where(domain_name: name).any? Dispute.active.where(domain_name: name).any?
end end
def validate_disputed def validate_disputed
return if persisted? || !in_disputed_list? return if persisted? || !in_disputed_list?
if reserved_pw.blank? if reserved_pw.blank?
errors.add(:base, :required_parameter_missing_disputed) errors.add(:base, :required_parameter_missing_disputed)
return false return false
end
return if Dispute.valid_auth?(name, reserved_pw)
errors.add(:base, :invalid_auth_information_reserved)
end
end end
return if Dispute.valid_auth?(name, reserved_pw)
errors.add(:base, :invalid_auth_information_reserved)
end end
end end

View file

@ -1,4 +1,4 @@
module Concerns::Domain::Expirable module Domain::Expirable
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do

View file

@ -1,4 +1,4 @@
module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength module Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do

View file

@ -1,63 +1,59 @@
module Concerns module Domain::RegistryLockable
module Domain extend ActiveSupport::Concern
module RegistryLockable
extend ActiveSupport::Concern
def apply_registry_lock def apply_registry_lock
return unless registry_lockable? return unless registry_lockable?
return if locked_by_registrant? return if locked_by_registrant?
transaction do transaction do
statuses << DomainStatus::SERVER_UPDATE_PROHIBITED statuses << DomainStatus::SERVER_UPDATE_PROHIBITED
statuses << DomainStatus::SERVER_DELETE_PROHIBITED statuses << DomainStatus::SERVER_DELETE_PROHIBITED
statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED
self.locked_by_registrant_at = Time.zone.now self.locked_by_registrant_at = Time.zone.now
alert_registrar_lock_changes!(lock: true) alert_registrar_lock_changes!(lock: true)
save! save!
end
end
def registry_lockable?
(statuses & [DomainStatus::PENDING_DELETE_CONFIRMATION,
DomainStatus::PENDING_CREATE, DomainStatus::PENDING_UPDATE,
DomainStatus::PENDING_DELETE, DomainStatus::PENDING_RENEW,
DomainStatus::PENDING_TRANSFER, DomainStatus::FORCE_DELETE]).empty?
end
def locked_by_registrant?
return false unless locked_by_registrant_at
lock_statuses = [DomainStatus::SERVER_UPDATE_PROHIBITED,
DomainStatus::SERVER_DELETE_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED]
(statuses & lock_statuses).count == 3
end
def remove_registry_lock
return unless locked_by_registrant?
transaction do
statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED)
self.locked_by_registrant_at = nil
alert_registrar_lock_changes!(lock: false)
save!
end
end
def alert_registrar_lock_changes!(lock: true)
translation = lock ? 'locked' : 'unlocked'
registrar.notifications.create!(
text: I18n.t("notifications.texts.registrar_#{translation}",
domain_name: name),
attached_obj_id: name,
attached_obj_type: self.class.name
)
end
end end
end end
def registry_lockable?
(statuses & [DomainStatus::PENDING_DELETE_CONFIRMATION,
DomainStatus::PENDING_CREATE, DomainStatus::PENDING_UPDATE,
DomainStatus::PENDING_DELETE, DomainStatus::PENDING_RENEW,
DomainStatus::PENDING_TRANSFER, DomainStatus::FORCE_DELETE]).empty?
end
def locked_by_registrant?
return false unless locked_by_registrant_at
lock_statuses = [DomainStatus::SERVER_UPDATE_PROHIBITED,
DomainStatus::SERVER_DELETE_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED]
(statuses & lock_statuses).count == 3
end
def remove_registry_lock
return unless locked_by_registrant?
transaction do
statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED)
self.locked_by_registrant_at = nil
alert_registrar_lock_changes!(lock: false)
save!
end
end
def alert_registrar_lock_changes!(lock: true)
translation = lock ? 'locked' : 'unlocked'
registrar.notifications.create!(
text: I18n.t("notifications.texts.registrar_#{translation}",
domain_name: name),
attached_obj_id: name,
attached_obj_type: self.class.name
)
end
end end

View file

@ -1,57 +1,53 @@
module Concerns module Domain::Releasable
module Domain extend ActiveSupport::Concern
module Releasable
extend ActiveSupport::Concern
class_methods do class_methods do
def release_domains def release_domains
releasable_domains.each do |domain| releasable_domains.each do |domain|
domain.release domain.release
yield domain if block_given? yield domain if block_given?
end
end
private
def releasable_domains
if release_to_auction
where('(delete_date <= ? OR force_delete_date <= ?)' \
' AND ? != ALL(coalesce(statuses, array[]::varchar[]))',
Time.zone.today,
Time.zone.today,
DomainStatus::SERVER_DELETE_PROHIBITED)
else
where('(delete_date <= ? OR force_delete_date <= ?)' \
' AND ? != ALL(coalesce(statuses, array[]::varchar[])) AND' \
' ? != ALL(COALESCE(statuses, array[]::varchar[]))',
Time.zone.today,
Time.zone.today,
DomainStatus::SERVER_DELETE_PROHIBITED,
DomainStatus::DELETE_CANDIDATE)
end
end
end end
end
included do private
class_attribute :release_to_auction
self.release_to_auction = ENV['release_domains_to_auction'] == 'true'
end
def release def releasable_domains
if release_to_auction if release_to_auction
ToStdout.msg 'Destroying domain' where('(delete_date <= ? OR force_delete_date <= ?)' \
destroy! ' AND ? != ALL(coalesce(statuses, array[]::varchar[]))',
ToStdout.msg "Checking if domain_name is auctionable: #{domain_name.auctionable?}" Time.zone.today,
domain_name.sell_at_auction if domain_name.auctionable? Time.zone.today,
DomainStatus::SERVER_DELETE_PROHIBITED)
ToStdout.msg 'Sending registrar notification' else
registrar.notifications.create!(text: "#{I18n.t(:domain_deleted)}: #{name}", where('(delete_date <= ? OR force_delete_date <= ?)' \
attached_obj_id: id, ' AND ? != ALL(coalesce(statuses, array[]::varchar[])) AND' \
attached_obj_type: self.class) ' ? != ALL(COALESCE(statuses, array[]::varchar[]))',
else Time.zone.today,
discard Time.zone.today,
end DomainStatus::SERVER_DELETE_PROHIBITED,
DomainStatus::DELETE_CANDIDATE)
end end
end end
end end
included do
class_attribute :release_to_auction
self.release_to_auction = ENV['release_domains_to_auction'] == 'true'
end
def release
if release_to_auction
ToStdout.msg 'Destroying domain'
destroy!
ToStdout.msg "Checking if domain_name is auctionable: #{domain_name.auctionable?}"
domain_name.sell_at_auction if domain_name.auctionable?
ToStdout.msg 'Sending registrar notification'
registrar.notifications.create!(text: "#{I18n.t(:domain_deleted)}: #{name}",
attached_obj_id: id,
attached_obj_type: self.class)
else
discard
end
end
end end

View file

@ -1,4 +1,4 @@
module Concerns::Domain::Transferable module Domain::Transferable
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do

View file

@ -1,95 +1,93 @@
module Concerns module EmailVerifable
module EmailVerifable extend ActiveSupport::Concern
extend ActiveSupport::Concern
def email_verification def email_verification
@email_verification ||= EmailAddressVerification.find_or_create_by(email: unicode_email, @email_verification ||= EmailAddressVerification.find_or_create_by(email: unicode_email,
domain: domain(email)) domain: domain(email))
end end
def billing_email_verification def billing_email_verification
return unless attribute_names.include?('billing_email') return unless attribute_names.include?('billing_email')
@billing_email_verification ||= EmailAddressVerification @billing_email_verification ||= EmailAddressVerification
.find_or_create_by(email: unicode_billing_email, .find_or_create_by(email: unicode_billing_email,
domain: domain(billing_email)) domain: domain(billing_email))
end end
def email_verification_failed? def email_verification_failed?
email_verification&.failed? email_verification&.failed?
end end
class_methods do
def domain(email)
Mail::Address.new(email).domain&.downcase || 'not_found'
rescue Mail::Field::IncompleteParseError
'not_found'
end
def local(email)
Mail::Address.new(email).local&.downcase || email
rescue Mail::Field::IncompleteParseError
email
end
def punycode_to_unicode(email)
return email if domain(email) == 'not_found'
local = local(email)
domain = SimpleIDN.to_unicode(domain(email))
"#{local}@#{domain}"&.downcase
end
def unicode_to_punycode(email)
return email if domain(email) == 'not_found'
local = local(email)
domain = SimpleIDN.to_ascii(domain(email))
"#{local}@#{domain}"&.downcase
end
end
def unicode_billing_email
self.class.punycode_to_unicode(billing_email)
end
def unicode_email
self.class.punycode_to_unicode(email)
end
class_methods do
def domain(email) def domain(email)
SimpleIDN.to_unicode(self.class.domain(email)) Mail::Address.new(email).domain&.downcase || 'not_found'
rescue Mail::Field::IncompleteParseError
'not_found'
end
def local(email)
Mail::Address.new(email).local&.downcase || email
rescue Mail::Field::IncompleteParseError
email
end end
def punycode_to_unicode(email) def punycode_to_unicode(email)
self.class.punycode_to_unicode(email) return email if domain(email) == 'not_found'
local = local(email)
domain = SimpleIDN.to_unicode(domain(email))
"#{local}@#{domain}"&.downcase
end end
def correct_email_format def unicode_to_punycode(email)
return if email.blank? return email if domain(email) == 'not_found'
result = email_verification.verify local = local(email)
process_result(result: result, field: :email) domain = SimpleIDN.to_ascii(domain(email))
"#{local}@#{domain}"&.downcase
end end
def correct_billing_email_format
return if email.blank?
result = billing_email_verification.verify
process_result(result: result, field: :billing_email)
end
# rubocop:disable Metrics/LineLength
def process_result(result:, field:)
case result[:errors].keys.first
when :smtp
errors.add(field, I18n.t('activerecord.errors.models.contact.attributes.email.email_smtp_check_error'))
when :mx
errors.add(field, I18n.t('activerecord.errors.models.contact.attributes.email.email_mx_check_error'))
when :regex
errors.add(field, I18n.t('activerecord.errors.models.contact.attributes.email.email_regex_check_error'))
end
end
# rubocop:enable Metrics/LineLength
end end
def unicode_billing_email
self.class.punycode_to_unicode(billing_email)
end
def unicode_email
self.class.punycode_to_unicode(email)
end
def domain(email)
SimpleIDN.to_unicode(self.class.domain(email))
end
def punycode_to_unicode(email)
self.class.punycode_to_unicode(email)
end
def correct_email_format
return if email.blank?
result = email_verification.verify
process_result(result: result, field: :email)
end
def correct_billing_email_format
return if email.blank?
result = billing_email_verification.verify
process_result(result: result, field: :billing_email)
end
# rubocop:disable Metrics/LineLength
def process_result(result:, field:)
case result[:errors].keys.first
when :smtp
errors.add(field, I18n.t('activerecord.errors.models.contact.attributes.email.email_smtp_check_error'))
when :mx
errors.add(field, I18n.t('activerecord.errors.models.contact.attributes.email.email_mx_check_error'))
when :regex
errors.add(field, I18n.t('activerecord.errors.models.contact.attributes.email.email_regex_check_error'))
end
end
# rubocop:enable Metrics/LineLength
end end

View file

@ -1,34 +1,30 @@
module Concerns module Invoice::BookKeeping
module Invoice extend ActiveSupport::Concern
module BookKeeping
extend ActiveSupport::Concern
def as_directo_json def as_directo_json
invoice = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self)) invoice = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self))
invoice['customer'] = compose_directo_customer invoice['customer'] = compose_directo_customer
invoice['issue_date'] = issue_date.strftime('%Y-%m-%d') invoice['issue_date'] = issue_date.strftime('%Y-%m-%d')
invoice['transaction_date'] = account_activity invoice['transaction_date'] = account_activity
.bank_transaction&.paid_at&.strftime('%Y-%m-%d') .bank_transaction&.paid_at&.strftime('%Y-%m-%d')
invoice['language'] = buyer.language == 'en' ? 'ENG' : '' invoice['language'] = buyer.language == 'en' ? 'ENG' : ''
invoice['invoice_lines'] = compose_directo_product invoice['invoice_lines'] = compose_directo_product
invoice invoice
end end
def compose_directo_product def compose_directo_product
[{ 'product_id': Setting.directo_receipt_product_name, 'description': order, [{ 'product_id': Setting.directo_receipt_product_name, 'description': order,
'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision( 'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision(
subtotal, precision: 2, separator: '.' subtotal, precision: 2, separator: '.'
) }].as_json ) }].as_json
end end
def compose_directo_customer def compose_directo_customer
{ {
'code': buyer.accounting_customer_code, 'code': buyer.accounting_customer_code,
'destination': buyer_country_code, 'destination': buyer_country_code,
'vat_reg_no': buyer_vat_no, 'vat_reg_no': buyer_vat_no,
}.as_json }.as_json
end
end
end end
end end

View file

@ -1,28 +1,24 @@
module Concerns module Invoice::Cancellable
module Invoice extend ActiveSupport::Concern
module Cancellable
extend ActiveSupport::Concern
included do included do
scope :non_cancelled, -> { where(cancelled_at: nil) } scope :non_cancelled, -> { where(cancelled_at: nil) }
end end
def cancellable? def cancellable?
unpaid? && not_cancelled? unpaid? && not_cancelled?
end end
def cancel def cancel
raise 'Invoice cannot be cancelled' unless cancellable? raise 'Invoice cannot be cancelled' unless cancellable?
update!(cancelled_at: Time.zone.now) update!(cancelled_at: Time.zone.now)
end end
def cancelled? def cancelled?
cancelled_at cancelled_at
end end
def not_cancelled? def not_cancelled?
!cancelled? !cancelled?
end
end
end end
end end

View file

@ -1,28 +1,24 @@
module Concerns module Invoice::Payable
module Invoice extend ActiveSupport::Concern
module Payable
extend ActiveSupport::Concern
included do included do
scope :unpaid, -> { where('id NOT IN (SELECT invoice_id FROM account_activities WHERE' \ scope :unpaid, -> { where('id NOT IN (SELECT invoice_id FROM account_activities WHERE' \
' invoice_id IS NOT NULL)') } ' invoice_id IS NOT NULL)') }
end end
def payable? def payable?
unpaid? && not_cancelled? unpaid? && not_cancelled?
end end
def paid? def paid?
account_activity account_activity
end end
def receipt_date def receipt_date
account_activity.created_at.to_date account_activity.created_at.to_date
end end
def unpaid? def unpaid?
!paid? !paid?
end
end
end end
end end

View file

@ -1,128 +1,124 @@
module Concerns module Registrar::BookKeeping
module Registrar extend ActiveSupport::Concern
module BookKeeping
extend ActiveSupport::Concern
DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI', DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI',
'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze 'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze
def monthly_summary(month:) def monthly_summary(month:)
activities = monthly_activites(month) activities = monthly_activites(month)
return unless activities.any? return unless activities.any?
invoice = { invoice = {
'number': 1, 'number': 1,
'customer': compose_directo_customer, 'customer': compose_directo_customer,
'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency, 'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency,
'date': month.end_of_month.strftime('%Y-%m-%d') 'date': month.end_of_month.strftime('%Y-%m-%d')
}.as_json }.as_json
invoice['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities) invoice['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities)
invoice invoice
end end
def prepare_invoice_lines(month:, activities:) def prepare_invoice_lines(month:, activities:)
lines = [] lines = []
lines << { 'description': title_for_summary(month) } lines << { 'description': title_for_summary(month) }
activities.each do |activity| activities.each do |activity|
fetch_invoice_lines(activity, lines) fetch_invoice_lines(activity, lines)
end end
lines << prepayment_for_all(lines) lines << prepayment_for_all(lines)
lines.as_json lines.as_json
end end
def title_for_summary(date) def title_for_summary(date)
I18n.with_locale(language == 'en' ? 'en' : 'et') do I18n.with_locale(language == 'en' ? 'en' : 'et') do
I18n.t('registrar.monthly_summary_title', date: I18n.l(date, format: '%B %Y')) I18n.t('registrar.monthly_summary_title', date: I18n.l(date, format: '%B %Y'))
end
end
def fetch_invoice_lines(activity, lines)
price = load_price(activity)
if price.duration.include? 'year'
price.duration.to_i.times do |duration|
lines << new_monthly_invoice_line(activity: activity, duration: duration + 1).as_json
end
else
lines << new_monthly_invoice_line(activity: activity).as_json
end
end
def monthly_activites(month)
AccountActivity.where(account_id: account_ids)
.where(created_at: month.beginning_of_month..month.end_of_month)
.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW])
end
def new_monthly_invoice_line(activity:, duration: nil)
price = load_price(activity)
line = {
'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym],
'quantity': 1,
'unit': language == 'en' ? 'pc' : 'tk',
}
finalize_invoice_line(line, price: price, duration: duration, activity: activity)
end
def finalize_invoice_line(line, price:, activity:, duration:)
yearly = price.duration.include?('year')
line['price'] = yearly ? (price.price.amount / price.duration.to_i) : price.price.amount
line['description'] = description_in_language(price: price, yearly: yearly)
if duration.present?
add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1
end
line
end
def add_product_timeframe(line:, activity:, duration:)
create_time = activity.created_at
line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d')
line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d')
end
def description_in_language(price:, yearly:)
timeframe_string = yearly ? 'yearly' : 'monthly'
locale_string = "registrar.invoice_#{timeframe_string}_product_description"
I18n.with_locale(language == 'en' ? 'en' : 'et') do
I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.to_i)
end
end
def prepayment_for_all(lines)
total = 0
en = language == 'en'
lines.each { |l| total += l['quantity'].to_f * l['price'].to_f }
{
'product_id': Setting.directo_receipt_product_name,
'description': en ? 'Domains prepayment' : 'Domeenide ettemaks',
'quantity': -1,
'price': total,
'unit': en ? 'pc' : 'tk',
}
end
def compose_directo_customer
{
'code': accounting_customer_code,
'destination': address_country_code,
'vat_reg_no': vat_no,
}.as_json
end
def load_price(account_activity)
@pricelists ||= {}
return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id
@pricelists[account_activity.price_id] = account_activity.price
end
end end
end end
def fetch_invoice_lines(activity, lines)
price = load_price(activity)
if price.duration.include? 'year'
price.duration.to_i.times do |duration|
lines << new_monthly_invoice_line(activity: activity, duration: duration + 1).as_json
end
else
lines << new_monthly_invoice_line(activity: activity).as_json
end
end
def monthly_activites(month)
AccountActivity.where(account_id: account_ids)
.where(created_at: month.beginning_of_month..month.end_of_month)
.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW])
end
def new_monthly_invoice_line(activity:, duration: nil)
price = load_price(activity)
line = {
'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym],
'quantity': 1,
'unit': language == 'en' ? 'pc' : 'tk',
}
finalize_invoice_line(line, price: price, duration: duration, activity: activity)
end
def finalize_invoice_line(line, price:, activity:, duration:)
yearly = price.duration.include?('year')
line['price'] = yearly ? (price.price.amount / price.duration.to_i) : price.price.amount
line['description'] = description_in_language(price: price, yearly: yearly)
if duration.present?
add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1
end
line
end
def add_product_timeframe(line:, activity:, duration:)
create_time = activity.created_at
line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d')
line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d')
end
def description_in_language(price:, yearly:)
timeframe_string = yearly ? 'yearly' : 'monthly'
locale_string = "registrar.invoice_#{timeframe_string}_product_description"
I18n.with_locale(language == 'en' ? 'en' : 'et') do
I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.to_i)
end
end
def prepayment_for_all(lines)
total = 0
en = language == 'en'
lines.each { |l| total += l['quantity'].to_f * l['price'].to_f }
{
'product_id': Setting.directo_receipt_product_name,
'description': en ? 'Domains prepayment' : 'Domeenide ettemaks',
'quantity': -1,
'price': total,
'unit': en ? 'pc' : 'tk',
}
end
def compose_directo_customer
{
'code': accounting_customer_code,
'destination': address_country_code,
'vat_reg_no': vat_no,
}.as_json
end
def load_price(account_activity)
@pricelists ||= {}
return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id
@pricelists[account_activity.price_id] = account_activity.price
end
end end

View file

@ -1,16 +1,12 @@
module Concerns module Registrar::LegalDoc
module Registrar extend ActiveSupport::Concern
module LegalDoc
extend ActiveSupport::Concern
def legaldoc_mandatory? def legaldoc_mandatory?
!legaldoc_not_mandatory? !legaldoc_not_mandatory?
end end
def legaldoc_not_mandatory? def legaldoc_not_mandatory?
setting = Setting.legal_document_is_mandatory setting = Setting.legal_document_is_mandatory
legaldoc_optout || !setting legaldoc_optout || !setting
end
end
end end
end end

View file

@ -7,10 +7,10 @@ module Versions
attr_accessor :version_loader attr_accessor :version_loader
if WITH_CHILDREN.include?(model_name.name) if WITH_CHILDREN.include?(model_name.name)
has_paper_trail versions: { class_name: "#{model_name}Version" }, has_paper_trail versions: { class_name: "Version::#{model_name}Version" },
meta: { children: :children_log } meta: { children: :children_log }
else else
has_paper_trail versions: { class_name: "#{model_name}Version" } has_paper_trail versions: { class_name: "Version::#{model_name}Version" }
end end
# add creator and updator # add creator and updator

View file

@ -1,74 +1,70 @@
module Concerns module Zone::WhoisQueryable
module Zone extend ActiveSupport::Concern
module WhoisQueryable
extend ActiveSupport::Concern
included do included do
after_save :update_whois_record, if: :subzone? after_save :update_whois_record, if: :subzone?
after_destroy :update_whois_record after_destroy :update_whois_record
end end
def subzone? def subzone?
origin.include? '.' origin.include? '.'
end end
def update_whois_record def update_whois_record
UpdateWhoisRecordJob.enqueue origin, 'zone' UpdateWhoisRecordJob.enqueue origin, 'zone'
end end
def generate_data def generate_data
wr = Whois::Record.find_or_initialize_by(name: origin) wr = Whois::Record.find_or_initialize_by(name: origin)
wr.json = generate_json wr.json = generate_json
wr.save wr.save
end end
def generate_json def generate_json
data = {}.with_indifferent_access data = {}.with_indifferent_access
[domain_vars, registrar_vars, registrant_vars].each do |h| [domain_vars, registrar_vars, registrant_vars].each do |h|
data.merge!(h) data.merge!(h)
end
data
end
# Take note - since this concern only used to zone whois queries, dnssec keys are set to
# empty array
def domain_vars
{ disclaimer: Setting.registry_whois_disclaimer, name: origin,
registered: created_at.try(:to_s, :iso8601), status: ['ok (paid and in zone)'],
changed: updated_at.try(:to_s, :iso8601), email: Setting.registry_email,
admin_contacts: [contact_vars], tech_contacts: [contact_vars],
nameservers: nameserver_vars, dnssec_keys: [], dnssec_changed: nil }
end
def registrar_vars
{ registrar: Setting.registry_juridical_name, registrar_website: Setting.registry_url,
registrar_phone: Setting.registry_phone }
end
def registrant_vars
{ registrant: Setting.registry_juridical_name, registrant_reg_no: Setting.registry_reg_no,
registrant_ident_country_code: Setting.registry_country_code, registrant_kind: 'org',
registrant_disclosed_attributes: %w[name email] }
end
def contact_vars
{ name: Setting.registry_invoice_contact, email: Setting.registry_email,
disclosed_attributes: %w[name email] }
end
def nameserver_vars
vars = []
return vars unless ns_records
parsed_ns = ns_records.gsub("\r", '').gsub("\n", '')
parsed_ns.split("#{origin}. IN NS ").each do |ns|
ns.delete_suffix! '.'
vars << ns if ns.match? Nameserver::HOSTNAME_REGEXP
end
vars
end
end end
data
end
# Take note - since this concern only used to zone whois queries, dnssec keys are set to
# empty array
def domain_vars
{ disclaimer: Setting.registry_whois_disclaimer, name: origin,
registered: created_at.try(:to_s, :iso8601), status: ['ok (paid and in zone)'],
changed: updated_at.try(:to_s, :iso8601), email: Setting.registry_email,
admin_contacts: [contact_vars], tech_contacts: [contact_vars],
nameservers: nameserver_vars, dnssec_keys: [], dnssec_changed: nil }
end
def registrar_vars
{ registrar: Setting.registry_juridical_name, registrar_website: Setting.registry_url,
registrar_phone: Setting.registry_phone }
end
def registrant_vars
{ registrant: Setting.registry_juridical_name, registrant_reg_no: Setting.registry_reg_no,
registrant_ident_country_code: Setting.registry_country_code, registrant_kind: 'org',
registrant_disclosed_attributes: %w[name email] }
end
def contact_vars
{ name: Setting.registry_invoice_contact, email: Setting.registry_email,
disclosed_attributes: %w[name email] }
end
def nameserver_vars
vars = []
return vars unless ns_records
parsed_ns = ns_records.gsub("\r", '').gsub("\n", '')
parsed_ns.split("#{origin}. IN NS ").each do |ns|
ns.delete_suffix! '.'
vars << ns if ns.match? Nameserver::HOSTNAME_REGEXP
end
vars
end end
end end

View file

@ -4,11 +4,11 @@ class Contact < ApplicationRecord
include Versions # version/contact_version.rb include Versions # version/contact_version.rb
include EppErrors include EppErrors
include UserEvents include UserEvents
include Concerns::Contact::Transferable include Contact::Transferable
include Concerns::Contact::Identical include Contact::Identical
include Concerns::Contact::Disclosable include Contact::Disclosable
include Concerns::Contact::Archivable include Contact::Archivable
include Concerns::EmailVerifable include EmailVerifable
belongs_to :original, class_name: self.name belongs_to :original, class_name: self.name
belongs_to :registrar, required: true belongs_to :registrar, required: true

View file

@ -1,4 +1,4 @@
module Concerns::Contact::Transferable module Contact::Transferable
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
@ -9,7 +9,7 @@ module Concerns::Contact::Transferable
def transfer(new_registrar) def transfer(new_registrar)
return identical(new_registrar) if identical(new_registrar) return identical(new_registrar) if identical(new_registrar)
new_contact = self.dup new_contact = dup
new_contact.registrar = new_registrar new_contact.registrar = new_registrar
new_contact.original = self new_contact.original = self
new_contact.code = nil new_contact.code = nil

View file

@ -5,7 +5,7 @@ module DNS
validates :origin, :ttl, :refresh, :retry, :expire, :minimum_ttl, :email, :master_nameserver, presence: true validates :origin, :ttl, :refresh, :retry, :expire, :minimum_ttl, :email, :master_nameserver, presence: true
validates :ttl, :refresh, :retry, :expire, :minimum_ttl, numericality: { only_integer: true } validates :ttl, :refresh, :retry, :expire, :minimum_ttl, numericality: { only_integer: true }
validates :origin, uniqueness: true validates :origin, uniqueness: true
include Concerns::Zone::WhoisQueryable include ::Zone::WhoisQueryable
before_destroy do before_destroy do
throw(:abort) if used? throw(:abort) if used?

View file

@ -1,16 +1,16 @@
class Domain < ApplicationRecord class Domain < ApplicationRecord
include UserEvents include UserEvents
include Versions # version/domain_version.rb include Versions # version/domain_version.rb
include Concerns::Domain::Expirable include Domain::Expirable
include Concerns::Domain::Activatable include Domain::Activatable
include Concerns::Domain::ForceDelete include Domain::ForceDelete
include Concerns::Domain::Discardable include Domain::Discardable
include Concerns::Domain::Deletable include Domain::Deletable
include Concerns::Domain::Transferable include Domain::Transferable
include Concerns::Domain::RegistryLockable include Domain::RegistryLockable
include Concerns::Domain::Releasable include Domain::Releasable
include Concerns::Domain::Disputable include Domain::Disputable
include Concerns::Domain::BulkUpdatable include Domain::BulkUpdatable
attr_accessor :roles attr_accessor :roles

View file

@ -1,8 +1,8 @@
class Invoice < ApplicationRecord class Invoice < ApplicationRecord
include Versions include Versions
include Concerns::Invoice::Cancellable include Invoice::Cancellable
include Concerns::Invoice::Payable include Invoice::Payable
include Concerns::Invoice::BookKeeping include Invoice::BookKeeping
belongs_to :buyer, class_name: 'Registrar' belongs_to :buyer, class_name: 'Registrar'
has_one :account_activity has_one :account_activity
@ -34,7 +34,7 @@ class Invoice < ApplicationRecord
before_create :calculate_total, unless: :total? before_create :calculate_total, unless: :total?
before_create :apply_default_buyer_vat_no, unless: :buyer_vat_no? before_create :apply_default_buyer_vat_no, unless: :buyer_vat_no?
attribute :vat_rate, ::Type::VATRate.new attribute :vat_rate, ::Type::VatRate.new
def set_invoice_number def set_invoice_number
last_no = Invoice.order(number: :desc).limit(1).pluck(:number).first last_no = Invoice.order(number: :desc).limit(1).pluck(:number).first

View file

@ -82,7 +82,7 @@ class LegalDocument < ApplicationRecord
end end
end end
contact_ids = DomainVersion.where(item_id: orig_legal.documentable_id).distinct. contact_ids = Version::DomainVersion.where(item_id: orig_legal.documentable_id).distinct.
pluck("object->>'registrant_id'", "object_changes->>'registrant_id'", pluck("object->>'registrant_id'", "object_changes->>'registrant_id'",
"children->>'tech_contacts'", "children->>'admin_contacts'").flatten.uniq "children->>'tech_contacts'", "children->>'admin_contacts'").flatten.uniq
contact_ids = contact_ids.map{|id| contact_ids = contact_ids.map{|id|

View file

@ -1,8 +1,8 @@
class Registrar < ApplicationRecord class Registrar < ApplicationRecord
include Versions # version/registrar_version.rb include Versions # version/registrar_version.rb
include Concerns::Registrar::BookKeeping include Registrar::BookKeeping
include Concerns::EmailVerifable include EmailVerifable
include Concerns::Registrar::LegalDoc include Registrar::LegalDoc
has_many :domains, dependent: :restrict_with_error has_many :domains, dependent: :restrict_with_error
has_many :contacts, dependent: :restrict_with_error has_many :contacts, dependent: :restrict_with_error
@ -30,7 +30,7 @@ class Registrar < ApplicationRecord
validates :vat_rate, numericality: { greater_than_or_equal_to: 0, less_than: 100 }, validates :vat_rate, numericality: { greater_than_or_equal_to: 0, less_than: 100 },
allow_nil: true allow_nil: true
attribute :vat_rate, ::Type::VATRate.new attribute :vat_rate, ::Type::VatRate.new
after_initialize :set_defaults after_initialize :set_defaults
validate :correct_email_format, if: proc { |c| c.will_save_change_to_email? } validate :correct_email_format, if: proc { |c| c.will_save_change_to_email? }

View file

@ -1,5 +1,5 @@
module Type module Type
class VATRate < ActiveRecord::Type::Decimal class VatRate < ActiveRecord::Type::Decimal
def deserialize(value) def deserialize(value)
super * 100 if value super * 100 if value
end end

1
app/models/version.rb Normal file
View file

@ -0,0 +1 @@
class Version; end

View file

@ -1,4 +1,4 @@
class AccountActivityVersion < PaperTrail::Version class Version::AccountActivityVersion < PaperTrail::Version
self.table_name = :log_account_activities self.table_name = :log_account_activities
self.sequence_name = :log_account_activities_id_seq self.sequence_name = :log_account_activities_id_seq
end end

View file

@ -1,4 +1,4 @@
class AccountVersion < PaperTrail::Version class Version::AccountVersion < PaperTrail::Version
self.table_name = :log_accounts self.table_name = :log_accounts
self.sequence_name = :log_accounts_id_seq self.sequence_name = :log_accounts_id_seq
end end

View file

@ -1,4 +1,4 @@
class ActionVersion < PaperTrail::Version class Version::ActionVersion < PaperTrail::Version
self.table_name = :log_actions self.table_name = :log_actions
self.sequence_name = :log_actions_id_seq self.sequence_name = :log_actions_id_seq
end end

View file

@ -1,4 +1,4 @@
class BankStatementVersion < PaperTrail::Version class Version::BankStatementVersion < PaperTrail::Version
self.table_name = :log_bank_statements self.table_name = :log_bank_statements
self.sequence_name = :log_bank_statements_id_seq self.sequence_name = :log_bank_statements_id_seq
end end

View file

@ -1,4 +1,4 @@
class BankTransactionVersion < PaperTrail::Version class Version::BankTransactionVersion < PaperTrail::Version
self.table_name = :log_bank_transactions self.table_name = :log_bank_transactions
self.sequence_name = :log_bank_transactions_id_seq self.sequence_name = :log_bank_transactions_id_seq
end end

View file

@ -1,7 +1,4 @@
module Billing class Version::Billing::PriceVersion < PaperTrail::Version
class PriceVersion < PaperTrail::Version self.table_name = :log_prices
self.table_name = :log_prices self.sequence_name = :log_prices_id_seq
self.sequence_name = :log_prices_id_seq
end
end end

View file

@ -1,4 +1,4 @@
class BlockedDomainVersion < PaperTrail::Version class Version::BlockedDomainVersion < PaperTrail::Version
self.table_name = :log_blocked_domains self.table_name = :log_blocked_domains
self.sequence_name = :log_blocked_domains_id_seq self.sequence_name = :log_blocked_domains_id_seq
end end

View file

@ -1,4 +1,4 @@
class CertificateVersion < PaperTrail::Version class Version::CertificateVersion < PaperTrail::Version
self.table_name = :log_certificates self.table_name = :log_certificates
self.sequence_name = :log_certificates_id_seq self.sequence_name = :log_certificates_id_seq
end end

View file

@ -1,4 +1,4 @@
class ContactVersion < PaperTrail::Version class Version::ContactVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_contacts self.table_name = :log_contacts
self.sequence_name = :log_contacts_id_seq self.sequence_name = :log_contacts_id_seq

View file

@ -1,4 +1,4 @@
class DnskeyVersion < PaperTrail::Version class Version::DnskeyVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_dnskeys self.table_name = :log_dnskeys
self.sequence_name = :log_dnskeys_id_seq self.sequence_name = :log_dnskeys_id_seq

View file

@ -1,4 +1,4 @@
class DomainContactVersion < PaperTrail::Version class Version::DomainContactVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_domain_contacts self.table_name = :log_domain_contacts
self.sequence_name = :log_domain_contacts_id_seq self.sequence_name = :log_domain_contacts_id_seq

View file

@ -1,4 +1,4 @@
class DomainVersion < PaperTrail::Version class Version::DomainVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_domains self.table_name = :log_domains

View file

@ -1,4 +1,4 @@
class InvoiceItemVersion < PaperTrail::Version class Version::InvoiceItemVersion < PaperTrail::Version
self.table_name = :log_invoice_items self.table_name = :log_invoice_items
self.sequence_name = :log_invoice_items_id_seq self.sequence_name = :log_invoice_items_id_seq
end end

View file

@ -1,4 +1,4 @@
class InvoiceVersion < PaperTrail::Version class Version::InvoiceVersion < PaperTrail::Version
self.table_name = :log_invoices self.table_name = :log_invoices
self.sequence_name = :log_invoices_id_seq self.sequence_name = :log_invoices_id_seq
end end

View file

@ -1,4 +1,4 @@
class NameserverVersion < PaperTrail::Version class Version::NameserverVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_nameservers self.table_name = :log_nameservers
self.sequence_name = :log_nameservers_id_seq self.sequence_name = :log_nameservers_id_seq

View file

@ -1,4 +1,4 @@
class NotificationVersion < PaperTrail::Version class Version::NotificationVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_notifications self.table_name = :log_notifications
self.sequence_name = :log_notifications_id_seq self.sequence_name = :log_notifications_id_seq

View file

@ -1,4 +1,4 @@
class PaymentOrderVersion < PaperTrail::Version class Version::PaymentOrderVersion < PaperTrail::Version
self.table_name = :log_payment_orders self.table_name = :log_payment_orders
self.sequence_name = :log_payment_orders_id_seq self.sequence_name = :log_payment_orders_id_seq
end end

View file

@ -1,4 +1,4 @@
class RegistrantVerificationVersion < PaperTrail::Version class Version::RegistrantVerificationVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_registrant_verifications self.table_name = :log_registrant_verifications
self.sequence_name = :log_registrant_verifications_id_seq self.sequence_name = :log_registrant_verifications_id_seq

View file

@ -1,4 +1,4 @@
class RegistrarVersion < PaperTrail::Version class Version::RegistrarVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_registrars self.table_name = :log_registrars
self.sequence_name = :log_registrars_id_seq self.sequence_name = :log_registrars_id_seq

View file

@ -1,4 +1,4 @@
class ReservedDomainVersion < PaperTrail::Version class Version::ReservedDomainVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_reserved_domains self.table_name = :log_reserved_domains
self.sequence_name = :log_reserved_domains_id_seq self.sequence_name = :log_reserved_domains_id_seq

View file

@ -1,4 +1,4 @@
class SettingEntryVersion < PaperTrail::Version class Version::SettingEntryVersion < PaperTrail::Version
self.table_name = :log_setting_entries self.table_name = :log_setting_entries
self.sequence_name = :log_setting_entries self.sequence_name = :log_setting_entries
end end

View file

@ -1,4 +1,4 @@
class SettingVersion < PaperTrail::Version class Version::SettingVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_settings self.table_name = :log_settings
self.sequence_name = :log_settings_id_seq self.sequence_name = :log_settings_id_seq

View file

@ -1,4 +1,4 @@
class UserVersion < PaperTrail::Version class Version::UserVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_users self.table_name = :log_users
self.sequence_name = :log_users_id_seq self.sequence_name = :log_users_id_seq

View file

@ -1,4 +1,4 @@
class WhiteIpVersion < PaperTrail::Version class Version::WhiteIpVersion < PaperTrail::Version
include VersionSession include VersionSession
self.table_name = :log_white_ips self.table_name = :log_white_ips
self.sequence_name = :log_white_ips_id_seq self.sequence_name = :log_white_ips_id_seq

View file

@ -1,4 +1,4 @@
class Registrar::DomainListCSVPresenter class Registrar::DomainListCsvPresenter
def initialize(domains:, view:) def initialize(domains:, view:)
@domains = domains @domains = domains
@view = view @view = view

View file

@ -66,7 +66,7 @@
= domain.registrant.name = domain.registrant.name
- else - else
- contact = Contact.all_versions_for([domain.registrant_id], version.created_at).first - contact = Contact.all_versions_for([domain.registrant_id], version.created_at).first
- if contact.nil? && ver = ContactVersion.where(item_id: domain.registrant_id).last - if contact.nil? && ver = Version::ContactVersion.where(item_id: domain.registrant_id).last
- contact = Contact.new(ver.object.to_h.merge(ver.object_changes.to_h.each_with_object({}) {|(k,v), o| o[k] = v.last })) - contact = Contact.new(ver.object.to_h.merge(ver.object_changes.to_h.each_with_object({}) {|(k,v), o| o[k] = v.last }))
= contact.try(:name) = contact.try(:name)
= "&#160;".html_safe = "&#160;".html_safe

View file

@ -23,7 +23,7 @@
- admin_contacts = domain.admin_contacts - admin_contacts = domain.admin_contacts
- registrant = domain.registrant - registrant = domain.registrant
- unless registrant - unless registrant
- ver = ContactVersion.where(item_id: domain.registrant_id).where(event: :destroy).last - ver = Version::ContactVersion.where(item_id: domain.registrant_id).where(event: :destroy).last
- registrant = ver.reify - registrant = ver.reify
- registrant.version_loader = ver - registrant.version_loader = ver
- registrant = [registrant] - registrant = [registrant]

View file

@ -17,7 +17,7 @@ end
module DomainNameRegistry module DomainNameRegistry
class Application < Rails::Application class Application < Rails::Application
config.load_defaults 6.0 config.load_defaults 6.0
config.autoloader = :classic # Do not use zeitwerk for now config.autoloader = :zeitwerk # Do not use zeitwerk for now
# Settings in config/environments/* take precedence over those specified here. # Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers # Application configuration should go into files in config/initializers
@ -35,9 +35,9 @@ module DomainNameRegistry
# config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')] # config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
# Autoload all model subdirs # Autoload all model subdirs
config.autoload_paths += Dir[Rails.root.join('app', 'models', '**/')] # config.autoload_paths += Dir[Rails.root.join('app', 'models', '**/')]
config.autoload_paths += Dir[Rails.root.join('app', 'lib', '**/')] # config.autoload_paths += Dir[Rails.root.join('app', 'lib', '**/')]
config.autoload_paths += Dir[Rails.root.join('app', 'interactions', '**/')] # config.autoload_paths += Dir[Rails.root.join('app', 'interactions', '**/')]
config.eager_load_paths << config.root.join('lib', 'validators') config.eager_load_paths << config.root.join('lib', 'validators')
config.eager_load_paths << config.root.join('app', 'lib') config.eager_load_paths << config.root.join('app', 'lib')
config.watchable_dirs['lib'] = %i[rb] config.watchable_dirs['lib'] = %i[rb]
@ -72,8 +72,7 @@ module DomainNameRegistry
} }
config.action_mailer.default_options = { from: ENV['action_mailer_default_from'] } config.action_mailer.default_options = { from: ENV['action_mailer_default_from'] }
require "#{Rails.root}/app/mailers/interceptors/punycode_interceptor" config.action_mailer.interceptors = ["Interceptors::PunycodeInterceptor"]
ActionMailer::Base.register_interceptor(PunycodeInterceptor)
config.action_view.default_form_builder = 'DefaultFormBuilder' config.action_view.default_form_builder = 'DefaultFormBuilder'
config.secret_key_base = Figaro.env.secret_key_base config.secret_key_base = Figaro.env.secret_key_base

View file

@ -247,12 +247,24 @@ Rails.application.routes.draw do
end end
end end
resources :version_domain_versions do
collection do
get 'search' => 'domain_versions#search', via: [:get, :post], as: :search
end
end
resources :contact_versions do resources :contact_versions do
collection do collection do
get 'search' get 'search'
end end
end end
resources :version_contact_versions do
collection do
get 'search' => 'contact_versions#search', via: [:get, :post], as: :search
end
end
resources :settings, only: %i[index create] resources :settings, only: %i[index create]
resources :blocked_domains do resources :blocked_domains do

View file

@ -16,8 +16,8 @@ namespace :documents do
next if x.documentable_id.blank? next if x.documentable_id.blank?
document_type = case x.documentable_type document_type = case x.documentable_type
when 'Domain' then DomainVersion when 'Domain' then Version::DomainVersion
when 'Contact'then ContactVersion when 'Contact'then Version::ContactVersion
end end
dc = document_type.where(item_id: x.documentable_id) dc = document_type.where(item_id: x.documentable_id)

View file

@ -7,7 +7,7 @@ class VersionsTest < ActiveSupport::TestCase
@nameserver.update(hostname: 'ns99.bestnames.test') @nameserver.update(hostname: 'ns99.bestnames.test')
@ignored_column_title = Nameserver.ignored_columns.first @ignored_column_title = Nameserver.ignored_columns.first
version = NameserverVersion.last version = Version::NameserverVersion.last
hash = version.object hash = version.object
hash[@ignored_column_title] = 123456 hash[@ignored_column_title] = 123456
version.update(object: hash) version.update(object: hash)

View file

@ -6,8 +6,8 @@ class ArchivableContactTest < ActiveSupport::TestCase
end end
def test_contact_is_archivable_when_it_was_linked_and_inactivity_period_has_passed def test_contact_is_archivable_when_it_was_linked_and_inactivity_period_has_passed
DomainVersion.stub(:was_contact_linked?, true) do Version::DomainVersion.stub(:was_contact_linked?, true) do
DomainVersion.stub(:contact_unlinked_more_than?, true) do Version::DomainVersion.stub(:contact_unlinked_more_than?, true) do
assert @contact.archivable? assert @contact.archivable?
end end
end end
@ -18,7 +18,7 @@ class ArchivableContactTest < ActiveSupport::TestCase
@contact.created_at = Time.zone.parse('2010-07-05 00:00:00') @contact.created_at = Time.zone.parse('2010-07-05 00:00:00')
travel_to Time.zone.parse('2010-07-05 00:00:01') travel_to Time.zone.parse('2010-07-05 00:00:01')
DomainVersion.stub(:was_contact_linked?, false) do Version::DomainVersion.stub(:was_contact_linked?, false) do
assert @contact.archivable? assert @contact.archivable?
end end
end end
@ -28,14 +28,14 @@ class ArchivableContactTest < ActiveSupport::TestCase
@contact.created_at = Time.zone.parse('2010-07-05') @contact.created_at = Time.zone.parse('2010-07-05')
travel_to Time.zone.parse('2010-07-05') travel_to Time.zone.parse('2010-07-05')
DomainVersion.stub(:contact_unlinked_more_than?, false) do Version::DomainVersion.stub(:contact_unlinked_more_than?, false) do
assert_not @contact.archivable? assert_not @contact.archivable?
end end
end end
def test_contact_is_not_archivable_when_it_was_ever_linked_but_linked_within_inactivity_period def test_contact_is_not_archivable_when_it_was_ever_linked_but_linked_within_inactivity_period
DomainVersion.stub(:was_contact_linked?, true) do Version::DomainVersion.stub(:was_contact_linked?, true) do
DomainVersion.stub(:contact_unlinked_more_than?, false) do Version::DomainVersion.stub(:contact_unlinked_more_than?, false) do
assert_not @contact.archivable? assert_not @contact.archivable?
end end
end end
@ -73,7 +73,7 @@ class ArchivableContactTest < ActiveSupport::TestCase
def archivable_contact def archivable_contact
contact = contacts(:john) contact = contacts(:john)
Setting.orphans_contacts_in_months = 0 Setting.orphans_contacts_in_months = 0
DomainVersion.delete_all Version::DomainVersion.delete_all
other_contact = contacts(:william) other_contact = contacts(:william)
assert_not_equal other_contact, contact assert_not_equal other_contact, contact

View file

@ -15,7 +15,7 @@ class RegistrantVerificationTest < ActiveSupport::TestCase
registrant_verification = registrant_verifications(:one) registrant_verification = registrant_verifications(:one)
random_action = "random#{rand(100)}" random_action = "random#{rand(100)}"
assert_difference -> { RegistrantVerificationVersion.count } do assert_difference -> { Version::RegistrantVerificationVersion.count } do
registrant_verification.update_attributes!(action: random_action) registrant_verification.update_attributes!(action: random_action)
end end
end end
@ -23,11 +23,11 @@ class RegistrantVerificationTest < ActiveSupport::TestCase
def test_reject_changes def test_reject_changes
@registrant_verification = RegistrantVerification.new(domain_id: @domain.id, @registrant_verification = RegistrantVerification.new(domain_id: @domain.id,
verification_token: @token) verification_token: @token)
start_versions_count = RegistrantVerificationVersion.count start_versions_count = Version::RegistrantVerificationVersion.count
assert_nothing_raised do assert_nothing_raised do
@registrant_verification.domain_registrant_change_reject!("email link, #{@initiator}") @registrant_verification.domain_registrant_change_reject!("email link, #{@initiator}")
end end
assert_equal RegistrantVerificationVersion.count, start_versions_count + 1 assert_equal Version::RegistrantVerificationVersion.count, start_versions_count + 1
end end
end end

View file

@ -11,7 +11,7 @@ class DomainVersionTest < ActiveSupport::TestCase
tech_contacts: [], tech_contacts: [],
registrant: [@contact.id] }) registrant: [@contact.id] })
assert DomainVersion.was_contact_linked?(@contact.id) assert Version::DomainVersion.was_contact_linked?(@contact.id)
end end
def test_was_contact_linked_returns_true_when_contact_was_used_as_admin_contact def test_was_contact_linked_returns_true_when_contact_was_used_as_admin_contact
@ -19,7 +19,7 @@ class DomainVersionTest < ActiveSupport::TestCase
tech_contacts: [], tech_contacts: [],
registrant: [] }) registrant: [] })
assert DomainVersion.was_contact_linked?(@contact.id) assert Version::DomainVersion.was_contact_linked?(@contact.id)
end end
def test_was_contact_linked_returns_true_when_contact_was_used_as_tech_contact def test_was_contact_linked_returns_true_when_contact_was_used_as_tech_contact
@ -27,7 +27,7 @@ class DomainVersionTest < ActiveSupport::TestCase
tech_contacts: [@contact.id], tech_contacts: [@contact.id],
registrant: [] }) registrant: [] })
assert DomainVersion.was_contact_linked?(@contact.id) assert Version::DomainVersion.was_contact_linked?(@contact.id)
end end
def test_was_contact_linked_returns_false_when_contact_was_not_used def test_was_contact_linked_returns_false_when_contact_was_not_used
@ -35,7 +35,7 @@ class DomainVersionTest < ActiveSupport::TestCase
tech_contacts: [], tech_contacts: [],
registrant: [] }) registrant: [] })
assert_not DomainVersion.was_contact_linked?(@contact.id) assert_not Version::DomainVersion.was_contact_linked?(@contact.id)
end end
def test_contact_unlinked_more_than_returns_true_when_contact_was_linked_as_registrant_more_than_given_period def test_contact_unlinked_more_than_returns_true_when_contact_was_linked_as_registrant_more_than_given_period
@ -45,7 +45,7 @@ class DomainVersionTest < ActiveSupport::TestCase
registrant: [@contact.id] }) registrant: [@contact.id] })
travel_to Time.zone.parse('2010-07-05 00:00:01') travel_to Time.zone.parse('2010-07-05 00:00:01')
assert DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day) assert Version::DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day)
end end
def test_contact_unlinked_more_than_given_period_as_admin_contact def test_contact_unlinked_more_than_given_period_as_admin_contact
@ -55,7 +55,7 @@ class DomainVersionTest < ActiveSupport::TestCase
registrant: [] }) registrant: [] })
travel_to Time.zone.parse('2010-07-05 00:00:01') travel_to Time.zone.parse('2010-07-05 00:00:01')
assert DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day) assert Version::DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day)
end end
def test_contact_unlinked_more_than_given_period_as_tech_contact def test_contact_unlinked_more_than_given_period_as_tech_contact
@ -65,7 +65,7 @@ class DomainVersionTest < ActiveSupport::TestCase
registrant: [] }) registrant: [] })
travel_to Time.zone.parse('2010-07-05 00:00:01') travel_to Time.zone.parse('2010-07-05 00:00:01')
assert DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day) assert Version::DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day)
end end
def test_contact_linked_within_given_period_as_registrant def test_contact_linked_within_given_period_as_registrant
@ -75,7 +75,7 @@ class DomainVersionTest < ActiveSupport::TestCase
registrant: [@contact.id] }) registrant: [@contact.id] })
travel_to Time.zone.parse('2010-07-05') travel_to Time.zone.parse('2010-07-05')
assert_not DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day) assert_not Version::DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day)
end end
def test_contact_linked_within_given_period_as_admin_contact def test_contact_linked_within_given_period_as_admin_contact
@ -85,7 +85,7 @@ class DomainVersionTest < ActiveSupport::TestCase
registrant: [] }) registrant: [] })
travel_to Time.zone.parse('2010-07-05') travel_to Time.zone.parse('2010-07-05')
assert_not DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day) assert_not Version::DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day)
end end
def test_contact_linked_within_given_period_as_tech_contact def test_contact_linked_within_given_period_as_tech_contact
@ -95,11 +95,11 @@ class DomainVersionTest < ActiveSupport::TestCase
registrant: [] }) registrant: [] })
travel_to Time.zone.parse('2010-07-05') travel_to Time.zone.parse('2010-07-05')
assert_not DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day) assert_not Version::DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day)
end end
def test_contact_was_never_linked def test_contact_was_never_linked
DomainVersion.delete_all Version::DomainVersion.delete_all
assert_not DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day) assert_not Version::DomainVersion.contact_unlinked_more_than?(contact_id: @contact.id, period: 1.day)
end end
end end

View file

@ -14,7 +14,7 @@ class ArchiveContactsTaskTest < ActiveSupport::TestCase
def archivable_contact def archivable_contact
contact = contacts(:john) contact = contacts(:john)
Setting.orphans_contacts_in_months = 0 Setting.orphans_contacts_in_months = 0
DomainVersion.delete_all Version::DomainVersion.delete_all
other_contact = contacts(:william) other_contact = contacts(:william)
assert_not_equal other_contact, contact assert_not_equal other_contact, contact

View file

@ -42,7 +42,7 @@ EInvoice.provider = EInvoice::Providers::TestProvider.new
class ActiveSupport::TestCase class ActiveSupport::TestCase
ActiveRecord::Migration.check_pending! ActiveRecord::Migration.check_pending!
fixtures :all fixtures :all
set_fixture_class log_domains: DomainVersion set_fixture_class log_domains: Version::DomainVersion
teardown do teardown do
travel_back travel_back