diff --git a/CHANGELOG.md b/CHANGELOG.md index 9afedbf17..6470a9471 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +26.02.2021 +* Domain delete is not affected by updateProhibited [#1844](https://github.com/internetee/registry/issues/1844) +* Registrant API fix for handling eidas personal identificators [#1864](https://github.com/internetee/registry/pull/1864) + +23.02.2021 +* UpdateProhibited status affects bulk actions in REPP [#1818](https://github.com/internetee/registry/issues/1818) +* Registrant api domain request now excludes tech only domains by default [#1836](https://github.com/internetee/registry/pull/1836) + +22.02.2021 +* serverDeleteProhibited prohibts delete action [#1849](https://github.com/internetee/registry/issues/1849) + +19.02.2021 +* Update prohibited staatus is kept after renew [#1843](https://github.com/internetee/registry/issues/1843) +* Fixed clientHold and serverManualInzone status conflict issue [#1845](https://github.com/internetee/registry/issues/1845) +* Replacing registrant object with another that has the same ident data set does not require registrant verification [#1852](https://github.com/internetee/registry/issues/1852) + 11.02.2021 * Poll messages on locking and unlocking a domain [#1828](https://github.com/internetee/registry/issues/1828) * Registrar's prefix is now checked and added to contact id for info and check requests [#1832](https://github.com/internetee/registry/issues/1832) diff --git a/app/controllers/api/v1/registrant/auth_controller.rb b/app/controllers/api/v1/registrant/auth_controller.rb index 03dfa45f3..728ef696d 100644 --- a/app/controllers/api/v1/registrant/auth_controller.rb +++ b/app/controllers/api/v1/registrant/auth_controller.rb @@ -19,6 +19,9 @@ module Api token = create_token(user) if token + msg = "Bearer for #{eid_params[:first_name]} #{eid_params[:last_name]} " \ + "(#{eid_params[:ident]}) - '#{token[:access_token]}'" + ToStdout.msg(msg) unless Rails.env.production? render json: token else render json: { errors: [{ base: ['Cannot create generate session token'] }] } @@ -37,7 +40,7 @@ module Api obj.require(key) end - params.permit(required_params) + params.permit(required_params + [:country_code]) end def create_token(user) diff --git a/app/controllers/api/v1/registrant/domains_controller.rb b/app/controllers/api/v1/registrant/domains_controller.rb index 73b534598..94d2c865a 100644 --- a/app/controllers/api/v1/registrant/domains_controller.rb +++ b/app/controllers/api/v1/registrant/domains_controller.rb @@ -4,6 +4,8 @@ module Api module V1 module Registrant class DomainsController < ::Api::V1::Registrant::BaseController + before_action :set_tech_flag, only: [:show] + def index limit = params[:limit] || 200 offset = params[:offset] || 0 @@ -25,7 +27,8 @@ module Api serializer.to_json end - render json: { count: domains.count, domains: serialized_domains } + render json: { total: current_user_domains_total_count, count: domains.count, + domains: serialized_domains } end def show @@ -41,10 +44,22 @@ module Api private - def current_user_domains - current_registrant_user.domains + def set_tech_flag + # current_user_domains scope depends on tech flag + # However, if it's not present, tech contact can not see specific domain entry at all. + params.merge!(tech: 'true') + end + + def current_user_domains_total_count + current_registrant_user.domains.count rescue CompanyRegister::NotAvailableError - current_registrant_user.direct_domains + current_registrant_user.direct_domains.count + end + + def current_user_domains + current_registrant_user.domains(admin: params[:tech] != 'true') + rescue CompanyRegister::NotAvailableError + current_registrant_user.direct_domains(admin: params[:tech] != 'true') end end end diff --git a/app/models/actions/contact_delete.rb b/app/models/actions/contact_delete.rb index 59032d566..60d3252c4 100644 --- a/app/models/actions/contact_delete.rb +++ b/app/models/actions/contact_delete.rb @@ -19,6 +19,11 @@ module Actions return end + if contact.delete_prohibited? + contact.errors.add(:statuses, :delete_prohibited) + return + end + commit end diff --git a/app/models/concerns/domain/deletable.rb b/app/models/concerns/domain/deletable.rb index 81518c739..3c63cf96d 100644 --- a/app/models/concerns/domain/deletable.rb +++ b/app/models/concerns/domain/deletable.rb @@ -1,6 +1,12 @@ module Concerns::Domain::Deletable extend ActiveSupport::Concern + DELETE_STATUSES = [ + DomainStatus::PENDING_DELETE_CONFIRMATION, + DomainStatus::PENDING_DELETE, + DomainStatus::FORCE_DELETE, + ].freeze + private def delete_later diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index 87e9a957b..5f09dd9fb 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -11,6 +11,11 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength lambda { where("(force_delete_data->>'contact_notification_sent_date') is null") } + + HOLD_STATUSES = [ + DomainStatus::SERVER_HOLD, + DomainStatus::CLIENT_HOLD, + ].freeze end class_methods do @@ -19,6 +24,10 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength end end + def hold_status? + HOLD_STATUSES.any? { |status| statuses.include? status } + end + def notification_template(explicit: nil) reason = explicit&.downcase return reason if %w[invalid_email invalid_phone].include?(reason) diff --git a/app/models/concerns/domain/transferable.rb b/app/models/concerns/domain/transferable.rb index 5400e9409..649600217 100644 --- a/app/models/concerns/domain/transferable.rb +++ b/app/models/concerns/domain/transferable.rb @@ -31,7 +31,9 @@ module Concerns::Domain::Transferable DomainStatus::PENDING_TRANSFER, DomainStatus::FORCE_DELETE, DomainStatus::SERVER_TRANSFER_PROHIBITED, - DomainStatus::CLIENT_TRANSFER_PROHIBITED + DomainStatus::CLIENT_TRANSFER_PROHIBITED, + DomainStatus::SERVER_UPDATE_PROHIBITED, + DomainStatus::CLIENT_UPDATE_PROHIBITED, ]).empty? end diff --git a/app/models/domain.rb b/app/models/domain.rb index 53f0fa5b6..f5fed455d 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -107,13 +107,13 @@ class Domain < ApplicationRecord validate :status_is_consistant def status_is_consistant - has_error = (statuses.include?(DomainStatus::SERVER_HOLD) && statuses.include?(DomainStatus::SERVER_MANUAL_INZONE)) - unless has_error - if (statuses & [DomainStatus::PENDING_DELETE_CONFIRMATION, DomainStatus::PENDING_DELETE, DomainStatus::FORCE_DELETE]).any? - has_error = statuses.include? DomainStatus::SERVER_DELETE_PROHIBITED - end + has_error = (hold_status? && statuses.include?(DomainStatus::SERVER_MANUAL_INZONE)) + unless has_error + if (statuses & DELETE_STATUSES).any? + has_error = statuses.include? DomainStatus::SERVER_DELETE_PROHIBITED end - errors.add(:domains, I18n.t(:object_status_prohibits_operation)) if has_error + end + errors.add(:domains, I18n.t(:object_status_prohibits_operation)) if has_error end attr_accessor :is_admin @@ -198,6 +198,23 @@ class Domain < ApplicationRecord Setting.nameserver_required end + def registrant_user_admin_registrant_domains(registrant_user) + companies = Contact.registrant_user_company_contacts(registrant_user) + from( + "(#{registrant_user_administered_domains(registrant_user).to_sql} UNION " \ + "#{registrant_user_company_registrant(companies).to_sql} UNION " \ + "#{registrant_user_domains_company(companies, except_tech: true).to_sql}) AS domains" + ) + end + + def registrant_user_direct_admin_registrant_domains(registrant_user) + from( + "(#{registrant_user_direct_domains_by_registrant(registrant_user).to_sql} UNION " \ + "#{registrant_user_direct_domains_by_contact(registrant_user, + except_tech: true).to_sql}) AS domains" + ) + end + def registrant_user_domains(registrant_user) from( "(#{registrant_user_domains_by_registrant(registrant_user).to_sql} UNION " \ @@ -247,16 +264,20 @@ class Domain < ApplicationRecord where(registrant: registrant_user.direct_contacts) end - def registrant_user_direct_domains_by_contact(registrant_user) - joins(:domain_contacts).where(domain_contacts: { contact_id: registrant_user.direct_contacts }) + def registrant_user_direct_domains_by_contact(registrant_user, except_tech: false) + request = { contact_id: registrant_user.direct_contacts } + request[:type] = [AdminDomainContact.name] if except_tech + joins(:domain_contacts).where(domain_contacts: request) end def registrant_user_company_registrant(companies) where(registrant: companies) end - def registrant_user_domains_company(companies) - joins(:domain_contacts).where(domain_contacts: { contact: companies }) + def registrant_user_domains_company(companies, except_tech: false) + request = { contact: companies } + request[:type] = [AdminDomainContact.name] if except_tech + joins(:domain_contacts).where(domain_contacts: request) end end diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index bf0ae2a51..30161c076 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -109,14 +109,12 @@ class DomainStatus < ApplicationRecord DELETE_PROHIBIT_STATES = [ DomainStatus::CLIENT_DELETE_PROHIBITED, DomainStatus::SERVER_DELETE_PROHIBITED, - DomainStatus::CLIENT_UPDATE_PROHIBITED, - DomainStatus::SERVER_UPDATE_PROHIBITED, DomainStatus::PENDING_CREATE, DomainStatus::PENDING_RENEW, DomainStatus::PENDING_TRANSFER, DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_DELETE - ] + ].freeze def epp_code_map { diff --git a/app/models/epp/contact.rb b/app/models/epp/contact.rb index 0c0ed3d5f..4cd876d5f 100644 --- a/app/models/epp/contact.rb +++ b/app/models/epp/contact.rb @@ -82,8 +82,11 @@ class Epp::Contact < Contact '2302' => [ # Object exists [:code, :epp_id_taken] ], + '2304' => [ # Status prohibits operation + [:statuses, :delete_prohibited], + ], '2305' => [ # Association exists - [:domains, :exist] + [:domains, :exist], ] } end diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index f280eb160..f3da8d533 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -465,7 +465,7 @@ class Epp::Domain < Domain def update(frame, current_user, verify = true) return super if frame.blank? - if discarded? + if discarded? || statuses_blocks_update? add_epp_error('2304', nil, nil, 'Object status prohibits operation') return end @@ -495,7 +495,7 @@ class Epp::Domain < Domain registrant_verification_needed = false # registrant block may not be present, so we need this to rule out false positives if frame.css('registrant').text.present? - registrant_verification_needed = (registrant.code != frame.css('registrant').text) + registrant_verification_needed = verification_needed?(code: frame.css('registrant').text) end if registrant_verification_needed && disputed? @@ -797,4 +797,13 @@ class Epp::Domain < Domain result end end + + private + + def verification_needed?(code:) + new_registrant = Registrant.find_by(code: code) + return false if new_registrant.try(:identical_to?, registrant) + + registrant.code != code + end end diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index aa41ccff8..f7e85c5af 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -9,7 +9,7 @@ class RegistrantUser < User delegate :can?, :cannot?, to: :ability def ident - registrant_ident.to_s.split('-').last + registrant_ident.to_s[3..] end def country @@ -18,6 +18,8 @@ class RegistrantUser < User end def companies(company_register = CompanyRegister::Client.new) + return [] if ident.include?('-') + company_register.representation_rights(citizen_personal_code: ident, citizen_country_code: country.alpha3) end @@ -30,11 +32,15 @@ class RegistrantUser < User Contact.registrant_user_direct_contacts(self) end - def domains + def domains(admin: false) + return Domain.registrant_user_admin_registrant_domains(self) if admin + Domain.registrant_user_domains(self) end - def direct_domains + def direct_domains(admin: false) + return Domain.registrant_user_direct_admin_registrant_domains(self) if admin + Domain.registrant_user_direct_domains(self) end @@ -72,7 +78,7 @@ class RegistrantUser < User return false unless user_data[:last_name] user_data[:country_code] ||= 'EE' - %i[ident country_code].each { |f| user_data[f].upcase! if user_data[f].is_a?(String) } + user_data[:country_code].upcase! if user_data[:country_code].is_a?(String) find_or_create_by_user_data(user_data) end diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 168dfdca7..652864fe5 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -153,7 +153,7 @@ class Registrar < ApplicationRecord puny = origin.domain.name_puny next unless domains.include?(idn) || domains.include?(puny) || domains.empty? - if origin.domain.nameservers.where(hostname: new_attributes[:hostname]).any? + if domain_not_updatable?(hostname: new_attributes[:hostname], domain: origin.domain) failed_list << idn next end @@ -202,6 +202,10 @@ class Registrar < ApplicationRecord private + def domain_not_updatable?(hostname:, domain:) + domain.nameservers.where(hostname: hostname).any? || domain.bulk_update_prohibited? + end + def set_defaults self.language = Setting.default_language unless language end diff --git a/config/locales/contacts.en.yml b/config/locales/contacts.en.yml index 906bde193..4b4d099d7 100644 --- a/config/locales/contacts.en.yml +++ b/config/locales/contacts.en.yml @@ -25,8 +25,10 @@ en: email_regex_check_error: Invalid format domains: exist: 'Object association prohibits operation' + delete_prohibited: Contact delete prohibited by status statuses: not_uniq: 'not uniq' + delete_prohibited: Contact delete prohibited by status country_code: invalid: Country code is not valid, should be in ISO_3166-1 alpha 2 format (%{value}) disclosed_attributes: diff --git a/lib/serializers/registrant_api/domain.rb b/lib/serializers/registrant_api/domain.rb index 64913a7fb..ed6eb2b9c 100644 --- a/lib/serializers/registrant_api/domain.rb +++ b/lib/serializers/registrant_api/domain.rb @@ -25,6 +25,7 @@ module Serializers registrant: { name: domain.registrant.name, id: domain.registrant.uuid, + org: domain.registrant.org?, }, tech_contacts: contacts(:tech), admin_contacts: contacts(:admin), @@ -60,7 +61,7 @@ module Serializers registrar: { name: domain.registrar.name, website: domain.registrar.website }, registrant: { name: domain.registrant.name, id: domain.registrant.uuid, phone: domain.registrant.phone, email: domain.registrant.email, - ident: domain.registrant.ident } + ident: domain.registrant.ident, org: domain.registrant.org? } } end diff --git a/test/integration/api/domain_transfers_test.rb b/test/integration/api/domain_transfers_test.rb index 3e9c10100..3ed5b0fc6 100644 --- a/test/integration/api/domain_transfers_test.rb +++ b/test/integration/api/domain_transfers_test.rb @@ -63,6 +63,23 @@ class APIDomainTransfersTest < ApplicationIntegrationTest assert_equal 1, @new_registrar.contacts.where(name: 'William').size end + def test_bulk_transfer_if_domain_has_update_prohibited_status + domains(:shop).update!(statuses: [DomainStatus::SERVER_UPDATE_PROHIBITED]) + + post '/repp/v1/domains/transfer', params: request_params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } + + assert_response :ok + assert_equal ({ code: 1000, + message: 'Command completed successfully', + data: { success: [], + failed: [{ type: "domain_transfer", + domain_name: "shop.test", + errors: [{:code=>"2304", :msg=>"Object status prohibits operation"}] }], + }}), + JSON.parse(response.body, symbolize_names: true) + end + private def request_params diff --git a/test/integration/api/nameservers/put_test.rb b/test/integration/api/nameservers/put_test.rb index 77b01a9b1..a55014709 100644 --- a/test/integration/api/nameservers/put_test.rb +++ b/test/integration/api/nameservers/put_test.rb @@ -104,6 +104,25 @@ class APINameserversPutTest < ApplicationIntegrationTest JSON.parse(response.body, symbolize_names: true) end + def test_bulk_namesaervers_if_domain_update_prohibited + domains(:shop).update!(statuses: [DomainStatus::SERVER_UPDATE_PROHIBITED]) + + params = { data: { type: 'nameserver', id: domains(:shop).nameservers.hostnames[0], + attributes: { hostname: 'ns55.bestnames.test' } } } + put '/repp/v1/registrar/nameservers', params: params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } + + assert_response :ok + assert_equal ({ code: 1000, + message: 'Command completed successfully', + data: { type: "nameserver", + id: "ns55.bestnames.test", + attributes: {hostname: "ns55.bestnames.test"}, + affected_domains: ["airport.test"], + skipped_domains: ["shop.test"]}}), + JSON.parse(response.body, symbolize_names: true) + end + def test_unauthenticated put '/repp/v1/registrar/nameservers' assert_response 401 diff --git a/test/integration/api/registrant/registrant_api_domains_test.rb b/test/integration/api/registrant/registrant_api_domains_test.rb index 61d635e5f..4cfa6bd55 100644 --- a/test/integration/api/registrant/registrant_api_domains_test.rb +++ b/test/integration/api/registrant/registrant_api_domains_test.rb @@ -5,9 +5,10 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest def setup super - @domain = domains(:hospital) + @domain = domains(:airport) @registrant = @domain.registrant @user = users(:registrant) + domains(:metro).tech_domain_contacts.update(contact_id: @registrant.id) @auth_headers = { 'HTTP_AUTHORIZATION' => auth_token } end @@ -19,7 +20,7 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest assert_equal('hospital.test', domain[:name]) assert_equal('5edda1a5-3548-41ee-8b65-6d60daf85a37', domain[:id]) - assert_equal({name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957'}, domain[:registrant]) + assert_equal({name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957', org: false}, domain[:registrant]) assert_equal([{name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957', email: 'john@inbox.test'}], @@ -57,6 +58,46 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest assert(array_of_domain_registrars.include?({name: 'Good Names', website: nil})) end + def test_return_domain_list_with_registrants_and_admins + domains(:hospital).admin_domain_contacts.update(contact_id: contacts(:william).id) + domains(:hospital).update(registrant: contacts(:william).becomes(Registrant)) + + get '/api/v1/registrant/domains', headers: @auth_headers, params: { 'offset' => 0 } + assert_equal(200, response.status) + + response_json = JSON.parse(response.body, symbolize_names: true) + response_json[:domains].each do |x| + if x[:registrant][:org] == false + x[:tech_contacts].each do |s| + assert_not s[:name].include?(@registrant.name) + end + end + end + end + + def test_return_domain_list_with_registrants_and_admins_tech + get '/api/v1/registrant/domains', headers: @auth_headers, params: { 'offset' => 0, 'tech' => true } + assert_equal(200, response.status) + + response_json = JSON.parse(response.body, symbolize_names: true) + response_json[:domains].each do |x| + if x[:name] == 'metro.test' + x[:tech_contacts].each do |s| + assert s[:name].include?(@registrant.name) + end + end + end + end + + def test_domains_total_if_an_incomplete_list_is_returned + get '/api/v1/registrant/domains', headers: @auth_headers, params: { 'offset' => 0 } + assert_equal(200, response.status) + + response_json = JSON.parse(response.body, symbolize_names: true) + assert_equal response_json[:domains].length, response_json[:count] + assert_equal response_json[:total], 5 + end + def test_root_accepts_limit_and_offset_parameters get '/api/v1/registrant/domains', params: { 'limit' => 2, 'offset' => 0 }, headers: @auth_headers diff --git a/test/integration/api/registrant/registrant_api_registry_locks_test.rb b/test/integration/api/registrant/registrant_api_registry_locks_test.rb index fb6d13aca..d024bb6c1 100644 --- a/test/integration/api/registrant/registrant_api_registry_locks_test.rb +++ b/test/integration/api/registrant/registrant_api_registry_locks_test.rb @@ -130,7 +130,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest response_json = JSON.parse(response.body, symbolize_names: true) assert_equal({ name: 'Best Names', website: 'https://bestnames.test' }, response_json[:registrar]) - assert_equal({name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957'}, response_json[:registrant]) + assert_equal({name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957', org: false}, response_json[:registrant]) assert_equal([{name: 'Jane', id: '9db3de62-2414-4487-bee2-d5c155567768', email: 'jane@mail.test' diff --git a/test/integration/epp/contact/delete/base_test.rb b/test/integration/epp/contact/delete/base_test.rb index 26ba63897..e86bea9dd 100644 --- a/test/integration/epp/contact/delete/base_test.rb +++ b/test/integration/epp/contact/delete/base_test.rb @@ -27,6 +27,60 @@ class EppContactDeleteBaseTest < EppTestCase assert_epp_response :completed_successfully end + def test_delete_contact_with_server_delete_prohibited + contact = deletable_contact + contact.update(statuses: Contact::SERVER_DELETE_PROHIBITED) + assert contact.statuses.include? Contact::SERVER_DELETE_PROHIBITED + + contact.update_columns(code: contact.code.upcase) + + request_xml = <<-XML + + + + + + #{contact.code.upcase} + + + + + XML + + post epp_delete_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert Contact.exists?(id: contact.id) + assert_epp_response :object_status_prohibits_operation + end + + def test_delete_contact_with_client_delete_prohibited + contact = deletable_contact + contact.update(statuses: Contact::CLIENT_DELETE_PROHIBITED) + assert contact.statuses.include? Contact::CLIENT_DELETE_PROHIBITED + + contact.update_columns(code: contact.code.upcase) + + request_xml = <<-XML + + + + + + #{contact.code.upcase} + + + + + XML + + post epp_delete_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert Contact.exists?(id: contact.id) + assert_epp_response :object_status_prohibits_operation + end + def test_undeletable_cannot_be_deleted contact = contacts(:john) assert_not contact.deletable? @@ -61,4 +115,4 @@ class EppContactDeleteBaseTest < EppTestCase DomainContact.delete_all contacts(:john) end -end \ No newline at end of file +end diff --git a/test/integration/epp/domain/delete/base_test.rb b/test/integration/epp/domain/delete/base_test.rb index 56a3cc31e..d32a89f63 100644 --- a/test/integration/epp/domain/delete/base_test.rb +++ b/test/integration/epp/domain/delete/base_test.rb @@ -133,6 +133,40 @@ class EppDomainDeleteBaseTest < EppTestCase assert_epp_response :completed_successfully end + def test_deletes_on_update_prohibited + assert_equal 'shop.test', @domain.name + @domain.update(statuses: [DomainStatus::SERVER_UPDATE_PROHIBITED]) + Setting.request_confirmation_on_domain_deletion_enabled = false + + request_xml = <<-XML + + + + + + shop.test + + + + + #{'test' * 2000} + + + + + XML + + perform_enqueued_jobs do + post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + @domain.reload + + assert_not @domain.registrant_verification_asked? + assert_not @domain.pending_delete_confirmation? + assert_no_emails + assert_epp_response :completed_successfully + end + def test_skips_registrant_confirmation_when_required_but_already_verified_by_registrar assert_equal 'shop.test', @domain.name Setting.request_confirmation_on_domain_deletion_enabled = true diff --git a/test/integration/epp/domain/update/base_test.rb b/test/integration/epp/domain/update/base_test.rb index 14e806fca..53531e8b5 100644 --- a/test/integration/epp/domain/update/base_test.rb +++ b/test/integration/epp/domain/update/base_test.rb @@ -62,6 +62,27 @@ class EppDomainUpdateBaseTest < EppTestCase assert_epp_response :object_status_prohibits_operation end + def test_prohibited_domain_cannot_be_updated + @domain.update!(statuses: [DomainStatus::SERVER_UPDATE_PROHIBITED]) + + request_xml = <<-XML + + + + + + shop.test + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + assert_epp_response :object_status_prohibits_operation + end + def test_does_not_return_server_delete_prohibited_status_when_pending_update_status_is_set @domain.update!(statuses: [DomainStatus::SERVER_DELETE_PROHIBITED, DomainStatus::PENDING_UPDATE]) @@ -123,6 +144,46 @@ class EppDomainUpdateBaseTest < EppTestCase assert_verification_and_notification_emails end + def test_domain_should_doesnt_have_pending_update_when_updated_registrant_with_same_idents_data + assert_not @domain.statuses.include? "pendingUpdate" + + old_registrant = @domain.registrant + new_registrant = contacts(:william).becomes(Registrant) + + new_registrant.update(ident: old_registrant.ident) + new_registrant.update(ident_country_code: old_registrant.ident_country_code) + new_registrant.update(ident_type: old_registrant.ident_type) + + request_xml = <<-XML + + + + + + #{@domain.name} + + #{new_registrant.code} + + + + + + #{'test' * 2000} + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + assert_epp_response :completed_successfully + + assert_equal @domain.registrant, new_registrant + assert_not @domain.statuses.include? "pendingUpdate" + end + def test_requires_verification_from_current_registrant_when_not_yet_verified_by_registrar Setting.request_confirmation_on_registrant_change_enabled = true new_registrant = contacts(:william) diff --git a/test/integration/repp/v1/registrar/nameservers_test.rb b/test/integration/repp/v1/registrar/nameservers_test.rb index f01769dfb..e2c6f890b 100644 --- a/test/integration/repp/v1/registrar/nameservers_test.rb +++ b/test/integration/repp/v1/registrar/nameservers_test.rb @@ -34,6 +34,33 @@ class ReppV1RegistrarNameserversTest < ActionDispatch::IntegrationTest assert json[:data][:affected_domains].include? 'shop.test' end + def test_fails_to_update_if_prohibited + domain = domains(:shop) + domain.update(statuses: [DomainStatus::CLIENT_UPDATE_PROHIBITED]) + nameserver = nameservers(:shop_ns1) + payload = { + "data": { + "id": nameserver.hostname, + "type": "nameserver", + "attributes": { + "hostname": "#{nameserver.hostname}.test", + "ipv4": ["1.1.1.1"] + } + } + } + + put '/repp/v1/registrar/nameservers', headers: @auth_headers, params: payload + json = JSON.parse(response.body, symbolize_names: true) + + assert_response :ok + assert_equal 1000, json[:code] + assert_equal 'Command completed successfully', json[:message] + assert_equal({ hostname: "#{nameserver.hostname}.test", ipv4: ["1.1.1.1"] }, json[:data][:attributes]) + assert_equal({ hostname: "#{nameserver.hostname}.test", ipv4: ["1.1.1.1"] }, json[:data][:attributes]) + assert json[:data][:affected_domains].include? 'airport.test' + assert json[:data][:skipped_domains].include? 'shop.test' + end + def test_nameserver_with_hostname_must_exist payload = { "data": { diff --git a/test/lib/serializers/registrant_api/domain_test.rb b/test/lib/serializers/registrant_api/domain_test.rb index f2623741f..d30a50ea3 100644 --- a/test/lib/serializers/registrant_api/domain_test.rb +++ b/test/lib/serializers/registrant_api/domain_test.rb @@ -30,8 +30,8 @@ class SerializersRegistrantApiDomainTest < ActiveSupport::TestCase assert_equal({name: 'Best Names', website: 'https://bestnames.test' }, @json[:registrar]) end - def test_returns_registrant_name_and_uuid - assert_equal({name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957'}, + def test_returns_registrant_name_uuid_and_org + assert_equal({name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957', org: false}, @json[:registrant]) end diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb index 2bb1b5b8f..19338f495 100644 --- a/test/models/domain/force_delete_test.rb +++ b/test/models/domain/force_delete_test.rb @@ -234,6 +234,19 @@ class ForceDeleteTest < ActionMailer::TestCase assert_includes(@domain.statuses, asserted_status) end + def test_client_hold_prohibits_manual_inzone + @domain.update(valid_to: Time.zone.parse('2012-08-05')) + @domain.update(template_name: 'legal_person') + travel_to Time.zone.parse('2010-07-05') + @domain.schedule_force_delete(type: :soft) + travel_to Time.zone.parse('2010-08-21') + Domains::ClientHold::SetClientHold.run! + @domain.reload + + @domain.statuses << DomainStatus::SERVER_MANUAL_INZONE + assert_not @domain.valid? + end + def test_force_delete_soft_year_ahead_not_sets_client_hold_before_threshold asserted_status = DomainStatus::CLIENT_HOLD