Disallow EPP domain:update/transfer/delete if a domain has "deleteCandidate" status

#355
This commit is contained in:
Artur Beljajev 2017-01-30 14:04:56 +02:00
parent f26783d340
commit 7d1a5558b0
12 changed files with 225 additions and 0 deletions

View file

@ -1,3 +1,6 @@
24.01.2017
* Disallow EPP domain:update/transfer/delete if a domain has "deleteCandidate" status
22.12.2016 22.12.2016
* Return business registry code and country for 'org' type registrants in WHOIS and Rest-WHOIS * Return business registry code and country for 'org' type registrants in WHOIS and Rest-WHOIS

View file

@ -0,0 +1,7 @@
module Concerns::Domain::Deletable
extend ActiveSupport::Concern
def discarded?
statuses.include?(DomainStatus::DELETE_CANDIDATE)
end
end

View file

@ -5,6 +5,7 @@ class Domain < ActiveRecord::Base
include Statuses include Statuses
include Concerns::Domain::Expirable include Concerns::Domain::Expirable
include Concerns::Domain::Activatable include Concerns::Domain::Activatable
include Concerns::Domain::Deletable
has_paper_trail class_name: "DomainVersion", meta: { children: :children_log } has_paper_trail class_name: "DomainVersion", meta: { children: :children_log }

View file

@ -472,6 +472,9 @@ class Epp::Domain < Domain
# rubocop: disable Metrics/CyclomaticComplexity # rubocop: disable Metrics/CyclomaticComplexity
def update(frame, current_user, verify = true) def update(frame, current_user, verify = true)
return super if frame.blank? return super if frame.blank?
check_discarded
at = {}.with_indifferent_access at = {}.with_indifferent_access
at.deep_merge!(attrs_from(frame.css('chg'), current_user, 'chg')) at.deep_merge!(attrs_from(frame.css('chg'), current_user, 'chg'))
at.deep_merge!(attrs_from(frame.css('rem'), current_user, 'rem')) at.deep_merge!(attrs_from(frame.css('rem'), current_user, 'rem'))
@ -563,6 +566,8 @@ class Epp::Domain < Domain
def epp_destroy(frame, user_id) def epp_destroy(frame, user_id)
return false unless valid? return false unless valid?
check_discarded
if doc = attach_legal_document(Epp::Domain.parse_legal_document_from_frame(frame)) if doc = attach_legal_document(Epp::Domain.parse_legal_document_from_frame(frame))
frame.css("legalDocument").first.content = doc.path if doc && doc.persisted? frame.css("legalDocument").first.content = doc.path if doc && doc.persisted?
end end
@ -629,6 +634,8 @@ class Epp::Domain < Domain
# rubocop: disable Metrics/CyclomaticComplexity # rubocop: disable Metrics/CyclomaticComplexity
def transfer(frame, action, current_user) def transfer(frame, action, current_user)
check_discarded
@is_transfer = true @is_transfer = true
case action case action
@ -925,5 +932,16 @@ class Epp::Domain < Domain
res res
end end
end end
private
def check_discarded
if discarded?
throw :epp_error, {
code: '2105',
msg: I18n.t(:object_is_not_eligible_for_renewal),
}
end
end
end end
# rubocop: enable Metrics/ClassLength # rubocop: enable Metrics/ClassLength

View file

@ -10,5 +10,9 @@ FactoryGirl.define do
domain.admin_domain_contacts << FactoryGirl.build(:admin_domain_contact) domain.admin_domain_contacts << FactoryGirl.build(:admin_domain_contact)
domain.tech_domain_contacts << FactoryGirl.build(:tech_domain_contact) domain.tech_domain_contacts << FactoryGirl.build(:tech_domain_contact)
end end
factory :domain_discarded do
statuses [DomainStatus::DELETE_CANDIDATE]
end
end end
end end

View file

@ -0,0 +1,17 @@
require 'rails_helper'
RSpec.describe Domain, db: false do
describe '#discarded?' do
context 'when :deleteCandidate status is present' do
let(:domain) { described_class.new(statuses: [DomainStatus::DELETE_CANDIDATE]) }
specify { expect(domain).to be_discarded }
end
context 'when :deleteCandidate status is absent' do
let(:domain) { described_class.new(statuses: []) }
specify { expect(domain).to_not be_discarded }
end
end
end

View file

@ -6,6 +6,7 @@ require 'capybara/poltergeist'
require 'paper_trail/frameworks/rspec' require 'paper_trail/frameworks/rspec'
require 'money-rails/test_helpers' require 'money-rails/test_helpers'
require 'support/requests/session_helpers' require 'support/requests/session_helpers'
require 'support/requests/epp_helpers'
require 'support/features/session_helpers' require 'support/features/session_helpers'
if ENV['ROBOT'] if ENV['ROBOT']
@ -15,6 +16,8 @@ end
require 'support/matchers/alias_attribute' require 'support/matchers/alias_attribute'
require 'support/matchers/active_job' require 'support/matchers/active_job'
require 'support/matchers/epp/code'
require 'support/capybara' require 'support/capybara'
require 'support/factory_girl' require 'support/factory_girl'
require 'support/database_cleaner' require 'support/database_cleaner'
@ -29,6 +32,7 @@ RSpec.configure do |config|
config.include Requests::SessionHelpers, type: :request config.include Requests::SessionHelpers, type: :request
config.include Features::SessionHelpers, type: :feature config.include Features::SessionHelpers, type: :feature
config.include AbstractController::Translation, type: :feature config.include AbstractController::Translation, type: :feature
config.include Requests::EPPHelpers, epp: true
config.define_derived_metadata(file_path: %r[/spec/features/]) do |metadata| config.define_derived_metadata(file_path: %r[/spec/features/]) do |metadata|
metadata[:db] = true if metadata[:db].nil? metadata[:db] = true if metadata[:db].nil?
@ -50,6 +54,10 @@ RSpec.configure do |config|
metadata[:type] = :request metadata[:type] = :request
end end
config.define_derived_metadata(file_path: %r[/spec/requests/epp/]) do |metadata|
metadata[:epp] = true if metadata[:epp].nil?
end
config.use_transactional_fixtures = false config.use_transactional_fixtures = false
config.infer_spec_type_from_file_location! config.infer_spec_type_from_file_location!

View file

@ -0,0 +1,44 @@
require 'rails_helper'
RSpec.describe 'EPP domain:delete' do
let(:request_xml) { <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<delete>
<domain:delete xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
<domain:name>test.com</domain:name>
</domain:delete>
</delete>
<extension>
<eis:extdata xmlns:eis="https://epp.tld.ee/schema/eis-1.0.xsd">
<eis:legalDocument type="pdf">dGVzdCBmYWlsCg==</eis:legalDocument>
</eis:extdata>
</extension>
</command>
</epp>
XML
}
before :example do
sign_in_to_epp_area
end
context 'when domain is not discarded' do
let!(:domain) { create(:domain, name: 'test.com') }
it 'returns epp code of 1001' do
post '/epp/command/delete', frame: request_xml
expect(response).to have_code_of(1001)
end
end
context 'when domain is discarded' do
let!(:domain) { create(:domain_discarded, name: 'test.com') }
it 'returns epp code of 2105' do
post '/epp/command/delete', frame: request_xml
expect(response).to have_code_of(2105)
end
end
end

View file

@ -0,0 +1,42 @@
require 'rails_helper'
RSpec.describe 'EPP domain:transfer' do
let(:request_xml) { <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<transfer op="request">
<domain:transfer xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
<domain:name>test.com</domain:name>
<domain:authInfo>
<domain:pw>98oiewslkfkd</domain:pw>
</domain:authInfo>
</domain:transfer>
</transfer>
</command>
</epp>
XML
}
before :example do
sign_in_to_epp_area
end
context 'when domain is not discarded' do
let!(:domain) { create(:domain, name: 'test.com') }
it 'returns epp code of 1000' do
post '/epp/command/transfer', frame: request_xml
expect(response).to have_code_of(1000)
end
end
context 'when domain is discarded' do
let!(:domain) { create(:domain_discarded, name: 'test.com') }
it 'returns epp code of 2105' do
post '/epp/command/transfer', frame: request_xml
expect(response).to have_code_of(2105)
end
end
end

View file

@ -0,0 +1,39 @@
require 'rails_helper'
RSpec.describe 'EPP domain:update' do
let(:request_xml) { <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<update>
<domain:update xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
<domain:name>test.com</domain:name>
</domain:update>
</update>
</command>
</epp>
XML
}
before :example do
sign_in_to_epp_area
end
context 'when domain is not discarded' do
let!(:domain) { create(:domain, name: 'test.com') }
it 'returns epp code of 1000' do
post '/epp/command/update', frame: request_xml
expect(response).to have_code_of(1000)
end
end
context 'when domain is discarded' do
let!(:domain) { create(:domain_discarded, name: 'test.com') }
it 'returns epp code of 2105' do
post '/epp/command/update', frame: request_xml
expect(response).to have_code_of(2105)
end
end
end

View file

@ -0,0 +1,35 @@
module Matchers
module EPP
class Code
def initialize(expected)
@expected = expected
end
def matches?(response)
@xml = response.body
actual == expected
end
def failure_message
"Expected EPP code of #{expected}, got #{actual} (#{description})"
end
private
attr_reader :xml
attr_reader :expected
def actual
xml_document.xpath('//xmlns:result').first['code'].to_i
end
def description
xml_document.css('result msg').text
end
def xml_document
@xml_document ||= Nokogiri::XML(xml)
end
end
end
end

View file

@ -0,0 +1,7 @@
module Requests
module EPPHelpers
def have_code_of(*args)
Matchers::EPP::Code.new(*args)
end
end
end