Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REPP: Domain management #1774

Merged
merged 91 commits into from
Mar 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
7459d7e
Nameserver deserializer
karlerikounapuu Nov 25, 2020
b683fe8
Implement partial domain deserializer
karlerikounapuu Nov 30, 2020
ccef105
Create DomainCreate action
karlerikounapuu Dec 8, 2020
ad2ccdb
Improve DomainCreate wrapper for EPP
karlerikounapuu Dec 8, 2020
2c8a4d3
Fix some styling issues
karlerikounapuu Dec 8, 2020
e81653a
Create deserializer for EPP DomainUpdate
karlerikounapuu Dec 9, 2020
096289a
Implement partial DomainUpdate action
karlerikounapuu Dec 9, 2020
766d843
Improve DomainUpdate logic
karlerikounapuu Dec 15, 2020
33b8f03
Fix DNSSEC modifitcations in DomainUpdate
karlerikounapuu Dec 17, 2020
b44ce9f
Port domain registrant confirmation post logic to DomainUpdate action
karlerikounapuu Dec 17, 2020
1fca6d9
Fix domain update confirm tests
karlerikounapuu Dec 18, 2020
221e4ba
Merge remote-tracking branch 'origin/master' into repp-domains
karlerikounapuu Dec 29, 2020
7caa544
Fix some CC issues
karlerikounapuu Dec 29, 2020
50bf708
Use central method for appending legaldocs to domains/contacts
karlerikounapuu Dec 29, 2020
d53622e
Merge remote-tracking branch 'origin/master' into repp-domains
karlerikounapuu Jan 6, 2021
c23075f
Fix some CC issues
karlerikounapuu Jan 6, 2021
c58b4fb
Hash: select entries by keys
karlerikounapuu Jan 7, 2021
e2ff5d4
REPP: Add Domain Create endpoint
karlerikounapuu Jan 11, 2021
70759cb
Merge remote-tracking branch 'origin/master' into repp-domains
karlerikounapuu Jan 11, 2021
d4b84a5
Fix disclosable scope when copying registrant to admin/tech
karlerikounapuu Jan 11, 2021
fcb97df
REPP: Fix domain create success response
karlerikounapuu Jan 11, 2021
2b3634b
REPP domains: Nameserver actions
karlerikounapuu Jan 18, 2021
9dcd40e
REPP domains: Modify DNSSEC keys
karlerikounapuu Jan 18, 2021
fda58e9
REPP Domains: Allow create/read/update for domain-scoped contacts
karlerikounapuu Jan 18, 2021
454433c
REPP: Update ApiDoc
karlerikounapuu Jan 21, 2021
dcb55a1
Create domain renew action
karlerikounapuu Jan 21, 2021
349df32
Improve renew action
karlerikounapuu Jan 21, 2021
f26dd52
EPP Renew: Use action instead
karlerikounapuu Jan 22, 2021
1d9850f
Fix REPP log locale issue
karlerikounapuu Jan 22, 2021
06088e3
REPP: Specific domain transfer action
karlerikounapuu Jan 22, 2021
99a1f1f
REPP: Read/Ack poll messages
karlerikounapuu Jan 22, 2021
cdf2866
REPP: Domain Delete endpoint, port EPP Delete to Actions
karlerikounapuu Jan 26, 2021
9a78271
REPP: Create domain serializer
karlerikounapuu Jan 26, 2021
988af6c
Fix domain renew porting to actions
karlerikounapuu Jan 27, 2021
57df268
REPP: Create domain statuses endpoints
karlerikounapuu Jan 27, 2021
e55fc83
REPP: Serialize domains
karlerikounapuu Jan 27, 2021
2ca9697
Remove redundant methods
karlerikounapuu Jan 27, 2021
d1cd086
Fix some CC issues
karlerikounapuu Jan 27, 2021
8c01385
REPP: Combine create/delete actions for domain contact add
karlerikounapuu Jan 27, 2021
0d2cb6b
REPP: Combine create/delete actions for DNSSEC keys
karlerikounapuu Jan 28, 2021
7c35083
Fix some CC issues
karlerikounapuu Jan 28, 2021
dd8d4c1
Fix CC issues
karlerikounapuu Jan 28, 2021
43e5b74
Merge remote-tracking branch 'origin/master' into repp-domains
karlerikounapuu Jan 28, 2021
c5e2ebe
Fix BL after master emrge
karlerikounapuu Jan 29, 2021
bad0630
REPP: Test domain status editing
karlerikounapuu Feb 1, 2021
4c7f970
REPP: Test domain nameserver actions
karlerikounapuu Feb 1, 2021
b3cf665
REPP: Domain contacts test
karlerikounapuu Feb 1, 2021
d838e56
REPP: Domain renew tests
karlerikounapuu Feb 1, 2021
8bb70fb
REPP: Domain DNSSEC key manipulation tests
karlerikounapuu Feb 1, 2021
f46f4aa
REPP: Registrar Poll notifications test
karlerikounapuu Feb 1, 2021
6a8eaaf
REPP: Scoped domain transfer test
karlerikounapuu Feb 1, 2021
095da29
REPP: Domain create test
karlerikounapuu Feb 1, 2021
92db43d
REPP: Domain list test
karlerikounapuu Feb 2, 2021
1461d2a
REPP: Domain registrant change test
karlerikounapuu Feb 2, 2021
24c3962
REPP: Domain delete test
karlerikounapuu Feb 2, 2021
9305602
Merge remote-tracking branch 'origin/master' into repp-domains
karlerikounapuu Feb 2, 2021
312f199
REPP: Forward Registrar ID for domain update action
karlerikounapuu Feb 5, 2021
d1bb6fc
REPP: Fix domain renew
karlerikounapuu Feb 5, 2021
bf4fa21
REPP: Fix domain renew
karlerikounapuu Feb 5, 2021
5db3b04
Fix some CC issues
karlerikounapuu Feb 8, 2021
2dff215
Merge branch 'repp-domains' of https://github.com/internetee/registry…
karlerikounapuu Feb 8, 2021
115cefc
Fix some CC issues
karlerikounapuu Feb 8, 2021
d7f01f2
Move actions to own namespace
karlerikounapuu Feb 8, 2021
fdef27c
Mode all the actions to Interactions folder
yulgolem Feb 8, 2021
42adaa7
Merge remote-tracking branch 'origin/master' into repp-domains
karlerikounapuu Feb 11, 2021
aedfeac
Attempt to fix renew issues
karlerikounapuu Feb 11, 2021
9d57f34
Reject registrant change if serverRegistrantUpdateProhibited
karlerikounapuu Feb 11, 2021
a03ac4f
Fix CC issues
karlerikounapuu Feb 11, 2021
44226aa
Fix domain renew erros
karlerikounapuu Feb 11, 2021
5693d0d
Tech replace: Skip if domain has update prohibited
karlerikounapuu Feb 11, 2021
6045cd4
Fix domain delete functionality
karlerikounapuu Feb 12, 2021
52d5752
Merge remote-tracking branch 'origin/master' into repp-domains
karlerikounapuu Feb 12, 2021
4ed4e36
added test when ipv4 and ipv6 isnt in array for bulk nameservers changed
Feb 15, 2021
cff2b0c
added test for bulk changes nameservers if there are array of domains
Feb 15, 2021
d77623c
added test for domain tech change prohibited
Feb 15, 2021
50d1838
added test for renew specif domains if domain renew before expire has…
Feb 15, 2021
48b8dfd
Merge remote-tracking branch 'origin/master' into repp-domains
karlerikounapuu Feb 15, 2021
c1763f8
Merge branch 'repp-domains' of https://github.com/internetee/registry…
karlerikounapuu Feb 15, 2021
dc68f69
Bulk NS change: Verify data type in JSON
karlerikounapuu Feb 15, 2021
f2e58d5
Make domains array optional
karlerikounapuu Feb 15, 2021
e71ea05
REPP: Fix response code for paramInvalid
karlerikounapuu Feb 15, 2021
082d287
Fix bulk NS change IP validation
karlerikounapuu Feb 18, 2021
e2f377f
Merge remote-tracking branch 'origin/master' into repp-domains
karlerikounapuu Mar 22, 2021
83bfc49
Rename admin_domain_contacts_attributes to admin_contacts
karlerikounapuu Mar 22, 2021
d6b2664
REPP: Ditch _id from registrant / registrar attributes
karlerikounapuu Mar 22, 2021
6e624a7
FIX code styling
karlerikounapuu Mar 22, 2021
117b682
Rename auth_info / authorization_code to transfer_code
karlerikounapuu Mar 22, 2021
2a3040f
REPP: Get all nameservers for domain
karlerikounapuu Mar 22, 2021
265e135
REPP: Remove fax from contact object
karlerikounapuu Mar 23, 2021
016c5e8
REPP: Domain info for not-sponsoring registrars
karlerikounapuu Mar 23, 2021
546330b
REPP: Add renew exp_date sanity check
karlerikounapuu Mar 23, 2021
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
4 changes: 4 additions & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ plugins:
duplication:
enabled: true
config:
count_threshold: 3
languages:
ruby:
mass_threshold: 100
Expand All @@ -38,6 +39,9 @@ checks:
method-lines:
config:
threshold: 40
method-count:
config:
threshold: 25
exclude_patterns:
- "app/models/version/"
- "bin/"
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ source 'https://rubygems.org'

# core
gem 'active_interaction', '~> 3.8'
gem 'apipie-rails', '~> 0.5.18'
gem 'bootsnap', '>= 1.1.0', require: false
gem 'iso8601', '0.12.1' # for dates and times
gem 'rails', '~> 6.0'
Expand Down Expand Up @@ -78,7 +79,6 @@ gem 'wkhtmltopdf-binary', '~> 0.12.5.1'

gem 'directo', github: 'internetee/directo', branch: 'master'


group :development, :test do
gem 'pry', '0.10.1'
gem 'puma'
Expand Down
6 changes: 5 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ GEM
akami (1.3.1)
gyoku (>= 0.4.0)
nokogiri
apipie-rails (0.5.18)
rails (>= 4.1)
attr_required (1.0.1)
autoprefixer-rails (10.0.0.2)
execjs
Expand Down Expand Up @@ -492,11 +494,13 @@ GEM

PLATFORMS
ruby
x86_64-linux

DEPENDENCIES
active_interaction (~> 3.8)
activerecord-import
airbrake
apipie-rails (~> 0.5.18)
aws-sdk-sesv2 (~> 1.16)
bootsnap (>= 1.1.0)
bootstrap-sass (~> 3.4)
Expand Down Expand Up @@ -555,4 +559,4 @@ DEPENDENCIES
wkhtmltopdf-binary (~> 0.12.5.1)

BUNDLED WITH
2.1.4
2.2.2
151 changes: 30 additions & 121 deletions app/controllers/epp/domains_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'deserializers/xml/domain_delete'
module Epp
class DomainsController < BaseController
before_action :find_domain, only: %i[info renew update transfer delete]
Expand Down Expand Up @@ -26,104 +27,39 @@ def info
end

def create
authorize! :create, Epp::Domain
authorize!(:create, Epp::Domain)

if Domain.release_to_auction
request_domain_name = params[:parsed_frame].css('name').text.strip.downcase
domain_name = DNS::DomainName.new(SimpleIDN.to_unicode(request_domain_name))
registrar_id = current_user.registrar.id
@domain = Epp::Domain.new
data = ::Deserializers::Xml::DomainCreate.new(params[:parsed_frame], registrar_id).call
action = Actions::DomainCreate.new(@domain, data)

if domain_name.at_auction?
epp_errors << {
code: '2306',
msg: 'Parameter value policy error: domain is at auction',
}
handle_errors
return
elsif domain_name.awaiting_payment?
epp_errors << {
code: '2003',
msg: 'Required parameter missing; reserved>pw element required for reserved domains',
}
handle_errors
return
elsif domain_name.pending_registration?
registration_code = params[:parsed_frame].css('reserved > pw').text

if registration_code.empty?
epp_errors << {
code: '2003',
msg: 'Required parameter missing; reserved>pw element is required',
}
handle_errors
return
end

unless domain_name.available_with_code?(registration_code)
epp_errors << {
code: '2202',
msg: 'Invalid authorization information; invalid reserved>pw value',
}
handle_errors
return
end
end
end

@domain = Epp::Domain.new_from_epp(params[:parsed_frame], current_user)
handle_errors(@domain) and return if @domain.errors.any?
@domain.valid?
@domain.errors.delete(:name_dirty) if @domain.errors[:puny_label].any?
handle_errors(@domain) and return if @domain.errors.any?
handle_errors and return unless balance_ok?('create') # loads pricelist in this method

ActiveRecord::Base.transaction do
@domain.add_legal_file_to_new(params[:parsed_frame])

if @domain.save # TODO: Maybe use validate: false here because we have already validated the domain?
current_user.registrar.debit!({
sum: @domain_pricelist.price.amount,
description: "#{I18n.t('create')} #{@domain.name}",
activity_type: AccountActivity::CREATE,
price: @domain_pricelist
})

if Domain.release_to_auction && domain_name.pending_registration?
active_auction = Auction.find_by(domain: domain_name.to_s,
status: Auction.statuses[:payment_received])
active_auction.domain_registered!
end
Dispute.close_by_domain(@domain.name)
render_epp_response '/epp/domains/create'
else
handle_errors(@domain)
end
end
action.call ? render_epp_response('/epp/domains/create') : handle_errors(@domain)
end

def update
authorize! :update, @domain, @password
authorize!(:update, @domain, @password)

updated = @domain.update(params[:parsed_frame], current_user)
(handle_errors(@domain) && return) unless updated
registrar_id = current_user.registrar.id
update_params = ::Deserializers::Xml::DomainUpdate.new(params[:parsed_frame],
registrar_id).call
action = Actions::DomainUpdate.new(@domain, update_params, false)
(handle_errors(@domain) and return) unless action.call

pending = @domain.epp_pending_update.present?
render_epp_response "/epp/domains/success#{'_pending' if pending}"
render_epp_response("/epp/domains/success#{'_pending' if pending}")
end

def delete
authorize! :delete, @domain, @password
authorize!(:delete, @domain, @password)
frame = params[:parsed_frame]
delete_params = ::Deserializers::Xml::DomainDelete.new(frame).call
action = Actions::DomainDelete.new(@domain, delete_params, current_user.registrar)

(handle_errors(@domain) && return) unless @domain.can_be_deleted?
(handle_errors(@domain) and return) unless action.call

if @domain.epp_destroy(params[:parsed_frame], current_user.id)
if @domain.epp_pending_delete.present?
render_epp_response '/epp/domains/success_pending'
else
render_epp_response '/epp/domains/success'
end
else
handle_errors(@domain)
end
pending = @domain.epp_pending_delete.present?
render_epp_response("/epp/domains/success#{'_pending' if pending}")
end

def check
Expand All @@ -137,42 +73,15 @@ def check
def renew
authorize! :renew, @domain

period_element = params[:parsed_frame].css('period').text
period = (period_element.to_i == 0) ? 1 : period_element.to_i
period_unit = Epp::Domain.parse_period_unit_from_frame(params[:parsed_frame]) || 'y'

balance_ok?('renew', period, period_unit) # loading pricelist

begin
ActiveRecord::Base.transaction(isolation: :serializable) do
@domain.reload

success = @domain.renew(
params[:parsed_frame].css('curExpDate').text,
period, period_unit
)

if success
unless balance_ok?('renew', period, period_unit)
handle_errors
fail ActiveRecord::Rollback
end

current_user.registrar.debit!({
sum: @domain_pricelist.price.amount,
description: "#{I18n.t('renew')} #{@domain.name}",
activity_type: AccountActivity::RENEW,
price: @domain_pricelist
})

render_epp_response '/epp/domains/renew'
else
handle_errors(@domain)
end
end
rescue ActiveRecord::StatementInvalid => e
sleep rand / 100
retry
registrar_id = current_user.registrar.id
renew_params = ::Deserializers::Xml::Domain.new(params[:parsed_frame],
registrar_id).call

action = Actions::DomainRenew.new(@domain, renew_params, current_user.registrar)
if action.call
render_epp_response '/epp/domains/renew'
else
handle_errors(@domain)
end
end

Expand Down
2 changes: 2 additions & 0 deletions app/controllers/repp/v1/accounts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module Repp
module V1
class AccountsController < BaseController
api :GET, '/repp/v1/accounts/balance'
desc "Get account's balance"
def balance
resp = { balance: current_user.registrar.cash_account.balance,
currency: current_user.registrar.cash_account.currency }
Expand Down
17 changes: 15 additions & 2 deletions app/controllers/repp/v1/base_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Repp
module V1
class BaseController < ActionController::API
class BaseController < ActionController::API # rubocop:disable Metrics/ClassLength
around_action :log_request
before_action :authenticate_user
before_action :validate_webclient_ca
Expand All @@ -16,9 +16,12 @@ def log_request
rescue ActiveRecord::RecordNotFound
@response = { code: 2303, message: 'Object does not exist' }
render(json: @response, status: :not_found)
rescue ActionController::ParameterMissing => e
rescue ActionController::ParameterMissing, Apipie::ParamMissing => e
@response = { code: 2003, message: e }
render(json: @response, status: :bad_request)
rescue Apipie::ParamInvalid => e
@response = { code: 2005, message: e }
render(json: @response, status: :bad_request)
ensure
create_repp_log
end
Expand All @@ -35,6 +38,16 @@ def create_repp_log
end
# rubocop:enable Metrics/AbcSize

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
end

def set_paper_trail_whodunnit
::PaperTrail.request.whodunnit = current_user
end
Expand Down
19 changes: 13 additions & 6 deletions app/controllers/repp/v1/contacts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
require 'serializers/repp/contact'
module Repp
module V1
class ContactsController < BaseController
class ContactsController < BaseController # rubocop:disable Metrics/ClassLength
before_action :find_contact, only: %i[show update destroy]

## GET /repp/v1/contacts
api :get, '/repp/v1/contacts'
desc 'Get all existing contacts'
def index
record_count = current_user.registrar.contacts.count
contacts = showable_contacts(params[:details], params[:limit] || 200,
Expand All @@ -13,22 +14,25 @@ def index
render(json: @response, status: :ok)
end

## GET /repp/v1/contacts/1
api :get, '/repp/v1/contacts/:contact_code'
desc 'Get a specific contact'
def show
serializer = ::Serializers::Repp::Contact.new(@contact,
show_address: Contact.address_processing?)
render_success(data: serializer.to_json)
end

## GET /repp/v1/contacts/check/1
api :get, '/repp/v1/contacts/check/:contact_code'
desc 'Check contact code availability'
def check
contact = Epp::Contact.find_by(code: params[:id])
data = { contact: { id: params[:id], available: contact.nil? } }

render_success(data: data)
end

## POST /repp/v1/contacts
api :POST, '/repp/v1/contacts'
desc 'Create a new contact'
def create
@contact = Epp::Contact.new(contact_params_with_address, current_user.registrar, epp: false)
action = Actions::ContactCreate.new(@contact, params[:legal_document],
Expand All @@ -42,7 +46,8 @@ def create
render_success(create_update_success_body)
end

## PUT /repp/v1/contacts/1
api :PUT, '/repp/v1/contacts/:contact_code'
desc 'Update existing contact'
def update
action = Actions::ContactUpdate.new(@contact, contact_params_with_address(required: false),
params[:legal_document],
Expand All @@ -56,6 +61,8 @@ def update
render_success(create_update_success_body)
end

api :DELETE, '/repp/v1/contacts/:contact_code'
desc 'Delete a specific contact'
def destroy
action = Actions::ContactDelete.new(@contact, params[:legal_document])
unless action.call
Expand Down
Loading