mirror of
https://github.com/internetee/registry.git
synced 2025-06-12 07:34:45 +02:00
parent
0ac3a43613
commit
8c915164c5
8 changed files with 51 additions and 38 deletions
|
@ -5,29 +5,33 @@ module Repp
|
|||
resource :domains do
|
||||
resource :contacts do
|
||||
patch '/' do
|
||||
predecessor = current_user.registrar.contacts.find_by(code: params[:predecessor])
|
||||
successor = current_user.registrar.contacts.find_by(code: params[:successor])
|
||||
current_contact = current_user.registrar.contacts
|
||||
.find_by(code: params[:current_contact_id])
|
||||
new_contact = current_user.registrar.contacts.find_by(code: params[:new_contact_id])
|
||||
|
||||
unless predecessor
|
||||
unless current_contact
|
||||
error!({ error: { type: 'invalid_request_error',
|
||||
param: 'predecessor',
|
||||
message: "No such contact: #{params[:predecessor]}" } }, :bad_request)
|
||||
param: 'current_contact_id',
|
||||
message: "No such contact: #{params[:current_contact_id]}"} },
|
||||
:bad_request)
|
||||
end
|
||||
|
||||
unless successor
|
||||
unless new_contact
|
||||
error!({ error: { type: 'invalid_request_error',
|
||||
param: 'successor',
|
||||
message: "No such contact: #{params[:successor]}" } }, :bad_request)
|
||||
param: 'new_contact_id',
|
||||
message: "No such contact: #{params[:new_contact_id]}" } },
|
||||
:bad_request)
|
||||
end
|
||||
|
||||
if predecessor == successor
|
||||
if current_contact == new_contact
|
||||
error!({ error: { type: 'invalid_request_error',
|
||||
message: 'New contact ID must be different from current' \
|
||||
' contact ID' } },
|
||||
:bad_request)
|
||||
end
|
||||
|
||||
affected_domains, skipped_domains = TechDomainContact.replace(predecessor, successor)
|
||||
affected_domains, skipped_domains = TechDomainContact
|
||||
.replace(current_contact, new_contact)
|
||||
@response = { affected_domains: affected_domains, skipped_domains: skipped_domains }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,8 @@ class Registrar
|
|||
uri = URI.parse("#{ENV['repp_url']}domains/contacts")
|
||||
|
||||
request = Net::HTTP::Patch.new(uri)
|
||||
request.set_form_data(predecessor: params[:predecessor], successor: params[:successor])
|
||||
request.set_form_data(current_contact_id: params[:current_contact_id],
|
||||
new_contact_id: params[:new_contact_id])
|
||||
request.basic_auth(current_user.username, current_user.password)
|
||||
|
||||
if Rails.env.test?
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class TechDomainContact < DomainContact
|
||||
# Audit log is needed, therefore no raw SQL
|
||||
def self.replace(predecessor, successor)
|
||||
def self.replace(current_contact, new_contact)
|
||||
affected_domains = []
|
||||
skipped_domains = []
|
||||
tech_contacts = where(contact: predecessor)
|
||||
tech_contacts = where(contact: current_contact)
|
||||
|
||||
transaction do
|
||||
tech_contacts.each do |tech_contact|
|
||||
|
@ -12,7 +12,7 @@ class TechDomainContact < DomainContact
|
|||
next
|
||||
end
|
||||
|
||||
tech_contact.contact = successor
|
||||
tech_contact.contact = new_contact
|
||||
tech_contact.save!
|
||||
affected_domains << tech_contact.domain.name
|
||||
end
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<%= label_tag :predecessor, t('.predecessor') %>
|
||||
<%= label_tag :current_contact_id %>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<%= text_field_tag :predecessor, params[:predecessor],
|
||||
<%= text_field_tag :current_contact_id, params[:current_contact_id],
|
||||
list: :contacts,
|
||||
required: true,
|
||||
autofocus: true,
|
||||
|
@ -21,11 +21,11 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<%= label_tag :successor, t('.successor') %>
|
||||
<%= label_tag :new_contact_id %>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<%= text_field_tag :successor, params[:successor],
|
||||
<%= text_field_tag :new_contact_id, params[:new_contact_id],
|
||||
list: :contacts,
|
||||
required: true,
|
||||
class: 'form-control' %>
|
||||
|
|
|
@ -8,8 +8,6 @@ en:
|
|||
bulk_transfer: Bulk transfer
|
||||
|
||||
tech_contact_form:
|
||||
predecessor: Current contact ID
|
||||
successor: New contact ID
|
||||
submit_btn: Replace technical contacts
|
||||
help_btn: Toggle help
|
||||
help: >-
|
||||
|
|
|
@ -8,8 +8,8 @@ Replaces all domain contacts of the current registrar.
|
|||
$ curl https://repp.internet.ee/v1/domains/contacts \
|
||||
-X PATCH \
|
||||
-u username:password \
|
||||
-d predecessor=foo \
|
||||
-d successor=bar
|
||||
-d current_contact_id=foo \
|
||||
-d new_contact_id=bar
|
||||
```
|
||||
### Example response
|
||||
```
|
||||
|
|
|
@ -2,7 +2,8 @@ require 'test_helper'
|
|||
|
||||
class APIDomainContactsTest < ActionDispatch::IntegrationTest
|
||||
def test_replace_all_tech_contacts_of_the_current_registrar
|
||||
patch '/repp/v1/domains/contacts', { predecessor: 'william-001', successor: 'john-001' },
|
||||
patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001',
|
||||
new_contact_id: 'john-001' },
|
||||
{ 'HTTP_AUTHORIZATION' => http_auth_key }
|
||||
|
||||
assert_nil domains(:shop).tech_contacts.find_by(code: 'william-001')
|
||||
|
@ -13,14 +14,16 @@ class APIDomainContactsTest < ActionDispatch::IntegrationTest
|
|||
def test_skip_discarded_domains
|
||||
domains(:airport).update!(statuses: [DomainStatus::DELETE_CANDIDATE])
|
||||
|
||||
patch '/repp/v1/domains/contacts', { predecessor: 'william-001', successor: 'john-001' },
|
||||
patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001',
|
||||
new_contact_id: 'john-001' },
|
||||
{ 'HTTP_AUTHORIZATION' => http_auth_key }
|
||||
|
||||
assert domains(:airport).tech_contacts.find_by(code: 'william-001')
|
||||
end
|
||||
|
||||
def test_return_affected_domains_in_alphabetical_order
|
||||
patch '/repp/v1/domains/contacts', { predecessor: 'william-001', successor: 'john-001' },
|
||||
patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001',
|
||||
new_contact_id: 'john-001' },
|
||||
{ 'HTTP_AUTHORIZATION' => http_auth_key }
|
||||
|
||||
assert_response :ok
|
||||
|
@ -33,7 +36,8 @@ class APIDomainContactsTest < ActionDispatch::IntegrationTest
|
|||
domains(:shop).update!(statuses: [DomainStatus::DELETE_CANDIDATE])
|
||||
domains(:airport).update!(statuses: [DomainStatus::DELETE_CANDIDATE])
|
||||
|
||||
patch '/repp/v1/domains/contacts', { predecessor: 'william-001', successor: 'john-001' },
|
||||
patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001',
|
||||
new_contact_id: 'john-001' },
|
||||
{ 'HTTP_AUTHORIZATION' => http_auth_key }
|
||||
|
||||
assert_response :ok
|
||||
|
@ -42,52 +46,58 @@ class APIDomainContactsTest < ActionDispatch::IntegrationTest
|
|||
end
|
||||
|
||||
def test_keep_other_tech_contacts_intact
|
||||
patch '/repp/v1/domains/contacts', { predecessor: 'william-001', successor: 'john-001' },
|
||||
patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001',
|
||||
new_contact_id: 'john-001' },
|
||||
{ 'HTTP_AUTHORIZATION' => http_auth_key }
|
||||
|
||||
assert domains(:shop).tech_contacts.find_by(code: 'acme-ltd-001')
|
||||
end
|
||||
|
||||
def test_keep_admin_contacts_intact
|
||||
patch '/repp/v1/domains/contacts', { predecessor: 'william-001', successor: 'john-001' },
|
||||
patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001',
|
||||
new_contact_id: 'john-001' },
|
||||
{ 'HTTP_AUTHORIZATION' => http_auth_key }
|
||||
|
||||
assert domains(:airport).admin_contacts.find_by(code: 'william-001')
|
||||
end
|
||||
|
||||
def test_restrict_contacts_to_the_current_registrar
|
||||
patch '/repp/v1/domains/contacts', { predecessor: 'jack-001', successor: 'william-002' },
|
||||
patch '/repp/v1/domains/contacts', { current_contact_id: 'jack-001',
|
||||
new_contact_id: 'william-002' },
|
||||
{ 'HTTP_AUTHORIZATION' => http_auth_key }
|
||||
|
||||
assert_response :bad_request
|
||||
assert_equal ({ error: { type: 'invalid_request_error',
|
||||
param: 'predecessor',
|
||||
param: 'current_contact_id',
|
||||
message: 'No such contact: jack-001' } }),
|
||||
JSON.parse(response.body, symbolize_names: true)
|
||||
end
|
||||
|
||||
def test_non_existent_predecessor
|
||||
patch '/repp/v1/domains/contacts', { predecessor: 'non-existent', successor: 'john-001' },
|
||||
def test_non_existent_current_contact
|
||||
patch '/repp/v1/domains/contacts', { current_contact_id: 'non-existent',
|
||||
new_contact_id: 'john-001' },
|
||||
{ 'HTTP_AUTHORIZATION' => http_auth_key }
|
||||
assert_response :bad_request
|
||||
assert_equal ({ error: { type: 'invalid_request_error',
|
||||
param: 'predecessor',
|
||||
param: 'current_contact_id',
|
||||
message: 'No such contact: non-existent' } }),
|
||||
JSON.parse(response.body, symbolize_names: true)
|
||||
end
|
||||
|
||||
def test_non_existent_successor
|
||||
patch '/repp/v1/domains/contacts', { predecessor: 'william-001', successor: 'non-existent' },
|
||||
def test_non_existent_new_contact
|
||||
patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001',
|
||||
new_contact_id: 'non-existent' },
|
||||
{ 'HTTP_AUTHORIZATION' => http_auth_key }
|
||||
assert_response :bad_request
|
||||
assert_equal ({ error: { type: 'invalid_request_error',
|
||||
param: 'successor',
|
||||
param: 'new_contact_id',
|
||||
message: 'No such contact: non-existent' } }),
|
||||
JSON.parse(response.body, symbolize_names: true)
|
||||
end
|
||||
|
||||
def test_disallow_self_replacement
|
||||
patch '/repp/v1/domains/contacts', { predecessor: 'william-001', successor: 'william-001' },
|
||||
patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001',
|
||||
new_contact_id: 'william-001' },
|
||||
{ 'HTTP_AUTHORIZATION' => http_auth_key }
|
||||
assert_response :bad_request
|
||||
assert_equal ({ error: { type: 'invalid_request_error',
|
||||
|
|
|
@ -7,7 +7,7 @@ class RegistrarAreaTechContactBulkChangeTest < ActionDispatch::IntegrationTest
|
|||
|
||||
def test_replace_domain_contacts_of_current_registrar
|
||||
request_stub = stub_request(:patch, /domains\/contacts/)
|
||||
.with(body: { predecessor: 'william-001', successor: 'john-001' },
|
||||
.with(body: { current_contact_id: 'william-001', new_contact_id: 'john-001' },
|
||||
basic_auth: ['test_bestnames', 'testtest'])
|
||||
.to_return(body: { affected_domains: %w[foo.test bar.test],
|
||||
skipped_domains: %w[baz.test qux.test] }.to_json,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue