From f6ac22df5214910fd22d1c1223d6eb88cf8db1ed Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Mon, 6 Oct 2014 15:29:23 +0300 Subject: [PATCH] Validate dnskey uniqueness --- app/models/dnskey.rb | 6 ++++ app/models/domain.rb | 13 +++++++++ .../domains/form_partials/_dnskeys.haml | 2 +- config/locales/en.yml | 2 ++ spec/epp/domain_spec.rb | 29 +++++++++++++++++++ 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/app/models/dnskey.rb b/app/models/dnskey.rb index 72788abc6..8cf4cdad2 100644 --- a/app/models/dnskey.rb +++ b/app/models/dnskey.rb @@ -15,6 +15,9 @@ class Dnskey < ActiveRecord::Base [:protocol, :invalid, { value: { obj: 'protocol', val: protocol } }], [:flags, :invalid, { value: { obj: 'flags', val: flags } }] ], + '2302' => [ + [:public_key, :taken, { value: { obj: 'pubKye', val: public_key } }] + ], '2303' => [ [:base, :dnskey_not_found, { value: { obj: 'pubKey', val: public_key } }] ], @@ -28,16 +31,19 @@ class Dnskey < ActiveRecord::Base end def validate_algorithm + return if alg.blank? return if %w(3 5 6 7 8 252 253 254 255).include?(alg.to_s) errors.add(:alg, :invalid) end def validate_protocol + return if protocol.blank? return if %w(3).include?(protocol.to_s) errors.add(:protocol, :invalid) end def validate_flags + return if flags.blank? return if %w(0 256 257).include?(flags.to_s) errors.add(:flags, :invalid) end diff --git a/app/models/domain.rb b/app/models/domain.rb index ff9f7ab56..15326ef23 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -53,6 +53,7 @@ class Domain < ActiveRecord::Base validate :validate_tech_contacts_uniqueness validate :validate_admin_contacts_uniqueness validate :validate_domain_statuses_uniqueness + validate :validate_dnskeys_uniqueness validate :validate_nameserver_ips attr_accessor :owner_contact_typeahead @@ -148,6 +149,18 @@ class Domain < ActiveRecord::Base end end + def validate_dnskeys_uniqueness + validated = [] + dnskeys.reject(&:marked_for_destruction?).each do |dnskey| + next if dnskey.public_key.blank? + existing = dnskeys.select { |x| x.public_key == dnskey.public_key } + next unless existing.length > 1 + validated << dnskey.public_key + errors.add(:dnskeys, :invalid) if errors[:dnskeys].blank? + dnskey.errors.add(:public_key, :taken) + end + end + def validate_period return unless period.present? if period_unit == 'd' diff --git a/app/views/client/domains/form_partials/_dnskeys.haml b/app/views/client/domains/form_partials/_dnskeys.haml index 3c537500f..36e765641 100644 --- a/app/views/client/domains/form_partials/_dnskeys.haml +++ b/app/views/client/domains/form_partials/_dnskeys.haml @@ -14,7 +14,7 @@ .row .col-md-4 .form-group - = key_fields.label :flags + = key_fields.label :flags, t('shared.flag') = key_fields.text_field :flags, class: 'form-control' .col-md-4 .form-group diff --git a/config/locales/en.yml b/config/locales/en.yml index 895e52833..0a15afdbc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -107,6 +107,7 @@ en: registrar: blank: 'Registrar is missing' dnskeys: + invalid: 'DNS keys are invalid' not_found: 'Dnskey was not found' domain: @@ -197,6 +198,7 @@ en: invalid: 'Flag is invalid' blank: 'Flag is missing' public_key: + taken: 'Public key already exists' blank: 'Public key is missing' diff --git a/spec/epp/domain_spec.rb b/spec/epp/domain_spec.rb index 5c244e7d7..e33f7a3ba 100644 --- a/spec/epp/domain_spec.rb +++ b/spec/epp/domain_spec.rb @@ -418,6 +418,35 @@ describe 'EPP Domain', epp: true do expect(response[:results][6][:msg]).to eq('Protocol is invalid') expect(response[:results][6][:value]).to eq('5') end + + it 'does not create a domain with two identical dnskeys' do + xml = domain_create_xml({ + dnssec: [ + { + dnskey: { + flags: { value: '257' }, + protocol: { value: '3' }, + alg: { value: '3' }, + pubKey: { value: '700b97b591ed27ec2590d19f06f88bba700b97b591ed27ec2590d19f' } + } + }, + { + dnskey: { + flags: { value: '0' }, + protocol: { value: '3' }, + alg: { value: '5' }, + pubKey: { value: '700b97b591ed27ec2590d19f06f88bba700b97b591ed27ec2590d19f' } + } + } + ] + }) + + response = epp_request(xml, :xml) + + expect(response[:result_code]).to eq('2302') + expect(response[:msg]).to eq('Public key already exists') + expect(response[:results][0][:value]).to eq('700b97b591ed27ec2590d19f06f88bba700b97b591ed27ec2590d19f') + end end context 'with juridical persion as an owner' do