Skip to content

Commit

Permalink
Disallow EPP domain:update/transfer/delete if a domain has "deleteCan…
Browse files Browse the repository at this point in the history
…didate" status

#355
  • Loading branch information
Artur Beljajev committed Jan 24, 2017
1 parent d4ddb5d commit edf1e33
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
24.01.2017
* Disallow EPP domain:update/transfer/delete if a domain has "deleteCandidate" status

22.12.2016
* Return business registry code and country for 'org' type registrants in WHOIS and Rest-WHOIS

Expand Down
11 changes: 11 additions & 0 deletions app/models/concerns/domain/deletable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Concerns::Domain::Deletable
extend ActiveSupport::Concern

included do
alias_attribute :delete_time, :delete_at
end

def discarded?
statuses.include?(DomainStatus::DELETE_CANDIDATE)
end
end
2 changes: 1 addition & 1 deletion app/models/domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Domain < ActiveRecord::Base
include Concerns::Domain::Expirable
include Concerns::Domain::Activatable
include Concerns::Domain::ForceDelete
include Concerns::Domain::Deletable

has_paper_trail class_name: "DomainVersion", meta: { children: :children_log }

Expand All @@ -14,7 +15,6 @@ class Domain < ActiveRecord::Base

alias_attribute :on_hold_time, :outzone_at
alias_attribute :outzone_time, :outzone_at
alias_attribute :delete_time, :delete_at

# TODO: whois requests ip whitelist for full info for own domains and partial info for other domains
# TODO: most inputs should be trimmed before validatation, probably some global logic?
Expand Down
18 changes: 18 additions & 0 deletions app/models/epp/domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,9 @@ def domain_status_list_from(frame)
# rubocop: disable Metrics/CyclomaticComplexity
def update(frame, current_user, verify = true)
return super if frame.blank?

check_discarded

at = {}.with_indifferent_access
at.deep_merge!(attrs_from(frame.css('chg'), current_user, 'chg'))
at.deep_merge!(attrs_from(frame.css('rem'), current_user, 'rem'))
Expand Down Expand Up @@ -563,6 +566,8 @@ def attach_legal_document(legal_document_data)
def epp_destroy(frame, user_id)
return false unless valid?

check_discarded

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
Expand Down Expand Up @@ -629,6 +634,8 @@ def renew(cur_exp_date, period, unit = 'y')

# rubocop: disable Metrics/CyclomaticComplexity
def transfer(frame, action, current_user)
check_discarded

@is_transfer = true

case action
Expand Down Expand Up @@ -925,5 +932,16 @@ def check_availability(domains)
res
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
# rubocop: enable Metrics/ClassLength
4 changes: 4 additions & 0 deletions spec/factories/domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@
force_delete_time nil
statuses []
end

factory :domain_discarded do
statuses [DomainStatus::DELETE_CANDIDATE]
end
end
end
19 changes: 19 additions & 0 deletions spec/models/concerns/domain/deletable_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'rails_helper'

RSpec.describe Domain, db: false do
it { is_expected.to alias_attribute(:delete_time, :delete_at) }

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
1 change: 0 additions & 1 deletion spec/models/domain_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,6 @@

RSpec.describe Domain, db: false do
it { is_expected.to alias_attribute(:on_hold_time, :outzone_at) }
it { is_expected.to alias_attribute(:delete_time, :delete_at) }
it { is_expected.to alias_attribute(:outzone_time, :outzone_at) }

describe 'nameserver validation', db: true do
Expand Down
48 changes: 48 additions & 0 deletions spec/requests/epp/domain/delete/discarded_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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
}

subject(:response_xml) { Nokogiri::XML(response.body) }
subject(:response_code) { response_xml.xpath('//xmlns:result').first['code'] }
subject(:response_description) { response_xml.css('result msg').text }

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_code).to eq('1001'), "Expected EPP code of 1001, got #{response_code} (#{response_description})"
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_code).to eq('2105'), "Expected EPP code of 2105, got #{response_code} (#{response_description})"
end
end
end
46 changes: 46 additions & 0 deletions spec/requests/epp/domain/transfer/discarded_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
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
}

subject(:response_xml) { Nokogiri::XML(response.body) }
subject(:response_code) { response_xml.xpath('//xmlns:result').first['code'] }
subject(:response_description) { response_xml.css('result msg').text }

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_code).to eq('1000'), "Expected EPP code of 1000, got #{response_code} (#{response_description})"
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_code).to eq('2105'), "Expected EPP code of 2105, got #{response_code} (#{response_description})"
end
end
end
43 changes: 43 additions & 0 deletions spec/requests/epp/domain/update/discarded_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
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
}

subject(:response_xml) { Nokogiri::XML(response.body) }
subject(:response_code) { response_xml.xpath('//xmlns:result').first['code'] }
subject(:response_description) { response_xml.css('result msg').text }

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_code).to eq('1000'), "Expected EPP code of 1000, got #{response_code} (#{response_description})"
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_code).to eq('2105'), "Expected EPP code of 2105, got #{response_code} (#{response_description})"
end
end
end

0 comments on commit edf1e33

Please sign in to comment.