mirror of
https://github.com/internetee/registry.git
synced 2025-07-22 18:56:05 +02:00
Merge remote-tracking branch 'origin/add-registrant-api-token-log' into add-role-filter-to-registrant-api
This commit is contained in:
commit
f60bf4013c
60 changed files with 1153 additions and 178 deletions
|
@ -19,6 +19,11 @@ module Actions
|
|||
return
|
||||
end
|
||||
|
||||
if contact.delete_prohibited?
|
||||
contact.errors.add(:statuses, :delete_prohibited)
|
||||
return
|
||||
end
|
||||
|
||||
commit
|
||||
end
|
||||
|
||||
|
|
|
@ -1,2 +1,26 @@
|
|||
class AdminDomainContact < DomainContact
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def self.replace(current_contact, new_contact)
|
||||
affected_domains = []
|
||||
skipped_domains = []
|
||||
admin_contacts = where(contact: current_contact)
|
||||
|
||||
admin_contacts.each do |admin_contact|
|
||||
if admin_contact.domain.bulk_update_prohibited?
|
||||
skipped_domains << admin_contact.domain.name
|
||||
next
|
||||
end
|
||||
begin
|
||||
admin_contact.contact = new_contact
|
||||
admin_contact.save!
|
||||
affected_domains << admin_contact.domain.name
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
skipped_domains << admin_contact.domain.name
|
||||
end
|
||||
end
|
||||
[affected_domains.sort, skipped_domains.sort]
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
class BouncedMailAddress < ApplicationRecord
|
||||
validates :email, :message_id, :bounce_type, :bounce_subtype, :action, :status, presence: true
|
||||
after_destroy :destroy_aws_suppression
|
||||
|
||||
def bounce_reason
|
||||
"#{action} (#{status} #{diagnostic})"
|
||||
|
@ -25,4 +26,20 @@ class BouncedMailAddress < ApplicationRecord
|
|||
diagnostic: bounced_record['diagnosticCode'],
|
||||
}
|
||||
end
|
||||
|
||||
def destroy_aws_suppression
|
||||
return unless BouncedMailAddress.ses_configured?
|
||||
|
||||
res = Aws::SESV2::Client.new.delete_suppressed_destination(email_address: email)
|
||||
res.successful?
|
||||
rescue Aws::SESV2::Errors::ServiceError => e
|
||||
logger.warn("Suppression not removed. #{e}")
|
||||
end
|
||||
|
||||
def self.ses_configured?
|
||||
ses ||= Aws::SESV2::Client.new
|
||||
ses.config.credentials.access_key_id.present?
|
||||
rescue Aws::Errors::MissingRegionError
|
||||
false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,6 +11,13 @@ module Concerns::Contact::Identical
|
|||
ident_country_code
|
||||
org_name
|
||||
]
|
||||
|
||||
IDENTICAL_ATTRIBUTES = %w[
|
||||
ident
|
||||
ident_type
|
||||
ident_country_code
|
||||
].freeze
|
||||
|
||||
private_constant :IDENTIFIABLE_ATTRIBUTES
|
||||
|
||||
def identical(registrar)
|
||||
|
@ -20,6 +27,12 @@ module Concerns::Contact::Identical
|
|||
.where.not(id: id).take
|
||||
end
|
||||
|
||||
def identical_to?(contact)
|
||||
IDENTICAL_ATTRIBUTES.all? do |attribute|
|
||||
attributes[attribute] == contact.attributes[attribute]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def identifiable_hash
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
module Concerns::Domain::Deletable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
DELETE_STATUSES = [
|
||||
DomainStatus::PENDING_DELETE_CONFIRMATION,
|
||||
DomainStatus::PENDING_DELETE,
|
||||
DomainStatus::FORCE_DELETE,
|
||||
].freeze
|
||||
|
||||
private
|
||||
|
||||
def delete_later
|
||||
|
|
|
@ -11,6 +11,11 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
|
|||
lambda {
|
||||
where("(force_delete_data->>'contact_notification_sent_date') is null")
|
||||
}
|
||||
|
||||
HOLD_STATUSES = [
|
||||
DomainStatus::SERVER_HOLD,
|
||||
DomainStatus::CLIENT_HOLD,
|
||||
].freeze
|
||||
end
|
||||
|
||||
class_methods do
|
||||
|
@ -19,6 +24,10 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
|
|||
end
|
||||
end
|
||||
|
||||
def hold_status?
|
||||
HOLD_STATUSES.any? { |status| statuses.include? status }
|
||||
end
|
||||
|
||||
def notification_template(explicit: nil)
|
||||
reason = explicit&.downcase
|
||||
return reason if %w[invalid_email invalid_phone].include?(reason)
|
||||
|
|
|
@ -12,6 +12,7 @@ module Concerns
|
|||
statuses << DomainStatus::SERVER_DELETE_PROHIBITED
|
||||
statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED
|
||||
self.locked_by_registrant_at = Time.zone.now
|
||||
alert_registrar_lock_changes!(lock: true)
|
||||
|
||||
save!
|
||||
end
|
||||
|
@ -42,10 +43,21 @@ module Concerns
|
|||
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
|
||||
|
|
40
app/models/contact_request.rb
Normal file
40
app/models/contact_request.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
class ContactRequest < ApplicationRecord
|
||||
establish_connection :"whois_#{Rails.env}"
|
||||
self.table_name = 'contact_requests'
|
||||
|
||||
STATUS_NEW = 'new'.freeze
|
||||
STATUS_CONFIRMED = 'confirmed'.freeze
|
||||
STATUS_SENT = 'sent'.freeze
|
||||
STATUSES = [STATUS_NEW, STATUS_CONFIRMED, STATUS_SENT].freeze
|
||||
|
||||
validates :whois_record_id, presence: true
|
||||
validates :email, presence: true
|
||||
validates :name, presence: true
|
||||
validates :status, inclusion: { in: STATUSES }
|
||||
|
||||
attr_readonly :secret,
|
||||
:valid_to
|
||||
|
||||
def self.save_record(params)
|
||||
contact_request = new(params)
|
||||
contact_request.secret = create_random_secret
|
||||
contact_request.valid_to = set_valid_to_24_hours_from_now
|
||||
contact_request.status = STATUS_NEW
|
||||
contact_request.save!
|
||||
contact_request
|
||||
end
|
||||
|
||||
def update_status(params)
|
||||
self.status = params['status']
|
||||
self.ip_address = params['ip']
|
||||
save!
|
||||
end
|
||||
|
||||
def self.create_random_secret
|
||||
SecureRandom.hex(64)
|
||||
end
|
||||
|
||||
def self.set_valid_to_24_hours_from_now
|
||||
(Time.zone.now + 24.hours)
|
||||
end
|
||||
end
|
|
@ -107,13 +107,13 @@ class Domain < ApplicationRecord
|
|||
|
||||
validate :status_is_consistant
|
||||
def status_is_consistant
|
||||
has_error = (statuses.include?(DomainStatus::SERVER_HOLD) && statuses.include?(DomainStatus::SERVER_MANUAL_INZONE))
|
||||
unless has_error
|
||||
if (statuses & [DomainStatus::PENDING_DELETE_CONFIRMATION, DomainStatus::PENDING_DELETE, DomainStatus::FORCE_DELETE]).any?
|
||||
has_error = statuses.include? DomainStatus::SERVER_DELETE_PROHIBITED
|
||||
end
|
||||
has_error = (hold_status? && statuses.include?(DomainStatus::SERVER_MANUAL_INZONE))
|
||||
unless has_error
|
||||
if (statuses & DELETE_STATUSES).any?
|
||||
has_error = statuses.include? DomainStatus::SERVER_DELETE_PROHIBITED
|
||||
end
|
||||
errors.add(:domains, I18n.t(:object_status_prohibits_operation)) if has_error
|
||||
end
|
||||
errors.add(:domains, I18n.t(:object_status_prohibits_operation)) if has_error
|
||||
end
|
||||
|
||||
attr_accessor :is_admin
|
||||
|
|
|
@ -42,17 +42,12 @@ class Epp::Contact < Contact
|
|||
)
|
||||
end
|
||||
|
||||
def check_availability(codes)
|
||||
def check_availability(codes, reg:)
|
||||
codes = [codes] if codes.is_a?(String)
|
||||
|
||||
res = []
|
||||
codes.each do |x|
|
||||
contact = find_by_epp_code(x)
|
||||
if contact
|
||||
res << { code: contact.code, avail: 0, reason: 'in use' }
|
||||
else
|
||||
res << { code: x, avail: 1 }
|
||||
end
|
||||
codes.map { |c| c.include?(':') ? c : "#{reg}:#{c}" }.map { |c| c.strip.upcase }.each do |x|
|
||||
c = find_by_epp_code(x)
|
||||
res << (c ? { code: c.code, avail: 0, reason: 'in use' } : { code: x, avail: 1 })
|
||||
end
|
||||
|
||||
res
|
||||
|
@ -87,8 +82,11 @@ class Epp::Contact < Contact
|
|||
'2302' => [ # Object exists
|
||||
[:code, :epp_id_taken]
|
||||
],
|
||||
'2304' => [ # Status prohibits operation
|
||||
[:statuses, :delete_prohibited],
|
||||
],
|
||||
'2305' => [ # Association exists
|
||||
[:domains, :exist]
|
||||
[:domains, :exist],
|
||||
]
|
||||
}
|
||||
end
|
||||
|
|
|
@ -495,7 +495,7 @@ class Epp::Domain < Domain
|
|||
registrant_verification_needed = false
|
||||
# registrant block may not be present, so we need this to rule out false positives
|
||||
if frame.css('registrant').text.present?
|
||||
registrant_verification_needed = (registrant.code != frame.css('registrant').text)
|
||||
registrant_verification_needed = verification_needed?(code: frame.css('registrant').text)
|
||||
end
|
||||
|
||||
if registrant_verification_needed && disputed?
|
||||
|
@ -612,7 +612,6 @@ class Epp::Domain < Domain
|
|||
|
||||
statuses.delete(DomainStatus::SERVER_HOLD)
|
||||
statuses.delete(DomainStatus::EXPIRED)
|
||||
statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED)
|
||||
cancel_pending_delete
|
||||
|
||||
save
|
||||
|
@ -798,4 +797,13 @@ class Epp::Domain < Domain
|
|||
result
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def verification_needed?(code:)
|
||||
new_registrant = Registrant.find_by(code: code)
|
||||
return false if new_registrant.try(:identical_to?, registrant)
|
||||
|
||||
registrant.code != code
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,6 +25,10 @@ class Notification < ApplicationRecord
|
|||
''
|
||||
end
|
||||
|
||||
def registry_lock?
|
||||
text.include?('has been locked') || text.include?('has been unlocked')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_defaults
|
||||
|
|
|
@ -4,8 +4,13 @@ class WhiteIp < ApplicationRecord
|
|||
|
||||
validate :valid_ipv4?
|
||||
validate :valid_ipv6?
|
||||
|
||||
validate :validate_ipv4_and_ipv6
|
||||
before_save :normalize_blank_values
|
||||
|
||||
def normalize_blank_values
|
||||
%i[ipv4 ipv6].each { |c| self[c].present? || self[c] = nil }
|
||||
end
|
||||
|
||||
def validate_ipv4_and_ipv6
|
||||
return if ipv4.present? || ipv6.present?
|
||||
errors.add(:base, I18n.t(:ipv4_or_ipv6_must_be_present))
|
||||
|
@ -50,10 +55,10 @@ class WhiteIp < ApplicationRecord
|
|||
def ids_including(ip)
|
||||
ipv4 = ipv6 = []
|
||||
if check_ip4(ip).present?
|
||||
ipv4 = select { |white_ip| IPAddr.new(white_ip.ipv4, Socket::AF_INET) === check_ip4(ip) }
|
||||
ipv4 = select { |white_ip| check_ip4(white_ip.ipv4) === check_ip4(ip) }
|
||||
end
|
||||
if check_ip6(ip).present?
|
||||
ipv6 = select { |white_ip| IPAddr.new(white_ip.ipv6, Socket::AF_INET6) === check_ip6(ip) }
|
||||
ipv6 = select { |white_ip| check_ip6(white_ip.ipv6) === check_ip6(ip) }
|
||||
end
|
||||
(ipv4 + ipv6).pluck(:id).flatten.uniq
|
||||
end
|
||||
|
|
|
@ -97,7 +97,9 @@ class WhoisRecord < ApplicationRecord
|
|||
end
|
||||
|
||||
def destroy_whois_record
|
||||
Whois::Record.without_auctions.where(name: name).delete_all
|
||||
return if Auction.find_by(domain: name).present?
|
||||
|
||||
Whois::Record.where(name: name).delete_all
|
||||
end
|
||||
|
||||
private
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue