Merge branch 'master' into 2334-remove-que

This commit is contained in:
Thiago Youssef 2022-09-28 07:40:02 -03:00
commit a6a3f72032
240 changed files with 5827 additions and 1432 deletions

View file

@ -3,21 +3,35 @@ module Serializers
class Contact
attr_reader :contact
def initialize(contact, show_address:)
def initialize(contact, options = {})
@contact = contact
@show_address = show_address
@show_address = options[:show_address]
@domain_params = options[:domain_params] || nil
@simplify = options[:simplify] || false
end
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/AbcSize
def to_json(obj = contact)
json = { id: obj.code, name: obj.name, ident: ident,
email: obj.email, phone: obj.phone,
auth_info: obj.auth_info, statuses: obj.statuses,
disclosed_attributes: obj.disclosed_attributes }
return simple_object if @simplify
json = { code: obj.code, name: obj.name, ident: ident, phone: obj.phone,
created_at: obj.created_at, auth_info: obj.auth_info, email: obj.email,
statuses: statuses, disclosed_attributes: obj.disclosed_attributes,
registrar: registrar }
json[:address] = address if @show_address
if @domain_params
json[:domains] = domains
json[:domains_count] = obj.qualified_domain_ids(@domain_params[:domain_filter]).size
end
json
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize
def registrar
contact.registrar.as_json(only: %i[name website])
end
def ident
{
@ -31,6 +45,34 @@ module Serializers
{ street: contact.street, zip: contact.zip, city: contact.city,
state: contact.state, country_code: contact.country_code }
end
def domains
contact.all_domains(page: @domain_params[:page],
per: @domain_params[:per_page],
params: @domain_params)
.map do |d|
{ id: d.uuid, name: d.name, registrar: { name: d.registrar.name },
valid_to: d.valid_to, roles: d.roles }
end
end
def statuses
statuses_with_notes = contact.status_notes
contact.statuses.each do |status|
statuses_with_notes.merge!({ "#{status}": '' }) unless statuses_with_notes.key?(status)
end
statuses_with_notes
end
private
def simple_object
{
id: contact.uuid,
code: contact.code,
name: contact.name,
}
end
end
end
end

View file

@ -3,42 +3,80 @@ module Serializers
class Domain
attr_reader :domain
def initialize(domain, sponsored: true)
def initialize(domain, sponsored: true, simplify: false)
@domain = domain
@sponsored = sponsored
@simplify = simplify
end
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/AbcSize
def to_json(obj = domain)
return simple_object if @simplify
json = {
name: obj.name, registrant: obj.registrant.code, created_at: obj.created_at,
updated_at: obj.updated_at, expire_time: obj.expire_time, outzone_at: obj.outzone_at,
delete_date: obj.delete_date, force_delete_date: obj.force_delete_date,
contacts: contacts, nameservers: nameservers, dnssec_keys: dnssec_keys,
statuses: obj.statuses, registrar: registrar
name: obj.name, registrant: registrant,
created_at: obj.created_at, updated_at: obj.updated_at,
expire_time: obj.expire_time,
outzone_at: obj.outzone_at, delete_date: obj.delete_date,
force_delete_date: obj.force_delete_date, contacts: contacts,
nameservers: nameservers, dnssec_keys: dnssec_keys,
statuses: statuses, registrar: registrar,
dispute: Dispute.active.exists?(domain_name: obj.name)
}
json[:transfer_code] = obj.auth_info if @sponsored
json
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize
def contacts
domain.domain_contacts.map { |c| { code: c.contact_code_cache, type: c.type } }
end
def nameservers
domain.nameservers.map { |ns| { hostname: ns.hostname, ipv4: ns.ipv4, ipv6: ns.ipv6 } }
end
def dnssec_keys
domain.dnskeys.map do |nssec|
{ flags: nssec.flags, protocol: nssec.protocol, alg: nssec.alg,
public_key: nssec.public_key }
domain.domain_contacts.includes(:contact).map do |dc|
contact = dc.contact
{ code: contact.code, type: dc.type,
name: contact.name_disclosed_by_registrar(domain.registrar_id) }
end
end
def nameservers
domain.nameservers.order(:created_at).as_json(only: %i[id hostname ipv4 ipv6])
end
def dnssec_keys
domain.dnskeys.order(:updated_at).as_json(only: %i[id flags protocol alg public_key])
end
def registrar
{ name: domain.registrar.name, website: domain.registrar.website }
domain.registrar.as_json(only: %i[name website])
end
def registrant
rant = domain.registrant
{
name: rant.name,
code: rant.code,
}
end
def statuses
statuses_with_notes = domain.status_notes
domain.statuses.each do |status|
statuses_with_notes.merge!({ "#{status}": '' }) unless statuses_with_notes.key?(status)
end
statuses_with_notes
end
private
def simple_object
json = {
name: domain.name,
expire_time: domain.expire_time,
registrant: registrant,
statuses: statuses,
}
json[:transfer_code] = domain.auth_info if @sponsored
json
end
end
end

View file

@ -0,0 +1,90 @@
module Serializers
module Repp
class Invoice
attr_reader :invoice
def initialize(invoice, simplify: false)
@invoice = invoice
@simplify = simplify
end
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/AbcSize
def to_json(obj = invoice)
return simple_object if @simplify
{
id: obj.id, issue_date: obj.issue_date, cancelled_at: obj.cancelled_at,
paid: obj.paid?, payable: obj.payable?, cancellable: invoice.cancellable?,
receipt_date: obj.receipt_date, payment_link: obj.payment_link,
number: obj.number, subtotal: obj.subtotal, vat_amount: obj.vat_amount,
vat_rate: obj.vat_rate, total: obj.total,
description: obj.description, reference_no: obj.reference_no,
created_at: obj.created_at, updated_at: obj.updated_at,
due_date: obj.due_date, currency: obj.currency,
seller: seller, buyer: buyer, items: items,
recipient: obj.buyer.billing_email,
monthly_invoice: obj.monthly_invoice
}
end
private
def seller
{
name: invoice.seller_name, reg_no: invoice.seller_reg_no,
iban: invoice.seller_iban, bank: invoice.seller_bank,
swift: invoice.seller_swift, vat_no: invoice.seller_vat_no,
address: invoice.seller_address, country: invoice.seller_country.name,
phone: invoice.seller_phone, url: invoice.seller_url,
email: invoice.seller_email,
contact_name: invoice.seller_contact_name
}
end
def buyer
{
name: invoice.buyer_name,
reg_no: invoice.buyer_reg_no,
address: invoice.buyer_address,
country: invoice.buyer_country.name,
phone: invoice.buyer_phone,
url: invoice.buyer_url,
email: invoice.buyer_email,
}
end
def items
if invoice.monthly_invoice
invoice.metadata['items']
else
invoice.items.map do |item|
{ description: item.description, unit: item.unit,
quantity: item.quantity, price: item.price,
sum_without_vat: item.item_sum_without_vat,
vat_amount: item.vat_amount, total: item.total }
end
end
end
def simple_object
{
id: invoice.id,
number: invoice.number,
paid: invoice.paid?,
payable: invoice.payable?,
payment_link: invoice.payment_link,
receipt_date: invoice.receipt_date,
cancelled: invoice.cancelled?,
cancellable: invoice.cancellable?,
due_date: invoice.due_date,
total: invoice.total,
recipient: invoice.buyer.billing_email,
monthly_invoice: invoice.monthly_invoice,
}
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize
end
end
end

View file

@ -0,0 +1,13 @@
desc 'Check Force Delete'
task check_force_delete: :environment do
validations = ValidationEvent.failed.where(validation_eventable_type: 'Contact').uniq(&:validation_eventable_id)
invalid_contact_ids = validations.select do |validation|
contact = validation.validation_eventable
next if contact.nil?
contact.need_to_start_force_delete? || contact.need_to_lift_force_delete?
end.pluck(:validation_eventable_id)
CheckForceDeleteJob.perform_later(invalid_contact_ids) if invalid_contact_ids.present?
end

View file

@ -0,0 +1,85 @@
BASE_URL = ENV['eis_billing_system_base_url'] || 'https://st-billing.infra.tld.ee'
INITIATOR = 'registry'.freeze
namespace :eis_billing do
desc 'One time task to export invoice data to billing system'
task export_invoices: :environment do
parsed_data = []
status = 'unpaid'
Invoice.all.each do |invoice|
if invoice.cancelled?
status = 'cancelled'
else
status = invoice.paid? ? 'paid' : 'unpaid'
end
transaction_time = invoice.receipt_date if invoice.paid?
parsed_data << {
invoice_number: invoice.number,
initiator: 'registry',
transaction_amount: invoice.total,
status: status,
in_directo: invoice.in_directo,
e_invoice_sent_at: invoice.e_invoice_sent_at,
transaction_time: transaction_time
}
end
base_request(url: import_invoice_data_url, json_obj: parsed_data)
end
desc 'One time task to export reference number of registrars to billing system'
task export_references: :environment do
parsed_data = []
Registrar.all.each do |registrar|
parsed_data << {
reference_number: registrar.reference_no,
initiator: 'registry',
registrar_name: registrar.name
}
end
base_request(url: import_reference_data_url, json_obj: parsed_data)
end
end
def import_reference_data_url
"#{BASE_URL}/api/v1/import_data/reference_data"
end
def import_invoice_data_url
"#{BASE_URL}/api/v1/import_data/invoice_data"
end
def base_request(url:, json_obj:)
uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
unless Rails.env.development?
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
http.post(url, json_obj.to_json, headers)
end
def generate_token
JWT.encode(payload, billing_secret)
end
def payload
{ initiator: INITIATOR }
end
def headers
{
'Authorization' => "Bearer #{generate_token}",
'Content-Type' => 'application/json',
}
end
def self.billing_secret
ENV['billing_secret']
end

View file

@ -17,7 +17,7 @@ namespace :registrars do
next if reload_pending || !threshold_reached
Registrar.transaction do
registrar.issue_prepayment_invoice(reload_amount)
registrar.issue_prepayment_invoice(reload_amount, 'reload balance')
registrar.settings['balance_auto_reload']['pending'] = true
registrar.save!
end

View file

@ -4,7 +4,7 @@ require 'syslog/logger'
require 'active_record'
namespace :verify_email do
# bundle exec rake verify_email:check_all -- --domain_name=shop.test --check_level=mx --spam_protect=true
# bundle exec rake verify_email:check_all -- --check_level=mx --spam_protect=true
# bundle exec rake verify_email:check_all -- -dshop.test -cmx -strue
desc 'Starts verifying email jobs with optional check level and spam protection'
task check_all: :environment do
@ -18,17 +18,11 @@ namespace :verify_email do
options = RakeOptionParserBoilerplate.process_args(options: options,
banner: banner,
hash: opts_hash)
batch_contacts = prepare_contacts(options)
logger.info 'No contacts to check email selected' and next if batch_contacts.blank?
batch_contacts.find_in_batches(batch_size: 10_000) do |contacts|
contacts.each do |contact|
VerifyEmailsJob.set(wait_until: spam_protect_timeout(options)).perform_later(
contact: contact,
check_level: check_level(options)
) if filter_check_level(contact)
end
ValidationEvent.old_records.destroy_all
email_contacts = prepare_contacts(options)
email_contacts.each do |email|
VerifyEmailsJob.set(wait_until: spam_protect_timeout(options))
.perform_later(email: email, check_level: check_level(options))
end
end
end
@ -45,10 +39,6 @@ def spam_protect_timeout(options)
spam_protect(options) ? 0.seconds : SPAM_PROTECT_TIMEOUT
end
def logger
@logger ||= ActiveSupport::TaggedLogging.new(Syslog::Logger.new('registry'))
end
def prepare_contacts(options)
if options[:domain_name].present?
contacts_by_domain(options[:domain_name])
@ -56,55 +46,27 @@ def prepare_contacts(options)
time = Time.zone.now - ValidationEvent::VALIDATION_PERIOD
validation_events_ids = ValidationEvent.where('created_at > ?', time).distinct.pluck(:validation_eventable_id)
contacts_ids = Contact.where.not(id: validation_events_ids).pluck(:id)
Contact.where(id: contacts_ids + failed_contacts)
contacts_emails = Contact.where.not(id: validation_events_ids).pluck(:email)
(contacts_emails + failed_email_contacts).uniq
end
end
def filter_check_level(contact)
return true unless contact.validation_events.exists?
data = contact.validation_events.order(created_at: :asc).last
return true if data.successful? && data.created_at < (Time.zone.now - ValidationEvent::VALIDATION_PERIOD)
if data.failed?
return false if data.event_data['check_level'] == 'regex'
# return false if data.event_data['check_level'] == 'smtp'
#
# return false if check_mx_contact_validation(contact)
return true
end
false
end
def failed_contacts
def failed_email_contacts
failed_contacts = []
failed_validations_ids = ValidationEvent.failed.distinct.pluck(:validation_eventable_id)
contacts = Contact.where(id: failed_validations_ids).includes(:validation_events)
contacts.find_each(batch_size: 10_000) do |contact|
failed_contacts << contact.id if filter_check_level(contact)
failed_contacts << contact.email
end
failed_contacts.uniq
end
# def check_mx_contact_validation(contact)
# data = contact.validation_events.mx.order(created_at: :asc).last(ValidationEvent::MX_CHECK)
#
# return false if data.size < ValidationEvent::MX_CHECK
#
# data.all? { |d| d.failed? }
# end
def contacts_by_domain(domain_name)
domain = ::Domain.find_by(name: domain_name)
return unless domain
domain.contacts
domain.contacts.pluck(:email).uniq
end
def opts_hash