Skip to content
Open

initial #2944

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions app/controllers/repp/v1/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,7 @@ class BaseController < ActionController::API # rubocop:disable Metrics/ClassLeng
private

def set_domain
registrar = current_user.registrar
@domain = Epp::Domain.find_by(registrar: registrar, name: params[:domain_id])
@domain ||= Epp::Domain.find_by!(registrar: registrar, name_puny: params[:domain_id])

return @domain if @domain

raise ActiveRecord::RecordNotFound
@domain = Epp::Domain.find_repp_by_name!(params[:domain_id], registrar: current_user.registrar)
end

def set_paper_trail_whodunnit
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/repp/v1/domains/renews_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def bulk_renew_domains
domains = []
if bulk_renew_params[:domains].instance_of?(Array)
bulk_renew_params[:domains].each do |idn|
domain = Epp::Domain.find_by(name: idn)
domain = Epp::Domain.find_repp_by_name(idn)
domains << domain if domain
next if domain

Expand Down
8 changes: 5 additions & 3 deletions app/controllers/repp/v1/domains/transfers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ def create

def set_domain
domain_id = transfer_params[:domain_id]
h = {}
h[domain_id.match?(/\A[0-9]+\z/) ? :id : :name] = domain_id
@domain = Epp::Domain.find_by!(h)
@domain = if domain_id.match?(/\A[0-9]+\z/)
Epp::Domain.find(domain_id)
else
Epp::Domain.find_repp_by_name!(domain_id)
end
end

def transfer_params
Expand Down
16 changes: 5 additions & 11 deletions app/controllers/repp/v1/domains_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def index
api :GET, '/repp/v1/domains/:domain_name'
desc 'Get a specific domain'
def show
@domain = Epp::Domain.find_by(name: params[:id])
@domain = Epp::Domain.find_repp_by_name(params[:id])
authorize! :info, @domain

sponsor = @domain.registrar == current_user.registrar
Expand Down Expand Up @@ -166,7 +166,8 @@ def serialized_domains(domains)
end

def initiate_transfer(transfer)
domain = Epp::Domain.find_or_initialize_by(name: transfer[:domain_name])
domain = Epp::Domain.find_repp_by_name(transfer[:domain_name])
domain ||= Epp::Domain.new(name: transfer[:domain_name])
action = Actions::DomainTransfer.new(domain, transfer[:transfer_code],
current_user.registrar)

Expand Down Expand Up @@ -195,14 +196,7 @@ def forward_registrar_id
end

def set_domain
registrar = current_user.registrar

@domain = Epp::Domain.find_by(registrar: registrar, name: params[:id])
@domain ||= Epp::Domain.find_by!(registrar: registrar, name_puny: params[:id])

return @domain if @domain

raise ActiveRecord::RecordNotFound
@domain = Epp::Domain.find_repp_by_name!(params[:id], registrar: current_user.registrar)
end

def find_password
Expand All @@ -228,7 +222,7 @@ def domain_from_url_hash
entry = params[:id]
return Epp::Domain.find(entry) if entry.match?(/\A[0-9]+\z/)

Epp::Domain.find_by!('name = ? OR name_puny = ?', entry, entry)
Epp::Domain.find_repp_by_name!(entry)
end

def limit
Expand Down
16 changes: 16 additions & 0 deletions app/models/domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,22 @@ def self.find_by_idn(name)
domain
end

def self.normalize_repp_domain_name(name)
name.to_s.strip.downcase.presence
end

def self.find_repp_by_name(name, registrar: nil)
normalized = normalize_repp_domain_name(name)
return nil unless normalized

relation = registrar ? where(registrar: registrar) : all
relation.find_by_idn(normalized) || relation.find_by(name_puny: normalized)
end

def self.find_repp_by_name!(name, registrar: nil)
find_repp_by_name(name, registrar: registrar) || raise(ActiveRecord::RecordNotFound)
end

def puny_label
name_puny.to_s.split('.').first
end
Expand Down
14 changes: 14 additions & 0 deletions test/integration/api/domain_transfers_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,26 @@ def test_bulk_transfer_if_domain_has_update_prohibited_status
JSON.parse(response.body, symbolize_names: true)
end

def test_bulk_transfer_with_uppercase_domain_name
post '/repp/v1/domains/transfer', params: uppercase_request_params, as: :json,
headers: { 'HTTP_AUTHORIZATION' => http_auth_key }

assert_response :ok
json = JSON.parse(response.body, symbolize_names: true)
assert_equal 'shop.test', json[:data][:success][0][:domain_name]
assert_equal @new_registrar, @domain.reload.registrar
end

private

def request_params
{ data: { domain_transfers: [{ domain_name: 'shop.test', transfer_code: '65078d5' }] } }
end

def uppercase_request_params
{ data: { domain_transfers: [{ domain_name: 'SHOP.TEST', transfer_code: '65078d5' }] } }
end

def http_auth_key
ActionController::HttpAuthentication::Basic.encode_credentials('test_goodnames', 'testtest')
end
Expand Down
20 changes: 20 additions & 0 deletions test/integration/repp/v1/domains/bulk_renew_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ def test_renews_domains
end
end

def test_renews_domains_with_uppercase_names
payload = {
"domains": [
'SHOP.TEST',
'AIRPORT.TEST',
'LIBRARY.TEST'
],
"renew_period": "1y"
}

post "/repp/v1/domains/renew/bulk", headers: @auth_headers, params: payload
json = JSON.parse(response.body, symbolize_names: true)

assert_response :ok
assert_equal 1000, json[:code]
assert json[:data][:updated_domains].include? 'shop.test'
assert json[:data][:updated_domains].include? 'airport.test'
assert json[:data][:updated_domains].include? 'library.test'
end

def test_keeps_update_prohibited_status
domain = domains(:shop)
domain.update(statuses: [DomainStatus::CLIENT_UPDATE_PROHIBITED, DomainStatus::SERVER_UPDATE_PROHIBITED])
Expand Down
9 changes: 9 additions & 0 deletions test/integration/repp/v1/domains/dnssec_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ def test_shows_dnssec_keys_associated_with_domain
assert_equal 1, json[:data][:dns_keys].length
end

def test_shows_dnssec_keys_with_uppercase_domain_name
get "/repp/v1/domains/#{@domain.name.upcase}/dnssec", headers: @auth_headers
json = JSON.parse(response.body, symbolize_names: true)

assert_response :ok
assert_equal 1000, json[:code]
assert_empty json[:data][:dns_keys]
end

def test_creates_dnssec_key_successfully
assert @domain.dnskeys.empty?
payload = {
Expand Down
12 changes: 12 additions & 0 deletions test/integration/repp/v1/domains/list_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ def test_returns_specific_domain_details_by_name
assert_equal serialized_domain.as_json, json[:data][:domain].as_json
end

def test_returns_specific_domain_details_by_uppercase_name
domain = domains(:shop)
get "/repp/v1/domains/#{domain.name.upcase}", headers: @auth_headers
json = JSON.parse(response.body, symbolize_names: true)

assert_response :ok
assert_equal 1000, json[:code]

serialized_domain = Serializers::Repp::Domain.new(domain).to_json
assert_equal serialized_domain.as_json, json[:data][:domain].as_json
end

def test_returns_detailed_registrar_domains_by_search_query
search_params = {
name_matches: '%library%',
Expand Down
12 changes: 12 additions & 0 deletions test/integration/repp/v1/domains/transfer_info_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ def test_can_query_domain_info
assert json[:data][:tech_contacts].present?
end

def test_can_query_domain_info_with_uppercase_name
headers = @auth_headers
headers['Auth-Code'] = @domain.transfer_code

get "/repp/v1/domains/#{@domain.name.upcase}/transfer_info", headers: headers
json = JSON.parse(response.body, symbolize_names: true)

assert_response :ok
assert_equal 1000, json[:code]
assert_equal @domain.name, json[:data][:domain]
end

def test_respects_domain_authorization_code
headers = @auth_headers
headers['Auth-Code'] = 'jhfgifhdg'
Expand Down
32 changes: 32 additions & 0 deletions test/integration/repp/v1/domains/transfer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,38 @@ def test_transfers_domain
assert @domain.registrar = @user.registrar
end

def test_transfers_domain_with_uppercase_name
payload = {
"data": {
"domain_transfers": [
{ "domain_name": @domain.name.upcase, "transfer_code": @domain.transfer_code }
]
}
}
post "/repp/v1/domains/transfer", headers: @auth_headers, params: payload
json = JSON.parse(response.body, symbolize_names: true)

assert_response :ok
assert_equal 1000, json[:code]
assert_equal @domain.name, json[:data][:success][0][:domain_name]

@domain.reload

assert_equal @user.registrar, @domain.registrar
end

def test_transfers_scoped_domain_with_uppercase_name
refute @domain.registrar == @user.registrar
payload = { transfer: { transfer_code: @domain.transfer_code } }
post "/repp/v1/domains/#{@domain.name.upcase}/transfer", headers: @auth_headers, params: payload
json = JSON.parse(response.body, symbolize_names: true)
@domain.reload

assert_response :ok
assert_equal 1000, json[:code]
assert_equal @user.registrar, @domain.registrar
end

def test_does_not_transfer_domain_if_not_transferable
@domain.schedule_force_delete(type: :fast_track)

Expand Down
25 changes: 25 additions & 0 deletions test/models/domain_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,31 @@ def test_normalizes_name
assert_equal unnormalized_name, domain.name_dirty
end

def test_find_repp_by_name_normalizes_uppercase_and_whitespace
domain = domains(:shop)

assert_equal domain, Domain.find_repp_by_name('SHOP.TEST')
assert_equal domain, Domain.find_repp_by_name(' shop.test ')
end

def test_find_repp_by_name_finds_by_punycode
domain = domains(:shop)
domain.update!(name_puny: 'xn--prototp-s2aa.ee')

assert_equal domain, Domain.find_repp_by_name('XN--PROTOTP-S2AA.EE')
end

def test_find_repp_by_name_scopes_by_registrar
domain = domains(:shop)

assert_equal domain, Domain.find_repp_by_name('SHOP.TEST', registrar: domain.registrar)
assert_nil Domain.find_repp_by_name('SHOP.TEST', registrar: registrars(:goodnames))
end

def test_find_repp_by_name_returns_nil_when_missing
assert_nil Domain.find_repp_by_name('missing.test')
end

def test_converts_name_to_punycode
domain = Domain.new(name: 'münchen.test')
assert_equal 'xn--mnchen-3ya.test', domain.name_puny
Expand Down