From 93b9049ded6dbd673cee6e132f16d5343c2f443d Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Thu, 12 Nov 2015 10:57:34 +0200 Subject: [PATCH 01/69] Story#107699154 - in whois add registrant email into @disclosed --- app/models/whois_record.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/whois_record.rb b/app/models/whois_record.rb index 9a725b013..83af9ee1d 100644 --- a/app/models/whois_record.rb +++ b/app/models/whois_record.rb @@ -48,6 +48,7 @@ class WhoisRecord < ActiveRecord::Base h[:registrant] = domain.registrant.name h[:registrant_email] = domain.registrant.email + @disclosed << domain.registrant.email h[:changed] = domain.registrant.updated_at.try(:to_s, :iso8601) h[:admin_contacts] = [] @@ -83,7 +84,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 From 714b8364cbc0c77023aaf34c88bc71ceeb84eb04 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 13 Nov 2015 15:01:18 +0200 Subject: [PATCH 02/69] Story #107192666 - only show dsData if allowed, or keyData if allowed --- app/views/epp/domains/info.xml.builder | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/app/views/epp/domains/info.xml.builder b/app/views/epp/domains/info.xml.builder index e7962002c..645c731e4 100644 --- a/app/views/epp/domains/info.xml.builder +++ b/app/views/epp/domains/info.xml.builder @@ -81,18 +81,17 @@ 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) + if Setting.ds_data_allowed + (@domain.dnskeys.find_all { |key| key.ds_digest.present? }).sort.each do |key| + tag_ds_data(xml, key) end else - @domain.dnskeys.sort.each do |key| - tag_ds_data(xml, key) + (@domain.dnskeys.find_all { |key| key.ds_digest.blank? }).sort.each do |key| + tag_key_data(xml, key) end end end - end if @domain.dnskeys.any? + end if @domain.dnskeys.any? && (Setting.ds_data_allowed ? @domain.dnskeys.any? { |key| key.ds_digest.present? } : Setting.key_data_allowed) render('epp/shared/trID', builder: xml) end From ad3a2a6adb89587e36d5e1dab4e742726244093c Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 13 Nov 2015 15:23:24 +0200 Subject: [PATCH 03/69] Story #107192666 - ensure registrary/domains/info shows only actual data patch updates previous revision 7d9272c60c90ba27f272a9495829a121ff26ca43 --- .../registrar/domains/partials/_dnskeys.haml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/app/views/registrar/domains/partials/_dnskeys.haml b/app/views/registrar/domains/partials/_dnskeys.haml index 46dcd0fce..5b8a95ade 100644 --- a/app/views/registrar/domains/partials/_dnskeys.haml +++ b/app/views/registrar/domains/partials/_dnskeys.haml @@ -4,23 +4,17 @@ .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| - %dl.dl-horizontal + - @data.css('keyData').each do |x| + %dl.dl-horizontal %dt= t(:flag) %dd= x.css('flags').text @@ -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 From e7c2444161978665f61a32428aa07cf7598683cf Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 13 Nov 2015 19:06:12 +0200 Subject: [PATCH 04/69] Story #107192666 - refactor to add stricter inclusion rules reformatted block, white space changes, indent for surounding if any? pull up find_all? if *_allowed then check if allowed.any? --- app/views/epp/domains/info.xml.builder | 63 ++++++++++++++------------ 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/app/views/epp/domains/info.xml.builder b/app/views/epp/domains/info.xml.builder index 645c731e4..17892a3cc 100644 --- a/app/views/epp/domains/info.xml.builder +++ b/app/views/epp/domains/info.xml.builder @@ -60,39 +60,44 @@ xml.epp_head do end end - xml.extension do - def tag_key_data(xml, key) - xml.tag!('secDNS:keyData') do - xml.tag!('secDNS:flags', key.flags) - xml.tag!('secDNS:protocol', key.protocol) - xml.tag!('secDNS:alg', key.alg) - xml.tag!('secDNS:pubKey', key.public_key) - 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.ds_digest.blank? } : [] - def tag_ds_data(xml, key) - xml.tag!('secDNS:dsData') do - xml.tag!('secDNS:keyTag', key.ds_key_tag) - xml.tag!('secDNS:alg', key.ds_alg) - xml.tag!('secDNS:digestType', key.ds_digest_type) - xml.tag!('secDNS:digest', key.ds_digest) - tag_key_data(xml, key) if key.public_key.present? - end - end - - xml.tag!('secDNS:infData', 'xmlns:secDNS' => 'urn:ietf:params:xml:ns:secDNS-1.1') do - if Setting.ds_data_allowed - (@domain.dnskeys.find_all { |key| key.ds_digest.present? }).sort.each do |key| - tag_ds_data(xml, key) - end - else - (@domain.dnskeys.find_all { |key| key.ds_digest.blank? }).sort.each do |key| - tag_key_data(xml, key) + # is there any reason to include without + xml.extension do + def tag_key_data(xml, key) + xml.tag!('secDNS:keyData') do + xml.tag!('secDNS:flags', key.flags) + xml.tag!('secDNS:protocol', key.protocol) + xml.tag!('secDNS:alg', key.alg) + xml.tag!('secDNS:pubKey', key.public_key) end end - end - end if @domain.dnskeys.any? && (Setting.ds_data_allowed ? @domain.dnskeys.any? { |key| key.ds_digest.present? } : Setting.key_data_allowed) + def tag_ds_data(xml, key) + xml.tag!('secDNS:dsData') do + xml.tag!('secDNS:keyTag', key.ds_key_tag) + xml.tag!('secDNS:alg', key.ds_alg) + xml.tag!('secDNS:digestType', key.ds_digest_type) + xml.tag!('secDNS:digest', key.ds_digest) + tag_key_data(xml, key) if key.public_key.present? + end + end + + xml.tag!('secDNS:infData', 'xmlns:secDNS' => 'urn:ietf:params:xml:ns:secDNS-1.1') do + 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 + end if key_data.present? || ds_data.present? + end render('epp/shared/trID', builder: xml) end end From fd4b2debb2c2c192ec129e1056427b94f314462e Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 13 Nov 2015 19:30:55 +0200 Subject: [PATCH 05/69] Story #107192666 - refactor dns sec key processing, ensure rules are applied and multiple keys ok --- app/models/epp/domain.rb | 112 +++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 46 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index f59df6ddc..582ad63f4 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -314,20 +314,11 @@ 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 - - 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) - + return [] if frame.empty? + keys = DnsSecKeys.new(self).values frame if action == 'rem' to_destroy = [] - dnskeys_list.each do |x| + keys.each do |x| dk = dnskeys.find_by(public_key: x[:public_key]) unless dk @@ -343,51 +334,80 @@ class Epp::Domain < Domain return to_destroy else - return dnskeys_list + return keys end 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(domain) + @domain = domain end - res - 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 + def values(frame) + if Setting.key_data_allowed + @domain.errors.add(:base, :ds_data_not_allowed) if frame.css('dsData').present? + return key_data_from frame + end + if Setting.ds_data_allowed + @domain.errors.add(:base, :key_data_not_allowed) if frame.css('keyData').present? + return ds_data_from frame + 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, value| + result[key] = frame.css(value).first.try(:text) + end + result + end + + # frame requires NodeSet with direct children of keyData + def key_data(frame) + result = xm_copy frame.css('keyData'), KEY_INTERFACE + # TODO: can these defaults go where they belong? + result.merge({ + ds_alg: 3, + ds_digest_type: Setting.ds_algorithm + }) + end + + # get all top level dsData from NodeSet + def ds_data_from(frame) + result = [] + frame.css('dsData').each do |ds_data| + key = ds_data.css('keyData') + ds = xm_copy ds_data, DS_INTERFACE + ds.merge! (key_data key) if key.present? + result << ds + end + result + end + + def key_data_from(frame) + result = [] + frame.css('keyData').each do |key| + result << key_data(key) + end + result end - res end + def domain_statuses_attrs(frame, action) status_list = domain_status_list_from(frame) if action == 'rem' From 035111e13022958763762f1cf6e8a624e034a369 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Mon, 16 Nov 2015 12:52:26 +0200 Subject: [PATCH 06/69] Story#107192666 - validation for settings that DS data allowed and Allow key data cannot be both true --- app/controllers/admin/settings_controller.rb | 16 +++++++++++----- app/models/setting.rb | 14 ++++++++++++++ app/views/admin/settings/_setting_row.haml | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 6a0c5c033..4014cd7fc 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -7,12 +7,18 @@ class Admin::SettingsController < AdminController end def create - casted_settings.each do |k, v| - Setting[k] = v - end + @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] + 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 diff --git a/app/models/setting.rb b/app/models/setting.rb index 122bfc99a..cb52fd1b7 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -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 diff --git a/app/views/admin/settings/_setting_row.haml b/app/views/admin/settings/_setting_row.haml index 632effc74..ab0d8d991 100644 --- a/app/views/admin/settings/_setting_row.haml +++ b/app/views/admin/settings/_setting_row.haml @@ -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 From 6fcf72a8e73f2a939a403f04780342d842daabec Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Sat, 14 Nov 2015 23:40:45 +0200 Subject: [PATCH 07/69] Story #107192666 - bug fix fd4b2debb2c2c192ec129e1056427b94f314462e, refactor, support secDNS:all --- app/models/epp/domain.rb | 79 +++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 582ad63f4..45694bb1f 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -314,8 +314,31 @@ class Epp::Domain < Domain # rubocop: disable Metrics/PerceivedComplexity # rubocop: disable Metrics/CyclomaticComplexity def dnskeys_attrs(frame, action) - return [] if frame.empty? - keys = DnsSecKeys.new(self).values frame + keys = [] + return keys if frame.blank? + + if frame.xpath('dnsSec:all').present? + # support delete all or all of + else + inf_data = DnsSecKeys.new(frame) + if Setting.key_data_allowed + if inf_data.ds_data.present? + errors.add(:base, :ds_data_not_allowed) + return + else + keys = inf_data.key_data + end + end + if Setting.ds_data_allowed + if inf_data.key_data.present? + errors.add(:base, :key_data_not_allowed) + return + else + keys = inf_data.ds_data + end + end + end + if action == 'rem' to_destroy = [] keys.each do |x| @@ -341,20 +364,22 @@ class Epp::Domain < Domain # rubocop: enable Metrics/CyclomaticComplexity class DnsSecKeys - def initialize(domain) - @domain = domain + def initialize(frame) + @key_data = [] + @ds_data = [] + if frame.css('dsData').present? + ds_data_from frame + end + frame.css('keyData').each do |key| + @key_data.append key_data_from(key) + end end - def values(frame) - if Setting.key_data_allowed - @domain.errors.add(:base, :ds_data_not_allowed) if frame.css('dsData').present? - return key_data_from frame - end - if Setting.ds_data_allowed - @domain.errors.add(:base, :key_data_not_allowed) if frame.css('keyData').present? - return ds_data_from frame - end - [] + attr_reader :key_data + attr_reader :ds_data + + def error + ds_data.present? && key_data.present? end private @@ -369,15 +394,15 @@ class Epp::Domain < Domain def xm_copy(frame, map) result = {} - map.each do |key, value| - result[key] = frame.css(value).first.try(:text) + map.each do |key, elem| + # content validation might happen later in Dnskey, if we get that far; or not. TODO: check handling + result[key] = frame.css(elem).first.try(:text) end result end - # frame requires NodeSet with direct children of keyData - def key_data(frame) - result = xm_copy frame.css('keyData'), KEY_INTERFACE + def key_data_from(frame) + result = xm_copy frame, KEY_INTERFACE # TODO: can these defaults go where they belong? result.merge({ ds_alg: 3, @@ -385,26 +410,14 @@ class Epp::Domain < Domain }) end - # get all top level dsData from NodeSet def ds_data_from(frame) - result = [] frame.css('dsData').each do |ds_data| key = ds_data.css('keyData') ds = xm_copy ds_data, DS_INTERFACE - ds.merge! (key_data key) if key.present? - result << ds + ds.merge! (key_data_from key) if key.present? + @ds_data << ds end - result end - - def key_data_from(frame) - result = [] - frame.css('keyData').each do |key| - result << key_data(key) - end - result - end - end From b0860b278b1a8f465cbe274d2663446be332b925 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Mon, 16 Nov 2015 12:14:11 +0200 Subject: [PATCH 08/69] Story #107192666 - feature fix, keyData interface should include flags=KSK --- app/views/epp/domains/info.xml.builder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/epp/domains/info.xml.builder b/app/views/epp/domains/info.xml.builder index 17892a3cc..f89fcd168 100644 --- a/app/views/epp/domains/info.xml.builder +++ b/app/views/epp/domains/info.xml.builder @@ -62,7 +62,7 @@ xml.epp_head do 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.ds_digest.blank? } : [] + key_data = Setting.key_data_allowed ? @domain.dnskeys.find_all { |key| key.public_key.present? } : [] # is there any reason to include without xml.extension do From d0fbec8f56b417607df2b158b8d150c24d4442fb Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Mon, 16 Nov 2015 13:26:52 +0200 Subject: [PATCH 09/69] Story #107192666 - EIS policy specifies keyData interface not dsData. Both true is not allowed --- config/initializers/initial_settings.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/initial_settings.rb b/config/initializers/initial_settings.rb index bcee95150..35c3eebb3 100644 --- a/config/initializers/initial_settings.rb +++ b/config/initializers/initial_settings.rb @@ -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) From 13c3d2092fe225a9e885a59b9b5729a2311b23e5 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Mon, 16 Nov 2015 17:51:52 +0200 Subject: [PATCH 10/69] Story #107192666 - refactor, add support for remove all, bug fix overly visible nodes --- app/models/epp/domain.rb | 110 +++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 45694bb1f..7b55b018d 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -316,49 +316,26 @@ class Epp::Domain < Domain def dnskeys_attrs(frame, action) keys = [] return keys if frame.blank? + inf_data = DnsSecKeys.new(frame) - if frame.xpath('dnsSec:all').present? - # support delete all or all of + if action == 'rem' && + frame.css('rem > all').first.try(:text) == 'true' + keys = inf_data.mark_destroy_all dnskeys else - inf_data = DnsSecKeys.new(frame) if Setting.key_data_allowed - if inf_data.ds_data.present? - errors.add(:base, :ds_data_not_allowed) - return - else - keys = inf_data.key_data - end + errors.add(:base, :ds_data_not_allowed) if inf_data.ds_data.present? + keys = inf_data.key_data end if Setting.ds_data_allowed - if inf_data.key_data.present? - errors.add(:base, :key_data_not_allowed) - return - else - keys = inf_data.ds_data - end + 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 - - if action == 'rem' - to_destroy = [] - keys.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 - else - return keys - end + errors.any? ? [] : keys end # rubocop: enable Metrics/PerceivedComplexity # rubocop: enable Metrics/CyclomaticComplexity @@ -367,19 +344,28 @@ class Epp::Domain < Domain 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 - end - frame.css('keyData').each do |key| - @key_data.append key_data_from(key) + else + frame.css('keyData').each do |key| + @key_data.append key_data_from(key) + end end end attr_reader :key_data attr_reader :ds_data - def error - ds_data.present? && key_data.present? + 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 @@ -395,7 +381,6 @@ class Epp::Domain < Domain def xm_copy(frame, map) result = {} map.each do |key, elem| - # content validation might happen later in Dnskey, if we get that far; or not. TODO: check handling result[key] = frame.css(elem).first.try(:text) end result @@ -405,8 +390,8 @@ class Epp::Domain < Domain result = xm_copy frame, KEY_INTERFACE # TODO: can these defaults go where they belong? result.merge({ - ds_alg: 3, - ds_digest_type: Setting.ds_algorithm + ds_alg: 3, # DSA/SHA-1 [DSA] RFC2536 + ds_digest_type: Setting.ds_algorithm # only 1 }) end @@ -414,13 +399,28 @@ class Epp::Domain < Domain 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.merge(key_data_from key) if key.present? @ds_data << ds end end + + 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) status_list = domain_status_list_from(frame) if action == 'rem' @@ -822,14 +822,14 @@ class Epp::Domain < Domain def transferrable? (statuses & [ DomainStatus::PENDING_DELETE_CONFIRMATION, - DomainStatus::PENDING_CREATE, - DomainStatus::PENDING_UPDATE, - DomainStatus::PENDING_DELETE, - DomainStatus::PENDING_RENEW, - DomainStatus::PENDING_TRANSFER, - DomainStatus::FORCE_DELETE, - DomainStatus::SERVER_TRANSFER_PROHIBITED, - DomainStatus::CLIENT_TRANSFER_PROHIBITED + DomainStatus::PENDING_CREATE, + DomainStatus::PENDING_UPDATE, + DomainStatus::PENDING_DELETE, + DomainStatus::PENDING_RENEW, + DomainStatus::PENDING_TRANSFER, + DomainStatus::FORCE_DELETE, + DomainStatus::SERVER_TRANSFER_PROHIBITED, + DomainStatus::CLIENT_TRANSFER_PROHIBITED ]).empty? end From 3bb6150c1f968836823219805b31aaf02a54d670 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Fri, 13 Nov 2015 15:09:04 +0200 Subject: [PATCH 11/69] Story#107279016 - admin shows all reserved domains line by line --- .../admin/reserved_domains_controller.rb | 28 +++++++++++++++---- app/models/reserved_domain.rb | 10 ++++++- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/reserved_domains_controller.rb b/app/controllers/admin/reserved_domains_controller.rb index 430fb9d8a..57e4b8ed3 100644 --- a/app/controllers/admin/reserved_domains_controller.rb +++ b/app/controllers/admin/reserved_domains_controller.rb @@ -2,9 +2,9 @@ class Admin::ReservedDomainsController < AdminController load_and_authorize_resource def index - rd = ReservedDomain.first_or_initialize - rd.names = nil if rd.names.blank? - @reserved_domains = rd.names.to_yaml.gsub(/---.?\n/, '').gsub(/\.\.\..?\n/, '') + names = ReservedDomain.pluck(:names).each_with_object({}){|e_h,h| h.merge!(e_h)} + names.names = nil if names.blank? + @reserved_domains = names.to_yaml.gsub(/---.?\n/, '').gsub(/\.\.\..?\n/, '') end def create @@ -20,9 +20,27 @@ class Admin::ReservedDomainsController < AdminController render :index and return end - rd = ReservedDomain.first_or_create + result = true + ReservedDomain.transaction do + # removing old ones + existing = ReservedDomain.any_of_domains(names.keys).pluck(:id) + ReservedDomain.where.not(id: existing).delete_all - if rd.update(names: names) + #updating and adding + names.each do |name, psw| + rec = ReservedDomain.by_domain(name).first + rec ||= ReservedDomain.new + rec.names = {name => psw} + + unless rec.save + result = false + raise ActiveRecord::Rollback + end + end + end + + + if result flash[:notice] = I18n.t('record_updated') redirect_to :back else diff --git a/app/models/reserved_domain.rb b/app/models/reserved_domain.rb index 6684d6541..936c744bf 100644 --- a/app/models/reserved_domain.rb +++ b/app/models/reserved_domain.rb @@ -9,7 +9,15 @@ class ReservedDomain < ActiveRecord::Base class << self def pw_for(domain_name) - select("names -> '#{domain_name}' AS pw").first.try(:pw) + by_domain(domain_name).select("names -> '#{domain_name}' AS pw").first.try(:pw) + end + + def by_domain name + where("names ? '#{name}'") + end + + def any_of_domains names + where("names ?| ARRAY['#{names.join("','")}']") end end end From 3db92b246ac62541f643d004f89ec96112236d7a Mon Sep 17 00:00:00 2001 From: Stas Date: Fri, 13 Nov 2015 15:49:13 +0200 Subject: [PATCH 12/69] 105361584-no access added --- app/views/epp/contacts/info.xml.builder | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/app/views/epp/contacts/info.xml.builder b/app/views/epp/contacts/info.xml.builder index e890e0fb6..d29e60298 100644 --- a/app/views/epp/contacts/info.xml.builder +++ b/app/views/epp/contacts/info.xml.builder @@ -15,6 +15,7 @@ xml.epp_head do xml.tag!('contact:postalInfo', type: 'int') do xml.tag!('contact:name', @contact.name) + if can? :view_full_info, @contact, @password xml.tag!('contact:org', @contact.org_name) if @contact.org_name.present? xml.tag!('contact:addr') do xml.tag!('contact:street', @contact.street) @@ -23,11 +24,27 @@ xml.epp_head do xml.tag!('contact:pc', @contact.zip) xml.tag!('contact:cc', @contact.country_code) end + else + xml.tag!('contact:org', 'No access') + xml.tag!('contact:addr') do + xml.tag!('contact:street', 'No access') + xml.tag!('contact:city', 'No access') + xml.tag!('contact:sp', 'No access') + xml.tag!('contact:pc', 'No access') + xml.tag!('contact:cc', 'No access') + end + end end + if can? :view_full_info, @contact, @password xml.tag!('contact:voice', @contact.phone) xml.tag!('contact:fax', @contact.fax) if @contact.fax.present? xml.tag!('contact:email', @contact.email) + else + xml.tag!('contact:voice', 'No access') + xml.tag!('contact:fax', 'No access') + xml.tag!('contact:email', 'No access') + end xml.tag!('contact:clID', @contact.registrar.try(:name)) if @contact.creator.try(:registrar).blank? && Rails.env.test? From 091ce79dd85e523d666550be612f0bd33d0b1b94 Mon Sep 17 00:00:00 2001 From: Stas Date: Fri, 13 Nov 2015 15:57:45 +0200 Subject: [PATCH 13/69] 105361584-no acces for country --- app/models/depp/contact.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/depp/contact.rb b/app/models/depp/contact.rb index 0fa9f777a..b4597867c 100644 --- a/app/models/depp/contact.rb +++ b/app/models/depp/contact.rb @@ -280,7 +280,7 @@ module Depp end def country_name - Country.new(country_code) + Country.new(country_code) || 'No access' end def org? From be64143db683b607e474f8e0bf52b6f1f25046f8 Mon Sep 17 00:00:00 2001 From: Stas Date: Fri, 13 Nov 2015 16:20:45 +0200 Subject: [PATCH 14/69] 105361584-no access for ident and pass --- app/views/epp/contacts/info.xml.builder | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/views/epp/contacts/info.xml.builder b/app/views/epp/contacts/info.xml.builder index d29e60298..24b37a13f 100644 --- a/app/views/epp/contacts/info.xml.builder +++ b/app/views/epp/contacts/info.xml.builder @@ -62,6 +62,10 @@ xml.epp_head do xml.tag!('contact:authInfo') do xml.tag!('contact:pw', @contact.auth_info) end + else + xml.tag!('contact:authInfo') do + xml.tag!('contact:pw', 'No access') + end end # xml << render('/epp/contacts/disclosure_policy') end @@ -73,6 +77,12 @@ xml.epp_head do type: @contact.ident_type, cc: @contact.ident_country_code) end end + else + xml.tag!('extension') do + xml.tag!('eis:extdata', 'xmlns:eis' => 'https://epp.tld.ee/schema/eis-1.0.xsd') do + xml.tag!('eis:ident', 'No access') + end + end end render('epp/shared/trID', builder: xml) From 71ea9dd961778fc4638da3dc08468bde9895447c Mon Sep 17 00:00:00 2001 From: Stas Date: Fri, 13 Nov 2015 16:40:54 +0200 Subject: [PATCH 15/69] 105361584-ident changes --- app/helpers/application_helper.rb | 9 +++++++-- app/views/epp/contacts/info.xml.builder | 6 ------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 751e1d998..9646bd5c9 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -23,8 +23,13 @@ module ApplicationHelper case ident_type when 'birthday' "#{ident} [#{ident_type}]" - else - "#{ident} [#{ident_country_code} #{ident_type}]" + else + if ident + "#{ident} [#{ident_country_code} #{ident_type}]" + else + "[No access]" + end + end end diff --git a/app/views/epp/contacts/info.xml.builder b/app/views/epp/contacts/info.xml.builder index 24b37a13f..18019208a 100644 --- a/app/views/epp/contacts/info.xml.builder +++ b/app/views/epp/contacts/info.xml.builder @@ -77,12 +77,6 @@ xml.epp_head do type: @contact.ident_type, cc: @contact.ident_country_code) end end - else - xml.tag!('extension') do - xml.tag!('eis:extdata', 'xmlns:eis' => 'https://epp.tld.ee/schema/eis-1.0.xsd') do - xml.tag!('eis:ident', 'No access') - end - end end render('epp/shared/trID', builder: xml) From 55abacdf6be58b1dc08eafb25b4d8918fd23a5e3 Mon Sep 17 00:00:00 2001 From: Stas Date: Fri, 13 Nov 2015 17:14:31 +0200 Subject: [PATCH 16/69] logic fix --- app/helpers/application_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9646bd5c9..098c10d9b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -24,7 +24,7 @@ module ApplicationHelper when 'birthday' "#{ident} [#{ident_type}]" else - if ident + if ident.present? "#{ident} [#{ident_country_code} #{ident_type}]" else "[No access]" From 8cf8d7c4c3c3074c35b6712766b463817243e171 Mon Sep 17 00:00:00 2001 From: Stas Date: Fri, 13 Nov 2015 19:48:46 +0200 Subject: [PATCH 17/69] User import changes --- lib/tasks/import.rake | 78 ++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake index 60574841f..eee769666 100644 --- a/lib/tasks/import.rake +++ b/lib/tasks/import.rake @@ -128,61 +128,69 @@ namespace :import do desc 'Import users' task users: :environment do start = Time.zone.now.to_f - puts '-----> Importing users...' + puts "-----> Importing users and IP's..." + id_users = [] users = [] ips = [] + temp = [] existing_ids = ApiUser.pluck(:legacy_id) - - count = 0 + existing_ips = WhiteIp.pluck(:ipv4) Legacy::Registrar.all.each do |x| - next if existing_ids.include?(x.id) - count += 1 + x.acl.all.each do |y| - if x.acl.last.try(:cert) != 'pki' - if x.acl.last.try(:cert) != 'idkaart' - users << ApiUser.new({ - username: x.handle.try(:strip), - password: x.acl.last.try(:password) ? x.acl.last.try(:password) : ('a'..'z').to_a.shuffle.first(8).join, - identity_code: x.handle.try(:strip), - registrar_id: Registrar.find_by(legacy_id: x.try(:id)).try(:id), - roles: ['epp'], - legacy_id: x.try(:id) - }) - elsif x.acl.last.try(:cert) == 'idkaart' - users << ApiUser.new({ - username: x.acl.last.try(:password) ? x.acl.last.try(:password) : x.acl.first.try(:password), - password: ('a'..'z').to_a.shuffle.first(8).join, - identity_code: x.acl.last.try(:password) ? x.acl.last.try(:password) : x.acl.first.try(:password), - registrar_id: Registrar.find_by(legacy_id: x.try(:id)).try(:id), - roles: ['billing'], - legacy_id: x.try(:id) - }) - end - end + next if existing_ids.include?(y.id) - existing_ips = WhiteIp.pluck(:ipv4) + if y.try(:cert) != 'pki' - x.acl.all.each do |y| - next if existing_ips.include?(y.ipaddr) - if !y.ipaddr.nil? && y.ipaddr != '' - ips << WhiteIp.new({ + if y.try(:cert) == 'idkaart' + id_users << ApiUser.new({ + username: y.try(:password) ? y.try(:password) : y.try(:password), + password: ('a'..'z').to_a.shuffle.first(8).join, + identity_code: y.try(:password) ? y.try(:password) : y.try(:password), registrar_id: Registrar.find_by(legacy_id: x.try(:id)).try(:id), - ipv4: y.ipaddr, - interfaces: ['api', 'registrar'] - }) + roles: ['billing'], + legacy_id: y.try(:id) + }) + else + temp << ApiUser.new({ + username: x.handle.try(:strip), + password: y.try(:password) ? y.try(:password) : ('a'..'z').to_a.shuffle.first(8).join, + registrar_id: Registrar.find_by(legacy_id: x.try(:id)).try(:id), + roles: ['epp'], + legacy_id: y.try(:id) + }) end end + temp = temp.reverse!.uniq{|u| u.username } + end + users = temp + + x.acl.all.each do |y| + next if existing_ips.include?(y.ipaddr) + if !y.ipaddr.nil? && y.ipaddr != '' + ips << WhiteIp.new({ + registrar_id: Registrar.find_by(legacy_id: x.try(:id)).try(:id), + ipv4: y.ipaddr, + interfaces: ['api', 'registrar'] + }) + end + end end + ApiUser.import id_users, validate: false ApiUser.import users, validate: false + if ips WhiteIp.import ips, validate: false end - puts "-----> Imported #{count} new users in #{(Time.zone.now.to_f - start).round(2)} seconds" + + puts "-----> Imported #{id_users.count} billing users and #{users.count} epp users" + puts "-----> Imported #{ips.count} white IP's in #{(Time.zone.now.to_f - start).round(2)} seconds" + end desc 'Import contacts' From e785bce41587280342f708f3ae28998409aadccf Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Mon, 16 Nov 2015 10:59:26 +0200 Subject: [PATCH 18/69] Story#107571572 - banklinks workflow fixes --- app/controllers/registrar/payments_controller.rb | 8 ++++---- app/models/bank_link.rb | 4 ++++ config/locales/en.yml | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index 674b8afed..931dffcf2 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -20,16 +20,16 @@ class Registrar::PaymentsController < RegistrarController # both back and IPN def back @bank_link = BankLink::Response.new(params[:bank], params) - if @bank_link.valid? + if @bank_link.valid? && @bank_link.ok? @bank_link.complete_payment if @bank_link.invoice.binded? - flash[:notice] = t(:pending_applieds) + flash[:notice] = t(:pending_applied) else - flash[:error] = t(:something_wrong) + flash[:alert] = t(:something_wrong) end else - flash[:error] = t(:something_wrong) + flash[:alert] = t(:something_wrong) end redirect_to registrar_invoice_path(@bank_link.invoice) end diff --git a/app/models/bank_link.rb b/app/models/bank_link.rb index b28611542..31be3e222 100644 --- a/app/models/bank_link.rb +++ b/app/models/bank_link.rb @@ -88,6 +88,10 @@ class BankLink !!validate end + def ok? + params["VK_SERVICE"] == "1111" + end + def complete_payment if valid? transaction = BankTransaction.find_by(description: params["VK_MSG"]) diff --git a/config/locales/en.yml b/config/locales/en.yml index 7a562afa6..937096ad6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -656,7 +656,7 @@ en: m_id: 'M-ID' pending_removed: Pending was successfully removed. pending_applied: Pending was successfully applied. - something_wrong: Not success, something went wrong + something_wrong: Sorry, something went wrong failure: Not success not_found: Not found no_connection_to_registry: Connection issue to the registry EPP or REPP server! Please try again later. From b166cec06e0e8ec08da0397f344e0e8e46eab8a6 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Mon, 16 Nov 2015 17:13:55 +0200 Subject: [PATCH 19/69] Story#105747240 - remove legal documents from domain history --- app/controllers/epp/domains_controller.rb | 7 ------- app/models/epp/domain.rb | 10 +++++++++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb index 57136be63..8426c8ccb 100644 --- a/app/controllers/epp/domains_controller.rb +++ b/app/controllers/epp/domains_controller.rb @@ -56,10 +56,6 @@ class Epp::DomainsController < EppController authorize! :update, @domain, @password begin if @domain.update(params[:parsed_frame], current_user) - - @domain.attach_legal_document(Epp::Domain.parse_legal_document_from_frame(params[:parsed_frame])) - @domain.save(validate: false) - if @domain.epp_pending_update.present? render_epp_response '/epp/domains/success_pending' else @@ -80,9 +76,6 @@ class Epp::DomainsController < EppController handle_errors(@domain) and return unless @domain.can_be_deleted? - @domain.attach_legal_document(Epp::Domain.parse_legal_document_from_frame(params[:parsed_frame])) - @domain.save(validate: false) - if @domain.epp_destroy(params[:parsed_frame], current_user.id) if @domain.epp_pending_delete.present? render_epp_response '/epp/domains/success_pending' diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 7b55b018d..9be98d6e6 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -472,6 +472,10 @@ class Epp::Domain < Domain at.deep_merge!(attrs_from(frame.css('chg'), current_user, 'chg')) at.deep_merge!(attrs_from(frame.css('rem'), current_user, 'rem')) + if doc = attach_legal_document(Epp::Domain.parse_legal_document_from_frame(frame)) + frame.css("legalDocument").first.content = doc.path if doc && doc.persisted? + end + at_add = attrs_from(frame.css('add'), current_user) at[:nameservers_attributes] += at_add[:nameservers_attributes] @@ -536,7 +540,7 @@ class Epp::Domain < Domain def attach_legal_document(legal_document_data) return unless legal_document_data - legal_documents.build( + legal_documents.create( document_type: legal_document_data[:type], body: legal_document_data[:body] ) @@ -545,6 +549,10 @@ class Epp::Domain < Domain def epp_destroy(frame, user_id) return false unless valid? + if doc = attach_legal_document(Epp::Domain.parse_legal_document_from_frame(frame)) + frame.css("legalDocument").first.content = doc.path if doc && doc.persisted? + end + if Setting.request_confirmation_on_domain_deletion_enabled && frame.css('delete').children.css('delete').attr('verified').to_s.downcase != 'yes' From 3ea53ad01641133dcb5ff9ac8f0f6a407ca22a35 Mon Sep 17 00:00:00 2001 From: Stas Date: Tue, 17 Nov 2015 14:43:50 +0200 Subject: [PATCH 20/69] 107997032-whois_db_delete (cherry picked from commit c4dbd4c) --- app/models/whois_record.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/models/whois_record.rb b/app/models/whois_record.rb index 9a725b013..7cb26a89c 100644 --- a/app/models/whois_record.rb +++ b/app/models/whois_record.rb @@ -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 @@ -109,4 +110,8 @@ class WhoisRecord < ActiveRecord::Base wd.json = json wd.save end + + def destroy_whois_record + Whois::Record.where(name: name).delete_all() + end end From 6ca6ff2bf8b38beab28d625fa53e3fafc4f0b0b9 Mon Sep 17 00:00:00 2001 From: Stas Date: Tue, 17 Nov 2015 15:22:35 +0200 Subject: [PATCH 21/69] 105361584-domains_list_hided --- app/views/registrar/contacts/show.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/registrar/contacts/show.haml b/app/views/registrar/contacts/show.haml index 96faa4ecc..9fcbe7942 100644 --- a/app/views/registrar/contacts/show.haml +++ b/app/views/registrar/contacts/show.haml @@ -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 'admin/contacts/partials/domains', contact: Contact.find_by(code: params[:id]) - else .row From 2dddace1b8b229caf7c21db4bbb998e4054c1d63 Mon Sep 17 00:00:00 2001 From: Stas Date: Tue, 17 Nov 2015 16:51:46 +0200 Subject: [PATCH 22/69] Merge branch 'staging' of github.com:internetee/registry into staging # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit. --- Gemfile | 3 ++ Gemfile.lock | 13 ++++++ app/jobs/domain_delete_confirm_job.rb | 2 +- app/jobs/domain_update_confirm_job.rb | 2 +- app/mailers/contact_mailer.rb | 11 +++-- app/mailers/domain_mailer.rb | 60 +++++++++++++++++---------- app/mailers/invoice_mailer.rb | 13 ++++-- app/models/contact.rb | 2 +- app/models/domain.rb | 12 +++--- app/models/epp/domain.rb | 8 ++-- app/models/invoice.rb | 2 +- spec/mailers/domain_mailer_spec.rb | 24 +++++------ 12 files changed, 97 insertions(+), 55 deletions(-) diff --git a/Gemfile b/Gemfile index b52a299cd..10c680786 100644 --- a/Gemfile +++ b/Gemfile @@ -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 diff --git a/Gemfile.lock b/Gemfile.lock index 844000672..b92d6dc1b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/app/jobs/domain_delete_confirm_job.rb b/app/jobs/domain_delete_confirm_job.rb index 7d890ef16..aa3effb12 100644 --- a/app/jobs/domain_delete_confirm_job.rb +++ b/app/jobs/domain_delete_confirm_job.rb @@ -9,7 +9,7 @@ class DomainDeleteConfirmJob < Que::Job domain.apply_pending_delete! domain.clean_pendings! when RegistrantVerification::REJECTED - DomainMailer.pending_delete_rejected_notification(domain).deliver_now + DomainMailer.pending_delete_rejected_notification(domain_id).deliver domain.statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION) domain.poll_message!(:poll_pending_delete_rejected_by_registrant) domain.clean_pendings! diff --git a/app/jobs/domain_update_confirm_job.rb b/app/jobs/domain_update_confirm_job.rb index f6e28e2c3..28294ef25 100644 --- a/app/jobs/domain_update_confirm_job.rb +++ b/app/jobs/domain_update_confirm_job.rb @@ -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"=>[])) diff --git a/app/mailers/contact_mailer.rb b/app/mailers/contact_mailer.rb index 2f8de7248..7905b0451 100644 --- a/app/mailers/contact_mailer.rb +++ b/app/mailers/contact_mailer.rb @@ -1,10 +1,13 @@ class ContactMailer < ApplicationMailer - def email_updated(email, contact) + include Que::Mailer + + def email_updated(email_id, contact_id) + email = Email.find_by(id: email_id) + @contact = Contact.find_by(id: contact_id) + return unless email || @contact return if delivery_off?(contact) - - @contact = contact - return if whitelist_blocked?(email) + begin mail(to: format(email), subject: "#{I18n.t(:contact_email_update_subject)} [#{@contact.code}]") rescue EOFError, diff --git a/app/mailers/domain_mailer.rb b/app/mailers/domain_mailer.rb index a8c79f66d..70f5d8f39 100644 --- a/app/mailers/domain_mailer.rb +++ b/app/mailers/domain_mailer.rb @@ -1,6 +1,9 @@ class DomainMailer < ApplicationMailer - def pending_update_request_for_old_registrant(domain) - @domain = domain + include Que::Mailer + + def pending_update_request_for_old_registrant(domain_id) + @domain = Domain.find_by(id: domain_id) + return unless @domain return if delivery_off?(@domain) if @domain.registrant_verification_token.blank? @@ -24,8 +27,9 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def pending_update_notification_for_new_registrant(domain) - @domain = domain + def pending_update_notification_for_new_registrant(domain_id) + @domain = Domain.find_by(id: domain_id) + return unless @domain return if delivery_off?(@domain) if @domain.registrant_verification_token.blank? @@ -47,8 +51,9 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def registrant_updated_notification_for_new_registrant(domain) - @domain = domain + def registrant_updated_notification_for_new_registrant(domain_id) + @domain = Domain.find_by(id: domain_id) + return unless @domain return if delivery_off?(@domain) return if whitelist_blocked?(@domain.registrant_email) @@ -57,8 +62,9 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def registrant_updated_notification_for_old_registrant(domain) - @domain = domain + def registrant_updated_notification_for_old_registrant(domain_id) + domain = Domain.find_by(id: domain_id) + return unless domain return if delivery_off?(@domain) @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,8 +107,9 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def pending_deleted(domain) - @domain = domain + def pending_deleted(domain_id) + @domain = Domain.find_by(id: domain_id) + return unless @domain return if delivery_off?(@domain) if @domain.registrant_verification_token.blank? @@ -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) + @domain = Domain.find_by(id: domain_id) + return unless @domain + return if delivery_off?(@domain) # 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) + @domain = Domain.find_by(id: domain_id) + return unless @domain + return if delivery_off?(@domain) # 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) + @domain = Domain.find_by(id: domain_id) + return unless @domain + return if delivery_off?(@domain) 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) + @domain = Domain.find_by(id: domain_id) + return if delivery_off?(@domain) emails = ([@domain.registrant.email] + @domain.admin_contacts.map { |x| format(x.email) }).uniq return if whitelist_blocked?(emails) diff --git a/app/mailers/invoice_mailer.rb b/app/mailers/invoice_mailer.rb index e78795b66..54c6a8605 100644 --- a/app/mailers/invoice_mailer.rb +++ b/app/mailers/invoice_mailer.rb @@ -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 diff --git a/app/models/contact.rb b/app/models/contact.rb index f332dc2c4..3c1e0d274 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -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, id).deliver end end diff --git a/app/models/domain.rb b/app/models/domain.rb index 9845e8ac8..8d02f7f83 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -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 end domain.clean_pendings! unless Rails.env.test? @@ -428,8 +428,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 + DomainMailer.pending_update_notification_for_new_registrant(id).deliver reload # revert back to original @@ -489,7 +489,7 @@ 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 end def pricelist(operation, period_i = nil, unit = nil) @@ -619,7 +619,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 return true end false diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index ffd525d9d..f31105f4d 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -478,7 +478,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) preclean_pendings user = ApiUser.find(pending_json['current_user_id']) frame = Nokogiri::XML(pending_json['frame']) @@ -488,8 +488,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 + old_registrant_email.deliver true end @@ -497,7 +497,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 # TODO: confirm that this actually makes sense clean_pendings! if valid? && set_pending_delete! diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 583f26825..0c4e23a08 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -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 diff --git a/spec/mailers/domain_mailer_spec.rb b/spec/mailers/domain_mailer_spec.rb index 71ed183ce..20662a2ba 100644 --- a/spec/mailers/domain_mailer_spec.rb +++ b/spec/mailers/domain_mailer_spec.rb @@ -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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) end it 'should render email subject' do From 90ad9ff8875ec537b16149db801523c32e7e3b73 Mon Sep 17 00:00:00 2001 From: Stas Date: Tue, 17 Nov 2015 16:56:53 +0200 Subject: [PATCH 23/69] 107821878-que_mailer --- app/mailers/contact_mailer.rb | 3 +-- app/models/contact.rb | 2 +- spec/mailers/contact_mailer_spec.rb | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/mailers/contact_mailer.rb b/app/mailers/contact_mailer.rb index 7905b0451..2f858a585 100644 --- a/app/mailers/contact_mailer.rb +++ b/app/mailers/contact_mailer.rb @@ -1,8 +1,7 @@ class ContactMailer < ApplicationMailer include Que::Mailer - def email_updated(email_id, contact_id) - email = Email.find_by(id: email_id) + def email_updated(email, contact_id) @contact = Contact.find_by(id: contact_id) return unless email || @contact return if delivery_off?(contact) diff --git a/app/models/contact.rb b/app/models/contact.rb index 3c1e0d274..9f623a262 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -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.id, id).deliver + ContactMailer.email_updated(e, id).deliver end end diff --git a/spec/mailers/contact_mailer_spec.rb b/spec/mailers/contact_mailer_spec.rb index 033843b50..f0402e3db 100644 --- a/spec/mailers/contact_mailer_spec.rb +++ b/spec/mailers/contact_mailer_spec.rb @@ -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) 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) 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) end it 'should render email subject' do From 9cf287b35c2e6e270991ec4f00d4a1b641b3a8a7 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Tue, 17 Nov 2015 17:48:11 +0200 Subject: [PATCH 24/69] Story #104525314 - fix missing error message on probibited change admin/tech contact --- app/models/epp/domain.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index f59df6ddc..2b273f93a 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -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 @@ -439,7 +439,7 @@ class Epp::Domain < Domain at.deep_merge!(attrs_from(frame.css('chg'), current_user, 'chg')) at.deep_merge!(attrs_from(frame.css('rem'), current_user, 'rem')) - 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? From afbddad42fc9aeb48c44fa3fb76b286104ce9d67 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Tue, 17 Nov 2015 17:48:28 +0200 Subject: [PATCH 25/69] Story #104525314 - avoid reporting no errors when error raised --- app/controllers/epp/domains_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb index 57136be63..db47570d2 100644 --- a/app/controllers/epp/domains_controller.rb +++ b/app/controllers/epp/domains_controller.rb @@ -68,8 +68,12 @@ class Epp::DomainsController < EppController else handle_errors(@domain) end - rescue - handle_errors(@domain) + rescue => e + if @domain.errors.any? + handle_errors(@domain) + else + throw e + end end end From 5b325882f1ff6d6cba501549296dcebd4a6072a4 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Wed, 18 Nov 2015 10:01:52 +0200 Subject: [PATCH 26/69] Story #104525314 - remove reject/accept button from pendingDelete, allow only for pending...Confirmation --- app/views/admin/domains/form/_pending_delete.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/domains/form/_pending_delete.haml b/app/views/admin/domains/form/_pending_delete.haml index 2e199d0b7..e3d71f3f4 100644 --- a/app/views/admin/domains/form/_pending_delete.haml +++ b/app/views/admin/domains/form/_pending_delete.haml @@ -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') From df3f91f4825b0735d4e99f0b4b4c73b08f8ac713 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Wed, 18 Nov 2015 10:28:23 +0200 Subject: [PATCH 27/69] Story #104525314 - clean up, finishes prior commit 9cf287b35c2e6e270991ec4f00d4a1b641b3a8a7 --- app/models/epp/domain.rb | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 2b273f93a..feafb36a7 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -441,19 +441,8 @@ class Epp::Domain < Domain 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[:admin_domain_contacts_attributes] += at_add[:admin_domain_contacts_attributes] + at[:tech_domain_contacts_attributes] += at_add[:tech_domain_contacts_attributes] at[:dnskeys_attributes] += at_add[:dnskeys_attributes] at[:statuses] = statuses - domain_statuses_attrs(frame.css('rem'), 'rem') + domain_statuses_attrs(frame.css('add'), 'add') From 9eb4be7d1844f54a1bbb46a30d5ace9758bad5fb Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Wed, 18 Nov 2015 10:30:55 +0200 Subject: [PATCH 28/69] merge has removed Gemfile.lock --- Gemfile.lock | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 844000672..b92d6dc1b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) From 69f0f8af1227a85ae6d609723309a95821b1b10d Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Wed, 18 Nov 2015 12:42:04 +0200 Subject: [PATCH 29/69] Story #104525314 - bug fix, now pendingDeleteConfirmation must transit to pendingDelete, or cancel pending --- app/jobs/domain_delete_confirm_job.rb | 4 +--- app/models/domain.rb | 6 ++++++ app/models/epp/domain.rb | 5 ++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/jobs/domain_delete_confirm_job.rb b/app/jobs/domain_delete_confirm_job.rb index 7d890ef16..785483cad 100644 --- a/app/jobs/domain_delete_confirm_job.rb +++ b/app/jobs/domain_delete_confirm_job.rb @@ -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) 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 diff --git a/app/models/domain.rb b/app/models/domain.rb index 5580cb837..3ce220733 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -492,6 +492,12 @@ class Domain < ActiveRecord::Base DomainMailer.pending_deleted(self).deliver_now end + def cancel_pending_delete + statuses.delete DomainStatus::PENDING_DELETE_CONFIRMATION + statuses.delete DomainStatus::PENDING_DELETE + delete_at = nil + end + def pricelist(operation, period_i = nil, unit = nil) period_i ||= period unit ||= period_unit diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index feafb36a7..614bf5963 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -483,9 +483,8 @@ class Epp::Domain < Domain statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION) statuses.delete(DomainStatus::PENDING_DELETE) DomainMailer.delete_confirmation(self).deliver_now - - # TODO: confirm that this actually makes sense - clean_pendings! if valid? && set_pending_delete! + clean_pendings! + set_pending_delete! true end From 6c559b8c254903bc53de1eaffb0c3a0113c181fe Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Thu, 19 Nov 2015 10:19:29 +0200 Subject: [PATCH 30/69] Story #104525314 - allow admin to remove pendingDelete and clear delete_at --- app/controllers/admin/domains_controller.rb | 1 + app/models/domain.rb | 31 +++++++++++++++------ app/models/domain_status.rb | 2 +- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/domains_controller.rb b/app/controllers/admin/domains_controller.rb index 562505dc1..377912bad 100644 --- a/app/controllers/admin/domains_controller.rb +++ b/app/controllers/admin/domains_controller.rb @@ -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') diff --git a/app/models/domain.rb b/app/models/domain.rb index 3ce220733..493fc14ac 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -495,7 +495,7 @@ class Domain < ActiveRecord::Base def cancel_pending_delete statuses.delete DomainStatus::PENDING_DELETE_CONFIRMATION statuses.delete DomainStatus::PENDING_DELETE - delete_at = nil + self.delete_at = nil end def pricelist(operation, period_i = nil, unit = nil) @@ -679,16 +679,31 @@ 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.includes? 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, - DomainStatus::CLIENT_UPDATE_PROHIBITED, - DomainStatus::SERVER_UPDATE_PROHIBITED, - DomainStatus::PENDING_CREATE, - DomainStatus::PENDING_UPDATE, - DomainStatus::PENDING_DELETE, - DomainStatus::PENDING_RENEW, - DomainStatus::PENDING_TRANSFER + DomainStatus::CLIENT_UPDATE_PROHIBITED, + DomainStatus::SERVER_UPDATE_PROHIBITED, + DomainStatus::PENDING_CREATE, + DomainStatus::PENDING_UPDATE, + DomainStatus::PENDING_DELETE, + DomainStatus::PENDING_RENEW, + DomainStatus::PENDING_TRANSFER ]).present? end diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index 543ba0ff4..c784a86e3 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -148,7 +148,7 @@ class DomainStatus < ActiveRecord::Base INACTIVE, FORCE_DELETE, PENDING_CREATE, - PENDING_DELETE, + #PENDING_DELETE, PENDING_RENEW, PENDING_TRANSFER, PENDING_UPDATE, From b8f1dbbf54b5d0abe8b2e4e03c5e472244205473 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Thu, 19 Nov 2015 12:27:06 +0200 Subject: [PATCH 31/69] Stroy#107699154 disclosed should have array --- app/models/whois_record.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/whois_record.rb b/app/models/whois_record.rb index 83af9ee1d..91d46a427 100644 --- a/app/models/whois_record.rb +++ b/app/models/whois_record.rb @@ -48,7 +48,7 @@ class WhoisRecord < ActiveRecord::Base h[:registrant] = domain.registrant.name h[:registrant_email] = domain.registrant.email - @disclosed << domain.registrant.email + @disclosed << [:email, domain.registrant.email] h[:changed] = domain.registrant.updated_at.try(:to_s, :iso8601) h[:admin_contacts] = [] From c013e9789cdf5698b82d0da564fea9e26caac70e Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Thu, 19 Nov 2015 13:39:04 +0200 Subject: [PATCH 32/69] Stroy#108423414 links in contact view's domain list use registrar --- .../registrar/contacts/partials/_domains.haml | 30 +++++++++++++++++++ app/views/registrar/contacts/show.haml | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 app/views/registrar/contacts/partials/_domains.haml diff --git a/app/views/registrar/contacts/partials/_domains.haml b/app/views/registrar/contacts/partials/_domains.haml new file mode 100644 index 000000000..ab590cd85 --- /dev/null +++ b/app/views/registrar/contacts/partials/_domains.haml @@ -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= link_to(x.registrar, registrar_contact_path(id: x.registrant.code)) + %td= l(x.valid_to, format: :short) + %td= x.roles.join(", ") + += paginate domains, param_name: :domain_page \ No newline at end of file diff --git a/app/views/registrar/contacts/show.haml b/app/views/registrar/contacts/show.haml index 96faa4ecc..41eda46c2 100644 --- a/app/views/registrar/contacts/show.haml +++ b/app/views/registrar/contacts/show.haml @@ -10,7 +10,7 @@ .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]) + .col-md-12= render 'registrar/contacts/partials/domains', contact: Contact.find_by(code: params[:id]) - else .row From 456bbaabde4d81d6cfc7d8be77f48d3437a6f071 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Thu, 19 Nov 2015 15:05:14 +0200 Subject: [PATCH 33/69] Story#105839906 - load history objects by id --- app/views/admin/domain_versions/_version.haml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/admin/domain_versions/_version.haml b/app/views/admin/domain_versions/_version.haml index 6f0d7dd24..fd449b4b0 100644 --- a/app/views/admin/domain_versions/_version.haml +++ b/app/views/admin/domain_versions/_version.haml @@ -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 From b426304e42e00b1ad13df1ac27f52fe3fc284d1d Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Tue, 17 Nov 2015 17:48:11 +0200 Subject: [PATCH 34/69] Story #104525314 - fix missing error message on probibited change admin/tech contact --- app/models/epp/domain.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index ffd525d9d..821b1eb77 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -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 @@ -443,7 +443,7 @@ 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? From a3c5dfbd1b28e2d6d587ceb3b0b3446b5079e928 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Tue, 17 Nov 2015 17:48:28 +0200 Subject: [PATCH 35/69] Story #104525314 - avoid reporting no errors when error raised --- app/controllers/epp/domains_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb index 8426c8ccb..33a602aed 100644 --- a/app/controllers/epp/domains_controller.rb +++ b/app/controllers/epp/domains_controller.rb @@ -64,8 +64,12 @@ class Epp::DomainsController < EppController else handle_errors(@domain) end - rescue - handle_errors(@domain) + rescue => e + if @domain.errors.any? + handle_errors(@domain) + else + throw e + end end end From 605e779bc902d89e59c04d1e98b7e0993574f5d2 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Wed, 18 Nov 2015 10:01:52 +0200 Subject: [PATCH 36/69] Story #104525314 - remove reject/accept button from pendingDelete, allow only for pending...Confirmation --- app/views/admin/domains/form/_pending_delete.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/domains/form/_pending_delete.haml b/app/views/admin/domains/form/_pending_delete.haml index 2e199d0b7..e3d71f3f4 100644 --- a/app/views/admin/domains/form/_pending_delete.haml +++ b/app/views/admin/domains/form/_pending_delete.haml @@ -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') From f54ed751bc9f8c4af30d44f12260ba9b7b8dff58 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Wed, 18 Nov 2015 10:28:23 +0200 Subject: [PATCH 37/69] Story #104525314 - clean up, finishes prior commit 9cf287b35c2e6e270991ec4f00d4a1b641b3a8a7 --- app/models/epp/domain.rb | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 821b1eb77..2c3c764f2 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -445,19 +445,8 @@ class Epp::Domain < Domain 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[:admin_domain_contacts_attributes] += at_add[:admin_domain_contacts_attributes] + at[:tech_domain_contacts_attributes] += at_add[:tech_domain_contacts_attributes] at[:dnskeys_attributes] += at_add[:dnskeys_attributes] at[:statuses] = statuses - domain_statuses_attrs(frame.css('rem'), 'rem') + domain_statuses_attrs(frame.css('add'), 'add') From b1c8eb5f316c38cc23b68a7c7668c768f6652618 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Wed, 18 Nov 2015 12:42:04 +0200 Subject: [PATCH 38/69] Story #104525314 - bug fix, now pendingDeleteConfirmation must transit to pendingDelete, or cancel pending --- app/jobs/domain_delete_confirm_job.rb | 4 +--- app/models/domain.rb | 6 ++++++ app/models/epp/domain.rb | 5 ++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/jobs/domain_delete_confirm_job.rb b/app/jobs/domain_delete_confirm_job.rb index 7d890ef16..785483cad 100644 --- a/app/jobs/domain_delete_confirm_job.rb +++ b/app/jobs/domain_delete_confirm_job.rb @@ -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) 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 diff --git a/app/models/domain.rb b/app/models/domain.rb index 9845e8ac8..4e1566d60 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -492,6 +492,12 @@ class Domain < ActiveRecord::Base DomainMailer.pending_deleted(self).deliver_now end + def cancel_pending_delete + statuses.delete DomainStatus::PENDING_DELETE_CONFIRMATION + statuses.delete DomainStatus::PENDING_DELETE + delete_at = nil + end + def pricelist(operation, period_i = nil, unit = nil) period_i ||= period unit ||= period_unit diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 2c3c764f2..9e2e7eb02 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -487,9 +487,8 @@ class Epp::Domain < Domain statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION) statuses.delete(DomainStatus::PENDING_DELETE) DomainMailer.delete_confirmation(self).deliver_now - - # TODO: confirm that this actually makes sense - clean_pendings! if valid? && set_pending_delete! + clean_pendings! + set_pending_delete! true end From a53451c2ef31537e9bacb7e4e8804b6147fcabb9 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Thu, 19 Nov 2015 10:19:29 +0200 Subject: [PATCH 39/69] Story #104525314 - allow admin to remove pendingDelete and clear delete_at --- app/controllers/admin/domains_controller.rb | 1 + app/models/domain.rb | 31 +++++++++++++++------ app/models/domain_status.rb | 2 +- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/domains_controller.rb b/app/controllers/admin/domains_controller.rb index 562505dc1..377912bad 100644 --- a/app/controllers/admin/domains_controller.rb +++ b/app/controllers/admin/domains_controller.rb @@ -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') diff --git a/app/models/domain.rb b/app/models/domain.rb index 4e1566d60..2bbc221da 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -495,7 +495,7 @@ class Domain < ActiveRecord::Base def cancel_pending_delete statuses.delete DomainStatus::PENDING_DELETE_CONFIRMATION statuses.delete DomainStatus::PENDING_DELETE - delete_at = nil + self.delete_at = nil end def pricelist(operation, period_i = nil, unit = nil) @@ -679,16 +679,31 @@ 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.includes? 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, - DomainStatus::CLIENT_UPDATE_PROHIBITED, - DomainStatus::SERVER_UPDATE_PROHIBITED, - DomainStatus::PENDING_CREATE, - DomainStatus::PENDING_UPDATE, - DomainStatus::PENDING_DELETE, - DomainStatus::PENDING_RENEW, - DomainStatus::PENDING_TRANSFER + DomainStatus::CLIENT_UPDATE_PROHIBITED, + DomainStatus::SERVER_UPDATE_PROHIBITED, + DomainStatus::PENDING_CREATE, + DomainStatus::PENDING_UPDATE, + DomainStatus::PENDING_DELETE, + DomainStatus::PENDING_RENEW, + DomainStatus::PENDING_TRANSFER ]).present? end diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index 543ba0ff4..c784a86e3 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -148,7 +148,7 @@ class DomainStatus < ActiveRecord::Base INACTIVE, FORCE_DELETE, PENDING_CREATE, - PENDING_DELETE, + #PENDING_DELETE, PENDING_RENEW, PENDING_TRANSFER, PENDING_UPDATE, From 32a3615ad60363b3ffb05ba376578e35002f38ba Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Thu, 19 Nov 2015 16:31:22 +0200 Subject: [PATCH 40/69] Story#107699154 - whois text report typo --- app/views/for_models/whois.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/for_models/whois.erb b/app/views/for_models/whois.erb index 385368b4a..cb6adac75 100644 --- a/app/views/for_models/whois.erb +++ b/app/views/for_models/whois.erb @@ -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('+', ' +') %> From bbc53700bd99667be201666c954f265cd1a34609 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Thu, 19 Nov 2015 19:11:30 +0200 Subject: [PATCH 41/69] Story #108518226 - add IDN lookup method to support info and check features of EPP --- app/controllers/epp/domains_controller.rb | 2 +- app/models/domain.rb | 11 +++++++++++ app/models/epp/domain.rb | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb index 8426c8ccb..74ad6ae63 100644 --- a/app/controllers/epp/domains_controller.rb +++ b/app/controllers/epp/domains_controller.rb @@ -225,7 +225,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 << { diff --git a/app/models/domain.rb b/app/models/domain.rb index 9845e8ac8..b8b7d55aa 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -334,6 +334,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 diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index ffd525d9d..51601bd51 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -850,7 +850,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 } From b8de6303f90d7e4fb7594e1ee5bc4f5b7091bd33 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 20 Nov 2015 11:22:08 +0200 Subject: [PATCH 42/69] Story #108518226 - add index on domain name --- db/migrate/20151120090455_index_domains_on_name.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20151120090455_index_domains_on_name.rb diff --git a/db/migrate/20151120090455_index_domains_on_name.rb b/db/migrate/20151120090455_index_domains_on_name.rb new file mode 100644 index 000000000..a429b6fbf --- /dev/null +++ b/db/migrate/20151120090455_index_domains_on_name.rb @@ -0,0 +1,5 @@ +class IndexDomainsOnName < ActiveRecord::Migration + def change + add_index :domains, :name, unique: true + end +end From 6140701e47f79124b6e07b30f31263a4d23480ad Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Tue, 17 Nov 2015 17:48:11 +0200 Subject: [PATCH 43/69] Story #104525314 - fix missing error message on probibited change admin/tech contact --- app/models/epp/domain.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index ffd525d9d..821b1eb77 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -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 @@ -443,7 +443,7 @@ 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? From 08114e722b52238a86ef5719ba233781f7e19d1b Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Tue, 17 Nov 2015 17:48:28 +0200 Subject: [PATCH 44/69] Story #104525314 - avoid reporting no errors when error raised --- app/controllers/epp/domains_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb index 8426c8ccb..33a602aed 100644 --- a/app/controllers/epp/domains_controller.rb +++ b/app/controllers/epp/domains_controller.rb @@ -64,8 +64,12 @@ class Epp::DomainsController < EppController else handle_errors(@domain) end - rescue - handle_errors(@domain) + rescue => e + if @domain.errors.any? + handle_errors(@domain) + else + throw e + end end end From 9f2bf36b9ea6f71dc94520d42119580d83e2af66 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Wed, 18 Nov 2015 10:01:52 +0200 Subject: [PATCH 45/69] Story #104525314 - remove reject/accept button from pendingDelete, allow only for pending...Confirmation --- app/views/admin/domains/form/_pending_delete.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/domains/form/_pending_delete.haml b/app/views/admin/domains/form/_pending_delete.haml index 2e199d0b7..e3d71f3f4 100644 --- a/app/views/admin/domains/form/_pending_delete.haml +++ b/app/views/admin/domains/form/_pending_delete.haml @@ -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') From a48abe621e3a2cf7d761824f66c3ba3ee4c6ff3a Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Wed, 18 Nov 2015 10:28:23 +0200 Subject: [PATCH 46/69] Story #104525314 - clean up, finishes prior commit 9cf287b35c2e6e270991ec4f00d4a1b641b3a8a7 --- app/models/epp/domain.rb | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 821b1eb77..2c3c764f2 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -445,19 +445,8 @@ class Epp::Domain < Domain 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[:admin_domain_contacts_attributes] += at_add[:admin_domain_contacts_attributes] + at[:tech_domain_contacts_attributes] += at_add[:tech_domain_contacts_attributes] at[:dnskeys_attributes] += at_add[:dnskeys_attributes] at[:statuses] = statuses - domain_statuses_attrs(frame.css('rem'), 'rem') + domain_statuses_attrs(frame.css('add'), 'add') From 64b0e391a4e20fb275d471d9ffbe42cb6f7f19dd Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Wed, 18 Nov 2015 12:42:04 +0200 Subject: [PATCH 47/69] Story #104525314 - bug fix, now pendingDeleteConfirmation must transit to pendingDelete, or cancel pending --- app/jobs/domain_delete_confirm_job.rb | 4 +--- app/models/domain.rb | 6 ++++++ app/models/epp/domain.rb | 5 ++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/jobs/domain_delete_confirm_job.rb b/app/jobs/domain_delete_confirm_job.rb index 7d890ef16..785483cad 100644 --- a/app/jobs/domain_delete_confirm_job.rb +++ b/app/jobs/domain_delete_confirm_job.rb @@ -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) 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 diff --git a/app/models/domain.rb b/app/models/domain.rb index 9845e8ac8..4e1566d60 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -492,6 +492,12 @@ class Domain < ActiveRecord::Base DomainMailer.pending_deleted(self).deliver_now end + def cancel_pending_delete + statuses.delete DomainStatus::PENDING_DELETE_CONFIRMATION + statuses.delete DomainStatus::PENDING_DELETE + delete_at = nil + end + def pricelist(operation, period_i = nil, unit = nil) period_i ||= period unit ||= period_unit diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 2c3c764f2..9e2e7eb02 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -487,9 +487,8 @@ class Epp::Domain < Domain statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION) statuses.delete(DomainStatus::PENDING_DELETE) DomainMailer.delete_confirmation(self).deliver_now - - # TODO: confirm that this actually makes sense - clean_pendings! if valid? && set_pending_delete! + clean_pendings! + set_pending_delete! true end From b561b8e543c63a3cf4525080b9cc4c04067cba9b Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Thu, 19 Nov 2015 10:19:29 +0200 Subject: [PATCH 48/69] Story #104525314 - allow admin to remove pendingDelete and clear delete_at --- app/controllers/admin/domains_controller.rb | 1 + app/models/domain.rb | 31 +++++++++++++++------ app/models/domain_status.rb | 2 +- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/domains_controller.rb b/app/controllers/admin/domains_controller.rb index 562505dc1..377912bad 100644 --- a/app/controllers/admin/domains_controller.rb +++ b/app/controllers/admin/domains_controller.rb @@ -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') diff --git a/app/models/domain.rb b/app/models/domain.rb index 4e1566d60..2bbc221da 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -495,7 +495,7 @@ class Domain < ActiveRecord::Base def cancel_pending_delete statuses.delete DomainStatus::PENDING_DELETE_CONFIRMATION statuses.delete DomainStatus::PENDING_DELETE - delete_at = nil + self.delete_at = nil end def pricelist(operation, period_i = nil, unit = nil) @@ -679,16 +679,31 @@ 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.includes? 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, - DomainStatus::CLIENT_UPDATE_PROHIBITED, - DomainStatus::SERVER_UPDATE_PROHIBITED, - DomainStatus::PENDING_CREATE, - DomainStatus::PENDING_UPDATE, - DomainStatus::PENDING_DELETE, - DomainStatus::PENDING_RENEW, - DomainStatus::PENDING_TRANSFER + DomainStatus::CLIENT_UPDATE_PROHIBITED, + DomainStatus::SERVER_UPDATE_PROHIBITED, + DomainStatus::PENDING_CREATE, + DomainStatus::PENDING_UPDATE, + DomainStatus::PENDING_DELETE, + DomainStatus::PENDING_RENEW, + DomainStatus::PENDING_TRANSFER ]).present? end diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index 543ba0ff4..c784a86e3 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -148,7 +148,7 @@ class DomainStatus < ActiveRecord::Base INACTIVE, FORCE_DELETE, PENDING_CREATE, - PENDING_DELETE, + #PENDING_DELETE, PENDING_RENEW, PENDING_TRANSFER, PENDING_UPDATE, From 229f5a34afd52f11eaa10bf8e11869ed529fa7c2 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 20 Nov 2015 15:55:31 +0200 Subject: [PATCH 49/69] Story #104525314 - remove s typo --- app/models/domain.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/domain.rb b/app/models/domain.rb index 2bbc221da..7eeff36c5 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -683,7 +683,7 @@ class Domain < ActiveRecord::Base def admin_status_update(update) # check for deleted status statuses.each do |s| - unless update.includes? s + unless update.include? s case s when DomainStatus::PENDING_DELETE self.delete_at = nil From b5c3a24bde1004804ecc67e069afd127f2d6d903 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 20 Nov 2015 16:16:18 +0200 Subject: [PATCH 50/69] Story #104525314 - admin is not allowed to reject pendingDeleteConfirmation --- app/views/admin/domains/form/_pending_delete.haml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/views/admin/domains/form/_pending_delete.haml b/app/views/admin/domains/form/_pending_delete.haml index e3d71f3f4..ad1844634 100644 --- a/app/views/admin/domains/form/_pending_delete.haml +++ b/app/views/admin/domains/form/_pending_delete.haml @@ -2,7 +2,3 @@ = 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') - - = link_to(t(:reject_delete), admin_domain_pending_delete_path(f.object.id, f.object.id), - method: :delete, data: { confirm: t(:are_you_sure) }, - class: 'btn btn-danger btn-xs') From 24f90d51197b2bdd670c5e2c8f3585b5427b4a6a Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 13 Nov 2015 15:01:18 +0200 Subject: [PATCH 51/69] Story #107192666 - only show dsData if allowed, or keyData if allowed --- app/views/epp/domains/info.xml.builder | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/app/views/epp/domains/info.xml.builder b/app/views/epp/domains/info.xml.builder index e7962002c..645c731e4 100644 --- a/app/views/epp/domains/info.xml.builder +++ b/app/views/epp/domains/info.xml.builder @@ -81,18 +81,17 @@ 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) + if Setting.ds_data_allowed + (@domain.dnskeys.find_all { |key| key.ds_digest.present? }).sort.each do |key| + tag_ds_data(xml, key) end else - @domain.dnskeys.sort.each do |key| - tag_ds_data(xml, key) + (@domain.dnskeys.find_all { |key| key.ds_digest.blank? }).sort.each do |key| + tag_key_data(xml, key) end end end - end if @domain.dnskeys.any? + end if @domain.dnskeys.any? && (Setting.ds_data_allowed ? @domain.dnskeys.any? { |key| key.ds_digest.present? } : Setting.key_data_allowed) render('epp/shared/trID', builder: xml) end From 334179fae956ec671204402a7cf157a2d90b3a56 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 13 Nov 2015 15:23:24 +0200 Subject: [PATCH 52/69] Story #107192666 - ensure registrary/domains/info shows only actual data patch updates previous revision 7d9272c60c90ba27f272a9495829a121ff26ca43 --- .../registrar/domains/partials/_dnskeys.haml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/app/views/registrar/domains/partials/_dnskeys.haml b/app/views/registrar/domains/partials/_dnskeys.haml index 46dcd0fce..5b8a95ade 100644 --- a/app/views/registrar/domains/partials/_dnskeys.haml +++ b/app/views/registrar/domains/partials/_dnskeys.haml @@ -4,23 +4,17 @@ .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| - %dl.dl-horizontal + - @data.css('keyData').each do |x| + %dl.dl-horizontal %dt= t(:flag) %dd= x.css('flags').text @@ -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 From 9ca17e6b4a775b50a0eca6d3e2b6c9c324791ab8 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 13 Nov 2015 19:06:12 +0200 Subject: [PATCH 53/69] Story #107192666 - refactor to add stricter inclusion rules reformatted block, white space changes, indent for surounding if any? pull up find_all? if *_allowed then check if allowed.any? --- app/views/epp/domains/info.xml.builder | 63 ++++++++++++++------------ 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/app/views/epp/domains/info.xml.builder b/app/views/epp/domains/info.xml.builder index 645c731e4..17892a3cc 100644 --- a/app/views/epp/domains/info.xml.builder +++ b/app/views/epp/domains/info.xml.builder @@ -60,39 +60,44 @@ xml.epp_head do end end - xml.extension do - def tag_key_data(xml, key) - xml.tag!('secDNS:keyData') do - xml.tag!('secDNS:flags', key.flags) - xml.tag!('secDNS:protocol', key.protocol) - xml.tag!('secDNS:alg', key.alg) - xml.tag!('secDNS:pubKey', key.public_key) - 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.ds_digest.blank? } : [] - def tag_ds_data(xml, key) - xml.tag!('secDNS:dsData') do - xml.tag!('secDNS:keyTag', key.ds_key_tag) - xml.tag!('secDNS:alg', key.ds_alg) - xml.tag!('secDNS:digestType', key.ds_digest_type) - xml.tag!('secDNS:digest', key.ds_digest) - tag_key_data(xml, key) if key.public_key.present? - end - end - - xml.tag!('secDNS:infData', 'xmlns:secDNS' => 'urn:ietf:params:xml:ns:secDNS-1.1') do - if Setting.ds_data_allowed - (@domain.dnskeys.find_all { |key| key.ds_digest.present? }).sort.each do |key| - tag_ds_data(xml, key) - end - else - (@domain.dnskeys.find_all { |key| key.ds_digest.blank? }).sort.each do |key| - tag_key_data(xml, key) + # is there any reason to include without + xml.extension do + def tag_key_data(xml, key) + xml.tag!('secDNS:keyData') do + xml.tag!('secDNS:flags', key.flags) + xml.tag!('secDNS:protocol', key.protocol) + xml.tag!('secDNS:alg', key.alg) + xml.tag!('secDNS:pubKey', key.public_key) end end - end - end if @domain.dnskeys.any? && (Setting.ds_data_allowed ? @domain.dnskeys.any? { |key| key.ds_digest.present? } : Setting.key_data_allowed) + def tag_ds_data(xml, key) + xml.tag!('secDNS:dsData') do + xml.tag!('secDNS:keyTag', key.ds_key_tag) + xml.tag!('secDNS:alg', key.ds_alg) + xml.tag!('secDNS:digestType', key.ds_digest_type) + xml.tag!('secDNS:digest', key.ds_digest) + tag_key_data(xml, key) if key.public_key.present? + end + end + + xml.tag!('secDNS:infData', 'xmlns:secDNS' => 'urn:ietf:params:xml:ns:secDNS-1.1') do + 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 + end if key_data.present? || ds_data.present? + end render('epp/shared/trID', builder: xml) end end From e01599fb1a8bce42b018be329fde516fb2ca61cd Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Fri, 13 Nov 2015 19:30:55 +0200 Subject: [PATCH 54/69] Story #107192666 - refactor dns sec key processing, ensure rules are applied and multiple keys ok --- app/models/epp/domain.rb | 112 +++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 46 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index ffd525d9d..2b1a9027b 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -314,20 +314,11 @@ 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 - - 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) - + return [] if frame.empty? + keys = DnsSecKeys.new(self).values frame if action == 'rem' to_destroy = [] - dnskeys_list.each do |x| + keys.each do |x| dk = dnskeys.find_by(public_key: x[:public_key]) unless dk @@ -343,51 +334,80 @@ class Epp::Domain < Domain return to_destroy else - return dnskeys_list + return keys end 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(domain) + @domain = domain end - res - 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 + def values(frame) + if Setting.key_data_allowed + @domain.errors.add(:base, :ds_data_not_allowed) if frame.css('dsData').present? + return key_data_from frame + end + if Setting.ds_data_allowed + @domain.errors.add(:base, :key_data_not_allowed) if frame.css('keyData').present? + return ds_data_from frame + 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, value| + result[key] = frame.css(value).first.try(:text) + end + result + end + + # frame requires NodeSet with direct children of keyData + def key_data(frame) + result = xm_copy frame.css('keyData'), KEY_INTERFACE + # TODO: can these defaults go where they belong? + result.merge({ + ds_alg: 3, + ds_digest_type: Setting.ds_algorithm + }) + end + + # get all top level dsData from NodeSet + def ds_data_from(frame) + result = [] + frame.css('dsData').each do |ds_data| + key = ds_data.css('keyData') + ds = xm_copy ds_data, DS_INTERFACE + ds.merge! (key_data key) if key.present? + result << ds + end + result + end + + def key_data_from(frame) + result = [] + frame.css('keyData').each do |key| + result << key_data(key) + end + result end - res end + def domain_statuses_attrs(frame, action) status_list = domain_status_list_from(frame) if action == 'rem' From e31087bf60cbcc8ee09108cb2f397a4a625f5cd3 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Mon, 16 Nov 2015 12:52:26 +0200 Subject: [PATCH 55/69] Story#107192666 - validation for settings that DS data allowed and Allow key data cannot be both true --- app/controllers/admin/settings_controller.rb | 16 +++++++++++----- app/models/setting.rb | 14 ++++++++++++++ app/views/admin/settings/_setting_row.haml | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 6a0c5c033..4014cd7fc 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -7,12 +7,18 @@ class Admin::SettingsController < AdminController end def create - casted_settings.each do |k, v| - Setting[k] = v - end + @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] + 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 diff --git a/app/models/setting.rb b/app/models/setting.rb index 122bfc99a..cb52fd1b7 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -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 diff --git a/app/views/admin/settings/_setting_row.haml b/app/views/admin/settings/_setting_row.haml index 632effc74..ab0d8d991 100644 --- a/app/views/admin/settings/_setting_row.haml +++ b/app/views/admin/settings/_setting_row.haml @@ -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 From 277b7390654a1b303189f2ce7e563281798f9e53 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Sat, 14 Nov 2015 23:40:45 +0200 Subject: [PATCH 56/69] Story #107192666 - bug fix fd4b2debb2c2c192ec129e1056427b94f314462e, refactor, support secDNS:all --- app/models/epp/domain.rb | 79 +++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 2b1a9027b..c90e5faa2 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -314,8 +314,31 @@ class Epp::Domain < Domain # rubocop: disable Metrics/PerceivedComplexity # rubocop: disable Metrics/CyclomaticComplexity def dnskeys_attrs(frame, action) - return [] if frame.empty? - keys = DnsSecKeys.new(self).values frame + keys = [] + return keys if frame.blank? + + if frame.xpath('dnsSec:all').present? + # support delete all or all of + else + inf_data = DnsSecKeys.new(frame) + if Setting.key_data_allowed + if inf_data.ds_data.present? + errors.add(:base, :ds_data_not_allowed) + return + else + keys = inf_data.key_data + end + end + if Setting.ds_data_allowed + if inf_data.key_data.present? + errors.add(:base, :key_data_not_allowed) + return + else + keys = inf_data.ds_data + end + end + end + if action == 'rem' to_destroy = [] keys.each do |x| @@ -341,20 +364,22 @@ class Epp::Domain < Domain # rubocop: enable Metrics/CyclomaticComplexity class DnsSecKeys - def initialize(domain) - @domain = domain + def initialize(frame) + @key_data = [] + @ds_data = [] + if frame.css('dsData').present? + ds_data_from frame + end + frame.css('keyData').each do |key| + @key_data.append key_data_from(key) + end end - def values(frame) - if Setting.key_data_allowed - @domain.errors.add(:base, :ds_data_not_allowed) if frame.css('dsData').present? - return key_data_from frame - end - if Setting.ds_data_allowed - @domain.errors.add(:base, :key_data_not_allowed) if frame.css('keyData').present? - return ds_data_from frame - end - [] + attr_reader :key_data + attr_reader :ds_data + + def error + ds_data.present? && key_data.present? end private @@ -369,15 +394,15 @@ class Epp::Domain < Domain def xm_copy(frame, map) result = {} - map.each do |key, value| - result[key] = frame.css(value).first.try(:text) + map.each do |key, elem| + # content validation might happen later in Dnskey, if we get that far; or not. TODO: check handling + result[key] = frame.css(elem).first.try(:text) end result end - # frame requires NodeSet with direct children of keyData - def key_data(frame) - result = xm_copy frame.css('keyData'), KEY_INTERFACE + def key_data_from(frame) + result = xm_copy frame, KEY_INTERFACE # TODO: can these defaults go where they belong? result.merge({ ds_alg: 3, @@ -385,26 +410,14 @@ class Epp::Domain < Domain }) end - # get all top level dsData from NodeSet def ds_data_from(frame) - result = [] frame.css('dsData').each do |ds_data| key = ds_data.css('keyData') ds = xm_copy ds_data, DS_INTERFACE - ds.merge! (key_data key) if key.present? - result << ds + ds.merge! (key_data_from key) if key.present? + @ds_data << ds end - result end - - def key_data_from(frame) - result = [] - frame.css('keyData').each do |key| - result << key_data(key) - end - result - end - end From a30c3db96807cfc0bcc4b25c7073725dff05d91f Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Mon, 16 Nov 2015 12:14:11 +0200 Subject: [PATCH 57/69] Story #107192666 - feature fix, keyData interface should include flags=KSK --- app/views/epp/domains/info.xml.builder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/epp/domains/info.xml.builder b/app/views/epp/domains/info.xml.builder index 17892a3cc..f89fcd168 100644 --- a/app/views/epp/domains/info.xml.builder +++ b/app/views/epp/domains/info.xml.builder @@ -62,7 +62,7 @@ xml.epp_head do 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.ds_digest.blank? } : [] + key_data = Setting.key_data_allowed ? @domain.dnskeys.find_all { |key| key.public_key.present? } : [] # is there any reason to include without xml.extension do From 4380cfcb3e53d7c0ecf4f6fdd3d4b7162aafb1d3 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Mon, 16 Nov 2015 13:26:52 +0200 Subject: [PATCH 58/69] Story #107192666 - EIS policy specifies keyData interface not dsData. Both true is not allowed --- config/initializers/initial_settings.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/initial_settings.rb b/config/initializers/initial_settings.rb index bcee95150..35c3eebb3 100644 --- a/config/initializers/initial_settings.rb +++ b/config/initializers/initial_settings.rb @@ -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) From db545e3de24fbd183671192756d034c24f360c05 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Mon, 16 Nov 2015 17:51:52 +0200 Subject: [PATCH 59/69] Story #107192666 - refactor, add support for remove all, bug fix overly visible nodes --- app/models/epp/domain.rb | 110 +++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index c90e5faa2..9be98d6e6 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -316,49 +316,26 @@ class Epp::Domain < Domain def dnskeys_attrs(frame, action) keys = [] return keys if frame.blank? + inf_data = DnsSecKeys.new(frame) - if frame.xpath('dnsSec:all').present? - # support delete all or all of + if action == 'rem' && + frame.css('rem > all').first.try(:text) == 'true' + keys = inf_data.mark_destroy_all dnskeys else - inf_data = DnsSecKeys.new(frame) if Setting.key_data_allowed - if inf_data.ds_data.present? - errors.add(:base, :ds_data_not_allowed) - return - else - keys = inf_data.key_data - end + errors.add(:base, :ds_data_not_allowed) if inf_data.ds_data.present? + keys = inf_data.key_data end if Setting.ds_data_allowed - if inf_data.key_data.present? - errors.add(:base, :key_data_not_allowed) - return - else - keys = inf_data.ds_data - end + 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 - - if action == 'rem' - to_destroy = [] - keys.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 - else - return keys - end + errors.any? ? [] : keys end # rubocop: enable Metrics/PerceivedComplexity # rubocop: enable Metrics/CyclomaticComplexity @@ -367,19 +344,28 @@ class Epp::Domain < Domain 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 - end - frame.css('keyData').each do |key| - @key_data.append key_data_from(key) + else + frame.css('keyData').each do |key| + @key_data.append key_data_from(key) + end end end attr_reader :key_data attr_reader :ds_data - def error - ds_data.present? && key_data.present? + 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 @@ -395,7 +381,6 @@ class Epp::Domain < Domain def xm_copy(frame, map) result = {} map.each do |key, elem| - # content validation might happen later in Dnskey, if we get that far; or not. TODO: check handling result[key] = frame.css(elem).first.try(:text) end result @@ -405,8 +390,8 @@ class Epp::Domain < Domain result = xm_copy frame, KEY_INTERFACE # TODO: can these defaults go where they belong? result.merge({ - ds_alg: 3, - ds_digest_type: Setting.ds_algorithm + ds_alg: 3, # DSA/SHA-1 [DSA] RFC2536 + ds_digest_type: Setting.ds_algorithm # only 1 }) end @@ -414,13 +399,28 @@ class Epp::Domain < Domain 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.merge(key_data_from key) if key.present? @ds_data << ds end end + + 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) status_list = domain_status_list_from(frame) if action == 'rem' @@ -830,14 +830,14 @@ class Epp::Domain < Domain def transferrable? (statuses & [ DomainStatus::PENDING_DELETE_CONFIRMATION, - DomainStatus::PENDING_CREATE, - DomainStatus::PENDING_UPDATE, - DomainStatus::PENDING_DELETE, - DomainStatus::PENDING_RENEW, - DomainStatus::PENDING_TRANSFER, - DomainStatus::FORCE_DELETE, - DomainStatus::SERVER_TRANSFER_PROHIBITED, - DomainStatus::CLIENT_TRANSFER_PROHIBITED + DomainStatus::PENDING_CREATE, + DomainStatus::PENDING_UPDATE, + DomainStatus::PENDING_DELETE, + DomainStatus::PENDING_RENEW, + DomainStatus::PENDING_TRANSFER, + DomainStatus::FORCE_DELETE, + DomainStatus::SERVER_TRANSFER_PROHIBITED, + DomainStatus::CLIENT_TRANSFER_PROHIBITED ]).empty? end From 99a66259f0487165a94fbde3e7b77772ddb38b9e Mon Sep 17 00:00:00 2001 From: Stas Date: Fri, 20 Nov 2015 18:27:00 +0200 Subject: [PATCH 60/69] 107821878-refactoring --- app/jobs/domain_delete_confirm_job.rb | 2 +- app/mailers/application_mailer.rb | 4 +-- app/mailers/contact_mailer.rb | 4 +-- app/mailers/domain_mailer.rb | 36 +++++++++++++-------------- app/models/contact.rb | 2 +- app/models/domain.rb | 10 ++++---- app/models/epp/domain.rb | 6 ++--- spec/mailers/contact_mailer_spec.rb | 6 ++--- spec/mailers/domain_mailer_spec.rb | 22 ++++++++-------- 9 files changed, 46 insertions(+), 46 deletions(-) diff --git a/app/jobs/domain_delete_confirm_job.rb b/app/jobs/domain_delete_confirm_job.rb index aa3effb12..de5e02737 100644 --- a/app/jobs/domain_delete_confirm_job.rb +++ b/app/jobs/domain_delete_confirm_job.rb @@ -9,7 +9,7 @@ class DomainDeleteConfirmJob < Que::Job domain.apply_pending_delete! domain.clean_pendings! when RegistrantVerification::REJECTED - DomainMailer.pending_delete_rejected_notification(domain_id).deliver + DomainMailer.pending_delete_rejected_notification(domain_id, deliver_emails).deliver domain.statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION) domain.poll_message!(:poll_pending_delete_rejected_by_registrant) domain.clean_pendings! diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 339638d80..b5b46e6f2 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -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 diff --git a/app/mailers/contact_mailer.rb b/app/mailers/contact_mailer.rb index 2f858a585..71e635540 100644 --- a/app/mailers/contact_mailer.rb +++ b/app/mailers/contact_mailer.rb @@ -1,10 +1,10 @@ class ContactMailer < ApplicationMailer include Que::Mailer - def email_updated(email, contact_id) + def email_updated(email, contact_id, should_deliver) @contact = Contact.find_by(id: contact_id) return unless email || @contact - return if delivery_off?(contact) + return if delivery_off?(contact, should_deliver) return if whitelist_blocked?(email) begin diff --git a/app/mailers/domain_mailer.rb b/app/mailers/domain_mailer.rb index 70f5d8f39..a149ff2ed 100644 --- a/app/mailers/domain_mailer.rb +++ b/app/mailers/domain_mailer.rb @@ -1,10 +1,10 @@ class DomainMailer < ApplicationMailer include Que::Mailer - def pending_update_request_for_old_registrant(domain_id) + 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) + 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}" @@ -27,10 +27,10 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def pending_update_notification_for_new_registrant(domain_id) + 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) + 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}" @@ -51,10 +51,10 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def registrant_updated_notification_for_new_registrant(domain_id) + 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) + return if delivery_off?(@domain, should_deliver) return if whitelist_blocked?(@domain.registrant_email) mail(to: format(@domain.registrant_email), @@ -62,10 +62,10 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def registrant_updated_notification_for_old_registrant(domain_id) + 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) + return if delivery_off?(@domain, should_deliver) @old_registrant_email = domain.registrant_email # Nb! before applying pending updates @@ -107,10 +107,10 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def pending_deleted(domain_id) + def pending_deleted(domain_id, should_deliver) @domain = Domain.find_by(id: domain_id) return unless @domain - return if delivery_off?(@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}" @@ -133,10 +133,10 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def pending_delete_rejected_notification(domain_id) + def pending_delete_rejected_notification(domain_id, should_deliver) @domain = Domain.find_by(id: domain_id) return unless @domain - return if delivery_off?(@domain) + return if delivery_off?(@domain, should_deliver) # no delivery off control, driggered by que, no epp request if @domain.registrant_verification_token.blank? @@ -155,10 +155,10 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def pending_delete_expired_notification(domain_id) + def pending_delete_expired_notification(domain_id, should_deliver) @domain = Domain.find_by(id: domain_id) return unless @domain - return if delivery_off?(@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) @@ -167,10 +167,10 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def delete_confirmation(domain_id) + def delete_confirmation(domain_id, should_deliver) @domain = Domain.find_by(id: domain_id) return unless @domain - return if delivery_off?(@domain) + return if delivery_off?(@domain, should_deliver) return if whitelist_blocked?(@domain.registrant.email) mail(to: format(@domain.registrant.email), @@ -178,9 +178,9 @@ class DomainMailer < ApplicationMailer name: @domain.name)} [#{@domain.name}]") end - def force_delete(domain_id) + def force_delete(domain_id, should_deliver) @domain = Domain.find_by(id: domain_id) - return if delivery_off?(@domain) + 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) diff --git a/app/models/contact.rb b/app/models/contact.rb index 9f623a262..20c11ae80 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -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, id).deliver + ContactMailer.email_updated(e, id, deliver_emails).deliver end end diff --git a/app/models/domain.rb b/app/models/domain.rb index 8d02f7f83..6730497e9 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -241,7 +241,7 @@ class Domain < ActiveRecord::Base DomainMailer.pending_update_expired_notification_for_new_registrant(id).deliver end if domain.pending_delete? || domain.pending_delete_confirmation? - DomainMailer.pending_delete_expired_notification(id).deliver + DomainMailer.pending_delete_expired_notification(id, deliver_emails).deliver end domain.clean_pendings! unless Rails.env.test? @@ -428,8 +428,8 @@ class Domain < ActiveRecord::Base new_registrant_email = registrant.email new_registrant_name = registrant.name - DomainMailer.pending_update_request_for_old_registrant(id).deliver - DomainMailer.pending_update_notification_for_new_registrant(id).deliver + 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 +489,7 @@ class Domain < ActiveRecord::Base pending_delete_confirmation! save(validate: false) # should check if this did succeed - DomainMailer.pending_deleted(id).deliver + DomainMailer.pending_deleted(id, deliver_emails).deliver end def pricelist(operation, period_i = nil, unit = nil) @@ -619,7 +619,7 @@ class Domain < ActiveRecord::Base registrar.messages.create!( body: I18n.t('force_delete_set_on_domain', domain: name) ) - DomainMailer.force_delete(id).deliver + DomainMailer.force_delete(id, deliver_emails).deliver return true end false diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index f31105f4d..69ffeb7f3 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -478,7 +478,7 @@ class Epp::Domain < Domain # rubocop: enable Metrics/CyclomaticComplexity def apply_pending_update! - old_registrant_email = DomainMailer.registrant_updated_notification_for_old_registrant(id) + 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,7 +488,7 @@ 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(id).deliver + DomainMailer.registrant_updated_notification_for_new_registrant(id, deliver_emails).deliver old_registrant_email.deliver true end @@ -497,7 +497,7 @@ class Epp::Domain < Domain preclean_pendings statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION) statuses.delete(DomainStatus::PENDING_DELETE) - DomainMailer.delete_confirmation(id).deliver + DomainMailer.delete_confirmation(id, deliver_emails).deliver # TODO: confirm that this actually makes sense clean_pendings! if valid? && set_pending_delete! diff --git a/spec/mailers/contact_mailer_spec.rb b/spec/mailers/contact_mailer_spec.rb index f0402e3db..2cb8fe344 100644 --- a/spec/mailers/contact_mailer_spec.rb +++ b/spec/mailers/contact_mailer_spec.rb @@ -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.id) + @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.id) + @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.id) + @mail = ContactMailer.email_updated('info@ääöü.org', @contact.id, deliver_emails) end it 'should render email subject' do diff --git a/spec/mailers/domain_mailer_spec.rb b/spec/mailers/domain_mailer_spec.rb index 20662a2ba..37605a668 100644 --- a/spec/mailers/domain_mailer_spec.rb +++ b/spec/mailers/domain_mailer_spec.rb @@ -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.id) + @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.id) + @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.id) + @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.id) + @mail = DomainMailer.pending_update_notification_for_new_registrant(@domain.id, deliver_emails) 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.id) + @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.id) + @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.id) + @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.id) + @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.id) + @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.id) + @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.id) + @mail = DomainMailer.delete_confirmation(@domain.id, deliver_emails) end it 'should render email subject' do From 107448d919893a40aaf9f76a70086cf879dca9c2 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Mon, 23 Nov 2015 09:14:49 +0200 Subject: [PATCH 61/69] Revert "Story #104525314 - admin is not allowed to reject pendingDeleteConfirmation" user actually does want this feature This reverts commit b5c3a24bde1004804ecc67e069afd127f2d6d903. --- app/views/admin/domains/form/_pending_delete.haml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/admin/domains/form/_pending_delete.haml b/app/views/admin/domains/form/_pending_delete.haml index ad1844634..e3d71f3f4 100644 --- a/app/views/admin/domains/form/_pending_delete.haml +++ b/app/views/admin/domains/form/_pending_delete.haml @@ -2,3 +2,7 @@ = 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') + + = link_to(t(:reject_delete), admin_domain_pending_delete_path(f.object.id, f.object.id), + method: :delete, data: { confirm: t(:are_you_sure) }, + class: 'btn btn-danger btn-xs') From 25388562f51a742976bb91640287c21beb572902 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Mon, 23 Nov 2015 10:17:16 +0200 Subject: [PATCH 62/69] Story#108423414 - remove link from registrar under registrar --- app/views/registrar/contacts/partials/_domains.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/registrar/contacts/partials/_domains.haml b/app/views/registrar/contacts/partials/_domains.haml index ab590cd85..efdf78504 100644 --- a/app/views/registrar/contacts/partials/_domains.haml +++ b/app/views/registrar/contacts/partials/_domains.haml @@ -23,7 +23,7 @@ - domains.each do |x| %tr %td= link_to(x.name, info_registrar_domains_path(domain_name: x.name)) - %td= link_to(x.registrar, registrar_contact_path(id: x.registrant.code)) + %td= x.registrar.name %td= l(x.valid_to, format: :short) %td= x.roles.join(", ") From 99f1a62518ed4750ed923c9e5d38798a2b78ea78 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Mon, 23 Nov 2015 12:31:07 +0200 Subject: [PATCH 63/69] Story #107192666 - secDNS alorithms remove 252-255, add 10,13,14 --- app/models/depp/dnskey.rb | 7 +++---- app/models/dnskey.rb | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/models/depp/dnskey.rb b/app/models/depp/dnskey.rb index 895dca74b..cd98bb70e 100644 --- a/app/models/depp/dnskey.rb +++ b/app/models/depp/dnskey.rb @@ -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] diff --git a/app/models/dnskey.rb b/app/models/dnskey.rb index 0c426978c..26f5a0afd 100644 --- a/app/models/dnskey.rb +++ b/app/models/dnskey.rb @@ -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 From abae4e254ab04c3d2e5c81391ce4ba360643af72 Mon Sep 17 00:00:00 2001 From: Georg Kahest Date: Mon, 23 Nov 2015 16:38:56 +0200 Subject: [PATCH 64/69] ratelimit fix --- app/controllers/epp_controller.rb | 2 +- config/application-example.yml | 1 + doc/debian_build_doc.md | 11 +++++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/controllers/epp_controller.rb b/app/controllers/epp_controller.rb index e4ebcf66f..15f6c6a49 100644 --- a/app/controllers/epp_controller.rb +++ b/app/controllers/epp_controller.rb @@ -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 diff --git a/config/application-example.yml b/config/application-example.yml index cce71e3a4..b08a1b007 100644 --- a/config/application-example.yml +++ b/config/application-example.yml @@ -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 diff --git a/doc/debian_build_doc.md b/doc/debian_build_doc.md index e14992994..084619b26 100644 --- a/doc/debian_build_doc.md +++ b/doc/debian_build_doc.md @@ -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 ```` From 8939078072844d6a9b57bb1a4ce7097df6ab40d8 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Tue, 24 Nov 2015 15:13:48 +0200 Subject: [PATCH 65/69] Story #108621138 - TCB Epp::Domain object not found after delete, allow message dequeue or view; without internal error --- app/views/epp/poll/poll_req.xml.builder | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/views/epp/poll/poll_req.xml.builder b/app/views/epp/poll/poll_req.xml.builder index 347f0a632..605ca496e 100644 --- a/app/views/epp/poll/poll_req.xml.builder +++ b/app/views/epp/poll/poll_req.xml.builder @@ -10,8 +10,11 @@ xml.epp_head do end xml.resData do - if @message.attached_obj_type == 'DomainTransfer' - xml << render('epp/domains/partials/transfer', builder: xml, dt: @object) + 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 From a0ff1c99d04654cb861834b2b4fa91656cd22aad Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Tue, 24 Nov 2015 15:20:28 +0200 Subject: [PATCH 66/69] Story #108621138 - add a registrar message for deleteCandidate was deleted --- app/controllers/epp/polls_controller.rb | 14 +++++++++++++- app/models/domain.rb | 14 ++++++++++++-- .../domains/partials/_delete_complete.xml.builder | 4 ++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 app/views/epp/domains/partials/_delete_complete.xml.builder diff --git a/app/controllers/epp/polls_controller.rb b/app/controllers/epp/polls_controller.rb index 26df210c1..531509a6c 100644 --- a/app/controllers/epp/polls_controller.rb +++ b/app/controllers/epp/polls_controller.rb @@ -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 - @object = Object.const_get(@message.attached_obj_type).find(@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' diff --git a/app/models/domain.rb b/app/models/domain.rb index 9845e8ac8..736fe5c74 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -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) diff --git a/app/views/epp/domains/partials/_delete_complete.xml.builder b/app/views/epp/domains/partials/_delete_complete.xml.builder new file mode 100644 index 000000000..509ac6953 --- /dev/null +++ b/app/views/epp/domains/partials/_delete_complete.xml.builder @@ -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 From 78dfd160e23962b5322569d7fc41943635db3b64 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Tue, 24 Nov 2015 17:40:38 +0200 Subject: [PATCH 67/69] Story#108553816 - repp can show transfer domain's contact information --- app/api/repp/domain_v1.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/app/api/repp/domain_v1.rb b/app/api/repp/domain_v1.rb index 4260c59b6..95dbb5af5 100644 --- a/app/api/repp/domain_v1.rb +++ b/app/api/repp/domain_v1.rb @@ -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 From 8a84d16283eb82116ec99bee485ba1e9dc8b7db0 Mon Sep 17 00:00:00 2001 From: Matt Farnsworth Date: Tue, 24 Nov 2015 18:14:46 +0200 Subject: [PATCH 68/69] Story #104525314 - correction, flag not needed on reject' --- app/controllers/admin/pending_deletes_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/admin/pending_deletes_controller.rb b/app/controllers/admin/pending_deletes_controller.rb index 4866d65c9..a64a34714 100644 --- a/app/controllers/admin/pending_deletes_controller.rb +++ b/app/controllers/admin/pending_deletes_controller.rb @@ -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 From abd97bd698ceafc28f7bb10f2be2c0730380a0d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Tue, 24 Nov 2015 19:00:12 +0200 Subject: [PATCH 69/69] Update domain.md fixed wrong element order in domain:update documentation --- doc/epp/domain.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/epp/domain.md b/doc/epp/domain.md index 79b3f8ed5..fb03e40a4 100644 --- a/doc/epp/domain.md +++ b/doc/epp/domain.md @@ -50,9 +50,6 @@ Domain name mapping protocol short version: 1 1 Attribute: xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd" 1 Domain name. Can contain unicode characters. - 0-1 Attributes to change - 0-1 Contact reference to the registrant - Optional attribute: verified="yes/no" 0-1 Objects to add 0-n Contact reference. Attribute: type="admin / tech" 0-n Status description. @@ -72,6 +69,9 @@ Domain name mapping protocol short version: 0-1 1 1 Hostname of the nameserver + 0-1 Attributes to change + 0-1 Contact reference to the registrant + Optional attribute: verified="yes/no" 0-1 Required if registrant is changing 0-1 Attribute: xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1" 0-1