Make sure that only admin contacts and registrants can lock a domain

This commit is contained in:
Maciej Szlosarczyk 2018-08-24 12:54:05 +03:00
parent 1d53e7bb5b
commit a64b03d204
No known key found for this signature in database
GPG key ID: 41D62D42D3B0D765
4 changed files with 49 additions and 14 deletions

View file

@ -3,6 +3,7 @@ module Api
module Registrant module Registrant
class RegistryLocksController < BaseController class RegistryLocksController < BaseController
before_action :set_domain before_action :set_domain
before_action :authorized_to_manage_locks?
def create def create
if @domain.apply_registry_lock if @domain.apply_registry_lock
@ -25,13 +26,22 @@ module Api
private private
def set_domain def set_domain
domain_pool = current_user.administrated_domains domain_pool = current_user.domains
@domain = domain_pool.find_by(uuid: params[:domain_uuid]) @domain = domain_pool.find_by(uuid: params[:domain_uuid])
return if @domain return if @domain
render json: { errors: [{ base: ['Domain not found'] }] }, render json: { errors: [{ base: ['Domain not found'] }] },
status: :not_found and return status: :not_found and return
end end
def authorized_to_manage_locks?
return if current_user.administrated_domains.include?(@domain)
render json: { errors: [
{ base: ['Only administrative contacts can manage registry locks'] }
] },
status: :unauthorized and return
end
end end
end end
end end

View file

@ -16,22 +16,30 @@ class RegistrantUser < User
end end
def domains def domains
Domain.includes(:registrar, :registrant).where( Domain.uniq
contacts: { .joins(:contacts)
ident_type: 'priv', .where(contacts: { ident_type: 'priv', ident: ident, ident_country_code: country_code })
ident: ident,
ident_country_code: country_code
}
)
end end
def contacts def contacts
Contact.where(ident_type: 'priv', ident: ident, ident_country_code: country_code) Contact.where(ident_type: 'priv', ident: ident, ident_country_code: country_code)
end end
# In Rails 5, can be replaced with a much simpler `or` query method and the raw SQL parts can be
# removed.
# https://guides.rubyonrails.org/active_record_querying.html#or-conditions
def administrated_domains def administrated_domains
Domain.joins(:domain_contacts) domains_where_is_administrative_contact = begin
.where(domain_contacts: { contact_id: contacts, type: AdminDomainContact }) Domain.joins(:domain_contacts)
.where(domain_contacts: { contact_id: contacts, type: [AdminDomainContact] })
end
domains_where_is_registrar = Domain.where(registrant_id: contacts)
Domain.from(
"(#{domains_where_is_registrar.to_sql} UNION " \
"#{domains_where_is_administrative_contact.to_sql}) AS domains"
)
end end
def to_s def to_s

View file

@ -99,6 +99,16 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest
assert_equal({ errors: [{ base: ['Domain not found'] }] }, response_json) assert_equal({ errors: [{ base: ['Domain not found'] }] }, response_json)
end end
def test_technical_contact_cannot_lock_a_domain
post '/api/v1/registrant/domains/647bcc48-8d5e-4a04-8ce5-2a3cd17b6eab/registry_lock',
{}, @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
assert_equal(401, response.status)
assert_equal({ errors: [{ base: ['Only administrative contacts can manage registry locks'] }] },
response_json)
end
private private
def auth_token def auth_token

View file

@ -4,20 +4,27 @@ class RegistrantUserTest < ActiveSupport::TestCase
def setup def setup
super super
@user = RegistrantUser.new(registrant_ident: 'US-1234') @user = users(:registrant)
end end
def teardown def teardown
super super
end end
def test_domains_returns_an_list_of_domains_associated_with_a_specific_id_code def test_domains_returns_an_list_of_distinct_domains_associated_with_a_specific_id_code
domain_names = @user.domains.pluck(:name) domain_names = @user.domains.pluck(:name)
assert_equal(3, domain_names.length) assert_equal(3, domain_names.length)
# User is a registrant, but not a contact for the domain.
refute(domain_names.include?('shop.test'))
end end
def test_administrated_domains_returns_a_list_of_domains_that_is_smaller_than_domains def test_administrated_domains_returns_a_list_of_domains
assert_equal(2, @user.administrated_domains.count) domain_names = @user.administrated_domains.pluck(:name)
assert_equal(3, domain_names.length)
# User is a tech contact for the domain.
refute(domain_names.include?('library.test'))
end end
def test_contacts_returns_an_list_of_contacts_associated_with_a_specific_id_code def test_contacts_returns_an_list_of_contacts_associated_with_a_specific_id_code