Merge pull request #7 from internetee/staging

Staging
This commit is contained in:
Timo Võhmar 2015-11-24 19:01:41 +02:00
commit 322d7e64e7
41 changed files with 447 additions and 240 deletions

View file

@ -94,6 +94,9 @@ gem 'uuidtools', '2.1.5' # For unique IDs (used by the epp gem)
gem 'que', '0.10.0'
gem 'que-web', '0.4.0'
gem 'daemons-rails', '1.2.1'
gem 'que_mailer',
github: 'prehnRA/que-mailer',
branch: 'master'
# for importing legacy db
gem 'activerecord-import', '0.7.0' # for inserting dummy data

View file

@ -24,6 +24,18 @@ GIT
hpricot
libxml-ruby
GIT
remote: https://github.com/prehnRA/que-mailer.git
revision: 32156f258993348b50a7db2a41eed1bdb0bf4fab
branch: master
specs:
que_mailer (0.0.2)
actionmailer (>= 4.0)
activesupport (>= 4.0)
pg (~> 0)
que (~> 0.6)
rails (>= 4.0)
GIT
remote: https://github.com/rubysec/bundler-audit.git
revision: f89ef7fae1090bbad825ea76812d56d72b417055
@ -599,6 +611,7 @@ DEPENDENCIES
pry (= 0.10.1)
que (= 0.10.0)
que-web (= 0.4.0)
que_mailer!
railroady (= 1.3.0)
rails (= 4.2.4)
rails-settings-cached (= 0.4.1)

View file

@ -25,6 +25,24 @@ module Repp
total_number_of_records: current_user.registrar.domains.count
}
end
# example: curl -u registrar1:password localhost:3000/repp/v1/domains/1/transfer_info -H "Auth-Code: authinfopw1"
get '/:id/transfer_info' do
domain = Domain.where("name = ? OR id=?", params[:id], params[:id]).where(auth_info: request.headers['Auth-Code']).first
error! I18n.t('errors.messages.epp_domain_not_found'), 401 unless domain
contact_repp_json = proc{|contact|
contact.attributes.slice("code", "ident_type", "ident_country_code", "phone", "email", "street", "city", "zip","country_code", "statuses")
}
@response = {
domain: domain.name,
registrant: contact_repp_json.call(domain.registrant),
admin_contacts: domain.admin_contacts.map{|e| contact_repp_json.call(e)},
tech_contacts: domain.tech_contacts.map{|e| contact_repp_json.call(e)}
}
end
end
end
end

View file

@ -47,6 +47,7 @@ class Admin::DomainsController < AdminController
def update
dp = ignore_empty_statuses
@domain.is_admin = true
@domain.admin_status_update dp[:statuses]
if @domain.update(dp)
flash[:notice] = I18n.t('domain_updated')

View file

@ -17,7 +17,6 @@ class Admin::PendingDeletesController < AdminController
def destroy
authorize! :destroy, :pending
@epp_domain.is_admin= true
if @domain.clean_pendings!
redirect_to admin_domain_path(@domain.id), notice: t(:pending_removed)
else

View file

@ -7,12 +7,18 @@ class Admin::SettingsController < AdminController
end
def create
@errors = Setting.params_errors(casted_settings)
if @errors.empty?
casted_settings.each do |k, v|
Setting[k] = v
end
flash[:notice] = I18n.t('records_updated')
redirect_to [:admin, :settings]
else
flash[:alert] = @errors.values.uniq.join(", ")
render "admin/settings/index"
end
end
def show; end

View file

@ -64,8 +64,12 @@ class Epp::DomainsController < EppController
else
handle_errors(@domain)
end
rescue
rescue => e
if @domain.errors.any?
handle_errors(@domain)
else
throw e
end
end
end
@ -225,7 +229,7 @@ class Epp::DomainsController < EppController
def find_domain
domain_name = params[:parsed_frame].css('name').text.strip.downcase
@domain = Epp::Domain.where(name: domain_name).includes(registrant: :registrar).first
@domain = Epp::Domain.find_by_idn domain_name
unless @domain
epp_errors << {

View file

@ -11,7 +11,19 @@ class Epp::PollsController < EppController
render_epp_response 'epp/poll/poll_no_messages' and return unless @message
if @message.attached_obj_type && @message.attached_obj_id
begin
@object = Object.const_get(@message.attached_obj_type).find(@message.attached_obj_id)
rescue => problem
# the data model might be inconsistent; or ...
# this could happen if the registrar does not dequeue messages, and then the domain was deleted
# SELECT messages.id, domains.name, messages.body FROM messages LEFT OUTER
# JOIN domains ON attached_obj_id::INTEGER = domains.id
# WHERE attached_obj_type = 'Epp::Domain' AND name IS NULL;
Rails.logger.error 'orphan message, error ignored: ' + problem.to_s
# now we should dequeue or delete the messages avoid duplicate log alarms
end
end
if @message.attached_obj_type == 'Keyrelay'

View file

@ -382,6 +382,6 @@ class EppController < ApplicationController
def iptables_counter_update
return if ENV['iptables_counter_enabled'].blank? && ENV['iptables_counter_enabled'] != 'true'
return if current_user.blank?
counter_update(current_user.registrar_code, request.ip)
counter_update(current_user.registrar_code, ENV['iptables_server_ip'])
end
end

View file

@ -7,12 +7,10 @@ class DomainDeleteConfirmJob < Que::Job
when RegistrantVerification::CONFIRMED
domain.poll_message!(:poll_pending_delete_confirmed_by_registrant)
domain.apply_pending_delete!
domain.clean_pendings!
when RegistrantVerification::REJECTED
DomainMailer.pending_delete_rejected_notification(domain).deliver_now
domain.statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION)
DomainMailer.pending_delete_rejected_notification(domain_id, deliver_emails).deliver
domain.poll_message!(:poll_pending_delete_rejected_by_registrant)
domain.clean_pendings!
domain.cancel_pending_delete
end
destroy # it's best to destroy the job in the same transaction
end

View file

@ -11,7 +11,7 @@ class DomainUpdateConfirmJob < Que::Job
end
domain.clean_pendings!
when RegistrantVerification::REJECTED
DomainMailer.pending_update_rejected_notification_for_new_registrant(domain).deliver_now
DomainMailer.pending_update_rejected_notification_for_new_registrant(domain_id).deliver
domain.poll_message!(:poll_pending_update_rejected_by_registrant)
domain.clean_pendings!
domain.instance_variable_set("@changed_attributes", domain.changed_attributes.merge("statuses"=>[]))

View file

@ -17,8 +17,8 @@ class ApplicationMailer < ActionMailer::Base
end
# turn on delivery on specific (epp) request only, thus rake tasks does not deliver anything
def delivery_off?(model)
return false if model.deliver_emails == true
def delivery_off?(model, deliver_email= false)
return false if deliver_emails == true
logger.info "EMAIL SENDING WAS NOT ACTIVATED " \
"BY MODEL OBJECT: id ##{model.try(:id)} deliver_emails returned false"
true

View file

@ -1,10 +1,12 @@
class ContactMailer < ApplicationMailer
def email_updated(email, contact)
return if delivery_off?(contact)
@contact = contact
include Que::Mailer
def email_updated(email, contact_id, should_deliver)
@contact = Contact.find_by(id: contact_id)
return unless email || @contact
return if delivery_off?(contact, should_deliver)
return if whitelist_blocked?(email)
begin
mail(to: format(email), subject: "#{I18n.t(:contact_email_update_subject)} [#{@contact.code}]")
rescue EOFError,

View file

@ -1,7 +1,10 @@
class DomainMailer < ApplicationMailer
def pending_update_request_for_old_registrant(domain)
@domain = domain
return if delivery_off?(@domain)
include Que::Mailer
def pending_update_request_for_old_registrant(domain_id, should_deliver)
@domain = Domain.find_by(id: domain_id)
return unless @domain
return if delivery_off?(@domain, should_deliver)
if @domain.registrant_verification_token.blank?
logger.warn "EMAIL NOT DELIVERED: registrant_verification_token is missing for #{@domain.name}"
@ -24,9 +27,10 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
def pending_update_notification_for_new_registrant(domain)
@domain = domain
return if delivery_off?(@domain)
def pending_update_notification_for_new_registrant(domain_id, should_deliver)
@domain = Domain.find_by(id: domain_id)
return unless @domain
return if delivery_off?(@domain, should_deliver)
if @domain.registrant_verification_token.blank?
logger.warn "EMAIL NOT DELIVERED: registrant_verification_token is missing for #{@domain.name}"
@ -47,9 +51,10 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
def registrant_updated_notification_for_new_registrant(domain)
@domain = domain
return if delivery_off?(@domain)
def registrant_updated_notification_for_new_registrant(domain_id, should_deliver)
@domain = Domain.find_by(id: domain_id)
return unless @domain
return if delivery_off?(@domain, should_deliver)
return if whitelist_blocked?(@domain.registrant_email)
mail(to: format(@domain.registrant_email),
@ -57,9 +62,10 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
def registrant_updated_notification_for_old_registrant(domain)
@domain = domain
return if delivery_off?(@domain)
def registrant_updated_notification_for_old_registrant(domain_id, should_deliver)
domain = Domain.find_by(id: domain_id)
return unless domain
return if delivery_off?(@domain, should_deliver)
@old_registrant_email = domain.registrant_email # Nb! before applying pending updates
@ -69,8 +75,9 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
def pending_update_rejected_notification_for_new_registrant(domain)
@domain = domain
def pending_update_rejected_notification_for_new_registrant(domain_id)
@domain = Domain.find_by(id: domain_id)
return unless @domain
# no delivery off control, driggered by que, no epp request
@new_registrant_email = @domain.pending_json['new_registrant_email']
@ -82,8 +89,9 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
def pending_update_expired_notification_for_new_registrant(domain)
@domain = domain
def pending_update_expired_notification_for_new_registrant(domain_id)
@domain = Domain.find_by(id: domain_id)
return unless @domain
# no delivery off control, driggered by cron, no epp request
@new_registrant_email = @domain.pending_json['new_registrant_email']
@ -99,9 +107,10 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
def pending_deleted(domain)
@domain = domain
return if delivery_off?(@domain)
def pending_deleted(domain_id, should_deliver)
@domain = Domain.find_by(id: domain_id)
return unless @domain
return if delivery_off?(@domain, should_deliver)
if @domain.registrant_verification_token.blank?
logger.warn "EMAIL NOT DELIVERED: registrant_verification_token is missing for #{@domain.name}"
@ -124,8 +133,10 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
def pending_delete_rejected_notification(domain)
@domain = domain
def pending_delete_rejected_notification(domain_id, should_deliver)
@domain = Domain.find_by(id: domain_id)
return unless @domain
return if delivery_off?(@domain, should_deliver)
# no delivery off control, driggered by que, no epp request
if @domain.registrant_verification_token.blank?
@ -144,8 +155,10 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
def pending_delete_expired_notification(domain)
@domain = domain
def pending_delete_expired_notification(domain_id, should_deliver)
@domain = Domain.find_by(id: domain_id)
return unless @domain
return if delivery_off?(@domain, should_deliver)
# no delivery off control, driggered by cron, no epp request
return if whitelist_blocked?(@domain.registrant.email)
@ -154,8 +167,10 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
def delete_confirmation(domain)
@domain = domain
def delete_confirmation(domain_id, should_deliver)
@domain = Domain.find_by(id: domain_id)
return unless @domain
return if delivery_off?(@domain, should_deliver)
return if whitelist_blocked?(@domain.registrant.email)
mail(to: format(@domain.registrant.email),
@ -163,8 +178,9 @@ class DomainMailer < ApplicationMailer
name: @domain.name)} [#{@domain.name}]")
end
def force_delete(domain)
@domain = domain
def force_delete(domain_id, should_deliver)
@domain = Domain.find_by(id: domain_id)
return if delivery_off?(@domain, should_deliver)
emails = ([@domain.registrant.email] + @domain.admin_contacts.map { |x| format(x.email) }).uniq
return if whitelist_blocked?(emails)

View file

@ -1,8 +1,15 @@
class InvoiceMailer < ApplicationMailer
def invoice_email(invoice, pdf)
return if whitelist_blocked?(invoice.billing_email)
include Que::Mailer
def invoice_email(invoice_id, html)
@invoice = Invoice.find_by(id: invoice_id)
return unless @invoice
return if whitelist_blocked?(@invoice.billing_email)
kit = PDFKit.new(html)
pdf = kit.to_pdf
invoice = @invoice
@invoice = invoice
attachments[invoice.pdf_name] = pdf
mail(to: format(invoice.billing_email), subject: invoice)
end

View file

@ -50,7 +50,7 @@ class Contact < ActiveRecord::Base
emails << domains.map(&:registrant_email) if domains.present?
emails = emails.flatten.uniq
emails.each do |e|
ContactMailer.email_updated(e, self).deliver_now
ContactMailer.email_updated(e, id, deliver_emails).deliver
end
end

View file

@ -12,10 +12,9 @@ module Depp
['6 - DSA-NSEC3-SHA1', 6],
['7 - RSASHA1-NSEC3-SHA1', 7],
['8 - RSA/SHA-256', 8],
['252 - Reserved for Indirect Keys', 252],
['253 - Private algorithm', 253],
['254 - Private algorithm OID', 254],
['255 - Reserved', 255]
['10 - RSA/SHA-512', 10],
['13 - ECDSA Curve P-256 with SHA-256', 13],
['14 - ECDSA Curve P-384 with SHA-384', 14]
]
PROTOCOLS = [3]

View file

@ -17,7 +17,7 @@ class Dnskey < ActiveRecord::Base
end
}
ALGORITHMS = %w(3 5 6 7 8 252 253 254 255)
ALGORITHMS = %w(3 5 6 7 8 10 13 14)
PROTOCOLS = %w(3)
FLAGS = %w(0 256 257) # 256 = ZSK, 257 = KSK

View file

@ -238,10 +238,10 @@ class Domain < ActiveRecord::Base
end
count += 1
if domain.pending_update?
DomainMailer.pending_update_expired_notification_for_new_registrant(domain).deliver_now
DomainMailer.pending_update_expired_notification_for_new_registrant(id).deliver
end
if domain.pending_delete? || domain.pending_delete_confirmation?
DomainMailer.pending_delete_expired_notification(domain).deliver_now
DomainMailer.pending_delete_expired_notification(id, deliver_emails).deliver
end
domain.clean_pendings!
unless Rails.env.test?
@ -307,14 +307,15 @@ class Domain < ActiveRecord::Base
c = 0
Domain.where("statuses @> '{deleteCandidate}'::varchar[]").each do |x|
Whois::Record.where('domain_id = ?', x.id).try(':destroy')
x.destroy
destroy_with_message x
STDOUT << "#{Time.zone.now.utc} Domain.destroy_delete_candidates: by deleteCandidate ##{x.id} (#{x.name})\n" unless Rails.env.test?
c += 1
end
Domain.where('force_delete_at <= ?', Time.zone.now).each do |x|
Whois::Record.where('domain_id = ?', x.id).try(':destroy')
x.destroy
destroy_with_message x
STDOUT << "#{Time.zone.now.utc} Domain.destroy_delete_candidates: by force delete time ##{x.id} (#{x.name})\n" unless Rails.env.test?
c += 1
end
@ -324,6 +325,15 @@ class Domain < ActiveRecord::Base
# rubocop: enable Metrics/AbcSize
# rubocop:enable Rails/FindEach
# rubocop: enable Metrics/LineLength
def destroy_with_message(domain)
domain.destroy
bye_bye = domain.versions.last
domain.registrar.messages.create!(
body: I18n.t(:domain_deleted),
attached_obj_id: bye_bye.id,
attached_obj_type: bye_bye.class.to_s # DomainVersion
)
end
end
def name=(value)
@ -334,6 +344,17 @@ class Domain < ActiveRecord::Base
self[:name_dirty] = value
end
# find by internationalized domain name
# internet domain name => ascii or puny, but db::domains.name is unicode
def self.find_by_idn(name)
domain = self.find_by_name name
if domain.blank? && name.include?('-')
unicode = SimpleIDN.to_unicode name # we have no index on domains.name_puny
domain = self.find_by_name unicode
end
domain
end
def roid
"EIS-#{id}"
end
@ -428,8 +449,8 @@ class Domain < ActiveRecord::Base
new_registrant_email = registrant.email
new_registrant_name = registrant.name
DomainMailer.pending_update_request_for_old_registrant(self).deliver_now
DomainMailer.pending_update_notification_for_new_registrant(self).deliver_now
DomainMailer.pending_update_request_for_old_registrant(id, deliver_emails).deliver
DomainMailer.pending_update_notification_for_new_registrant(id, deliver_emails).deliver
reload # revert back to original
@ -489,7 +510,13 @@ class Domain < ActiveRecord::Base
pending_delete_confirmation!
save(validate: false) # should check if this did succeed
DomainMailer.pending_deleted(self).deliver_now
DomainMailer.pending_deleted(id, deliver_emails).deliver
end
def cancel_pending_delete
statuses.delete DomainStatus::PENDING_DELETE_CONFIRMATION
statuses.delete DomainStatus::PENDING_DELETE
self.delete_at = nil
end
def pricelist(operation, period_i = nil, unit = nil)
@ -619,7 +646,7 @@ class Domain < ActiveRecord::Base
registrar.messages.create!(
body: I18n.t('force_delete_set_on_domain', domain: name)
)
DomainMailer.force_delete(self).deliver_now
DomainMailer.force_delete(id, deliver_emails).deliver
return true
end
false
@ -673,6 +700,21 @@ class Domain < ActiveRecord::Base
statuses.include?(DomainStatus::FORCE_DELETE)
end
# special handling for admin changing status
def admin_status_update(update)
# check for deleted status
statuses.each do |s|
unless update.include? s
case s
when DomainStatus::PENDING_DELETE
self.delete_at = nil
# Handle any other special remove cases?
# when DomainStatus::FORCE_DELETE unset_force_delete
end
end
end
end
def pending_update_prohibited?
(statuses_was & [
DomainStatus::PENDING_DELETE_CONFIRMATION,

View file

@ -148,7 +148,7 @@ class DomainStatus < ActiveRecord::Base
INACTIVE,
FORCE_DELETE,
PENDING_CREATE,
PENDING_DELETE,
#PENDING_DELETE,
PENDING_RENEW,
PENDING_TRANSFER,
PENDING_UPDATE,

View file

@ -236,7 +236,7 @@ class Epp::Domain < Domain
def admin_domain_contacts_attrs(frame, action)
admin_attrs = domain_contact_attrs_from(frame, action, 'admin')
if action && !admin_attrs.empty? && admin_change_prohibited?
if admin_attrs.present? && admin_change_prohibited?
add_epp_error('2304', 'admin', DomainStatus::SERVER_ADMIN_CHANGE_PROHIBITED, I18n.t(:object_status_prohibits_operation))
return []
end
@ -252,7 +252,7 @@ class Epp::Domain < Domain
def tech_domain_contacts_attrs(frame, action)
tech_attrs = domain_contact_attrs_from(frame, action, 'tech')
if action && !tech_attrs.empty? && tech_change_prohibited?
if tech_attrs.present? && tech_change_prohibited?
add_epp_error('2304', 'tech', DomainStatus::SERVER_TECH_CHANGE_PROHIBITED, I18n.t(:object_status_prohibits_operation))
return []
end
@ -314,78 +314,111 @@ class Epp::Domain < Domain
# rubocop: disable Metrics/PerceivedComplexity
# rubocop: disable Metrics/CyclomaticComplexity
def dnskeys_attrs(frame, action)
if frame.css('dsData').any? && !Setting.ds_data_allowed
errors.add(:base, :ds_data_not_allowed)
end
keys = []
return keys if frame.blank?
inf_data = DnsSecKeys.new(frame)
if frame.xpath('keyData').any? && !Setting.key_data_allowed
errors.add(:base, :key_data_not_allowed)
end
res = ds_data_from(frame)
dnskeys_list = key_data_from(frame, res)
if action == 'rem'
to_destroy = []
dnskeys_list.each do |x|
dk = dnskeys.find_by(public_key: x[:public_key])
unless dk
add_epp_error('2303', 'publicKey', x[:public_key], [:dnskeys, :not_found])
next
end
to_destroy << {
id: dk.id,
_destroy: 1
}
end
return to_destroy
if action == 'rem' &&
frame.css('rem > all').first.try(:text) == 'true'
keys = inf_data.mark_destroy_all dnskeys
else
return dnskeys_list
if Setting.key_data_allowed
errors.add(:base, :ds_data_not_allowed) if inf_data.ds_data.present?
keys = inf_data.key_data
end
if Setting.ds_data_allowed
errors.add(:base, :key_data_not_allowed) if inf_data.key_data.present?
keys = inf_data.ds_data
end
if action == 'rem'
keys = inf_data.mark_destroy(dnskeys)
add_epp_error('2303', nil, nil, [:dnskeys, :not_found]) if keys.include? nil
end
end
errors.any? ? [] : keys
end
# rubocop: enable Metrics/PerceivedComplexity
# rubocop: enable Metrics/CyclomaticComplexity
def key_data_from(frame, res)
frame.xpath('keyData').each do |x|
res << {
flags: x.css('flags').first.try(:text),
protocol: x.css('protocol').first.try(:text),
alg: x.css('alg').first.try(:text),
public_key: x.css('pubKey').first.try(:text),
ds_alg: 3,
ds_digest_type: Setting.ds_algorithm
}
class DnsSecKeys
def initialize(frame)
@key_data = []
@ds_data = []
# schema validation prevents both in the same parent node
if frame.css('dsData').present?
ds_data_from frame
else
frame.css('keyData').each do |key|
@key_data.append key_data_from(key)
end
end
end
res
attr_reader :key_data
attr_reader :ds_data
def mark_destroy_all(dns_keys)
# if transition support required mark_destroy dns_keys when has ds/key values otherwise ...
dns_keys.map { |inf_data| mark inf_data }
end
def mark_destroy(dns_keys)
(ds_data.present? ? ds_filter(dns_keys) : kd_filter(dns_keys)).map do |inf_data|
inf_data.blank? ? nil : mark(inf_data)
end
end
private
KEY_INTERFACE = {flags: 'flags', protocol: 'protocol', alg: 'alg', public_key: 'pubKey' }
DS_INTERFACE =
{ ds_key_tag: 'keyTag',
ds_alg: 'alg',
ds_digest_type: 'digestType',
ds_digest: 'digest'
}
def xm_copy(frame, map)
result = {}
map.each do |key, elem|
result[key] = frame.css(elem).first.try(:text)
end
result
end
def key_data_from(frame)
result = xm_copy frame, KEY_INTERFACE
# TODO: can these defaults go where they belong?
result.merge({
ds_alg: 3, # DSA/SHA-1 [DSA] RFC2536
ds_digest_type: Setting.ds_algorithm # only 1
})
end
def ds_data_from(frame)
res = []
frame.css('dsData').each do |x|
data = {
ds_key_tag: x.css('keyTag').first.try(:text),
ds_alg: x.css('alg').first.try(:text),
ds_digest_type: x.css('digestType').first.try(:text),
ds_digest: x.css('digest').first.try(:text)
}
kd = x.css('keyData').first
data.merge!({
flags: kd.css('flags').first.try(:text),
protocol: kd.css('protocol').first.try(:text),
alg: kd.css('alg').first.try(:text),
public_key: kd.css('pubKey').first.try(:text)
}) if kd
res << data
frame.css('dsData').each do |ds_data|
key = ds_data.css('keyData')
ds = xm_copy ds_data, DS_INTERFACE
ds.merge(key_data_from key) if key.present?
@ds_data << ds
end
end
res
def ds_filter(dns_keys)
@ds_data.map do |ds|
dns_keys.find_by(ds.slice(*DS_INTERFACE.keys))
end
end
def kd_filter(dns_keys)
@key_data.map do |key|
dns_keys.find_by(key)
end
end
def mark(inf_data)
{ id: inf_data.id, _destroy: 1 }
end
end
def domain_statuses_attrs(frame, action)
@ -443,21 +476,10 @@ class Epp::Domain < Domain
frame.css("legalDocument").first.content = doc.path if doc && doc.persisted?
end
at_add = attrs_from(frame.css('add'), current_user)
at_add = attrs_from(frame.css('add'), current_user, 'add')
at[:nameservers_attributes] += at_add[:nameservers_attributes]
if !at[:admin_domain_contacts_attributes].empty? && admin_change_prohibited?
add_epp_error('2304', 'admin', DomainStatus::SERVER_ADMIN_CHANGE_PROHIBITED, I18n.t(:object_status_prohibits_operation))
else
at[:admin_domain_contacts_attributes] += at_add[:admin_domain_contacts_attributes]
end
if !at[:tech_domain_contacts_attributes].empty? && tech_change_prohibited?
add_epp_error('2304', 'tech', DomainStatus::SERVER_TECH_CHANGE_PROHIBITED, I18n.t(:object_status_prohibits_operation))
else
at[:tech_domain_contacts_attributes] += at_add[:tech_domain_contacts_attributes]
end
at[:dnskeys_attributes] += at_add[:dnskeys_attributes]
at[:statuses] =
statuses - domain_statuses_attrs(frame.css('rem'), 'rem') + domain_statuses_attrs(frame.css('add'), 'add')
@ -478,7 +500,7 @@ class Epp::Domain < Domain
# rubocop: enable Metrics/CyclomaticComplexity
def apply_pending_update!
old_registrant_email = DomainMailer.registrant_updated_notification_for_old_registrant(self)
old_registrant_email = DomainMailer.registrant_updated_notification_for_old_registrant(id, deliver_emails)
preclean_pendings
user = ApiUser.find(pending_json['current_user_id'])
frame = Nokogiri::XML(pending_json['frame'])
@ -488,8 +510,8 @@ class Epp::Domain < Domain
return unless update(frame, user, false)
clean_pendings!
self.deliver_emails = true # turn on email delivery
DomainMailer.registrant_updated_notification_for_new_registrant(self).deliver_now
old_registrant_email.deliver_now
DomainMailer.registrant_updated_notification_for_new_registrant(id, deliver_emails).deliver
old_registrant_email.deliver
true
end
@ -497,7 +519,7 @@ class Epp::Domain < Domain
preclean_pendings
statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION)
statuses.delete(DomainStatus::PENDING_DELETE)
DomainMailer.delete_confirmation(self).deliver_now
DomainMailer.delete_confirmation(id, deliver_emails).deliver
# TODO: confirm that this actually makes sense
clean_pendings! if valid? && set_pending_delete!
@ -850,7 +872,7 @@ class Epp::Domain < Domain
next
end
if Domain.find_by(name: x)
if Domain.find_by_idn x
res << { name: x, avail: 0, reason: 'in use' }
else
res << { name: x, avail: 1 }

View file

@ -117,7 +117,7 @@ class Invoice < ActiveRecord::Base
return false unless valid?
return false unless billing_email.present?
InvoiceMailer.invoice_email(self, pdf(html)).deliver_now
InvoiceMailer.invoice_email(id, html).deliver
true
end

View file

@ -6,4 +6,18 @@ class Setting < RailsSettings::CachedSettings
Rails.cache.delete_matched('settings:.*')
STDOUT << "#{Time.zone.now.utc} - Settings cache cleared\n"
end
# cannot do instance validation because CachedSetting use save!
def self.params_errors(params)
errors = {}
# DS data allowed and Allow key data cannot be both true
if !!params["key_data_allowed"] && params["key_data_allowed"] == params["ds_data_allowed"]
msg = "#{I18n.t(:key_data_allowed)} and #{I18n.t(:ds_data_with_key_allowed)} cannot be both true"
errors["key_data_allowed"] = msg
errors["ds_data_allowed"] = msg
end
return errors
end
end

View file

@ -7,6 +7,7 @@ class WhoisRecord < ActiveRecord::Base
before_validation :populate
after_save :update_whois_server
after_destroy :destroy_whois_record
class << self
def included
@ -48,6 +49,7 @@ class WhoisRecord < ActiveRecord::Base
h[:registrant] = domain.registrant.name
h[:registrant_email] = domain.registrant.email
@disclosed << [:email, domain.registrant.email]
h[:changed] = domain.registrant.updated_at.try(:to_s, :iso8601)
h[:admin_contacts] = []
@ -83,7 +85,7 @@ class WhoisRecord < ActiveRecord::Base
h[:dnssec_changed] = domain.dnskeys.pluck(:updated_at).max.try(:to_s, :iso8601) rescue nil
h[:disclosed] = @disclosed
h[:disclosed] = @disclosed # later we can replace
h
end
@ -109,4 +111,8 @@ class WhoisRecord < ActiveRecord::Base
wd.json = json
wd.save
end
def destroy_whois_record
Whois::Record.where(name: name).delete_all()
end
end

View file

@ -6,10 +6,10 @@
- if domain.present?
- if version # normal history
- children = HashWithIndifferentAccess.new(version.children)
- nameservers = children[:nameservers] || []
- tech_contacts = children[:tech_contacts] || []
- admin_contacts = children[:admin_contacts] || []
- registrant = children[:registrant] || []
- nameservers = Nameserver.where(id: children[:nameservers])
- tech_contacts = Contact.where(id: children[:tech_contacts])
- admin_contacts = Contact.where(id: children[:admin_contacts])
- registrant = Contact.where(id: children[:registrant])
- event = version.event
- creator = plain_username(version.terminator)
- else # pending history

View file

@ -1,4 +1,4 @@
- if (status == DomainStatus::PENDING_DELETE || status == DomainStatus::PENDING_DELETE_CONFIRMATION)
- if status == DomainStatus::PENDING_DELETE_CONFIRMATION
= link_to(t(:accept_delete), admin_domain_pending_delete_path(f.object.id, f.object.id),
method: :patch, data: { confirm: t(:are_you_sure) },
class: 'btn btn-danger btn-xs')

View file

@ -1,5 +1,5 @@
- value = Setting.send(var)
%tr
%tr{class: (@errors && @errors.has_key?(var.to_s) && "danger")}
%td= t(var)
- if [TrueClass, FalseClass].include?(value.class)
%td

View file

@ -60,6 +60,11 @@ xml.epp_head do
end
end
if @domain.dnskeys.any?
ds_data = Setting.ds_data_allowed ? @domain.dnskeys.find_all { |key| key.ds_digest.present? } : []
key_data = Setting.key_data_allowed ? @domain.dnskeys.find_all { |key| key.public_key.present? } : []
# is there any reason to include <extension> without <secDNS:infData>
xml.extension do
def tag_key_data(xml, key)
xml.tag!('secDNS:keyData') do
@ -81,19 +86,18 @@ xml.epp_head do
end
xml.tag!('secDNS:infData', 'xmlns:secDNS' => 'urn:ietf:params:xml:ns:secDNS-1.1') do
# might not have ds in first key? maybe check any? k.ds_digest if requirements change (DS not accepted by EIS)
if @domain.dnskeys[0].ds_digest.blank?
@domain.dnskeys.sort.each do |key|
tag_key_data(xml, key)
end
else
@domain.dnskeys.sort.each do |key|
if Setting.ds_data_allowed
ds_data.sort.each do |key|
tag_ds_data(xml, key)
end
else
key_data.sort.each do |key|
tag_key_data(xml, key)
end
end
end if @domain.dnskeys.any?
end
end if key_data.present? || ds_data.present?
end
render('epp/shared/trID', builder: xml)
end
end

View file

@ -0,0 +1,4 @@
builder.tag!('domain:delData', 'xmlns:domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd') do
builder.tag!('domain:name', bye_bye.object['name'])
builder.tag!('domain:exDate', bye_bye.created_at)
end

View file

@ -10,8 +10,11 @@ xml.epp_head do
end
xml.resData do
if @message.attached_obj_type == 'DomainTransfer'
case @message.attached_obj_type
when 'DomainTransfer'
xml << render('epp/domains/partials/transfer', builder: xml, dt: @object)
when 'DomainVersion'
xml << render('epp/domains/partials/delete_complete', builder: xml, bye_bye: @object)
end
end if @object

View file

@ -27,7 +27,7 @@ changed: <%= contact['changed'].to_s.tr('T',' ').sub('+', ' +') %>
<%- end -%>
<% if json['tech_contacts'].present? %>
Technical contact:
<%- for contact in json['admin_contacts'] -%>
<%- for contact in json['tech_contacts'] -%>
name: <%= contact['name'] %>
email: Not Disclosed - Visit www.internet.ee for webbased WHOIS
changed: <%= contact['changed'].to_s.tr('T',' ').sub('+', ' +') %>

View file

@ -0,0 +1,30 @@
- domains = contact.all_domains(page: params[:domain_page], per: 20, params: params)
#contacts.panel.panel-default
.panel-heading
.pull-left
= t(:domains)
.pull-right
= form_tag request.path, method: :get do
= select_tag :domain_filter, options_for_select(%w(Registrant AdminDomainContact TechDomainContact), selected: params[:domain_filter]),
include_blank: true, class: 'form-control2 selectize2'
%button.btn.btn-primary
%span.glyphicon.glyphicon-search
.clearfix
.table-responsive
%table.table.table-hover.table-bordered.table-condensed
%thead
%tr
%th{class: 'col-xs-3'}=custom_sort_link t(:domain_name), :name
%th{class: 'col-xs-3'}=custom_sort_link t(:registrar), :registrar_name
%th{class: 'col-xs-3'}=custom_sort_link t(:valid_to), :valid_to
%th{class: 'col-xs-3'}= t(:roles)
%tbody
- domains.each do |x|
%tr
%td= link_to(x.name, info_registrar_domains_path(domain_name: x.name))
%td= x.registrar.name
%td= l(x.valid_to, format: :short)
%td= x.roles.join(", ")
= paginate domains, param_name: :domain_page

View file

@ -10,7 +10,8 @@
.row
.col-md-12= render 'registrar/contacts/partials/statuses', statuses: @contact.statuses
.row
.col-md-12= render 'admin/contacts/partials/domains', contact: Contact.find_by(code: params[:id])
- if @contact.ident.present?
.col-md-12= render 'registrar/contacts/partials/domains', contact: Contact.find_by(code: params[:id])
- else
.row

View file

@ -4,19 +4,13 @@
.panel-body{style: 'word-wrap: break-word;'}
- @data.css('dsData').each do |x|
%dl.dl-horizontal
- if x.css('keyTag').text.present?
- if x.css('digest').text.present?
%dt= t(:ds_key_tag)
%dd= x.css('keyTag').text
- if x.css('alg').first.text.present?
%dt= t(:ds_algorithm)
%dd= x.css('alg').first.text
- if x.css('digestType').text.present?
%dt= t(:ds_digest_type)
%dd= x.css('digestType').text
- if x.css('digest').text.present?
%dt= t(:ds_digest)
%dd= x.css('digest').text
- @data.css('keyData').each do |x|
@ -32,9 +26,9 @@
%dt= t(:public_key)
%dd= x.css('pubKey').text
- @data.css('keyData').each do |x|
- if @data.css('dsData').empty?
%dl.dl-horizontal
- @data.css('keyData').each do |x|
%dt= t(:flag)
%dd= x.css('flags').text

View file

@ -61,6 +61,7 @@ contact_org_enabled: 'false'
# Enable iptables counter updater
# iptables_counter_enabled: 'true'
# iptables_server_ip: '127.0.0.1'
# Custom legal document types. Changing this requires updating EPP extension schema for allowed legalDocEnumType values.
# System default for legal document types is: pdf,bdoc,ddoc,zip,rar,gz,tar,7z,odt,doc,docx

View file

@ -13,7 +13,7 @@ if con.present? && con.table_exists?('settings')
Setting.save_default(:expire_pending_confirmation, 48)
Setting.save_default(:ds_algorithm, 2)
Setting.save_default(:ds_data_allowed, true)
Setting.save_default(:ds_data_allowed, false)
Setting.save_default(:key_data_allowed, true)
Setting.save_default(:dnskeys_min_count, 0)

View file

@ -0,0 +1,5 @@
class IndexDomainsOnName < ActiveRecord::Migration
def change
add_index :domains, :name, unique: true
end
end

View file

@ -83,11 +83,14 @@ Iptables hitcounter is updated by application. For every registrar there is one
````
#!/bin/bash
iptables -A INPUT -p tcp --dport 700 -j CHKLIMITS
iptables -A INPUT -p tcp --dport 700 -s $REGISTRAR_SOURCE -m recent --name $REGISTRAR_CODE --rdest --rcheck --hitcount 100 --seconds 60 -j DROP
iptables -A INPUT -p tcp --dport 700 -s $REGISTRAR_SOURCE2 -m recent --name $REGISTRAR_CODE --rdest --rcheck --hitcount 100 --seconds 60 -j DROP
iptables -A INPUT -p tcp --dport 700 -s $REGISTRAR2_SOURCE -m recent --name $REGISTRAR2_CODE --rdest --rcheck --hitcount 100 --seconds 60 -j DROP
iptables -A INPUT -p tcp --dport 700 -s $REGISTRAR2_SOURCE2 -m recent --name $REGISTRAR2_CODE --rdest --rcheck --hitcount 100 --seconds 60 -j DROP
iptables -N CHKLIMITS
iptables -A CHKLIMITS -p tcp --dport 700 -s $REGISTRAR_SOURCE -m recent --name $REGISTRAR_CODE --rdest --rcheck --hitcount 100 --seconds 60 -j DROP
iptables -A CHKLIMITS -p tcp --dport 700 -s $REGISTRAR_SOURCE2 -m recent --name $REGISTRAR_CODE --rdest --rcheck --hitcount 100 --seconds 60 -j DROP
iptables -A CHKLIMITS -p tcp --dport 700 -s $REGISTRAR2_SOURCE -m recent --name $REGISTRAR2_CODE --rdest --rcheck --hitcount 100 --seconds 60 -j DROP
iptables -A CHKLIMITS -p tcp --dport 700 -s $REGISTRAR2_SOURCE2 -m recent --name $REGISTRAR2_CODE --rdest --rcheck --hitcount 100 --seconds 60 -j DROP
````

View file

@ -50,9 +50,6 @@ Domain name mapping protocol short version:
<update> 1
<domain:update> 1 Attribute: xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd"
<domain:name> 1 Domain name. Can contain unicode characters.
<domain:chg> 0-1 Attributes to change
<domain:registrant> 0-1 Contact reference to the registrant
Optional attribute: verified="yes/no"
<domain:add> 0-1 Objects to add
<domain:contact> 0-n Contact reference. Attribute: type="admin / tech"
<domain:status> 0-n Status description.
@ -72,6 +69,9 @@ Domain name mapping protocol short version:
<domain:ns> 0-1
<domain:hostAttr> 1
<domain:hostName> 1 Hostname of the nameserver
<domain:chg> 0-1 Attributes to change
<domain:registrant> 0-1 Contact reference to the registrant
Optional attribute: verified="yes/no"
<extension> 0-1 Required if registrant is changing
<secDNS:update> 0-1 Attribute: xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"
<secDNS:add> 0-1

View file

@ -8,7 +8,7 @@ describe ContactMailer do
describe 'email changed notification when delivery turned off' do
before :all do
@contact = Fabricate(:contact, email: 'test@example.ee')
@mail = ContactMailer.email_updated('test@example.com', @contact)
@mail = ContactMailer.email_updated('test@example.com', @contact.id, deliver_emails)
end
it 'should not render email subject' do
@ -34,7 +34,7 @@ describe ContactMailer do
@contact = @domain.registrant
@contact.reload # until figured out why registrant_domains not loaded
@contact.deliver_emails = true
@mail = ContactMailer.email_updated('info@example.org', @contact)
@mail = ContactMailer.email_updated('info@example.org', @contact.id, deliver_emails)
end
it 'should render email subject' do
@ -60,7 +60,7 @@ describe ContactMailer do
@contact = @domain.registrant
@contact.reload # until figured out why registrant_domains not loaded
@contact.deliver_emails = true
@mail = ContactMailer.email_updated('info@ääöü.org', @contact)
@mail = ContactMailer.email_updated('info@ääöü.org', @contact.id, deliver_emails)
end
it 'should render email subject' do

View file

@ -9,7 +9,7 @@ describe DomainMailer do
before :all do
@registrant = Fabricate(:registrant, email: 'test@example.com')
@domain = Fabricate(:domain, registrant: @registrant)
@mail = DomainMailer.pending_update_request_for_old_registrant(@domain)
@mail = DomainMailer.pending_update_request_for_old_registrant(@domain.id, deliver_emails)
end
it 'should not render email subject' do
@ -38,7 +38,7 @@ describe DomainMailer do
@domain.registrant_verification_token = '123'
@domain.registrant_verification_asked_at = Time.zone.now
@domain.registrant = @new_registrant
@mail = DomainMailer.pending_update_request_for_old_registrant(@domain)
@mail = DomainMailer.pending_update_request_for_old_registrant(@domain.id, deliver_emails)
end
it 'should render email subject' do
@ -71,7 +71,7 @@ describe DomainMailer do
@domain.registrant_verification_token = '123'
@domain.registrant_verification_asked_at = Time.zone.now
@domain.registrant = @new_registrant
@mail = DomainMailer.pending_update_notification_for_new_registrant(@domain)
@mail = DomainMailer.pending_update_notification_for_new_registrant(@domain.id, deliver_emails)
end
it 'should render email subject' do
@ -100,7 +100,7 @@ describe DomainMailer do
@domain.registrant_verification_token = '123'
@domain.registrant_verification_asked_at = Time.zone.now
@domain.registrant = @new_registrant
@mail = DomainMailer.pending_update_notification_for_new_registrant(@domain)
@mail = DomainMailer.pending_update_notification_for_new_registrant(@domain.id, deliver_emails)
end
it 'should render email subject' do
@ -128,7 +128,7 @@ describe DomainMailer do
@domain.deliver_emails = true
@domain.pending_json['new_registrant_email'] = 'new@example.org'
@domain.pending_json['new_registrant_name'] = 'test name'
@mail = DomainMailer.pending_update_rejected_notification_for_new_registrant(@domain)
@mail = DomainMailer.pending_update_rejected_notification_for_new_registrant(@domain.id)
end
it 'should render email subject' do
@ -153,7 +153,7 @@ describe DomainMailer do
@registrant = Fabricate(:registrant, email: 'test@example.com')
@domain = Fabricate(:domain, registrant: @registrant)
@domain.deliver_emails = true
@mail = DomainMailer.registrant_updated_notification_for_new_registrant(@domain)
@mail = DomainMailer.registrant_updated_notification_for_new_registrant(@domain.id, deliver_emails)
end
it 'should render email subject' do
@ -178,7 +178,7 @@ describe DomainMailer do
@registrant = Fabricate(:registrant, email: 'test@example.com')
@domain = Fabricate(:domain, registrant: @registrant)
@domain.deliver_emails = true
@mail = DomainMailer.registrant_updated_notification_for_old_registrant(@domain)
@mail = DomainMailer.registrant_updated_notification_for_old_registrant(@domain.id, deliver_emails)
end
it 'should render email subject' do
@ -202,7 +202,7 @@ describe DomainMailer do
before :all do
@registrant = Fabricate(:registrant, email: 'test@example.com')
@domain = Fabricate(:domain, registrant: @registrant)
@mail = DomainMailer.pending_deleted(@domain)
@mail = DomainMailer.pending_deleted(@domain.id, deliver_emails)
end
it 'should not render email subject' do
@ -229,7 +229,7 @@ describe DomainMailer do
@domain.deliver_emails = true
@domain.registrant_verification_token = '123'
@domain.registrant_verification_asked_at = Time.zone.now
@mail = DomainMailer.pending_deleted(@domain)
@mail = DomainMailer.pending_deleted(@domain.id, deliver_emails)
end
it 'should render email subject' do
@ -260,7 +260,7 @@ describe DomainMailer do
@domain.deliver_emails = true
@domain.registrant_verification_token = '123'
@domain.registrant_verification_asked_at = Time.zone.now
@mail = DomainMailer.pending_delete_rejected_notification(@domain)
@mail = DomainMailer.pending_delete_rejected_notification(@domain.id, deliver_emails)
end
it 'should render email subject' do
@ -287,7 +287,7 @@ describe DomainMailer do
@domain.deliver_emails = true
@domain.registrant_verification_token = '123'
@domain.registrant_verification_asked_at = Time.zone.now
@mail = DomainMailer.pending_delete_expired_notification(@domain)
@mail = DomainMailer.pending_delete_expired_notification(@domain.id, deliver_emails)
end
it 'should render email subject' do
@ -314,7 +314,7 @@ describe DomainMailer do
@domain.deliver_emails = true
@domain.registrant_verification_token = '123'
@domain.registrant_verification_asked_at = Time.zone.now
@mail = DomainMailer.delete_confirmation(@domain)
@mail = DomainMailer.delete_confirmation(@domain.id, deliver_emails)
end
it 'should render email subject' do