mirror of
https://github.com/internetee/registry.git
synced 2025-07-30 14:36:22 +02:00
Merge branch 'master' into 2334-remove-que
This commit is contained in:
commit
a6a3f72032
240 changed files with 5827 additions and 1432 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
90
lib/serializers/repp/invoice.rb
Normal file
90
lib/serializers/repp/invoice.rb
Normal 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
|
13
lib/tasks/check_force_delete.rake
Normal file
13
lib/tasks/check_force_delete.rake
Normal 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
|
85
lib/tasks/eis_billing_import_data.rake
Normal file
85
lib/tasks/eis_billing_import_data.rake
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue