From 5258c43faa86f1dd11baea56eaa5f214afa9f5cd Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Mon, 18 Aug 2014 16:00:34 +0300 Subject: [PATCH 1/8] Make epp code map dynamic --- app/models/concerns/epp_errors.rb | 8 +++++-- app/models/contact.rb | 26 ++++++++++++----------- app/models/domain.rb | 35 ++++++++++++++++++++++++------- app/models/nameserver.rb | 14 +++++++++---- config/locales/en.yml | 2 -- 5 files changed, 57 insertions(+), 28 deletions(-) diff --git a/app/models/concerns/epp_errors.rb b/app/models/concerns/epp_errors.rb index e8c56918e..cb7f53dd2 100644 --- a/app/models/concerns/epp_errors.rb +++ b/app/models/concerns/epp_errors.rb @@ -51,8 +51,12 @@ module EppErrors end def find_epp_code(msg) - self.class::EPP_CODE_MAP.each do |code, values| - return code if values.include?(msg) + epp_code_map.each do |code, values| + values.each do |x| + t = errors.generate_message(*x) if x.is_a?(Array) + t = x if x.is_a?(String) + return code if t == msg + end end nil end diff --git a/app/models/contact.rb b/app/models/contact.rb index ecce51574..4c6778183 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -4,12 +4,6 @@ class Contact < ActiveRecord::Base include EppErrors - EPP_CODE_MAP = { - '2302' => ['Contact id already exists'], - '2303' => [:not_found, :epp_obj_does_not_exist], - '2005' => ['Phone nr is invalid', 'Email is invalid'] - } - EPP_ATTR_MAP = {} has_one :address @@ -81,7 +75,7 @@ class Contact < ActiveRecord::Base relation = get_relation(model) return true unless relation.nil? || relation.blank? false - end + end @@ -94,27 +88,35 @@ class Contact < ActiveRecord::Base false end + def epp_code_map + { + '2302' => [[:code, :epp_id_taken]], + '2303' => [:not_found, :epp_obj_does_not_exist], + '2005' => ['Phone nr is invalid', 'Email is invalid'] + } + end + class << self def extract_attributes ph, type=:create - + contact_hash = { phone: ph[:voice], ident: ph[:ident], email: ph[:email] } - + contact_hash = contact_hash.merge({ name: ph[:postalInfo][:name], org_name: ph[:postalInfo][:org] }) if ph[:postalInfo].is_a? Hash - + contact_hash[:code] = ph[:id] if type == :create - + contact_hash.delete_if { |k, v| v.nil? } end - + def check_availability(codes) codes = [codes] if codes.is_a?(String) diff --git a/app/models/domain.rb b/app/models/domain.rb index a3775a244..08f0ff4ce 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -4,14 +4,6 @@ class Domain < ActiveRecord::Base include EppErrors - EPP_CODE_MAP = { - '2302' => ['Domain name already exists', 'Domain name is reserved or restricted'], # Object exists - '2306' => ['Registrant is missing', 'Admin contact is missing', 'Given and current expire dates do not match'], # Parameter policy error - '2004' => ['Nameservers count must be between 1-13', 'Period must add up to 1, 2 or 3 years'], # Parameter value range error - '2303' => ['Registrant not found', 'Contact was not found'], # Object does not exist - '2200' => ['Authentication error'] - } - EPP_ATTR_MAP = { owner_contact: 'registrant', name_dirty: 'name', @@ -159,6 +151,33 @@ class Domain < ActiveRecord::Base }) if cur_exp_date.to_date != valid_to end + def epp_code_map + domain_validation_sg = SettingGroup.find_by(code: SettingGroup::DOMAIN_VALIDATION_CODE) + + { + '2302' => [ # Object exists + [:name_dirty, :taken], + [:name_dirty, :reserved] + ], + '2306' => [ # Parameter policy error + [:owner_contact, :blank], + [:admin_contacts, :blank], + [:valid_to, :epp_exp_dates_do_not_match] + ], + '2004' => [ # Parameter value range error + [:nameservers, :out_of_range, {min: domain_validation_sg.get(:ns_min_count), max: domain_validation_sg.get(:ns_max_count)}], + [:period, :out_of_range] + ], + '2303' => [ # Object does not exist + [:owner_contact, :epp_registrant_not_found], + [:domain_contacts, :not_found] + ], + '2200' => [ + [:auth_info, :wrong_pw] + ] + } + end + ## SHARED # For domain transfer diff --git a/app/models/nameserver.rb b/app/models/nameserver.rb index e033d29b4..e3cf257c8 100644 --- a/app/models/nameserver.rb +++ b/app/models/nameserver.rb @@ -1,10 +1,6 @@ class Nameserver < ActiveRecord::Base include EppErrors - EPP_CODE_MAP = { - '2005' => ['Hostname is invalid', 'IPv4 is invalid', 'IPv6 is invalid'] - } - EPP_ATTR_MAP = { hostname: 'hostName' } @@ -15,4 +11,14 @@ class Nameserver < ActiveRecord::Base validates :hostname, format: { with: /\A(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])\z/ } validates :ipv4, format: { with: /\A(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\z/, allow_nil: true } validates :ipv6, format: { with: /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/, allow_nil: true } + + def epp_code_map + { + '2005' => [ + [:hostname, :invalid], + [:ipv4, :invalid], + [:ipv6, :invalid] + ] + } + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 1fcbfb07b..6ebdc2805 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -50,8 +50,6 @@ en: blank: 'Admin contact is missing' nameservers: out_of_range: 'Nameservers count must be between %{min}-%{max}' - hostname_invalid: 'Hostname is invalid' - ip_invalid: 'IPv4 is invalid' period: out_of_range: 'Period must add up to 1, 2 or 3 years' auth_info: From b0e9828a014b4ddc73fa3a24caf988d5ba477b44 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Mon, 18 Aug 2014 16:33:56 +0300 Subject: [PATCH 2/8] Refactor dynamic validation, test for it --- app/models/domain.rb | 9 +++++---- app/models/setting_group.rb | 11 +++++++---- spec/models/domain_spec.rb | 13 +++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/app/models/domain.rb b/app/models/domain.rb index 08f0ff4ce..551815de9 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -119,8 +119,9 @@ class Domain < ActiveRecord::Base ### VALIDATIONS ### def validate_nameservers_count - sg = SettingGroup.find_by(code: SettingGroup::DOMAIN_VALIDATION_CODE) - min, max = sg.get(:ns_min_count).to_i, sg.get(:ns_max_count).to_i + sg = SettingGroup.domain_validation + min, max = sg.setting(:ns_min_count).value.to_i, sg.setting(:ns_max_count).value.to_i + unless nameservers.length.between?(min, max) errors.add(:nameservers, :out_of_range, {min: min, max: max}) end @@ -152,7 +153,7 @@ class Domain < ActiveRecord::Base end def epp_code_map - domain_validation_sg = SettingGroup.find_by(code: SettingGroup::DOMAIN_VALIDATION_CODE) + domain_validation_sg = SettingGroup.domain_validation { '2302' => [ # Object exists @@ -165,7 +166,7 @@ class Domain < ActiveRecord::Base [:valid_to, :epp_exp_dates_do_not_match] ], '2004' => [ # Parameter value range error - [:nameservers, :out_of_range, {min: domain_validation_sg.get(:ns_min_count), max: domain_validation_sg.get(:ns_max_count)}], + [:nameservers, :out_of_range, {min: domain_validation_sg.setting(:ns_min_count).value, max: domain_validation_sg.setting(:ns_max_count).value}], [:period, :out_of_range] ], '2303' => [ # Object does not exist diff --git a/app/models/setting_group.rb b/app/models/setting_group.rb index 0435677f8..25b4a79cb 100644 --- a/app/models/setting_group.rb +++ b/app/models/setting_group.rb @@ -3,10 +3,13 @@ class SettingGroup < ActiveRecord::Base accepts_nested_attributes_for :settings - DOMAIN_VALIDATION_CODE = 'domain_validation' + def setting(key) + settings.find_by(code: key.to_s) + end - def get(key) - s = settings.find_by(code: key.to_s) - s.try(:value) + class << self + def domain_validation + find_by(code: 'domain_validation') + end end end diff --git a/spec/models/domain_spec.rb b/spec/models/domain_spec.rb index 244fe75c1..2f674de5e 100644 --- a/spec/models/domain_spec.rb +++ b/spec/models/domain_spec.rb @@ -48,6 +48,19 @@ describe Domain do admin_contacts: ["Admin contact is missing"], nameservers: ["Nameservers count must be between 1-13"] }) + + sg = SettingGroup.domain_validation + min = sg.setting(:ns_min_count) + max = sg.setting(:ns_max_count) + + min.value = 2 + min.save + + max.value = 7 + max.save + + expect(d.valid?).to be false + expect(d.errors.messages[:nameservers]).to eq(['Nameservers count must be between 2-7']) end it 'does not create a reserved domain' do From 32fc26b5a465bf5c976d6cb93e54e3af8080555b Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Tue, 19 Aug 2014 13:43:01 +0300 Subject: [PATCH 3/8] Add statuses to domain --- app/models/domain.rb | 6 +++++ app/models/domain_status.rb | 4 ++++ app/models/setting_group.rb | 4 ++++ app/views/setting_groups/index.haml | 18 +++++++-------- .../20140819095802_create_domains_statuses.rb | 8 +++++++ ...20140819103517_populate_domain_statuses.rb | 23 +++++++++++++++++++ db/schema.rb | 7 +++++- 7 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 app/models/domain_status.rb create mode 100644 db/migrate/20140819095802_create_domains_statuses.rb create mode 100644 db/migrate/20140819103517_populate_domain_statuses.rb diff --git a/app/models/domain.rb b/app/models/domain.rb index 551815de9..a420f19ee 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -25,6 +25,12 @@ class Domain < ActiveRecord::Base has_and_belongs_to_many :nameservers + has_many :domain_statuses + + has_many :statuses, -> { + where(setting_group: SettingGroup.domain_statuses) + }, through: :domain_statuses, source: :setting + delegate :code, to: :owner_contact, prefix: true delegate :name, to: :registrar, prefix: true diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb new file mode 100644 index 000000000..d71e6be2d --- /dev/null +++ b/app/models/domain_status.rb @@ -0,0 +1,4 @@ +class DomainStatus < ActiveRecord::Base + belongs_to :domain + belongs_to :setting +end diff --git a/app/models/setting_group.rb b/app/models/setting_group.rb index 25b4a79cb..ace904acf 100644 --- a/app/models/setting_group.rb +++ b/app/models/setting_group.rb @@ -11,5 +11,9 @@ class SettingGroup < ActiveRecord::Base def domain_validation find_by(code: 'domain_validation') end + + def domain_statuses + find_by(code: 'domain_statuses') + end end end diff --git a/app/views/setting_groups/index.haml b/app/views/setting_groups/index.haml index 492d76d54..07bbdcafd 100644 --- a/app/views/setting_groups/index.haml +++ b/app/views/setting_groups/index.haml @@ -1,14 +1,14 @@ %h2= t('shared.setting_groups') %hr -- @setting_groups.each do |x| - .row - .col-md-12 - %table.table.table-striped.table-bordered - %tr - %th{class: 'col-xs-9'} - = t('.setting_group') - %th{class: 'col-xs-2'} - = t('shared.action') +.row + .col-md-12 + %table.table.table-striped.table-bordered + %tr + %th{class: 'col-xs-9'} + = t('.setting_group') + %th{class: 'col-xs-2'} + = t('shared.action') + - @setting_groups.each do |x| %tr %td= t("setting_groups.codes.#{x.code}") %td= link_to(t('.edit_settings'), setting_group_path(x), class: 'btn btn-primary btn-xs') diff --git a/db/migrate/20140819095802_create_domains_statuses.rb b/db/migrate/20140819095802_create_domains_statuses.rb new file mode 100644 index 000000000..90e4f1a22 --- /dev/null +++ b/db/migrate/20140819095802_create_domains_statuses.rb @@ -0,0 +1,8 @@ +class CreateDomainsStatuses < ActiveRecord::Migration + def change + create_table :domain_statuses do |t| + t.integer :domain_id + t.integer :setting_id + end + end +end diff --git a/db/migrate/20140819103517_populate_domain_statuses.rb b/db/migrate/20140819103517_populate_domain_statuses.rb new file mode 100644 index 000000000..0adfc67df --- /dev/null +++ b/db/migrate/20140819103517_populate_domain_statuses.rb @@ -0,0 +1,23 @@ +class PopulateDomainStatuses < ActiveRecord::Migration + def change + SettingGroup.create(code: 'domain_statuses', settings: [ + Setting.create(code: 'clientDeleteProhibited'.underscore, value: 'clientDeleteProhibited'), + Setting.create(code: 'serverDeleteProhibited'.underscore, value: 'serverDeleteProhibited'), + Setting.create(code: 'clientHold'.underscore, value: 'clientHold'), + Setting.create(code: 'serverHold'.underscore, value: 'serverHold'), + Setting.create(code: 'clientRenewProhibited'.underscore, value: 'clientRenewProhibited'), + Setting.create(code: 'serverRenewProhibited'.underscore, value: 'serverRenewProhibited'), + Setting.create(code: 'clientTransferProhibited'.underscore, value: 'clientTransferProhibited'), + Setting.create(code: 'serverTransferProhibited'.underscore, value: 'serverTransferProhibited'), + Setting.create(code: 'clientUpdateProhibited'.underscore, value: 'clientUpdateProhibited'), + Setting.create(code: 'serverUpdateProhibited'.underscore, value: 'serverUpdateProhibited'), + Setting.create(code: 'inactive', value: 'inactive'), + Setting.create(code: 'ok', value: 'ok'), + Setting.create(code: 'pendingCreate'.underscore, value: 'pendingCreate'), + Setting.create(code: 'pendingDelete'.underscore, value: 'pendingDelete'), + Setting.create(code: 'pendingRenew'.underscore, value: 'pendingRenew'), + Setting.create(code: 'pendingTransfer'.underscore, value: 'pendingTransfer'), + Setting.create(code: 'pendingUpdate'.underscore, value: 'pendingUpdate') + ]) + end +end diff --git a/db/schema.rb b/db/schema.rb index 71db15ed3..bef49d930 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140815114000) do +ActiveRecord::Schema.define(version: 20140819103517) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -61,6 +61,11 @@ ActiveRecord::Schema.define(version: 20140815114000) do t.datetime "updated_at" end + create_table "domain_statuses", force: true do |t| + t.integer "domain_id" + t.integer "setting_id" + end + create_table "domains", force: true do |t| t.string "name" t.integer "registrar_id" From 290182b7d158bbf4b3b24ef12fdf7f1bfc19354e Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Tue, 19 Aug 2014 15:38:19 +0300 Subject: [PATCH 4/8] Domain updating - adding contacts and nameservers --- app/helpers/epp/domains_helper.rb | 2 ++ app/models/domain.rb | 2 +- spec/epp/domain_spec.rb | 12 +++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/helpers/epp/domains_helper.rb b/app/helpers/epp/domains_helper.rb index 2abf3aa27..fe7c1289c 100644 --- a/app/helpers/epp/domains_helper.rb +++ b/app/helpers/epp/domains_helper.rb @@ -38,6 +38,8 @@ module Epp::DomainsHelper @domain = find_domain handle_errors(@domain) and return unless @domain + handle_errors(@domain) and return unless @domain.attach_objects(@ph, parsed_frame.css('add')) + handle_errors(@domain) and return unless @domain.save render '/epp/domains/success' end diff --git a/app/models/domain.rb b/app/models/domain.rb index a420f19ee..ab4d4cda9 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -54,7 +54,7 @@ class Domain < ActiveRecord::Base ### CREATE ### def attach_objects(ph, parsed_frame) - attach_owner_contact(ph[:registrant]) + attach_owner_contact(ph[:registrant]) if ph[:registrant] attach_contacts(self.class.parse_contacts_from_frame(parsed_frame)) attach_nameservers(self.class.parse_nameservers_from_frame(parsed_frame)) diff --git a/spec/epp/domain_spec.rb b/spec/epp/domain_spec.rb index 87d5a5f60..3199d13cb 100644 --- a/spec/epp/domain_spec.rb +++ b/spec/epp/domain_spec.rb @@ -244,13 +244,23 @@ describe 'EPP Domain', epp: true do expect(response[:results][0][:msg]).to eq('Domain not found') end - it 'updates domain', pending: true do + it 'updates domain' do + response = epp_request('domains/update.xml') + expect(response[:results][0][:result_code]).to eq('2303') + expect(response[:results][0][:msg]).to eq('Contact was not found') + + Fabricate(:contact, code: 'mak21') + response = epp_request('domains/update.xml') expect(response[:results][0][:result_code]).to eq('1000') d = Domain.first + new_ns = d.nameservers.find_by(hostname: 'ns2.example.com') expect(new_ns).to be_truthy + + new_contact = d.tech_contacts.find_by(code: 'mak21') + expect(new_contact).to be_truthy end end From f43662e8b07c1acd0996f8a3b3438574ab60f08f Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Tue, 19 Aug 2014 16:52:58 +0300 Subject: [PATCH 5/8] Add status adding to domain update epp request --- app/models/domain.rb | 22 +++++++++++++++++++- spec/epp/domain_spec.rb | 1 + spec/fabricators/setting_group_fabricator.rb | 7 +++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/models/domain.rb b/app/models/domain.rb index ab4d4cda9..4fb7e8b50 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -28,7 +28,7 @@ class Domain < ActiveRecord::Base has_many :domain_statuses has_many :statuses, -> { - where(setting_group: SettingGroup.domain_statuses) + where(setting_group: SettingGroup.domain_statuses).uniq }, through: :domain_statuses, source: :setting delegate :code, to: :owner_contact, prefix: true @@ -57,6 +57,7 @@ class Domain < ActiveRecord::Base attach_owner_contact(ph[:registrant]) if ph[:registrant] attach_contacts(self.class.parse_contacts_from_frame(parsed_frame)) attach_nameservers(self.class.parse_nameservers_from_frame(parsed_frame)) + attach_statuses(self.class.parse_statuses_from_frame(parsed_frame)) errors.empty? end @@ -107,6 +108,12 @@ class Domain < ActiveRecord::Base end end + def attach_statuses(status_list) + status_list.each do |x| + statuses << SettingGroup.domain_statuses.settings.find_by(value: x[:value]) + end + end + ### RENEW ### def renew(cur_exp_date, period, unit='y') @@ -237,6 +244,19 @@ class Domain < ActiveRecord::Base p[:unit] end + def parse_statuses_from_frame(parsed_frame) + res = [] + + parsed_frame.css('status').each do |x| + res << { + value: x['s'], + description: x.text + } + end + + res + end + def check_availability(domains) domains = [domains] if domains.is_a?(String) diff --git a/spec/epp/domain_spec.rb b/spec/epp/domain_spec.rb index 3199d13cb..e5a398b41 100644 --- a/spec/epp/domain_spec.rb +++ b/spec/epp/domain_spec.rb @@ -7,6 +7,7 @@ describe 'EPP Domain', epp: true do before(:each) do Fabricate(:epp_user) Fabricate(:domain_validation_setting_group) + Fabricate(:domain_statuses_setting_group) end it 'returns error if contact does not exists' do diff --git a/spec/fabricators/setting_group_fabricator.rb b/spec/fabricators/setting_group_fabricator.rb index 0a05b7125..e4ea0ac1a 100644 --- a/spec/fabricators/setting_group_fabricator.rb +++ b/spec/fabricators/setting_group_fabricator.rb @@ -13,3 +13,10 @@ Fabricator(:domain_validation_setting_group, from: :setting_group) do Fabricate(:setting, code: 'ns_max_count', value: 13) ]} end + +Fabricator(:domain_statuses_setting_group, from: :setting_group) do + code 'domain_statuses' + settings { [ + Fabricate(:setting, code: 'client_hold', value: 'clientHold') + ]} +end From e20944151eb7fd6a3b4e226bbf67bf9e487d351d Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Thu, 21 Aug 2014 12:14:34 +0300 Subject: [PATCH 6/8] Domain statuses improvements --- app/models/domain.rb | 14 +++++++------ app/models/domain_status.rb | 21 +++++++++++++++++++ app/models/setting.rb | 2 ++ app/models/setting_group.rb | 2 ++ config/locales/en.yml | 4 ++++ .../20140819095802_create_domains_statuses.rb | 1 + ...20140819103517_populate_domain_statuses.rb | 6 ++++-- db/schema.rb | 1 + spec/epp/domain_spec.rb | 11 +++++++++- spec/models/setting_spec.rb | 2 +- 10 files changed, 54 insertions(+), 10 deletions(-) diff --git a/app/models/domain.rb b/app/models/domain.rb index 4fb7e8b50..ad53ca3a5 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -25,11 +25,9 @@ class Domain < ActiveRecord::Base has_and_belongs_to_many :nameservers - has_many :domain_statuses - - has_many :statuses, -> { - where(setting_group: SettingGroup.domain_statuses).uniq - }, through: :domain_statuses, source: :setting + has_many :domain_statuses, -> { + joins(:setting).where(settings: {setting_group_id: SettingGroup.domain_statuses.id}) + } delegate :code, to: :owner_contact, prefix: true delegate :name, to: :registrar, prefix: true @@ -110,7 +108,11 @@ class Domain < ActiveRecord::Base def attach_statuses(status_list) status_list.each do |x| - statuses << SettingGroup.domain_statuses.settings.find_by(value: x[:value]) + setting = SettingGroup.domain_statuses.settings.find_by(value: x[:value]) + self.domain_statuses.build( + setting: setting, + description: x[:description] + ) end end diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index d71e6be2d..e3a9c47e7 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -1,4 +1,25 @@ class DomainStatus < ActiveRecord::Base + # Domain statuses are stored as settings + include EppErrors + + EPP_ATTR_MAP = { + setting: 'status' + } + belongs_to :domain belongs_to :setting + + delegate :value, :code, to: :setting + + validates :setting, uniqueness: { scope: :domain_id } + + def setting_uniqueness + + end + + def epp_code_map + { + '2302' => [[:setting, :taken]] + } + end end diff --git a/app/models/setting.rb b/app/models/setting.rb index 3bdda2a0c..eb4dbe7f5 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -1,4 +1,6 @@ class Setting < ActiveRecord::Base belongs_to :setting_group + has_many :domain_statuses + has_many :domains, through: :domain_statuses validates :code, uniqueness: { scope: :setting_group_id } end diff --git a/app/models/setting_group.rb b/app/models/setting_group.rb index ace904acf..3fea54616 100644 --- a/app/models/setting_group.rb +++ b/app/models/setting_group.rb @@ -3,6 +3,8 @@ class SettingGroup < ActiveRecord::Base accepts_nested_attributes_for :settings + validates :code, uniqueness: true + def setting(key) settings.find_by(code: key.to_s) end diff --git a/config/locales/en.yml b/config/locales/en.yml index 6ebdc2805..df0e07895 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -66,6 +66,10 @@ en: attributes: code: taken: 'Code already exists' + domain_status: + attributes: + setting: + taken: 'Status already exists on this domain' attributes: domain: name: 'Domain name' diff --git a/db/migrate/20140819095802_create_domains_statuses.rb b/db/migrate/20140819095802_create_domains_statuses.rb index 90e4f1a22..bd7323982 100644 --- a/db/migrate/20140819095802_create_domains_statuses.rb +++ b/db/migrate/20140819095802_create_domains_statuses.rb @@ -3,6 +3,7 @@ class CreateDomainsStatuses < ActiveRecord::Migration create_table :domain_statuses do |t| t.integer :domain_id t.integer :setting_id + t.string :description end end end diff --git a/db/migrate/20140819103517_populate_domain_statuses.rb b/db/migrate/20140819103517_populate_domain_statuses.rb index 0adfc67df..51695125f 100644 --- a/db/migrate/20140819103517_populate_domain_statuses.rb +++ b/db/migrate/20140819103517_populate_domain_statuses.rb @@ -1,6 +1,7 @@ class PopulateDomainStatuses < ActiveRecord::Migration def change - SettingGroup.create(code: 'domain_statuses', settings: [ + sg = SettingGroup.create(code: 'domain_statuses') + sg.settings = [ Setting.create(code: 'clientDeleteProhibited'.underscore, value: 'clientDeleteProhibited'), Setting.create(code: 'serverDeleteProhibited'.underscore, value: 'serverDeleteProhibited'), Setting.create(code: 'clientHold'.underscore, value: 'clientHold'), @@ -18,6 +19,7 @@ class PopulateDomainStatuses < ActiveRecord::Migration Setting.create(code: 'pendingRenew'.underscore, value: 'pendingRenew'), Setting.create(code: 'pendingTransfer'.underscore, value: 'pendingTransfer'), Setting.create(code: 'pendingUpdate'.underscore, value: 'pendingUpdate') - ]) + ] + sg.save end end diff --git a/db/schema.rb b/db/schema.rb index bef49d930..71d2b04e3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -64,6 +64,7 @@ ActiveRecord::Schema.define(version: 20140819103517) do create_table "domain_statuses", force: true do |t| t.integer "domain_id" t.integer "setting_id" + t.string "description" end create_table "domains", force: true do |t| diff --git a/spec/epp/domain_spec.rb b/spec/epp/domain_spec.rb index e5a398b41..1b5b01b17 100644 --- a/spec/epp/domain_spec.rb +++ b/spec/epp/domain_spec.rb @@ -262,6 +262,15 @@ describe 'EPP Domain', epp: true do new_contact = d.tech_contacts.find_by(code: 'mak21') expect(new_contact).to be_truthy + + expect(d.domain_statuses.count).to eq(1) + expect(d.domain_statuses.first.description).to eq('Payment overdue.') + expect(d.domain_statuses.first.value).to eq('clientHold') + expect(d.domain_statuses.first.code).to eq('client_hold') + + response = epp_request('domains/update.xml') + + expect(d.domain_statuses.count).to eq(1) end end @@ -283,7 +292,7 @@ describe 'EPP Domain', epp: true do expect(name.text).to eq('example.ee') expect(name[:avail]).to eq('0') - expect(reason.text).to eq('in use') #confirm this with current API + expect(reason.text).to eq('in use') end it 'checks multiple domains' do diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb index 5aaa13b50..3a8e60330 100644 --- a/spec/models/setting_spec.rb +++ b/spec/models/setting_spec.rb @@ -13,7 +13,7 @@ describe Setting do err = sg.settings.last.errors[:code].first expect(err).to eq('Code already exists') - sg_2 = Fabricate(:setting_group) + sg_2 = Fabricate(:setting_group, code: 'domain_statuses') sg_2.settings.build(code: 'this_is_code') expect(sg_2.save).to be true From c0d25ccedfa44f6ef5034863bf53884d2b2c9826 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Thu, 21 Aug 2014 12:54:22 +0300 Subject: [PATCH 7/8] Test improvement --- spec/epp/domain_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/epp/domain_spec.rb b/spec/epp/domain_spec.rb index 1b5b01b17..98e9b9527 100644 --- a/spec/epp/domain_spec.rb +++ b/spec/epp/domain_spec.rb @@ -270,6 +270,8 @@ describe 'EPP Domain', epp: true do response = epp_request('domains/update.xml') + expect(response[:results][0][:result_code]).to eq('2302') + expect(response[:results][0][:msg]).to eq('Status already exists on this domain') expect(d.domain_statuses.count).to eq(1) end end From 87cc7799be53209fc163858b54a46f9650ca76ba Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Thu, 21 Aug 2014 16:47:21 +0300 Subject: [PATCH 8/8] Nameserver removing with domain update request --- app/helpers/epp/domains_helper.rb | 1 + app/models/domain.rb | 18 ++++++++-- app/models/domain_status.rb | 4 --- config/locales/en.yml | 2 ++ spec/epp/domain_spec.rb | 33 ++++++++++++++----- spec/epp/requests/domains/update.xml | 1 + .../requests/domains/update_add_objects.xml | 22 +++++++++++++ .../domains/update_remove_objects.xml | 19 +++++++++++ spec/fabricators/setting_group_fabricator.rb | 3 +- 9 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 spec/epp/requests/domains/update_add_objects.xml create mode 100644 spec/epp/requests/domains/update_remove_objects.xml diff --git a/app/helpers/epp/domains_helper.rb b/app/helpers/epp/domains_helper.rb index fe7c1289c..566f5ebd2 100644 --- a/app/helpers/epp/domains_helper.rb +++ b/app/helpers/epp/domains_helper.rb @@ -39,6 +39,7 @@ module Epp::DomainsHelper handle_errors(@domain) and return unless @domain handle_errors(@domain) and return unless @domain.attach_objects(@ph, parsed_frame.css('add')) + handle_errors(@domain) and return unless @domain.detach_objects(@ph, parsed_frame.css('rem')) handle_errors(@domain) and return unless @domain.save render '/epp/domains/success' diff --git a/app/models/domain.rb b/app/models/domain.rb index ad53ca3a5..1f52863ed 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -49,7 +49,7 @@ class Domain < ActiveRecord::Base write_attribute(:name_dirty, value) end - ### CREATE ### + ### CREATE & UPDATE ### def attach_objects(ph, parsed_frame) attach_owner_contact(ph[:registrant]) if ph[:registrant] @@ -60,6 +60,10 @@ class Domain < ActiveRecord::Base errors.empty? end + def detach_objects(ph, parsed_frame) + detach_nameservers(self.class.parse_nameservers_from_frame(parsed_frame)) + end + def attach_owner_contact(code) self.owner_contact = Contact.find_by(code: code) @@ -116,6 +120,15 @@ class Domain < ActiveRecord::Base end end + def detach_nameservers(ns_list) + to_delete = [] + ns_list.each do |ns_attrs| + to_delete << self.nameservers.where(ns_attrs) + end + + self.nameservers.delete(to_delete) + end + ### RENEW ### def renew(cur_exp_date, period, unit='y') @@ -255,7 +268,6 @@ class Domain < ActiveRecord::Base description: x.text } end - res end @@ -275,7 +287,7 @@ class Domain < ActiveRecord::Base end if Domain.find_by(name: x) - res << {name: x, avail: 0, reason: 'in use'} #confirm reason with current API + res << {name: x, avail: 0, reason: 'in use'} else res << {name: x, avail: 1} end diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index e3a9c47e7..80c898161 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -13,10 +13,6 @@ class DomainStatus < ActiveRecord::Base validates :setting, uniqueness: { scope: :domain_id } - def setting_uniqueness - - end - def epp_code_map { '2302' => [[:setting, :taken]] diff --git a/config/locales/en.yml b/config/locales/en.yml index df0e07895..6465dd977 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -70,6 +70,8 @@ en: attributes: setting: taken: 'Status already exists on this domain' + value: + taken: 'Status already exists on this domain' attributes: domain: name: 'Domain name' diff --git a/spec/epp/domain_spec.rb b/spec/epp/domain_spec.rb index 98e9b9527..0ef3e6671 100644 --- a/spec/epp/domain_spec.rb +++ b/spec/epp/domain_spec.rb @@ -245,34 +245,51 @@ describe 'EPP Domain', epp: true do expect(response[:results][0][:msg]).to eq('Domain not found') end - it 'updates domain' do - response = epp_request('domains/update.xml') + it 'updates domain and adds objects' do + response = epp_request('domains/update_add_objects.xml') expect(response[:results][0][:result_code]).to eq('2303') expect(response[:results][0][:msg]).to eq('Contact was not found') Fabricate(:contact, code: 'mak21') - response = epp_request('domains/update.xml') + response = epp_request('domains/update_add_objects.xml') expect(response[:results][0][:result_code]).to eq('1000') d = Domain.first - new_ns = d.nameservers.find_by(hostname: 'ns2.example.com') - expect(new_ns).to be_truthy + new_ns_count = d.nameservers.where(hostname: ['ns1.example.com', 'ns2.example.com']).count + expect(new_ns_count).to eq(2) new_contact = d.tech_contacts.find_by(code: 'mak21') expect(new_contact).to be_truthy - expect(d.domain_statuses.count).to eq(1) + expect(d.domain_statuses.count).to eq(2) expect(d.domain_statuses.first.description).to eq('Payment overdue.') expect(d.domain_statuses.first.value).to eq('clientHold') expect(d.domain_statuses.first.code).to eq('client_hold') - response = epp_request('domains/update.xml') + expect(d.domain_statuses.last.value).to eq('clientUpdateProhibited') + + response = epp_request('domains/update_add_objects.xml') expect(response[:results][0][:result_code]).to eq('2302') expect(response[:results][0][:msg]).to eq('Status already exists on this domain') - expect(d.domain_statuses.count).to eq(1) + expect(d.domain_statuses.count).to eq(2) + end + + it 'updates a domain and removes objects' do + Fabricate(:contact, code: 'mak21') + epp_request('domains/update_add_objects.xml') + + d = Domain.last + + new_ns = d.nameservers.find_by(hostname: 'ns1.example.com') + expect(new_ns).to be_truthy + + response = epp_request('domains/update_remove_objects.xml') + + rem_ns = d.nameservers.find_by(hostname: 'ns1.example.com') + expect(rem_ns).to be_falsey end end diff --git a/spec/epp/requests/domains/update.xml b/spec/epp/requests/domains/update.xml index 0c4bd59dd..d3a5b9a6c 100644 --- a/spec/epp/requests/domains/update.xml +++ b/spec/epp/requests/domains/update.xml @@ -7,6 +7,7 @@ example.ee + ns1.example.com ns2.example.com mak21 diff --git a/spec/epp/requests/domains/update_add_objects.xml b/spec/epp/requests/domains/update_add_objects.xml new file mode 100644 index 000000000..8cfd17616 --- /dev/null +++ b/spec/epp/requests/domains/update_add_objects.xml @@ -0,0 +1,22 @@ + + + + + + example.ee + + + ns1.example.com + ns2.example.com + + mak21 + Payment overdue. + + + + + ABC-12345 + + diff --git a/spec/epp/requests/domains/update_remove_objects.xml b/spec/epp/requests/domains/update_remove_objects.xml new file mode 100644 index 000000000..fd79586c3 --- /dev/null +++ b/spec/epp/requests/domains/update_remove_objects.xml @@ -0,0 +1,19 @@ + + + + + + example.ee + + + ns1.example.com + + sh8013 + + + + + ABC-12345 + + diff --git a/spec/fabricators/setting_group_fabricator.rb b/spec/fabricators/setting_group_fabricator.rb index e4ea0ac1a..f4bb09221 100644 --- a/spec/fabricators/setting_group_fabricator.rb +++ b/spec/fabricators/setting_group_fabricator.rb @@ -17,6 +17,7 @@ end Fabricator(:domain_statuses_setting_group, from: :setting_group) do code 'domain_statuses' settings { [ - Fabricate(:setting, code: 'client_hold', value: 'clientHold') + Fabricate(:setting, code: 'client_hold', value: 'clientHold'), + Fabricate(:setting, code: 'client_update_prohibited', value: 'clientUpdateProhibited') ]} end