mirror of
https://github.com/internetee/registry.git
synced 2025-07-22 02:35:57 +02:00
parent 64e3bc885a2cb8b46a1aaa4bf4f121ee7f5d44a6
author Karl Erik Õunapuu <karlerik@kreative.ee> 1591359032 +0300 committer Alex Sherman <yul.golem@gmail.com> 1617029320 +0500 CsyncJob: Don't respect IPv6 if nessecary
This commit is contained in:
parent
e46fdd57af
commit
88e1bc3727
33 changed files with 1475 additions and 119 deletions
132
app/models/csync_record.rb
Normal file
132
app/models/csync_record.rb
Normal file
|
@ -0,0 +1,132 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CsyncRecord < ApplicationRecord
|
||||
include CsyncRecord::Diggable
|
||||
belongs_to :domain, optional: false
|
||||
validates :domain, uniqueness: true
|
||||
validates :cdnskey, :action, :last_scan, presence: true
|
||||
validate :validate_unique_pub_key
|
||||
validate :validate_csync_action
|
||||
validate :validate_cdnskey_format
|
||||
after_save :process_new_dnskey, if: proc { pushable? && !disable_requested? }
|
||||
after_save :remove_dnskeys, if: proc { pushable? && disable_requested? }
|
||||
|
||||
SCAN_CYCLES = 3
|
||||
|
||||
def record_new_scan(result)
|
||||
assign_scanner_data!(result)
|
||||
prefix = "CsyncRecord: #{domain.name}:"
|
||||
|
||||
if save
|
||||
log.info "#{prefix} Cycle done."
|
||||
else
|
||||
log.info "#{prefix}: not processing. Reason: #{errors.full_messages.join(' .')}"
|
||||
CsyncRecord.where(domain: domain).delete_all
|
||||
end
|
||||
end
|
||||
|
||||
def assign_scanner_data!(result)
|
||||
state = result[:type]
|
||||
self.last_scan = Time.zone.now
|
||||
self.times_scanned = (persisted? && cdnskey != result[:cdnskey] ? 1 : times_scanned + 1)
|
||||
self.cdnskey = result[:cdnskey]
|
||||
self.action = initializes_dnssec?(state) ? 'initialized' : determine_csync_intention(state)
|
||||
end
|
||||
|
||||
def dnskey
|
||||
key = Dnskey.new_from_csync(domain: domain, cdnskey: cdnskey)
|
||||
log.info "DNSKEY not valid. #{key.errors.full_messages.join('. ')}." unless key.valid?
|
||||
|
||||
key
|
||||
end
|
||||
|
||||
def destroy_all_but_last_one
|
||||
domain.dnskeys.order(id: :desc).offset(1).destroy_all
|
||||
end
|
||||
|
||||
def process_new_dnskey
|
||||
return unless dnssec_validates?
|
||||
|
||||
if dnskey.save
|
||||
destroy_all_but_last_one
|
||||
finalize_and_notify
|
||||
else
|
||||
log.info "Failed to save DNSKEY. Errors: #{dnskey.errors.full_messages.join('. ')}"
|
||||
end
|
||||
end
|
||||
|
||||
def finalize_and_notify
|
||||
CsyncMailer.dnssec_updated(domain: domain).deliver_now
|
||||
notify_registrar_about_csync
|
||||
CsyncRecord.where(domain: domain).destroy_all
|
||||
log.info "CsyncRecord: #{domain.name}: DNSKEYs updated."
|
||||
end
|
||||
|
||||
def pushable?
|
||||
return true if domain.dnskeys.any? || times_scanned >= SCAN_CYCLES
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def disable_requested?
|
||||
['0 3 0 AA==', '0 3 0 0'].include? cdnskey
|
||||
end
|
||||
|
||||
def remove_dnskeys
|
||||
log.info "CsyncJob: Removing DNSKEYs for domain '#{domain.name}'"
|
||||
domain.dnskeys.destroy_all
|
||||
CsyncMailer.dnssec_deleted(domain: domain).deliver_now
|
||||
notify_registrar_about_csync
|
||||
|
||||
destroy
|
||||
end
|
||||
|
||||
def notify_registrar_about_csync
|
||||
domain.update_whois_record
|
||||
domain.registrar.notifications.create!(text: I18n.t('notifications.texts.csync',
|
||||
domain: domain.name, action: action))
|
||||
end
|
||||
|
||||
def validate_unique_pub_key
|
||||
return false unless domain
|
||||
return true if disable_requested?
|
||||
return true unless domain.dnskeys.where(public_key: dnskey.public_key).any?
|
||||
|
||||
errors.add(:public_key, 'already tied to this domain')
|
||||
end
|
||||
|
||||
def self.by_domain_name(domain_name)
|
||||
domain = Domain.find_by(name: domain_name)
|
||||
log.info "CsyncRecord: '#{domain_name}' not in zone. Not initializing record." unless domain
|
||||
CsyncRecord.find_or_initialize_by(domain: domain) if domain
|
||||
end
|
||||
|
||||
def determine_csync_intention(scan_state)
|
||||
return unless domain.dnskeys.any? && scan_state == 'secure'
|
||||
|
||||
disable_requested? ? 'deactivate' : 'rollover'
|
||||
end
|
||||
|
||||
def initializes_dnssec?(scan_state)
|
||||
true if domain.dnskeys.empty? && !disable_requested? && scan_state == 'insecure'
|
||||
end
|
||||
|
||||
def log
|
||||
@log ||= Rails.env.test? ? logger : Logger.new(STDOUT)
|
||||
@log
|
||||
end
|
||||
|
||||
def validate_csync_action
|
||||
return true if %w[initialized rollover].include? action
|
||||
return true if action == 'deactivate' && disable_requested?
|
||||
|
||||
errors.add(:action, :invalid)
|
||||
end
|
||||
|
||||
def validate_cdnskey_format
|
||||
return true if disable_requested?
|
||||
return true if dnskey.valid?
|
||||
|
||||
errors.add(:cdnskey, :invalid)
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue