Refactor domain transfer

This commit is contained in:
Martin Lensment 2015-01-05 15:03:11 +02:00
parent 1996ff725e
commit 003a4ca3c0
5 changed files with 189 additions and 58 deletions

View file

@ -64,15 +64,37 @@ module Epp::DomainsHelper
def transfer_domain def transfer_domain
@domain = find_domain(secure: false) @domain = find_domain(secure: false)
handle_errors(@domain) and return unless @domain handle_errors(@domain) and return unless @domain
handle_errors(@domain) and return unless @domain.authenticate(domain_transfer_params[:pw])
@domain_transfer = @domain.transfer(domain_transfer_params) if domain_transfer_params[:action] == 'query'
if @domain_transfer
@domain.attach_legal_document(Epp::EppDomain.parse_legal_document_from_frame(parsed_frame)) if @domain.pending_transfer
@domain.save @domain_transfer = @domain.pending_transfer
else
@domain_transfer = @domain.query_transfer(domain_transfer_params, parsed_frame)
handle_errors(@domain) and return unless @domain_transfer
end
elsif domain_transfer_params[:action] == 'approve'
if @domain.pending_transfer
@domain_transfer = @domain.approve_transfer(domain_transfer_params, parsed_frame)
handle_errors(@domain) and return unless @domain_transfer
else
epp_errors << { code: '2303', msg: I18n.t('pending_transfer_was_not_found') }
handle_errors(@domain) and return
end
elsif domain_transfer_params[:action] == 'reject'
if @domain.pending_transfer
@domain_transfer = @domain.reject_transfer(domain_transfer_params, parsed_frame)
handle_errors(@domain) and return unless @domain_transfer
else
epp_errors << { code: '2303', msg: I18n.t('pending_transfer_was_not_found') }
handle_errors(@domain) and return
end
end end
handle_errors(@domain) and return unless @domain_transfer
render '/epp/domains/transfer' render '/epp/domains/transfer'
end end
@ -167,7 +189,7 @@ module Epp::DomainsHelper
return false unless attrs_present return false unless attrs_present
op = parsed_frame.css('transfer').first[:op] op = parsed_frame.css('transfer').first[:op]
return true if %w(approve query).include?(op) return true if %w(approve query reject).include?(op)
epp_errors << { code: '2306', msg: I18n.t('errors.messages.attribute_op_is_invalid') } epp_errors << { code: '2306', msg: I18n.t('errors.messages.attribute_op_is_invalid') }
false false
end end

View file

@ -290,66 +290,104 @@ class Epp::EppDomain < Domain
### TRANSFER ### ### TRANSFER ###
# rubocop: disable Metrics/PerceivedComplexity
# rubocop: disable Metrics/MethodLength # rubocop: disable Metrics/MethodLength
# rubocop: disable Metrics/CyclomaticComplexity def query_transfer(params, parsed_frame)
def transfer(params) return false unless can_be_transferred_to?(params[:current_user].registrar)
return false unless authenticate(params[:pw])
pt = pending_transfer transaction do
if pt && params[:action] == 'approve' begin
if approve_pending_transfer(params[:current_user]) if Setting.transfer_wait_time > 0
return pt.reload dt = domain_transfers.create!(
else status: DomainTransfer::PENDING,
return false transfer_requested_at: Time.zone.now,
transfer_to: params[:current_user].registrar,
transfer_from: registrar
)
registrar.messages.create!(
body: I18n.t('transfer_requested'),
attached_obj_id: dt.id,
attached_obj_type: dt.class.to_s
)
else
dt = domain_transfers.create!(
status: DomainTransfer::SERVER_APPROVED,
transfer_requested_at: Time.zone.now,
transferred_at: Time.zone.now,
transfer_to: params[:current_user].registrar,
transfer_from: registrar
)
generate_auth_info
self.registrar = params[:current_user].registrar
end
attach_legal_document(self.class.parse_legal_document_from_frame(parsed_frame))
save!(validate: false)
return dt
rescue => _e
add_epp_error('2306', nil, nil, I18n.t('action_failed_due_to_internal_error'))
raise ActiveRecord::Rollback
end end
end end
end
# rubocop: enable Metrics/MethodLength
if !pt && params[:action] != 'query' def approve_transfer(params, parsed_frame)
add_epp_error('2306', nil, nil, I18n.t('errors.messages.attribute_op_is_invalid')) pt = pending_transfer
if params[:current_user].registrar != pt.transfer_from
add_epp_error('2304', nil, nil, I18n.t('transfer_can_be_approved_only_by_current_registrar'))
return false return false
end end
if !pt && params[:action] == 'query' transaction do
return false unless can_be_transferred_to?(params[:current_user].registrar) begin
pt.update!(
status: DomainTransfer::CLIENT_APPROVED,
transferred_at: Time.zone.now
)
generate_auth_info
self.registrar = pt.transfer_to
attach_legal_document(self.class.parse_legal_document_from_frame(parsed_frame))
save!(validate: false)
rescue => _e
add_epp_error('2306', nil, nil, I18n.t('action_failed_due_to_internal_error'))
raise ActiveRecord::Rollback
end
end end
return pt if pt pt
if Setting.transfer_wait_time > 0 end
dt = domain_transfers.create(
status: DomainTransfer::PENDING, def reject_transfer(params, parsed_frame)
transfer_requested_at: Time.zone.now, pt = pending_transfer
transfer_to: params[:current_user].registrar, if params[:current_user].registrar != pt.transfer_from
transfer_from: registrar add_epp_error('2304', nil, nil, I18n.t('transfer_can_be_rejected_only_by_current_registrar'))
) return false
end
registrar.messages.create(
body: I18n.t('transfer_requested'), transaction do
attached_obj_id: dt.id, begin
attached_obj_type: dt.class.to_s pt.update!(
) status: DomainTransfer::CLIENT_REJECTED
)
else
dt = domain_transfers.create( attach_legal_document(self.class.parse_legal_document_from_frame(parsed_frame))
status: DomainTransfer::SERVER_APPROVED, save!(validate: false)
transfer_requested_at: Time.zone.now, rescue => _e
transferred_at: Time.zone.now, add_epp_error('2306', nil, nil, I18n.t('action_failed_due_to_internal_error'))
transfer_to: params[:current_user].registrar, raise ActiveRecord::Rollback
transfer_from: registrar end
) end
generate_auth_info pt
self.registrar = params[:current_user].registrar
save(validate: false)
end
dt
end end
# rubocop: enable Metrics/PerceivedComplexity
# rubocop: enable Metrics/MethodLength
# rubocop: enable Metrics/CyclomaticComplexity
def approve_pending_transfer(current_user) def approve_pending_transfer(current_user)
pt = pending_transfer pt = pending_transfer

View file

@ -478,3 +478,6 @@ en:
admin_contacts_max_count: 'Admin contacts maximum count' admin_contacts_max_count: 'Admin contacts maximum count'
tech_contacts_min_count: 'Tech contacts minimum count' tech_contacts_min_count: 'Tech contacts minimum count'
tech_contacts_max_count: 'Tech contacts maximum count' tech_contacts_max_count: 'Tech contacts maximum count'
action_failed_due_to_internal_error: 'Action failed due to internal error'
pending_transfer_was_not_found: 'Pending transfer was not found'
transfer_can_be_rejected_only_by_current_registrar: 'Transfer can be rejected only by current registrar'

View file

@ -218,6 +218,74 @@ describe 'EPP Domain', epp: true do
expect(response[:result_code]).to eq('2201') expect(response[:result_code]).to eq('2201')
expect(response[:msg]).to eq('Authorization error') expect(response[:msg]).to eq('Authorization error')
end end
it 'creates a domain transfer with legal document' do
expect(domain.legal_documents.count).to eq(0)
pw = domain.auth_info
xml = domain_transfer_xml({ authInfo: { pw: { value: pw } } }, 'query', {
_anonymus: [
legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==',
attrs: { type: 'pdf' }
}
]
})
response = epp_request(xml, :xml, :elkdata)
expect(response[:result_code]).to eq('1000')
expect(domain.legal_documents.count).to eq(1)
end
it 'creates a domain transfer with legal document' do
Setting.transfer_wait_time = 1
expect(domain.legal_documents.count).to eq(0)
pw = domain.auth_info
xml = domain_transfer_xml({ authInfo: { pw: { value: pw } } }, 'query', {
_anonymus: [
legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==',
attrs: { type: 'pdf' }
}
]
})
response = epp_request(xml, :xml, :elkdata)
expect(response[:result_code]).to eq('1000')
expect(domain.legal_documents.count).to eq(1)
response = epp_request(xml, :xml, :elkdata)
expect(response[:result_code]).to eq('1000')
expect(domain.legal_documents.count).to eq(1) # does not add another legal document
end
it 'rejects a domain transfer' do
domain.domain_transfers.create({
status: DomainTransfer::PENDING,
transfer_requested_at: Time.zone.now,
transfer_to: elkdata,
transfer_from: zone
})
pw = domain.auth_info
xml = domain_transfer_xml({ authInfo: { pw: { value: pw } } }, 'reject', {
_anonymus: [
legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==',
attrs: { type: 'pdf' }
}
]
})
response = epp_request(xml, :xml, :elkdata)
expect(response[:result_code]).to eq('2304')
expect(response[:msg]).to eq('Transfer can be rejected only by current registrar')
expect(domain.legal_documents.count).to eq(0)
response = epp_request(xml, :xml, :zone)
expect(response[:result_code]).to eq('1000')
expect(domain.pending_transfer).to be_nil
expect(domain.legal_documents.count).to eq(1)
end
end end
context 'with citizen as an owner' do context 'with citizen as an owner' do

View file

@ -279,7 +279,7 @@ module Epp
epp_xml.check(xml_params) epp_xml.check(xml_params)
end end
def domain_transfer_xml(xml_params = {}, op = 'query') def domain_transfer_xml(xml_params = {}, op = 'query', custom_params = {})
defaults = { defaults = {
name: { value: 'example.ee' }, name: { value: 'example.ee' },
authInfo: { authInfo: {
@ -289,7 +289,7 @@ module Epp
xml_params = defaults.deep_merge(xml_params) xml_params = defaults.deep_merge(xml_params)
epp_xml = EppXml::Domain.new(cl_trid: 'ABC-12345') epp_xml = EppXml::Domain.new(cl_trid: 'ABC-12345')
epp_xml.transfer(xml_params, op) epp_xml.transfer(xml_params, op, custom_params)
end end
def log(req, res) def log(req, res)