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
class RegistryLocksController < BaseController
before_action :set_domain
before_action :authorized_to_manage_locks?
def create
if @domain.apply_registry_lock
@ -25,13 +26,22 @@ module Api
private
def set_domain
domain_pool = current_user.administrated_domains
domain_pool = current_user.domains
@domain = domain_pool.find_by(uuid: params[:domain_uuid])
return if @domain
render json: { errors: [{ base: ['Domain not found'] }] },
status: :not_found and return
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

View file

@ -16,22 +16,30 @@ class RegistrantUser < User
end
def domains
Domain.includes(:registrar, :registrant).where(
contacts: {
ident_type: 'priv',
ident: ident,
ident_country_code: country_code
}
)
Domain.uniq
.joins(:contacts)
.where(contacts: { ident_type: 'priv', ident: ident, ident_country_code: country_code })
end
def contacts
Contact.where(ident_type: 'priv', ident: ident, ident_country_code: country_code)
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
Domain.joins(:domain_contacts)
.where(domain_contacts: { contact_id: contacts, type: AdminDomainContact })
domains_where_is_administrative_contact = begin
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
def to_s

View file

@ -99,6 +99,16 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest
assert_equal({ errors: [{ base: ['Domain not found'] }] }, response_json)
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
def auth_token

View file

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