From 1637d6beb8d5103979857ce3099fbe088a0292e3 Mon Sep 17 00:00:00 2001 From: Priit Tark Date: Wed, 29 Apr 2015 12:51:20 +0300 Subject: [PATCH] Added contact rem support and updated domain errors --- app/models/epp/contact.rb | 64 ++++++++---- app/models/epp/domain.rb | 35 ++++--- db/schema.rb | 4 + spec/epp/contact_spec.rb | 210 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 279 insertions(+), 34 deletions(-) diff --git a/app/models/epp/contact.rb b/app/models/epp/contact.rb index 49c0b4ef4..bb436dc1a 100644 --- a/app/models/epp/contact.rb +++ b/app/models/epp/contact.rb @@ -9,20 +9,34 @@ class Epp::Contact < Contact # rubocop: disable Metrics/PerceivedComplexity # rubocop: disable Metrics/CyclomaticComplexity # rubocop: disable Metrics/MethodLength - def attrs_from(frame) + def attrs_from(frame, rem = nil) f = frame at = {}.with_indifferent_access - at[:name] = f.css('postalInfo name').text if f.css('postalInfo name').present? - at[:org_name] = f.css('postalInfo org').text if f.css('postalInfo org').present? - at[:email] = f.css('email').text if f.css('email').present? - at[:fax] = f.css('fax').text if f.css('fax').present? - at[:phone] = f.css('voice').text if f.css('voice').present? - at[:city] = f.css('postalInfo addr city').text if f.css('postalInfo addr city').present? - at[:zip] = f.css('postalInfo addr pc').text if f.css('postalInfo addr pc').present? - at[:street] = f.css('postalInfo addr street').text if f.css('postalInfo addr street').present? - at[:state] = f.css('postalInfo addr sp').text if f.css('postalInfo addr sp').present? - at[:country_code] = f.css('postalInfo addr cc').text if f.css('postalInfo addr cc').present? - at[:auth_info] = f.css('authInfo pw').text if f.css('authInfo pw').present? + if rem + at[:name] = nil if f.css('postalInfo name').present? + at[:org_name] = nil if f.css('postalInfo org').present? + at[:email] = nil if f.css('email').present? + at[:fax] = nil if f.css('fax').present? + at[:phone] = nil if f.css('voice').present? + at[:city] = nil if f.css('postalInfo addr city').present? + at[:zip] = nil if f.css('postalInfo addr pc').present? + at[:street] = nil if f.css('postalInfo addr street').present? + at[:state] = nil if f.css('postalInfo addr sp').present? + at[:country_code] = nil if f.css('postalInfo addr cc').present? + at[:auth_info] = nil if f.css('authInfo pw').present? + else + at[:name] = f.css('postalInfo name').text if f.css('postalInfo name').present? + at[:org_name] = f.css('postalInfo org').text if f.css('postalInfo org').present? + at[:email] = f.css('email').text if f.css('email').present? + at[:fax] = f.css('fax').text if f.css('fax').present? + at[:phone] = f.css('voice').text if f.css('voice').present? + at[:city] = f.css('postalInfo addr city').text if f.css('postalInfo addr city').present? + at[:zip] = f.css('postalInfo addr pc').text if f.css('postalInfo addr pc').present? + at[:street] = f.css('postalInfo addr street').text if f.css('postalInfo addr street').present? + at[:state] = f.css('postalInfo addr sp').text if f.css('postalInfo addr sp').present? + at[:country_code] = f.css('postalInfo addr cc').text if f.css('postalInfo addr cc').present? + at[:auth_info] = f.css('authInfo pw').text if f.css('authInfo pw').present? + end legal_frame = f.css('legalDocument').first if legal_frame.present? @@ -80,18 +94,30 @@ class Epp::Contact < Contact def epp_code_map # rubocop:disable Metrics/MethodLength { + '2003' => [ # Required parameter missing + [:name, :blank], + [:email, :blank], + [:phone, :blank], + [:city, :blank], + [:zip, :blank], + [:street, :blank], + [:country_code, :blank] + ], + '2005' => [ # Value syntax error + [:name, :invalid], + [:phone, :invalid], + [:email, :invalid], + [:ident, :invalid], + [:ident, :invalid_EE_identity_format], + [:ident, :invalid_birthday_format] + ], '2302' => [ # Object exists [:code, :epp_id_taken] ], '2305' => [ # Association exists [:domains, :exist] ], - '2005' => [ # Value syntax error - [:phone, :invalid], - [:email, :invalid], - [:ident, :invalid], - [:ident, :invalid_EE_identity_format], - [:ident, :invalid_birthday_format] + '2306' => [ # Parameter policy error ] } end @@ -99,6 +125,8 @@ class Epp::Contact < Contact def update_attributes(frame) return super if frame.blank? at = {}.with_indifferent_access + at.deep_merge!(self.class.attrs_from(frame.css('rem'), 'rem')) + at.deep_merge!(self.class.attrs_from(frame.css('add'))) at.deep_merge!(self.class.attrs_from(frame.css('chg'))) at.merge!(self.class.ident_attrs(frame.css('ident').first)) legal_frame = frame.css('legalDocument').first diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 2a29aab32..ccdb38436 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -13,23 +13,12 @@ class Epp::Domain < Domain def epp_code_map # rubocop:disable Metrics/MethodLength { - '2002' => [ + '2002' => [ # Command use error [:base, :domain_already_belongs_to_the_querying_registrar] ], - '2302' => [ # Object exists - [:name_dirty, :taken, { value: { obj: 'name', val: name_dirty } }], - [:name_dirty, :reserved, { value: { obj: 'name', val: name_dirty } }] - ], - '2304' => [ - [:base, :domain_status_prohibits_operation] - ], - '2306' => [ # Parameter policy error + '2003' => [ # Required parameter missing [:registrant, :blank], - [:base, :ds_data_with_key_not_allowed], - [:base, :ds_data_not_allowed], - [:base, :key_data_not_allowed], - [:period, :not_a_number], - [:period, :not_an_integer] + [:registrar, :blank] ], '2004' => [ # Parameter value range error [:nameservers, :out_of_range, @@ -58,11 +47,25 @@ class Epp::Domain < Domain } ] ], - '2005' => [ + '2005' => [ # Parameter value syntax error [:name_dirty, :invalid, { obj: 'name', val: name_dirty }] ], - '2201' => [ + '2201' => [ # Authorisation error [:auth_info, :wrong_pw] + ], + '2302' => [ # Object exists + [:name_dirty, :taken, { value: { obj: 'name', val: name_dirty } }], + [:name_dirty, :reserved, { value: { obj: 'name', val: name_dirty } }] + ], + '2304' => [ # Object status prohibits operation + [:base, :domain_status_prohibits_operation] + ], + '2306' => [ # Parameter policy error + [:base, :ds_data_with_key_not_allowed], + [:base, :ds_data_not_allowed], + [:base, :key_data_not_allowed], + [:period, :not_a_number], + [:period, :not_an_integer] ] } end diff --git a/db/schema.rb b/db/schema.rb index aa45f6165..4acc0aea6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -297,8 +297,12 @@ ActiveRecord::Schema.define(version: 20150428075052) do t.integer "legacy_id" t.integer "legacy_registrar_id" t.integer "legacy_registrant_id" + t.datetime "outzone_at" + t.datetime "delete_at" end + add_index "domains", ["delete_at"], name: "index_domains_on_delete_at", using: :btree + add_index "domains", ["outzone_at"], name: "index_domains_on_outzone_at", using: :btree add_index "domains", ["registrant_id"], name: "index_domains_on_registrant_id", using: :btree add_index "domains", ["registrar_id"], name: "index_domains_on_registrar_id", using: :btree diff --git a/spec/epp/contact_spec.rb b/spec/epp/contact_spec.rb index 2de7040ef..cb5f4555e 100644 --- a/spec/epp/contact_spec.rb +++ b/spec/epp/contact_spec.rb @@ -357,6 +357,216 @@ describe 'EPP Contact', epp: true do Setting.client_status_editing_enabled = true end + + it 'should add value voice value' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + add: { + voice: { value: '+372.11111111' } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == 'Command completed successfully' + response[:results][0][:result_code].should == '1000' + + contact = Contact.find_by(code: 'sh8013') + contact.phone.should == '+372.11111111' + + contact.update_attribute(:phone, '+372.7654321') # restore default value + end + + it 'should return error when add attributes phone value is empty' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + add: { + voice: { value: '' } + }, + chg: { + postalInfo: { email: { value: 'example@example.ee' } } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == 'Required parameter missing - phone [phone]' + response[:results][0][:result_code].should == '2003' + Contact.find_by(code: 'sh8013').phone.should == '+372.7654321' # aka not changed + end + + it 'should honor chg value over add value when both changes same attribute' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + chg: { + voice: { value: '+372.2222222222222' } + }, + add: { + voice: { value: '+372.11111111111' } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == 'Command completed successfully' + response[:results][0][:result_code].should == '1000' + + contact = Contact.find_by(code: 'sh8013') + contact.phone.should == '+372.2222222222222' + + contact.update_attribute(:phone, '+372.7654321') # restore default value + end + + it 'should not allow to remove required voice attribute' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + rem: { + voice: { value: '+372.7654321' } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == 'Required parameter missing - phone [phone]' + response[:results][0][:result_code].should == '2003' + + contact = Contact.find_by(code: 'sh8013') + contact.phone.should == '+372.7654321' + end + + it 'should not allow to remove required attribute' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + rem: { + voice: { value: '+372.7654321' } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == 'Required parameter missing - phone [phone]' + response[:results][0][:result_code].should == '2003' + + contact = Contact.find_by(code: 'sh8013') + contact.phone.should == '+372.7654321' + end + + it 'should honor add over rem' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + rem: { + voice: { value: 'not important' } + }, + add: { + voice: { value: '+372.3333333' } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == 'Command completed successfully' + response[:results][0][:result_code].should == '1000' + + contact = Contact.find_by(code: 'sh8013') + contact.phone.should == '+372.3333333' + + contact.update_attribute(:phone, '+372.7654321') # restore default value + end + + it 'should honor chg over rem' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + rem: { + voice: { value: 'not important' } + }, + chg: { + voice: { value: '+372.44444444' } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == 'Command completed successfully' + response[:results][0][:result_code].should == '1000' + + contact = Contact.find_by(code: 'sh8013') + contact.phone.should == '+372.44444444' + + contact.update_attribute(:phone, '+372.7654321') # restore default value + end + + it 'should honor chg over rem and add' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + chg: { + voice: { value: '+372.666666' } + }, + add: { + voice: { value: '+372.555555' } + }, + rem: { + voice: { value: 'not important' } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == 'Command completed successfully' + response[:results][0][:result_code].should == '1000' + + contact = Contact.find_by(code: 'sh8013') + contact.phone.should == '+372.666666' + + contact.update_attribute(:phone, '+372.7654321') # restore default value + end + + it 'should return authorization error when removing auth info' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + rem: { + authInfo: { pw: { value: 'password' } } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == 'Authorization error' + response[:results][0][:result_code].should == '2201' + + contact = Contact.find_by(code: 'sh8013') + contact.auth_info.should == 'password' + end + + it 'should return general policy error when removing org' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + rem: { + postalInfo: { org: { value: 'not important' } } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == + 'Parameter value policy error. Org must be blank: postalInfo > org [org]' + response[:results][0][:result_code].should == '2306' + end + + it 'should return error when removing street' do + xml = @epp_xml.update({ + id: { value: 'sh8013' }, + authInfo: { pw: { value: 'password' } }, + rem: { + postalInfo: { + name: { value: 'not important' } + } + } + }) + + response = epp_plain_request(xml, :xml) + response[:results][0][:msg].should == "Required parameter missing - name [name]" + response[:results][0][:result_code].should == '2003' + end end context 'delete command' do