mirror of
https://github.com/internetee/registry.git
synced 2025-07-28 05:26:17 +02:00
Updated REPP API for new registrar portal
This commit is contained in:
parent
e17b21436d
commit
a5ffce290d
61 changed files with 1269 additions and 408 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,6 +5,7 @@
|
||||||
/coverage/
|
/coverage/
|
||||||
/.bundle
|
/.bundle
|
||||||
/vendor/bundle
|
/vendor/bundle
|
||||||
|
/vendor/gems
|
||||||
/config/database.yml
|
/config/database.yml
|
||||||
/config/application.yml
|
/config/application.yml
|
||||||
/config/environments/development.rb
|
/config/environments/development.rb
|
||||||
|
|
|
@ -3,6 +3,7 @@ FROM internetee/ruby:3.0-buster
|
||||||
RUN mkdir -p /opt/webapps/app/tmp/pids
|
RUN mkdir -p /opt/webapps/app/tmp/pids
|
||||||
WORKDIR /opt/webapps/app
|
WORKDIR /opt/webapps/app
|
||||||
COPY Gemfile Gemfile.lock ./
|
COPY Gemfile Gemfile.lock ./
|
||||||
|
# ADD vendor/gems/omniauth-tara ./vendor/gems/omniauth-tara
|
||||||
RUN gem install bundler && bundle install --jobs 20 --retry 5
|
RUN gem install bundler && bundle install --jobs 20 --retry 5
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
4
Gemfile
4
Gemfile
|
@ -57,10 +57,9 @@ gem 'digidoc_client',
|
||||||
ref: '1645e83a5a548addce383f75703b0275c5310c32'
|
ref: '1645e83a5a548addce383f75703b0275c5310c32'
|
||||||
|
|
||||||
# TARA
|
# TARA
|
||||||
gem 'omniauth'
|
|
||||||
gem 'omniauth-rails_csrf_protection'
|
gem 'omniauth-rails_csrf_protection'
|
||||||
gem 'omniauth-tara', github: 'internetee/omniauth-tara'
|
gem 'omniauth-tara', github: 'internetee/omniauth-tara'
|
||||||
|
# gem 'omniauth-tara', path: 'vendor/gems/omniauth-tara'
|
||||||
|
|
||||||
gem 'airbrake'
|
gem 'airbrake'
|
||||||
gem 'daemons-rails', '1.2.1'
|
gem 'daemons-rails', '1.2.1'
|
||||||
|
@ -81,6 +80,7 @@ gem 'lhv', github: 'internetee/lhv', branch: 'master'
|
||||||
gem 'rexml'
|
gem 'rexml'
|
||||||
gem 'wkhtmltopdf-binary', '~> 0.12.5.1'
|
gem 'wkhtmltopdf-binary', '~> 0.12.5.1'
|
||||||
|
|
||||||
|
|
||||||
gem 'directo', github: 'internetee/directo', branch: 'master'
|
gem 'directo', github: 'internetee/directo', branch: 'master'
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
|
|
|
@ -338,7 +338,7 @@ GEM
|
||||||
omniauth-rails_csrf_protection (0.1.2)
|
omniauth-rails_csrf_protection (0.1.2)
|
||||||
actionpack (>= 4.2)
|
actionpack (>= 4.2)
|
||||||
omniauth (>= 1.3.1)
|
omniauth (>= 1.3.1)
|
||||||
openid_connect (1.2.0)
|
openid_connect (1.3.0)
|
||||||
activemodel
|
activemodel
|
||||||
attr_required (>= 1.0.0)
|
attr_required (>= 1.0.0)
|
||||||
json-jwt (>= 1.5.0)
|
json-jwt (>= 1.5.0)
|
||||||
|
@ -477,7 +477,7 @@ GEM
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
spy (1.0.1)
|
spy (1.0.1)
|
||||||
swd (1.2.0)
|
swd (1.3.0)
|
||||||
activesupport (>= 3)
|
activesupport (>= 3)
|
||||||
attr_required (>= 0.0.5)
|
attr_required (>= 0.0.5)
|
||||||
httpclient (>= 2.4)
|
httpclient (>= 2.4)
|
||||||
|
@ -496,7 +496,7 @@ GEM
|
||||||
validate_email (0.1.6)
|
validate_email (0.1.6)
|
||||||
activemodel (>= 3.0)
|
activemodel (>= 3.0)
|
||||||
mail (>= 2.2.5)
|
mail (>= 2.2.5)
|
||||||
validate_url (1.0.13)
|
validate_url (1.0.15)
|
||||||
activemodel (>= 3.0.0)
|
activemodel (>= 3.0.0)
|
||||||
public_suffix
|
public_suffix
|
||||||
validates_email_format_of (1.6.3)
|
validates_email_format_of (1.6.3)
|
||||||
|
@ -511,7 +511,7 @@ GEM
|
||||||
nokogiri (~> 1.6)
|
nokogiri (~> 1.6)
|
||||||
rubyzip (>= 1.3.0)
|
rubyzip (>= 1.3.0)
|
||||||
selenium-webdriver (>= 3.0, < 4.0)
|
selenium-webdriver (>= 3.0, < 4.0)
|
||||||
webfinger (1.1.0)
|
webfinger (1.2.0)
|
||||||
activesupport
|
activesupport
|
||||||
httpclient (>= 2.4)
|
httpclient (>= 2.4)
|
||||||
webmock (3.14.0)
|
webmock (3.14.0)
|
||||||
|
@ -572,7 +572,6 @@ DEPENDENCIES
|
||||||
newrelic-infinite_tracing
|
newrelic-infinite_tracing
|
||||||
newrelic_rpm
|
newrelic_rpm
|
||||||
nokogiri (~> 1.13.0)
|
nokogiri (~> 1.13.0)
|
||||||
omniauth
|
|
||||||
omniauth-rails_csrf_protection
|
omniauth-rails_csrf_protection
|
||||||
omniauth-tara!
|
omniauth-tara!
|
||||||
paper_trail (~> 12.1)
|
paper_trail (~> 12.1)
|
||||||
|
|
149
app/controllers/repp/v1/account_controller.rb
Normal file
149
app/controllers/repp/v1/account_controller.rb
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
module Repp
|
||||||
|
module V1
|
||||||
|
class AccountController < BaseController
|
||||||
|
load_and_authorize_resource
|
||||||
|
|
||||||
|
api :get, '/repp/v1/account'
|
||||||
|
desc 'Get all activities'
|
||||||
|
def index
|
||||||
|
records = current_user.registrar.cash_account.activities
|
||||||
|
|
||||||
|
q = records.ransack(search_params)
|
||||||
|
q.sorts = 'created_at desc' if q.sorts.empty?
|
||||||
|
activities = q.result(distinct: true)
|
||||||
|
|
||||||
|
limited_activities = activities.limit(limit).offset(offset)
|
||||||
|
.includes(:invoice)
|
||||||
|
|
||||||
|
render_success(data: { activities: serialized_activities(limited_activities),
|
||||||
|
count: activities.count,
|
||||||
|
types_for_select: AccountActivity.types_for_select })
|
||||||
|
end
|
||||||
|
|
||||||
|
api :get, '/repp/v1/account/details'
|
||||||
|
desc 'Get current registrar account details'
|
||||||
|
def details
|
||||||
|
registrar = current_user.registrar
|
||||||
|
type = registrar.settings['balance_auto_reload']&.dig('type')
|
||||||
|
resp = { account: { billing_email: registrar.billing_email,
|
||||||
|
iban: registrar.iban,
|
||||||
|
iban_max_length: Iban.max_length,
|
||||||
|
linked_users: serialized_users(current_user.linked_users),
|
||||||
|
balance_auto_reload: type,
|
||||||
|
min_deposit: Setting.minimum_deposit } }
|
||||||
|
render_success(data: resp)
|
||||||
|
end
|
||||||
|
|
||||||
|
api :put, '/repp/v1/account'
|
||||||
|
desc 'Update current registrar account details'
|
||||||
|
def update
|
||||||
|
registrar = current_user.registrar
|
||||||
|
unless registrar.update(account_params)
|
||||||
|
handle_non_epp_errors(registrar)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
render_success(data: { account: account_params },
|
||||||
|
message: I18n.t('registrar.account.update.saved'))
|
||||||
|
end
|
||||||
|
|
||||||
|
api :post, '/repp/v1/account/update_auto_reload_balance'
|
||||||
|
desc 'Enable current registrar balance auto reload'
|
||||||
|
def update_auto_reload_balance
|
||||||
|
type = BalanceAutoReloadTypes::Threshold.new(type_params)
|
||||||
|
unless type.valid?
|
||||||
|
handle_non_epp_errors(type)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
settings = { balance_auto_reload: { type: type.as_json } }
|
||||||
|
current_user.registrar.update!(settings: settings)
|
||||||
|
render_success(data: { settings: settings },
|
||||||
|
message: I18n.t('registrar.settings.balance_auto_reload.update.saved'))
|
||||||
|
end
|
||||||
|
|
||||||
|
api :get, '/repp/v1/account/disable_auto_reload_balance'
|
||||||
|
desc 'Disable current registrar balance auto reload'
|
||||||
|
def disable_auto_reload_balance
|
||||||
|
registrar = current_user.registrar
|
||||||
|
registrar.settings.delete('balance_auto_reload')
|
||||||
|
registrar.save!
|
||||||
|
|
||||||
|
render_success(data: { settings: registrar.settings },
|
||||||
|
message: I18n.t('registrar.settings.balance_auto_reload.destroy.disabled'))
|
||||||
|
end
|
||||||
|
|
||||||
|
api :get, '/repp/v1/account/balance'
|
||||||
|
desc "Get account's balance"
|
||||||
|
def balance
|
||||||
|
resp = { balance: current_user.registrar.cash_account.balance,
|
||||||
|
currency: current_user.registrar.cash_account.currency }
|
||||||
|
if params[:detailed] == 'true'
|
||||||
|
activities = current_user.registrar.cash_account.activities.order(created_at: :desc)
|
||||||
|
activities = activities.where('created_at >= ?', params[:from]) if params[:from]
|
||||||
|
activities = activities.where('created_at <= ?', params[:until]) if params[:until]
|
||||||
|
resp[:transactions] = serialized_activities(activities)
|
||||||
|
end
|
||||||
|
render_success(data: resp)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def account_params
|
||||||
|
params.require(:account).permit(:billing_email, :iban)
|
||||||
|
end
|
||||||
|
|
||||||
|
def index_params
|
||||||
|
params.permit(:id, :limit, :offset, :q,
|
||||||
|
:page, :per_page,
|
||||||
|
q: [:description_matches, :created_at_gteq,
|
||||||
|
:created_at_lteq, :s, { s: [] }, { activity_type_in: [] }])
|
||||||
|
end
|
||||||
|
|
||||||
|
def type_params
|
||||||
|
permitted_params = params.require(:type).permit(:amount, :threshold)
|
||||||
|
normalize_params(permitted_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def normalize_params(params)
|
||||||
|
params[:amount] = params[:amount].to_f
|
||||||
|
params[:threshold] = params[:threshold].to_f
|
||||||
|
params
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_params
|
||||||
|
index_params.fetch(:q, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
def limit
|
||||||
|
index_params[:limit] || 200
|
||||||
|
end
|
||||||
|
|
||||||
|
def offset
|
||||||
|
index_params[:offset] || 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialized_users(users)
|
||||||
|
arr = []
|
||||||
|
users.each do |u|
|
||||||
|
arr << { id: u.id, username: u.username,
|
||||||
|
role: u.roles.first }
|
||||||
|
end
|
||||||
|
|
||||||
|
arr
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialized_activities(activities)
|
||||||
|
arr = []
|
||||||
|
activities.each do |a|
|
||||||
|
arr << { created_at: a.created_at, description: a.description,
|
||||||
|
type: a.activity_type == 'add_credit' ? 'credit' : 'debit',
|
||||||
|
sum: a.sum, balance: a.new_balance, currency: a.currency,
|
||||||
|
updator: a.updator_str }
|
||||||
|
end
|
||||||
|
|
||||||
|
arr
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,33 +0,0 @@
|
||||||
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 }
|
|
||||||
resp[:transactions] = activities if params[:detailed] == 'true'
|
|
||||||
render_success(data: resp)
|
|
||||||
end
|
|
||||||
|
|
||||||
def activities
|
|
||||||
arr = []
|
|
||||||
registrar_activities.each do |a|
|
|
||||||
arr << { created_at: a.created_at, description: a.description,
|
|
||||||
type: a.activity_type == 'add_credit' ? 'credit' : 'debit',
|
|
||||||
sum: a.sum, balance: a.new_balance }
|
|
||||||
end
|
|
||||||
|
|
||||||
arr
|
|
||||||
end
|
|
||||||
|
|
||||||
def registrar_activities
|
|
||||||
activities = current_user.registrar.cash_account.activities.order(created_at: :desc)
|
|
||||||
activities = activities.where('created_at >= ?', params[:from]) if params[:from]
|
|
||||||
activities = activities.where('created_at <= ?', params[:until]) if params[:until]
|
|
||||||
|
|
||||||
activities
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,12 +1,12 @@
|
||||||
module Repp
|
module Repp
|
||||||
module V1
|
module V1
|
||||||
class BaseController < ActionController::API # rubocop:disable Metrics/ClassLength
|
class BaseController < ActionController::API # rubocop:disable Metrics/ClassLength
|
||||||
|
attr_reader :current_user
|
||||||
|
|
||||||
around_action :log_request
|
around_action :log_request
|
||||||
before_action :authenticate_user
|
before_action :authenticate_user
|
||||||
before_action :validate_webclient_ca
|
before_action :validate_webclient_ca
|
||||||
before_action :check_ip_restriction
|
before_action :check_ip_restriction
|
||||||
attr_reader :current_user
|
|
||||||
|
|
||||||
before_action :set_paper_trail_whodunnit
|
before_action :set_paper_trail_whodunnit
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -22,6 +22,10 @@ module Repp
|
||||||
rescue Apipie::ParamInvalid => e
|
rescue Apipie::ParamInvalid => e
|
||||||
@response = { code: 2005, message: e.message.gsub(/\n/, '. ') }
|
@response = { code: 2005, message: e.message.gsub(/\n/, '. ') }
|
||||||
render(json: @response, status: :bad_request)
|
render(json: @response, status: :bad_request)
|
||||||
|
rescue CanCan::AccessDenied => e
|
||||||
|
@response = { code: 2201, message: 'Authorization error' }
|
||||||
|
logger.error e.to_s
|
||||||
|
render(json: @response, status: :unauthorized)
|
||||||
ensure
|
ensure
|
||||||
create_repp_log
|
create_repp_log
|
||||||
end
|
end
|
||||||
|
@ -65,7 +69,6 @@ module Repp
|
||||||
|
|
||||||
def handle_errors(obj = nil)
|
def handle_errors(obj = nil)
|
||||||
@epp_errors ||= ActiveModel::Errors.new(self)
|
@epp_errors ||= ActiveModel::Errors.new(self)
|
||||||
|
|
||||||
if obj
|
if obj
|
||||||
obj.construct_epp_errors
|
obj.construct_epp_errors
|
||||||
obj.errors.each { |error| @epp_errors.import error }
|
obj.errors.each { |error| @epp_errors.import error }
|
||||||
|
@ -85,6 +88,12 @@ module Repp
|
||||||
render(json: @response, status: status)
|
render(json: @response, status: status)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_non_epp_errors(obj, message = nil)
|
||||||
|
@response = { message: message || obj.errors.full_messages.join(', '),
|
||||||
|
data: {} }
|
||||||
|
render(json: @response, status: :bad_request)
|
||||||
|
end
|
||||||
|
|
||||||
def basic_token
|
def basic_token
|
||||||
pattern = /^Basic /
|
pattern = /^Basic /
|
||||||
header = request.headers['Authorization']
|
header = request.headers['Authorization']
|
||||||
|
@ -94,7 +103,8 @@ module Repp
|
||||||
|
|
||||||
def authenticate_user
|
def authenticate_user
|
||||||
username, password = Base64.urlsafe_decode64(basic_token).split(':')
|
username, password = Base64.urlsafe_decode64(basic_token).split(':')
|
||||||
@current_user ||= ApiUser.find_by(username: username, plain_text_password: password)
|
@current_user ||= ApiUser.find_by(username: username, plain_text_password: password,
|
||||||
|
active: true)
|
||||||
|
|
||||||
return if @current_user
|
return if @current_user
|
||||||
|
|
||||||
|
@ -123,6 +133,7 @@ module Repp
|
||||||
return unless webclient_request?
|
return unless webclient_request?
|
||||||
|
|
||||||
request_name = request.env['HTTP_SSL_CLIENT_S_DN_CN']
|
request_name = request.env['HTTP_SSL_CLIENT_S_DN_CN']
|
||||||
|
|
||||||
webclient_cn = ENV['webclient_cert_common_name'] || 'webclient'
|
webclient_cn = ENV['webclient_cert_common_name'] || 'webclient'
|
||||||
return if request_name == webclient_cn
|
return if request_name == webclient_cn
|
||||||
|
|
||||||
|
@ -135,6 +146,16 @@ module Repp
|
||||||
def logger
|
def logger
|
||||||
Rails.logger
|
Rails.logger
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def auth_values_to_data(registrar:)
|
||||||
|
data = current_user.as_json(only: %i[id username roles])
|
||||||
|
data[:registrar_name] = registrar.name
|
||||||
|
data[:legaldoc_mandatory] = registrar.legaldoc_mandatory?
|
||||||
|
data[:balance] = { amount: registrar.cash_account&.balance,
|
||||||
|
currency: registrar.cash_account&.currency }
|
||||||
|
data[:abilities] = Ability.new(current_user).permissions
|
||||||
|
data
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,23 +3,61 @@ module Repp
|
||||||
module V1
|
module V1
|
||||||
class ContactsController < BaseController # rubocop:disable Metrics/ClassLength
|
class ContactsController < BaseController # rubocop:disable Metrics/ClassLength
|
||||||
before_action :find_contact, only: %i[show update destroy]
|
before_action :find_contact, only: %i[show update destroy]
|
||||||
|
skip_around_action :log_request, only: :search
|
||||||
|
|
||||||
api :get, '/repp/v1/contacts'
|
api :get, '/repp/v1/contacts'
|
||||||
desc 'Get all existing contacts'
|
desc 'Get all existing contacts'
|
||||||
def index
|
def index
|
||||||
record_count = current_user.registrar.contacts.count
|
authorize! :check, Epp::Contact
|
||||||
contacts = showable_contacts(params[:details], params[:limit] || 200,
|
records = current_user.registrar.contacts.order(created_at: :desc)
|
||||||
params[:offset] || 0)
|
|
||||||
@response = { contacts: contacts, total_number_of_records: record_count }
|
q = records.ransack(search_params)
|
||||||
render(json: @response, status: :ok)
|
q.sorts = 'created_at desc' if q.sorts.empty?
|
||||||
|
contacts = q.result(distinct: true)
|
||||||
|
|
||||||
|
limited_contacts = contacts.limit(limit).offset(offset)
|
||||||
|
.includes(:domain_contacts, :registrant_domains, :registrar)
|
||||||
|
|
||||||
|
render_success(data: { contacts: serialized_contacts(limited_contacts),
|
||||||
|
count: contacts.count,
|
||||||
|
statuses: Contact::STATUSES,
|
||||||
|
ident_types: Contact::Ident.types })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# rubocop:disable Metrics/MethodLength
|
||||||
|
api :get, '/repp/v1/contacts/search(/:id)'
|
||||||
|
desc 'Search all existing contacts by optional id or query param'
|
||||||
|
def search
|
||||||
|
scope = current_user.registrar.contacts
|
||||||
|
if params[:query]
|
||||||
|
escaped_str = ActiveRecord::Base.connection.quote_string params[:query]
|
||||||
|
scope = scope.where("name ilike '%#{escaped_str}%' OR code ilike '%#{escaped_str}%'
|
||||||
|
OR ident ilike '%#{escaped_str}%'")
|
||||||
|
elsif params[:id]
|
||||||
|
scope = scope.where(code: params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
render_success(data: scope.limit(10)
|
||||||
|
.map do |c|
|
||||||
|
{ value: c.code,
|
||||||
|
label: "#{c.code} #{c.name}",
|
||||||
|
selected: scope.size == 1 }
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
# rubocop:enable Metrics/MethodLength
|
||||||
|
|
||||||
api :get, '/repp/v1/contacts/:contact_code'
|
api :get, '/repp/v1/contacts/:contact_code'
|
||||||
desc 'Get a specific contact'
|
desc 'Get a specific contact'
|
||||||
def show
|
def show
|
||||||
serializer = ::Serializers::Repp::Contact.new(@contact,
|
authorize! :check, Epp::Contact
|
||||||
show_address: Contact.address_processing?)
|
|
||||||
render_success(data: serializer.to_json)
|
simple = params[:simple] == 'true' || false
|
||||||
|
serializer = Serializers::Repp::Contact.new(@contact,
|
||||||
|
show_address: Contact.address_processing?,
|
||||||
|
domain_params: domain_filter_params,
|
||||||
|
simplify: simple)
|
||||||
|
|
||||||
|
render_success(data: { contact: serializer.to_json })
|
||||||
end
|
end
|
||||||
|
|
||||||
api :get, '/repp/v1/contacts/check/:contact_code'
|
api :get, '/repp/v1/contacts/check/:contact_code'
|
||||||
|
@ -35,7 +73,7 @@ module Repp
|
||||||
desc 'Create a new contact'
|
desc 'Create a new contact'
|
||||||
def create
|
def create
|
||||||
@contact = Epp::Contact.new(contact_params_with_address, current_user.registrar, epp: false)
|
@contact = Epp::Contact.new(contact_params_with_address, current_user.registrar, epp: false)
|
||||||
action = Actions::ContactCreate.new(@contact, params[:legal_document],
|
action = Actions::ContactCreate.new(@contact, contact_params[:legal_document],
|
||||||
contact_ident_params)
|
contact_ident_params)
|
||||||
|
|
||||||
unless action.call
|
unless action.call
|
||||||
|
@ -50,7 +88,7 @@ module Repp
|
||||||
desc 'Update existing contact'
|
desc 'Update existing contact'
|
||||||
def update
|
def update
|
||||||
action = Actions::ContactUpdate.new(@contact, contact_params_with_address(required: false),
|
action = Actions::ContactUpdate.new(@contact, contact_params_with_address(required: false),
|
||||||
params[:legal_document],
|
contact_params[:legal_document],
|
||||||
contact_ident_params(required: false), current_user)
|
contact_ident_params(required: false), current_user)
|
||||||
|
|
||||||
unless action.call
|
unless action.call
|
||||||
|
@ -73,29 +111,71 @@ module Repp
|
||||||
render_success
|
render_success
|
||||||
end
|
end
|
||||||
|
|
||||||
def contact_addr_present?
|
private
|
||||||
return false unless contact_addr_params.key?(:addr)
|
|
||||||
|
|
||||||
contact_addr_params[:addr].keys.any?
|
def index_params
|
||||||
|
params.permit(:id, :limit, :offset, :details, :q, :simple,
|
||||||
|
:page, :per_page, :domain_filter,
|
||||||
|
domain_filter: [],
|
||||||
|
q: %i[s name_matches code_eq ident_matches ident_type_eq
|
||||||
|
email_matches country_code_eq types_contains_array
|
||||||
|
updated_at_gteq created_at_gteq created_at_lteq
|
||||||
|
statuses_contains_array] + [s: []])
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_params
|
||||||
|
index_params.fetch(:q, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
def domain_filter_params
|
||||||
|
filter_params = index_params.slice(:id, :page, :per_page, :domain_filter).to_h
|
||||||
|
filter_params.merge!({ sort: hashify(index_params[:q].fetch(:s)) }) if index_params[:q]
|
||||||
|
filter_params
|
||||||
|
end
|
||||||
|
|
||||||
|
def hashify(sort)
|
||||||
|
return unless sort
|
||||||
|
|
||||||
|
sort_hash = {}
|
||||||
|
if sort.is_a?(Array)
|
||||||
|
sort.each do |s|
|
||||||
|
sort_hash.merge!(Hash[*s.split(' ')])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
sort_hash.merge!(Hash[*sort.split(' ')])
|
||||||
|
end
|
||||||
|
sort_hash
|
||||||
|
end
|
||||||
|
|
||||||
|
def limit
|
||||||
|
index_params[:limit] || 200
|
||||||
|
end
|
||||||
|
|
||||||
|
def offset
|
||||||
|
index_params[:offset] || 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialized_contacts(contacts)
|
||||||
|
return contacts.map {|c| c.code } unless index_params[:details] == 'true'
|
||||||
|
|
||||||
|
address_processing = Contact.address_processing?
|
||||||
|
contacts.map do |c|
|
||||||
|
Serializers::Repp::Contact.new(c, show_address: address_processing).to_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def contact_addr_present?
|
||||||
|
return false unless contact_addr_params
|
||||||
|
|
||||||
|
contact_addr_params.keys.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_update_success_body
|
def create_update_success_body
|
||||||
{ code: opt_addr? ? 1100 : nil, data: { contact: { id: @contact.code } },
|
{ code: opt_addr? ? 1100 : nil,
|
||||||
|
data: { contact: { code: @contact.code } },
|
||||||
message: opt_addr? ? I18n.t('epp.contacts.completed_without_address') : nil }
|
message: opt_addr? ? I18n.t('epp.contacts.completed_without_address') : nil }
|
||||||
end
|
end
|
||||||
|
|
||||||
def showable_contacts(details, limit, offset)
|
|
||||||
contacts = current_user.registrar.contacts.limit(limit).offset(offset)
|
|
||||||
|
|
||||||
return contacts.pluck(:code) unless details
|
|
||||||
|
|
||||||
contacts.map do |contact|
|
|
||||||
serializer = ::Serializers::Repp::Contact.new(contact,
|
|
||||||
show_address: Contact.address_processing?)
|
|
||||||
serializer.to_json
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def opt_addr?
|
def opt_addr?
|
||||||
!Contact.address_processing? && contact_addr_present?
|
!Contact.address_processing? && contact_addr_present?
|
||||||
end
|
end
|
||||||
|
@ -106,36 +186,36 @@ module Repp
|
||||||
end
|
end
|
||||||
|
|
||||||
def contact_params_with_address(required: true)
|
def contact_params_with_address(required: true)
|
||||||
return contact_create_params(required: required) unless contact_addr_params.key?(:addr)
|
return contact_create_params(required: required) unless contact_addr_present?
|
||||||
|
|
||||||
addr = {}
|
contact_create_params(required: required).merge(contact_addr_params)
|
||||||
contact_addr_params[:addr].each_key { |k| addr[k] = contact_addr_params[:addr][k] }
|
|
||||||
contact_create_params(required: required).merge(addr)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def contact_create_params(required: true)
|
def contact_create_params(required: true)
|
||||||
params.require(:contact).require(%i[name email phone]) if required
|
create_params = %i[name email phone]
|
||||||
params.require(:contact).permit(:name, :email, :phone, :id)
|
contact_params.require(create_params) if required
|
||||||
|
contact_params.slice(*create_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def contact_ident_params(required: true)
|
def contact_ident_params(required: true)
|
||||||
if required
|
ident_params = %i[ident ident_type ident_country_code]
|
||||||
params.require(:contact).require(:ident).require(%i[ident ident_type ident_country_code])
|
contact_params.require(:ident).require(ident_params) if required
|
||||||
params.require(:contact).require(:ident).permit(:ident, :ident_type, :ident_country_code)
|
contact_params[:ident].to_h
|
||||||
else
|
|
||||||
params.permit(contact: { ident: %i[ident ident_type ident_country_code] })
|
|
||||||
end
|
|
||||||
|
|
||||||
params[:contact][:ident]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def contact_addr_params
|
def contact_addr_params
|
||||||
if Contact.address_processing?
|
return contact_params[:addr] unless Contact.address_processing?
|
||||||
params.require(:contact).require(:addr).require(%i[country_code city street zip])
|
|
||||||
params.require(:contact).require(:addr).permit(:country_code, :city, :street, :zip)
|
addr_params = %i[country_code city street zip]
|
||||||
else
|
contact_params.require(:addr).require(addr_params)
|
||||||
params.require(:contact).permit(addr: %i[country_code city street zip])
|
contact_params[:addr]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def contact_params
|
||||||
|
params.require(:contact).permit(:name, :email, :phone, :legal_document,
|
||||||
|
legal_document: %i[body type],
|
||||||
|
ident: [%i[ident ident_type ident_country_code]],
|
||||||
|
addr: [%i[country_code city street zip state]])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,19 +2,16 @@ module Repp
|
||||||
module V1
|
module V1
|
||||||
module Domains
|
module Domains
|
||||||
class BaseContactsController < BaseController
|
class BaseContactsController < BaseController
|
||||||
before_action :set_current_contact, only: [:update]
|
before_action :set_contacts, only: [:update]
|
||||||
before_action :set_new_contact, only: [:update]
|
|
||||||
|
|
||||||
def set_current_contact
|
def set_contacts
|
||||||
@current_contact = current_user.registrar.contacts
|
contacts = current_user.registrar.contacts
|
||||||
.find_by!(code: contact_params[:current_contact_id])
|
@current_contact = contacts.find_by!(code: contact_params[:current_contact_id])
|
||||||
end
|
@new_contact = contacts.find_by!(code: contact_params[:new_contact_id])
|
||||||
|
|
||||||
def set_new_contact
|
|
||||||
@new_contact = current_user.registrar.contacts.find_by!(code: params[:new_contact_id])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
authorize! :manage, :repp
|
||||||
@epp_errors ||= ActiveModel::Errors.new(self)
|
@epp_errors ||= ActiveModel::Errors.new(self)
|
||||||
return unless @new_contact.invalid?
|
return unless @new_contact.invalid?
|
||||||
|
|
||||||
|
@ -26,8 +23,11 @@ module Repp
|
||||||
private
|
private
|
||||||
|
|
||||||
def contact_params
|
def contact_params
|
||||||
params.require(%i[current_contact_id new_contact_id])
|
param_list = %i[current_contact_id new_contact_id]
|
||||||
params.permit(:current_contact_id, :new_contact_id)
|
params.require(param_list)
|
||||||
|
params.permit(:current_contact_id, :new_contact_id,
|
||||||
|
contact: {},
|
||||||
|
admin_contact: [param_list])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,28 +8,29 @@ module Repp
|
||||||
|
|
||||||
api :POST, 'repp/v1/domains/:domain_name/renew'
|
api :POST, 'repp/v1/domains/:domain_name/renew'
|
||||||
desc 'Renew domain'
|
desc 'Renew domain'
|
||||||
param :renew, Hash, required: true, desc: 'Renew parameters' do
|
param :renews, Hash, required: true, desc: 'Renew parameters' do
|
||||||
param :period, Integer, required: true, desc: 'Renew period. Month (m) or year (y)'
|
param :period, Integer, required: true, desc: 'Renew period. Month (m) or year (y)'
|
||||||
param :period_unit, String, required: true, desc: 'For how many months or years to renew'
|
param :period_unit, String, required: true, desc: 'For how many months or years to renew'
|
||||||
param :exp_date, String, required: true, desc: 'Current expiry date for domain'
|
param :exp_date, String, required: true, desc: 'Current expiry date for domain'
|
||||||
end
|
end
|
||||||
def create
|
def create
|
||||||
authorize!(:renew, @domain)
|
authorize!(:renew, @domain)
|
||||||
action = Actions::DomainRenew.new(@domain, renew_params[:renew], current_user.registrar)
|
action = Actions::DomainRenew.new(@domain, renew_params[:renews], current_user.registrar)
|
||||||
|
|
||||||
unless action.call
|
unless action.call
|
||||||
handle_errors(@domain)
|
handle_errors(@domain)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
render_success(data: { domain: { name: @domain.name } })
|
render_success(data: { domain: { name: @domain.name, id: @domain.uuid } })
|
||||||
end
|
end
|
||||||
|
|
||||||
def bulk_renew
|
def bulk_renew
|
||||||
|
authorize! :manage, :repp
|
||||||
renew = run_bulk_renew_task(@domains, bulk_renew_params[:renew_period])
|
renew = run_bulk_renew_task(@domains, bulk_renew_params[:renew_period])
|
||||||
return render_success(data: { updated_domains: @domains.map(&:name) }) if renew.valid?
|
return render_success(data: { updated_domains: @domains.map(&:name) }) if renew.valid?
|
||||||
|
|
||||||
msg = renew.errors.keys.map { |k, _v| renew.errors[k] }.join(', ')
|
msg = renew.errors.attribute_names.map { |k, _v| renew.errors[k] }.join(', ')
|
||||||
@epp_errors.add(:epp_errors, msg: msg, code: '2002')
|
@epp_errors.add(:epp_errors, msg: msg, code: '2002')
|
||||||
handle_errors
|
handle_errors
|
||||||
end
|
end
|
||||||
|
@ -37,7 +38,7 @@ module Repp
|
||||||
private
|
private
|
||||||
|
|
||||||
def renew_params
|
def renew_params
|
||||||
params.permit(:domain_id, renew: %i[period period_unit exp_date])
|
params.permit(:domain_id, renews: %i[period period_unit exp_date])
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_renew_period
|
def validate_renew_period
|
||||||
|
@ -53,6 +54,7 @@ module Repp
|
||||||
|
|
||||||
if bulk_renew_params[:domains].instance_of?(Array)
|
if bulk_renew_params[:domains].instance_of?(Array)
|
||||||
@domains = bulk_renew_domains
|
@domains = bulk_renew_domains
|
||||||
|
@epp_errors.add(:epp_errors, msg: 'Domains cannot be empty', code: '2005') if @domains.empty?
|
||||||
else
|
else
|
||||||
@epp_errors.add(:epp_errors, msg: 'Domains attribute must be an array', code: '2005')
|
@epp_errors.add(:epp_errors, msg: 'Domains attribute must be an array', code: '2005')
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,7 @@ module Repp
|
||||||
module V1
|
module V1
|
||||||
class DomainsController < BaseController # rubocop:disable Metrics/ClassLength
|
class DomainsController < BaseController # rubocop:disable Metrics/ClassLength
|
||||||
before_action :set_authorized_domain, only: %i[transfer_info destroy]
|
before_action :set_authorized_domain, only: %i[transfer_info destroy]
|
||||||
|
before_action :find_password, only: %i[update destroy]
|
||||||
before_action :validate_registrar_authorization, only: %i[transfer_info destroy]
|
before_action :validate_registrar_authorization, only: %i[transfer_info destroy]
|
||||||
before_action :forward_registrar_id, only: %i[create update destroy]
|
before_action :forward_registrar_id, only: %i[create update destroy]
|
||||||
before_action :set_domain, only: %i[update]
|
before_action :set_domain, only: %i[update]
|
||||||
|
@ -10,20 +11,31 @@ module Repp
|
||||||
api :GET, '/repp/v1/domains'
|
api :GET, '/repp/v1/domains'
|
||||||
desc 'Get all existing domains'
|
desc 'Get all existing domains'
|
||||||
def index
|
def index
|
||||||
|
authorize! :info, Epp::Domain
|
||||||
records = current_user.registrar.domains
|
records = current_user.registrar.domains
|
||||||
domains = records.limit(limit).offset(offset)
|
q = records.ransack(search_params)
|
||||||
|
q.sorts = ['valid_to asc', 'created_at desc'] if q.sorts.empty?
|
||||||
|
# use distinct: false here due to ransack bug:
|
||||||
|
# https://github.com/activerecord-hackery/ransack/issues/429
|
||||||
|
domains = q.result(distinct: false)
|
||||||
|
|
||||||
render_success(data: { domains: serialized_domains(domains),
|
limited_domains = domains.limit(limit).offset(offset).includes(:registrar, :registrant)
|
||||||
total_number_of_records: records.count })
|
|
||||||
|
render_success(data: { new_domain: records.any? ? serialized_domains([records.last]) : [],
|
||||||
|
domains: serialized_domains(limited_domains.to_a.uniq),
|
||||||
|
count: domains.count,
|
||||||
|
statuses: DomainStatus::STATUSES })
|
||||||
end
|
end
|
||||||
|
|
||||||
api :GET, '/repp/v1/domains/:domain_name'
|
api :GET, '/repp/v1/domains/:domain_name'
|
||||||
desc 'Get a specific domain'
|
desc 'Get a specific domain'
|
||||||
def show
|
def show
|
||||||
@domain = Epp::Domain.find_by!(name: params[:id])
|
@domain = Epp::Domain.find_by_name(params[:id])
|
||||||
|
authorize! :info, @domain
|
||||||
|
|
||||||
sponsor = @domain.registrar == current_user.registrar
|
sponsor = @domain.registrar == current_user.registrar
|
||||||
render_success(data: { domain: Serializers::Repp::Domain.new(@domain,
|
serializer = Serializers::Repp::Domain.new(@domain, sponsored: sponsor)
|
||||||
sponsored: sponsor).to_json })
|
render_success(data: { domain: serializer.to_json })
|
||||||
end
|
end
|
||||||
|
|
||||||
api :POST, '/repp/v1/domains'
|
api :POST, '/repp/v1/domains'
|
||||||
|
@ -33,7 +45,7 @@ module Repp
|
||||||
param :registrant, String, required: true, desc: 'Registrant contact code'
|
param :registrant, String, required: true, desc: 'Registrant contact code'
|
||||||
param :reserved_pw, String, required: false, desc: 'Reserved password for domain'
|
param :reserved_pw, String, required: false, desc: 'Reserved password for domain'
|
||||||
param :transfer_code, String, required: false, desc: 'Desired transfer code for domain'
|
param :transfer_code, String, required: false, desc: 'Desired transfer code for domain'
|
||||||
# param :period, String, required: true, desc: 'Registration period in months or years'
|
param :period, Integer, required: true, desc: 'Registration period in months or years'
|
||||||
param :period_unit, String, required: true, desc: 'Period type (month m) or (year y)'
|
param :period_unit, String, required: true, desc: 'Period type (month m) or (year y)'
|
||||||
param :nameservers_attributes, Array, required: false, desc: 'Domain nameservers' do
|
param :nameservers_attributes, Array, required: false, desc: 'Domain nameservers' do
|
||||||
param :hostname, String, required: true, desc: 'Nameserver hostname'
|
param :hostname, String, required: true, desc: 'Nameserver hostname'
|
||||||
|
@ -56,15 +68,18 @@ module Repp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
def create
|
def create
|
||||||
authorize!(:create, Epp::Domain)
|
authorize! :create, Epp::Domain
|
||||||
@domain = Epp::Domain.new
|
@domain = Epp::Domain.new
|
||||||
action = Actions::DomainCreate.new(@domain, domain_create_params)
|
|
||||||
|
action = Actions::DomainCreate.new(@domain, domain_params)
|
||||||
|
|
||||||
# rubocop:disable Style/AndOr
|
# rubocop:disable Style/AndOr
|
||||||
handle_errors(@domain) and return unless action.call
|
handle_errors(@domain) and return unless action.call
|
||||||
# rubocop:enable Style/AndOr
|
# rubocop:enable Style/AndOr
|
||||||
|
|
||||||
render_success(data: { domain: { name: @domain.name, transfer_code: @domain.transfer_code } })
|
render_success(data: { domain: { name: @domain.name,
|
||||||
|
transfer_code: @domain.transfer_code,
|
||||||
|
id: @domain.reload.uuid } })
|
||||||
end
|
end
|
||||||
|
|
||||||
api :PUT, '/repp/v1/domains/:domain_name'
|
api :PUT, '/repp/v1/domains/:domain_name'
|
||||||
|
@ -73,20 +88,20 @@ module Repp
|
||||||
param :domain, Hash, required: true, desc: 'Changes of domain object' do
|
param :domain, Hash, required: true, desc: 'Changes of domain object' do
|
||||||
param :registrant, Hash, required: false, desc: 'New registrant object' do
|
param :registrant, Hash, required: false, desc: 'New registrant object' do
|
||||||
param :code, String, required: true, desc: 'New registrant contact code'
|
param :code, String, required: true, desc: 'New registrant contact code'
|
||||||
param :verified, [true, false], required: false,
|
param :verified, [true, false, 'true', 'false'], required: false,
|
||||||
desc: 'Registrant change is already verified'
|
desc: 'Registrant change is already verified'
|
||||||
end
|
end
|
||||||
param :transfer_code, String, required: false, desc: 'New authorization code'
|
param :transfer_code, String, required: false, desc: 'New authorization code'
|
||||||
end
|
end
|
||||||
def update
|
def update
|
||||||
action = Actions::DomainUpdate.new(@domain, params[:domain], false)
|
authorize!(:update, @domain, @password)
|
||||||
|
action = Actions::DomainUpdate.new(@domain, update_params, false)
|
||||||
unless action.call
|
unless action.call
|
||||||
handle_errors(@domain)
|
handle_errors(@domain)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
render_success(data: { domain: { name: @domain.name } })
|
render_success(data: { domain: { name: @domain.name, id: @domain.uuid } })
|
||||||
end
|
end
|
||||||
|
|
||||||
api :GET, '/repp/v1/domains/:domain_name/transfer_info'
|
api :GET, '/repp/v1/domains/:domain_name/transfer_info'
|
||||||
|
@ -108,23 +123,28 @@ module Repp
|
||||||
api :POST, '/repp/v1/domains/transfer'
|
api :POST, '/repp/v1/domains/transfer'
|
||||||
desc 'Transfer multiple domains'
|
desc 'Transfer multiple domains'
|
||||||
def transfer
|
def transfer
|
||||||
|
authorize! :transfer, Epp::Domain
|
||||||
@errors ||= []
|
@errors ||= []
|
||||||
@successful = []
|
@successful = []
|
||||||
|
|
||||||
transfer_params[:domain_transfers].each do |transfer|
|
transfer_params[:domain_transfers].each do |transfer|
|
||||||
initiate_transfer(transfer)
|
initiate_transfer(transfer)
|
||||||
end
|
end
|
||||||
|
|
||||||
render_success(data: { success: @successful, failed: @errors })
|
render_success(data: { success: @successful, failed: @errors })
|
||||||
end
|
end
|
||||||
|
|
||||||
api :DELETE, '/repp/v1/domains/:domain_name'
|
api :DELETE, '/repp/v1/domains/:domain_name'
|
||||||
desc 'Delete specific domain'
|
desc 'Delete specific domain'
|
||||||
param :delete, Hash, required: true, desc: 'Object holding verified key' do
|
param :id, String, desc: 'Domain name in IDN / Puny format'
|
||||||
param :verified, [true, false], required: true,
|
param :domain, Hash, required: true, desc: 'Changes of domain object' do
|
||||||
desc: 'Whether to ask registrant verification or not'
|
param :delete, Hash, required: true, desc: 'Object holding verified key' do
|
||||||
|
param :verified, [true, false, 'true', 'false'], required: true,
|
||||||
|
desc: 'Whether to ask registrant verification or not'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
def destroy
|
def destroy
|
||||||
action = Actions::DomainDelete.new(@domain, params, current_user.registrar)
|
authorize!(:delete, @domain, @password)
|
||||||
|
action = Actions::DomainDelete.new(@domain, domain_params, current_user.registrar)
|
||||||
|
|
||||||
# rubocop:disable Style/AndOr
|
# rubocop:disable Style/AndOr
|
||||||
handle_errors(@domain) and return unless action.call
|
handle_errors(@domain) and return unless action.call
|
||||||
|
@ -138,7 +158,8 @@ module Repp
|
||||||
def serialized_domains(domains)
|
def serialized_domains(domains)
|
||||||
return domains.pluck(:name) unless index_params[:details] == 'true'
|
return domains.pluck(:name) unless index_params[:details] == 'true'
|
||||||
|
|
||||||
domains.map { |d| Serializers::Repp::Domain.new(d).to_json }
|
simple = index_params[:simple] == 'true' || false
|
||||||
|
domains.map { |d| Serializers::Repp::Domain.new(d, simplify: simple).to_json }
|
||||||
end
|
end
|
||||||
|
|
||||||
def initiate_transfer(transfer)
|
def initiate_transfer(transfer)
|
||||||
|
@ -155,18 +176,13 @@ module Repp
|
||||||
end
|
end
|
||||||
|
|
||||||
def transfer_params
|
def transfer_params
|
||||||
params.require(:data).require(:domain_transfers).each do |t|
|
params.require(:data).require(:domain_transfers)
|
||||||
t.require(:domain_name)
|
params.require(:data).permit(domain_transfers: [%i[domain_name transfer_code]])
|
||||||
t.permit(:domain_name)
|
|
||||||
t.require(:transfer_code)
|
|
||||||
t.permit(:transfer_code)
|
|
||||||
end
|
|
||||||
params.require(:data).permit(domain_transfers: %i[domain_name transfer_code])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def transfer_info_params
|
def transfer_info_params
|
||||||
params.require(:id)
|
params.require(:id)
|
||||||
params.permit(:id)
|
params.permit(:id, :legal_document, delete: [:verified])
|
||||||
end
|
end
|
||||||
|
|
||||||
def forward_registrar_id
|
def forward_registrar_id
|
||||||
|
@ -177,6 +193,7 @@ module Repp
|
||||||
|
|
||||||
def set_domain
|
def set_domain
|
||||||
registrar = current_user.registrar
|
registrar = current_user.registrar
|
||||||
|
|
||||||
@domain = Epp::Domain.find_by(registrar: registrar, name: params[:id])
|
@domain = Epp::Domain.find_by(registrar: registrar, name: params[:id])
|
||||||
@domain ||= Epp::Domain.find_by!(registrar: registrar, name_puny: params[:id])
|
@domain ||= Epp::Domain.find_by!(registrar: registrar, name_puny: params[:id])
|
||||||
|
|
||||||
|
@ -185,6 +202,10 @@ module Repp
|
||||||
raise ActiveRecord::RecordNotFound
|
raise ActiveRecord::RecordNotFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_password
|
||||||
|
@password = domain_params[:transfer_code]
|
||||||
|
end
|
||||||
|
|
||||||
def set_authorized_domain
|
def set_authorized_domain
|
||||||
@epp_errors ||= ActiveModel::Errors.new(self)
|
@epp_errors ||= ActiveModel::Errors.new(self)
|
||||||
@domain = domain_from_url_hash
|
@domain = domain_from_url_hash
|
||||||
|
@ -201,7 +222,7 @@ module Repp
|
||||||
end
|
end
|
||||||
|
|
||||||
def domain_from_url_hash
|
def domain_from_url_hash
|
||||||
entry = transfer_info_params[:id]
|
entry = params[:id]
|
||||||
return Epp::Domain.find(entry) if entry.match?(/\A[0-9]+\z/)
|
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_by!('name = ? OR name_puny = ?', entry, entry)
|
||||||
|
@ -216,15 +237,48 @@ module Repp
|
||||||
end
|
end
|
||||||
|
|
||||||
def index_params
|
def index_params
|
||||||
params.permit(:limit, :offset, :details)
|
params.permit(:limit, :offset, :details, :simple, :q,
|
||||||
|
q: %i[s name_matches registrant_id_eq contacts_ident_eq
|
||||||
|
nameservers_hostname_eq valid_to_gteq valid_to_lteq
|
||||||
|
statuses_contains_array] + [s: []])
|
||||||
end
|
end
|
||||||
|
|
||||||
def domain_create_params
|
def search_params
|
||||||
params.require(:domain).permit(:name, :registrant, :period, :period_unit, :registrar,
|
index_params.fetch(:q, {})
|
||||||
:transfer_code, :reserved_pw,
|
end
|
||||||
dnskeys_attributes: [%i[flags alg protocol public_key]],
|
|
||||||
nameservers_attributes: [[:hostname, { ipv4: [], ipv6: [] }]],
|
def update_params
|
||||||
admin_contacts: [], tech_contacts: [])
|
dup_params = domain_params.to_h.dup
|
||||||
|
return dup_params unless dup_params[:contacts]
|
||||||
|
|
||||||
|
new_contact_params = dup_params[:contacts].map do |c|
|
||||||
|
c.to_h.symbolize_keys
|
||||||
|
end
|
||||||
|
|
||||||
|
old_contact_params = @domain.domain_contacts.map do |c|
|
||||||
|
{ code: c.contact_code_cache, type: c.name.downcase }
|
||||||
|
end
|
||||||
|
dup_params[:contacts] = (new_contact_params - old_contact_params).map { |c| c.merge(action: 'add') }
|
||||||
|
dup_params[:contacts].concat((old_contact_params - new_contact_params)
|
||||||
|
.map { |c| c.merge(action: 'rem') })
|
||||||
|
|
||||||
|
dup_params
|
||||||
|
end
|
||||||
|
|
||||||
|
def domain_params
|
||||||
|
params.require(:domain)
|
||||||
|
.permit(:name, :period, :period_unit, :registrar,
|
||||||
|
:transfer_code, :reserved_pw, :legal_document,
|
||||||
|
:registrant, legal_document: %i[body type],
|
||||||
|
registrant: [%i[code verified]],
|
||||||
|
dns_keys: [%i[id flags alg protocol public_key action]],
|
||||||
|
nameservers: [[:id, :hostname,
|
||||||
|
:action, { ipv4: [], ipv6: [] }]],
|
||||||
|
contacts: [%i[code type action]],
|
||||||
|
nameservers_attributes: [[:hostname, { ipv4: [], ipv6: [] }]],
|
||||||
|
admin_contacts: [], tech_contacts: [],
|
||||||
|
dnskeys_attributes: [%i[flags alg protocol public_key]],
|
||||||
|
delete: [:verified])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
118
app/controllers/repp/v1/invoices_controller.rb
Normal file
118
app/controllers/repp/v1/invoices_controller.rb
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
require 'serializers/repp/invoice'
|
||||||
|
module Repp
|
||||||
|
module V1
|
||||||
|
class InvoicesController < BaseController
|
||||||
|
load_and_authorize_resource
|
||||||
|
|
||||||
|
api :get, '/repp/v1/invoices'
|
||||||
|
desc 'Get all invoices'
|
||||||
|
def index
|
||||||
|
records = current_user.registrar.invoices
|
||||||
|
|
||||||
|
q = records.ransack(search_params)
|
||||||
|
q.sorts = 'created_at desc' if q.sorts.empty?
|
||||||
|
invoices = q.result(distinct: true)
|
||||||
|
|
||||||
|
limited_invoices = invoices.limit(limit).offset(offset)
|
||||||
|
.includes(:items, :account_activity, :buyer)
|
||||||
|
|
||||||
|
render_success(data: { invoices: serialized_invoices(limited_invoices),
|
||||||
|
count: invoices.count })
|
||||||
|
end
|
||||||
|
|
||||||
|
api :get, '/repp/v1/invoices/:id'
|
||||||
|
desc 'Get a specific invoice'
|
||||||
|
def show
|
||||||
|
serializer = Serializers::Repp::Invoice.new(@invoice)
|
||||||
|
render_success(data: { invoice: serializer.to_json })
|
||||||
|
end
|
||||||
|
|
||||||
|
api :get, '/repp/v1/invoices/:id/download'
|
||||||
|
desc 'Download a specific invoice as pdf file'
|
||||||
|
def download
|
||||||
|
filename = "Invoice-#{@invoice.number}.pdf"
|
||||||
|
@response = { code: 1000, message: 'Command completed successfully',
|
||||||
|
data: filename }
|
||||||
|
send_data @invoice.as_pdf, filename: filename
|
||||||
|
end
|
||||||
|
|
||||||
|
api :post, '/repp/v1/invoices/:id/send_to_recipient'
|
||||||
|
desc 'Send invoice pdf to recipient'
|
||||||
|
def send_to_recipient
|
||||||
|
recipient = invoice_params[:recipient]
|
||||||
|
InvoiceMailer.invoice_email(invoice: @invoice, recipient: recipient)
|
||||||
|
.deliver_now
|
||||||
|
serializer = Serializers::Repp::Invoice.new(@invoice, simplify: true)
|
||||||
|
render_success(data: { invoice: serializer.to_json
|
||||||
|
.merge!(recipient: recipient) })
|
||||||
|
end
|
||||||
|
|
||||||
|
api :post, '/repp/v1/invoices/:id/cancel'
|
||||||
|
desc 'Cancel a specific invoice'
|
||||||
|
def cancel
|
||||||
|
action = Actions::InvoiceCancel.new(@invoice)
|
||||||
|
if action.call
|
||||||
|
EisBilling::SendInvoiceStatus.send_info(invoice_number: @invoice.number,
|
||||||
|
status: 'cancelled')
|
||||||
|
else
|
||||||
|
handle_non_epp_errors(@invoice)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
serializer = Serializers::Repp::Invoice.new(@invoice, simplify: true)
|
||||||
|
render_success(data: { invoice: serializer.to_json })
|
||||||
|
end
|
||||||
|
|
||||||
|
api :post, '/repp/v1/invoices/add_credit'
|
||||||
|
desc 'Generate add credit invoice'
|
||||||
|
def add_credit
|
||||||
|
deposit = Deposit.new(invoice_params.merge(registrar: current_user.registrar))
|
||||||
|
invoice = deposit.issue_prepayment_invoice
|
||||||
|
if invoice
|
||||||
|
serializer = Serializers::Repp::Invoice.new(invoice, simplify: true)
|
||||||
|
render_success(data: { invoice: serializer.to_json })
|
||||||
|
else
|
||||||
|
handle_errors(deposit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def index_params
|
||||||
|
params.permit(:id, :limit, :offset, :details, :q, :simple,
|
||||||
|
:page, :per_page,
|
||||||
|
q: %i[number_str_matches due_date_gteq due_date_lteq
|
||||||
|
account_activity_created_at_gteq
|
||||||
|
account_activity_created_at_lteq
|
||||||
|
account_activity_id_not_null
|
||||||
|
account_activity_id_null
|
||||||
|
cancelled_at_not_null
|
||||||
|
number_gteq number_lteq
|
||||||
|
total_gteq total_lteq s] + [s: []])
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_params
|
||||||
|
index_params.fetch(:q, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
def invoice_params
|
||||||
|
params.require(:invoice).permit(:id, :recipient, :amount, :description)
|
||||||
|
end
|
||||||
|
|
||||||
|
def limit
|
||||||
|
index_params[:limit] || 200
|
||||||
|
end
|
||||||
|
|
||||||
|
def offset
|
||||||
|
index_params[:offset] || 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialized_invoices(invoices)
|
||||||
|
return invoices.pluck(:number) unless index_params[:details] == 'true'
|
||||||
|
|
||||||
|
simple = index_params[:simple] == 'true' || false
|
||||||
|
invoices.map { |i| Serializers::Repp::Invoice.new(i, simplify: simple).to_json }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
49
app/controllers/repp/v1/registrar/auth_controller.rb
Normal file
49
app/controllers/repp/v1/registrar/auth_controller.rb
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
module Repp
|
||||||
|
module V1
|
||||||
|
module Registrar
|
||||||
|
class AuthController < BaseController
|
||||||
|
skip_before_action :authenticate_user, only: :tara_callback
|
||||||
|
skip_before_action :check_ip_restriction, only: :tara_callback
|
||||||
|
|
||||||
|
api :GET, 'repp/v1/registrar/auth'
|
||||||
|
desc 'check user auth info and return data'
|
||||||
|
def index
|
||||||
|
registrar = current_user.registrar
|
||||||
|
render_success(data: auth_values_to_data(registrar: registrar))
|
||||||
|
end
|
||||||
|
|
||||||
|
api :POST, 'repp/v1/registrar/auth/tara_callback'
|
||||||
|
desc 'check tara callback omniauth user info and return token'
|
||||||
|
def tara_callback
|
||||||
|
user = ApiUser.from_omniauth(auth_params)
|
||||||
|
handle_non_epp_errors(user, I18n.t(:no_such_user)) and return unless user && user&.active
|
||||||
|
|
||||||
|
token = Base64.urlsafe_encode64("#{user.username}:#{user.plain_text_password}")
|
||||||
|
render_success(data: { token: token, username: user.username })
|
||||||
|
end
|
||||||
|
|
||||||
|
api :put, '/repp/v1/registrar/auth/switch_user/:new_user_id'
|
||||||
|
desc 'Switch session to another api user'
|
||||||
|
def switch_user
|
||||||
|
new_user = ApiUser.find(auth_params[:new_user_id])
|
||||||
|
unless current_user.linked_with?(new_user)
|
||||||
|
handle_non_epp_errors(new_user, 'Cannot switch to unlinked user')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
@current_user = new_user
|
||||||
|
data = auth_values_to_data(registrar: current_user.registrar)
|
||||||
|
message = I18n.t('registrar.current_user.switch.switched', new_user: new_user)
|
||||||
|
token = Base64.urlsafe_encode64("#{new_user.username}:#{new_user.plain_text_password}")
|
||||||
|
render_success(data: { token: token, registrar: data }, message: message)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def auth_params
|
||||||
|
params.require(:auth).permit(:uid, :new_user_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -19,13 +19,16 @@ module Repp
|
||||||
end
|
end
|
||||||
|
|
||||||
def update # rubocop:disable Metrics/MethodLength
|
def update # rubocop:disable Metrics/MethodLength
|
||||||
|
authorize! :manage, :repp
|
||||||
affected, errored = if hostname.present?
|
affected, errored = if hostname.present?
|
||||||
current_user.registrar.replace_nameservers(hostname,
|
current_user.registrar
|
||||||
hostname_params[:data][:attributes],
|
.replace_nameservers(hostname,
|
||||||
domains: domains_from_params)
|
hostname_params[:attributes],
|
||||||
|
domains: domains_from_params)
|
||||||
else
|
else
|
||||||
current_user.registrar.add_nameservers(hostname_params[:data][:attributes],
|
current_user.registrar
|
||||||
domains: domains_from_params)
|
.add_nameservers(hostname_params[:attributes],
|
||||||
|
domains: domains_from_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
render_success(data: data_format_for_success(affected, errored))
|
render_success(data: data_format_for_success(affected, errored))
|
||||||
|
@ -36,34 +39,32 @@ module Repp
|
||||||
private
|
private
|
||||||
|
|
||||||
def domains_from_params
|
def domains_from_params
|
||||||
return [] unless params[:data][:domains]
|
return [] unless hostname_params[:domains]
|
||||||
|
|
||||||
params[:data][:domains].map(&:downcase)
|
hostname_params[:domains].map(&:downcase)
|
||||||
end
|
end
|
||||||
|
|
||||||
def data_format_for_success(affected_domains, errored_domains)
|
def data_format_for_success(affected_domains, errored_domains)
|
||||||
{
|
{
|
||||||
type: 'nameserver',
|
type: 'nameserver',
|
||||||
id: params[:data][:attributes][:hostname],
|
id: hostname_params[:attributes][:hostname],
|
||||||
attributes: params[:data][:attributes],
|
attributes: hostname_params[:attributes],
|
||||||
affected_domains: affected_domains,
|
affected_domains: affected_domains,
|
||||||
skipped_domains: errored_domains,
|
skipped_domains: errored_domains,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def hostname_params
|
def hostname_params
|
||||||
params.require(:data).require(%i[type])
|
params.require(:data).permit(:type, :id, nameserver: [], domains: [],
|
||||||
params.require(:data).require(:attributes).require([:hostname])
|
attributes: [:hostname, { ipv4: [], ipv6: [] }])
|
||||||
|
.tap do |data|
|
||||||
params.permit(data: [
|
data.require(:type)
|
||||||
:type, :id,
|
data.require(:attributes).require([:hostname])
|
||||||
{ domains: [],
|
end
|
||||||
attributes: [:hostname, { ipv4: [], ipv6: [] }] }
|
|
||||||
])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def hostname
|
def hostname
|
||||||
hostname_params[:data][:id] || nil
|
hostname_params[:id] || nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def verify_nameserver_existance
|
def verify_nameserver_existance
|
||||||
|
|
|
@ -2,7 +2,7 @@ module Repp
|
||||||
module V1
|
module V1
|
||||||
module Registrar
|
module Registrar
|
||||||
class NotificationsController < BaseController
|
class NotificationsController < BaseController
|
||||||
before_action :set_notification, only: [:update]
|
before_action :set_notification, only: %i[update show]
|
||||||
|
|
||||||
api :GET, '/repp/v1/registrar/notifications'
|
api :GET, '/repp/v1/registrar/notifications'
|
||||||
desc 'Get the latest unread poll message'
|
desc 'Get the latest unread poll message'
|
||||||
|
@ -39,7 +39,6 @@ module Repp
|
||||||
api :GET, '/repp/v1/registrar/notifications/:notification_id'
|
api :GET, '/repp/v1/registrar/notifications/:notification_id'
|
||||||
desc 'Get a specific poll message'
|
desc 'Get a specific poll message'
|
||||||
def show
|
def show
|
||||||
@notification = current_user.registrar.notifications.find(params[:id])
|
|
||||||
data = @notification.as_json(only: %i[id text attached_obj_id attached_obj_type read])
|
data = @notification.as_json(only: %i[id text attached_obj_id attached_obj_type read])
|
||||||
|
|
||||||
render_success(data: data)
|
render_success(data: data)
|
||||||
|
@ -51,6 +50,7 @@ module Repp
|
||||||
param :read, [true, 'true'], required: true, desc: 'Set as true to mark as read'
|
param :read, [true, 'true'], required: true, desc: 'Set as true to mark as read'
|
||||||
end
|
end
|
||||||
def update
|
def update
|
||||||
|
authorize! :manage, :poll
|
||||||
# rubocop:disable Style/AndOr
|
# rubocop:disable Style/AndOr
|
||||||
handle_errors(@notification) and return unless @notification.mark_as_read
|
handle_errors(@notification) and return unless @notification.mark_as_read
|
||||||
# rubocop:enable Style/AndOr
|
# rubocop:enable Style/AndOr
|
||||||
|
|
111
app/controllers/repp/v1/registrar/summary_controller.rb
Normal file
111
app/controllers/repp/v1/registrar/summary_controller.rb
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
module Repp
|
||||||
|
module V1
|
||||||
|
module Registrar
|
||||||
|
class SummaryController < BaseController
|
||||||
|
api :GET, 'repp/v1/registrar/summary'
|
||||||
|
desc 'check user summary info and return data'
|
||||||
|
|
||||||
|
def index
|
||||||
|
user = current_user
|
||||||
|
registrar = user.registrar
|
||||||
|
if can?(:manage, :poll)
|
||||||
|
user_notifications = user.unread_notifications
|
||||||
|
notification = user_notifications.order('created_at DESC').take
|
||||||
|
notifications_count = user_notifications.count
|
||||||
|
if notification&.attached_obj_type && notification&.attached_obj_id
|
||||||
|
begin
|
||||||
|
object = object_by_type(notification.attached_obj_type)
|
||||||
|
.find(notification.attached_obj_id)
|
||||||
|
rescue => e
|
||||||
|
# the data model might be inconsistent; or ...
|
||||||
|
# this could happen if the registrar does not dequeue messages, and then the domain was deleted
|
||||||
|
# SELECT messages.id, domains.name, messages.body FROM messages LEFT OUTER
|
||||||
|
# JOIN domains ON attached_obj_id::INTEGER = domains.id
|
||||||
|
# WHERE attached_obj_type = 'Epp::Domain' AND name IS NULL;
|
||||||
|
message = 'orphan message, domain deleted, registrar should dequeue: '
|
||||||
|
Rails.logger.error message + e.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
data = serialize_data(registrar: registrar,
|
||||||
|
notification: notification,
|
||||||
|
notifications_count: notifications_count,
|
||||||
|
object: object)
|
||||||
|
|
||||||
|
render_success(data: data)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def object_by_type(object_type)
|
||||||
|
Object.const_get(object_type)
|
||||||
|
rescue NameError
|
||||||
|
Object.const_get("Version::#{object_type}")
|
||||||
|
end
|
||||||
|
|
||||||
|
# rubocop:disable Metrics/MethodLength
|
||||||
|
def serialize_data(registrar:, notification:, notifications_count:, object: nil)
|
||||||
|
data = current_user.as_json(only: %i[id username])
|
||||||
|
data[:registrar_name] = registrar.name
|
||||||
|
data[:registrar_reg_no] = registrar.reg_no
|
||||||
|
data[:last_login_date] = last_login_date
|
||||||
|
data[:domains] = registrar.domains.count if can? :view, Depp::Domain
|
||||||
|
data[:contacts] = registrar.contacts.count if can? :view, Depp::Contact
|
||||||
|
data[:phone] = registrar.phone
|
||||||
|
data[:email] = registrar.email
|
||||||
|
data[:billing_email] = registrar.billing_email
|
||||||
|
data[:billing_address] = registrar.address
|
||||||
|
data[:notification] = serialized_notification(notification, object)
|
||||||
|
data[:notifications_count] = notifications_count
|
||||||
|
data
|
||||||
|
end
|
||||||
|
# rubocop:enable Metrics/MethodLength
|
||||||
|
|
||||||
|
def last_login_date
|
||||||
|
q = ApiLog::ReppLog.ransack({ request_path_eq: '/repp/v1/registrar/auth',
|
||||||
|
response_code_eq: '200',
|
||||||
|
api_user_name_cont: current_user.username,
|
||||||
|
request_method_eq: 'GET' })
|
||||||
|
q.sorts = 'id desc'
|
||||||
|
q.result.offset(1).first&.created_at
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialized_notification(notification, object)
|
||||||
|
return unless notification
|
||||||
|
|
||||||
|
notification.created_at = notification.created_at.utc.xmlschema
|
||||||
|
obj_data = serialized_object(object, notification.attached_obj_type)
|
||||||
|
notification.as_json(only: %i[id text created_at attached_obj_id attached_obj_type])
|
||||||
|
.merge({ attached_obj_data: obj_data })
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialized_object(object, obj_type)
|
||||||
|
return unless object
|
||||||
|
|
||||||
|
case obj_type
|
||||||
|
when 'DomainTransfer'
|
||||||
|
{
|
||||||
|
name: object.domain_name,
|
||||||
|
trStatus: object.status,
|
||||||
|
reID: object.new_registrar.code,
|
||||||
|
reDate: object.transfer_requested_at.try(:iso8601),
|
||||||
|
acID: object.old_registrar.code,
|
||||||
|
acDate: object.transferred_at.try(:iso8601) || object.wait_until.try(:iso8601),
|
||||||
|
exDate: object.domain_valid_to.iso8601,
|
||||||
|
}
|
||||||
|
when 'ContactUpdateAction'
|
||||||
|
{
|
||||||
|
contacts: object.to_non_available_contact_codes,
|
||||||
|
operation: object.operation,
|
||||||
|
opDate: object.created_at.utc.xmlschema,
|
||||||
|
svTrid: object.id,
|
||||||
|
who: object.user.username,
|
||||||
|
reason: 'Auto-update according to official data',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -32,7 +32,7 @@ module Actions
|
||||||
|
|
||||||
def verify?
|
def verify?
|
||||||
return false unless Setting.request_confirmation_on_domain_deletion_enabled
|
return false unless Setting.request_confirmation_on_domain_deletion_enabled
|
||||||
return false if params[:delete][:verified] == true
|
return false if true?(params[:delete][:verified])
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
@ -51,5 +51,9 @@ module Actions
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def true?(obj)
|
||||||
|
obj.to_s.downcase == 'true'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,6 +14,7 @@ module Actions
|
||||||
assign_new_registrant if params[:registrant]
|
assign_new_registrant if params[:registrant]
|
||||||
assign_relational_modifications
|
assign_relational_modifications
|
||||||
assign_requested_statuses
|
assign_requested_statuses
|
||||||
|
|
||||||
::Actions::BaseAction.maybe_attach_legal_doc(domain, params[:legal_document])
|
::Actions::BaseAction.maybe_attach_legal_doc(domain, params[:legal_document])
|
||||||
|
|
||||||
commit
|
commit
|
||||||
|
@ -240,7 +241,7 @@ module Actions
|
||||||
|
|
||||||
def verify_registrant_change?
|
def verify_registrant_change?
|
||||||
return validate_dispute_case if params[:reserved_pw]
|
return validate_dispute_case if params[:reserved_pw]
|
||||||
return false if !@changes_registrant || params[:registrant][:verified] == true
|
return false if !@changes_registrant || true?(params[:registrant][:verified])
|
||||||
return true unless domain.disputed?
|
return true unless domain.disputed?
|
||||||
|
|
||||||
domain.add_epp_error('2304', nil, nil, 'Required parameter missing; reservedpw element ' \
|
domain.add_epp_error('2304', nil, nil, 'Required parameter missing; reservedpw element ' \
|
||||||
|
@ -282,5 +283,9 @@ module Actions
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def true?(obj)
|
||||||
|
obj.to_s.downcase == 'true'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
15
app/interactions/actions/invoice_cancel.rb
Normal file
15
app/interactions/actions/invoice_cancel.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
module Actions
|
||||||
|
class InvoiceCancel
|
||||||
|
attr_reader :invoice
|
||||||
|
|
||||||
|
def initialize(invoice)
|
||||||
|
@invoice = invoice
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
return false unless @invoice.can_be_cancelled?
|
||||||
|
|
||||||
|
@invoice.update(cancelled_at: Time.zone.now)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -34,9 +34,11 @@ class Ability
|
||||||
if @user.registrar.api_ip_white?(@ip)
|
if @user.registrar.api_ip_white?(@ip)
|
||||||
can :manage, Depp::Contact
|
can :manage, Depp::Contact
|
||||||
can :manage, :xml_console
|
can :manage, :xml_console
|
||||||
can :manage, Depp::Domain
|
can :manage, Depp::Domain
|
||||||
end
|
end
|
||||||
|
|
||||||
|
can :manage, Account
|
||||||
|
|
||||||
# Poll
|
# Poll
|
||||||
can :manage, :poll
|
can :manage, :poll
|
||||||
|
|
||||||
|
@ -65,12 +67,13 @@ class Ability
|
||||||
can(:update, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
can(:update, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
||||||
can(:delete, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
can(:delete, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
||||||
can(:renew, Epp::Contact)
|
can(:renew, Epp::Contact)
|
||||||
can(:transfer, Epp::Contact)
|
can(:transfer, Epp::Contact)
|
||||||
can(:view_password, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
can(:view_password, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
||||||
end
|
end
|
||||||
|
|
||||||
def billing # Registrar/api_user dynamic role
|
def billing # Registrar/api_user dynamic role
|
||||||
can(:manage, Invoice) { |i| i.buyer_id == @user.registrar_id }
|
can(:manage, Invoice) { |i| i.buyer_id == @user.registrar_id }
|
||||||
|
can :manage, Account
|
||||||
can :manage, :deposit
|
can :manage, :deposit
|
||||||
can :read, AccountActivity
|
can :read, AccountActivity
|
||||||
can :manage, :balance_auto_reload
|
can :manage, :balance_auto_reload
|
||||||
|
|
|
@ -28,14 +28,20 @@ class Action < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_non_available_contact_codes
|
def to_non_available_contact_codes
|
||||||
return [] unless bulk_action?
|
return [serialized_contact(contact)] unless bulk_action?
|
||||||
|
|
||||||
subactions.map do |a|
|
subactions.map do |a|
|
||||||
{
|
serialized_contact(a.contact)
|
||||||
code: a.contact.code,
|
|
||||||
avail: 0,
|
|
||||||
reason: 'in use',
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def serialized_contact(contact)
|
||||||
|
{
|
||||||
|
code: contact.code,
|
||||||
|
avail: 0,
|
||||||
|
reason: 'in use',
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ class AdminDomainContact < DomainContact
|
||||||
skipped_domains = []
|
skipped_domains = []
|
||||||
admin_contacts = where(contact: current_contact)
|
admin_contacts = where(contact: current_contact)
|
||||||
|
|
||||||
admin_contacts.each do |admin_contact|
|
admin_contacts.includes(:domain).each do |admin_contact|
|
||||||
if admin_contact.domain.bulk_update_prohibited?
|
if admin_contact.domain.bulk_update_prohibited?
|
||||||
skipped_domains << admin_contact.domain.name
|
skipped_domains << admin_contact.domain.name
|
||||||
next
|
next
|
||||||
|
|
|
@ -30,11 +30,11 @@ class ApiUser < User
|
||||||
|
|
||||||
alias_attribute :login, :username
|
alias_attribute :login, :username
|
||||||
|
|
||||||
SUPER = 'super'
|
SUPER = 'super'.freeze
|
||||||
EPP = 'epp'
|
EPP = 'epp'.freeze
|
||||||
BILLING = 'billing'
|
BILLING = 'billing'.freeze
|
||||||
|
|
||||||
ROLES = %w(super epp billing) # should not match to admin roles
|
ROLES = %w[super epp billing].freeze # should not match to admin roles
|
||||||
|
|
||||||
def ability
|
def ability
|
||||||
@ability ||= Ability.new(self)
|
@ability ||= Ability.new(self)
|
||||||
|
@ -72,8 +72,8 @@ class ApiUser < User
|
||||||
|
|
||||||
def linked_users
|
def linked_users
|
||||||
self.class.where(identity_code: identity_code)
|
self.class.where(identity_code: identity_code)
|
||||||
.where("identity_code IS NOT NULL AND identity_code != ''")
|
.where("identity_code IS NOT NULL AND identity_code != ''")
|
||||||
.where.not(id: id)
|
.where.not(id: id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def linked_with?(another_api_user)
|
def linked_with?(another_api_user)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
module BalanceAutoReloadTypes
|
module BalanceAutoReloadTypes
|
||||||
class Threshold
|
class Threshold
|
||||||
include ActiveModel::Model
|
include ActiveModel::Model
|
||||||
|
include ActiveModel::Validations
|
||||||
|
|
||||||
attr_accessor :amount, :threshold
|
attr_accessor :amount, :threshold
|
||||||
|
|
||||||
|
@ -11,8 +12,9 @@ module BalanceAutoReloadTypes
|
||||||
Setting.minimum_deposit
|
Setting.minimum_deposit
|
||||||
end
|
end
|
||||||
|
|
||||||
def as_json(options)
|
def as_json(options = nil)
|
||||||
{ name: name }.merge(super)
|
{ name: name }.merge(super)
|
||||||
|
.except('errors', 'validation_context')
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
class BulkAction < Action; end
|
|
|
@ -5,12 +5,22 @@ module Invoice::Cancellable
|
||||||
scope :non_cancelled, -> { where(cancelled_at: nil) }
|
scope :non_cancelled, -> { where(cancelled_at: nil) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_be_cancelled?
|
||||||
|
unless cancellable?
|
||||||
|
errors.add(:base, :invoice_status_prohibits_operation)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
def cancellable?
|
def cancellable?
|
||||||
unpaid? && not_cancelled?
|
unpaid? && not_cancelled?
|
||||||
end
|
end
|
||||||
|
|
||||||
def cancel
|
def cancel
|
||||||
raise 'Invoice cannot be cancelled' unless cancellable?
|
raise 'Invoice cannot be cancelled' unless cancellable?
|
||||||
|
|
||||||
update!(cancelled_at: Time.zone.now)
|
update!(cancelled_at: Time.zone.now)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ module Invoice::Payable
|
||||||
end
|
end
|
||||||
|
|
||||||
def receipt_date
|
def receipt_date
|
||||||
|
return unless paid?
|
||||||
|
|
||||||
account_activity.created_at.to_date
|
account_activity.created_at.to_date
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -80,41 +80,41 @@ class Contact < ApplicationRecord
|
||||||
|
|
||||||
self.ignored_columns = %w[legacy_id legacy_history_id]
|
self.ignored_columns = %w[legacy_id legacy_history_id]
|
||||||
|
|
||||||
ORG = 'org'
|
ORG = 'org'.freeze
|
||||||
PRIV = 'priv'
|
PRIV = 'priv'.freeze
|
||||||
|
|
||||||
# For foreign private persons who has no national identification number
|
# For foreign private persons who has no national identification number
|
||||||
BIRTHDAY = 'birthday'.freeze
|
BIRTHDAY = 'birthday'.freeze
|
||||||
|
|
||||||
# From old registry software ("Fred"). No new contact can be created with this status
|
# From old registry software ("Fred"). No new contact can be created with this status
|
||||||
PASSPORT = 'passport'
|
PASSPORT = 'passport'.freeze
|
||||||
|
|
||||||
#
|
#
|
||||||
# STATUSES
|
# STATUSES
|
||||||
#
|
#
|
||||||
# Requests to delete the object MUST be rejected.
|
# Requests to delete the object MUST be rejected.
|
||||||
CLIENT_DELETE_PROHIBITED = 'clientDeleteProhibited'
|
CLIENT_DELETE_PROHIBITED = 'clientDeleteProhibited'.freeze
|
||||||
SERVER_DELETE_PROHIBITED = 'serverDeleteProhibited'
|
SERVER_DELETE_PROHIBITED = 'serverDeleteProhibited'.freeze
|
||||||
|
|
||||||
# Requests to transfer the object MUST be rejected.
|
# Requests to transfer the object MUST be rejected.
|
||||||
CLIENT_TRANSFER_PROHIBITED = 'clientTransferProhibited'
|
CLIENT_TRANSFER_PROHIBITED = 'clientTransferProhibited'.freeze
|
||||||
SERVER_TRANSFER_PROHIBITED = 'serverTransferProhibited'
|
SERVER_TRANSFER_PROHIBITED = 'serverTransferProhibited'.freeze
|
||||||
|
|
||||||
# The contact object has at least one active association with
|
# The contact object has at least one active association with
|
||||||
# another object, such as a domain object. Servers SHOULD provide
|
# another object, such as a domain object. Servers SHOULD provide
|
||||||
# services to determine existing object associations.
|
# services to determine existing object associations.
|
||||||
# "linked" status MAY be combined with any status.
|
# "linked" status MAY be combined with any status.
|
||||||
LINKED = 'linked'
|
LINKED = 'linked'.freeze
|
||||||
|
|
||||||
# This is the normal status value for an object that has no pending
|
# This is the normal status value for an object that has no pending
|
||||||
# operations or prohibitions. This value is set and removed by the
|
# operations or prohibitions. This value is set and removed by the
|
||||||
# server as other status values are added or removed.
|
# server as other status values are added or removed.
|
||||||
# "ok" status MAY only be combined with "linked" status.
|
# "ok" status MAY only be combined with "linked" status.
|
||||||
OK = 'ok'
|
OK = 'ok'.freeze
|
||||||
|
|
||||||
# Requests to update the object (other than to remove this status) MUST be rejected.
|
# Requests to update the object (other than to remove this status) MUST be rejected.
|
||||||
CLIENT_UPDATE_PROHIBITED = 'clientUpdateProhibited'
|
CLIENT_UPDATE_PROHIBITED = 'clientUpdateProhibited'.freeze
|
||||||
SERVER_UPDATE_PROHIBITED = 'serverUpdateProhibited'
|
SERVER_UPDATE_PROHIBITED = 'serverUpdateProhibited'.freeze
|
||||||
|
|
||||||
# A transform command has been processed for the object, but the
|
# A transform command has been processed for the object, but the
|
||||||
# action has not been completed by the server. Server operators can
|
# action has not been completed by the server. Server operators can
|
||||||
|
@ -129,16 +129,16 @@ class Contact < ApplicationRecord
|
||||||
# the status of the object has changed.
|
# the status of the object has changed.
|
||||||
# The pendingCreate, pendingDelete, pendingTransfer, and pendingUpdate
|
# The pendingCreate, pendingDelete, pendingTransfer, and pendingUpdate
|
||||||
# status values MUST NOT be combined with each other.
|
# status values MUST NOT be combined with each other.
|
||||||
PENDING_CREATE = 'pendingCreate'
|
PENDING_CREATE = 'pendingCreate'.freeze
|
||||||
# "pendingTransfer" status MUST NOT be combined with either
|
# "pendingTransfer" status MUST NOT be combined with either
|
||||||
# "clientTransferProhibited" or "serverTransferProhibited" status.
|
# "clientTransferProhibited" or "serverTransferProhibited" status.
|
||||||
PENDING_TRANSFER = 'pendingTransfer'
|
PENDING_TRANSFER = 'pendingTransfer'.freeze
|
||||||
# "pendingUpdate" status MUST NOT be combined with either
|
# "pendingUpdate" status MUST NOT be combined with either
|
||||||
# "clientUpdateProhibited" or "serverUpdateProhibited" status.
|
# "clientUpdateProhibited" or "serverUpdateProhibited" status.
|
||||||
PENDING_UPDATE = 'pendingUpdate'
|
PENDING_UPDATE = 'pendingUpdate'.freeze
|
||||||
# "pendingDelete" MUST NOT be combined with either
|
# "pendingDelete" MUST NOT be combined with either
|
||||||
# "clientDeleteProhibited" or "serverDeleteProhibited" status.
|
# "clientDeleteProhibited" or "serverDeleteProhibited" status.
|
||||||
PENDING_DELETE = 'pendingDelete'
|
PENDING_DELETE = 'pendingDelete'.freeze
|
||||||
|
|
||||||
STATUSES = [
|
STATUSES = [
|
||||||
CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED,
|
CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED,
|
||||||
|
@ -146,18 +146,18 @@ class Contact < ApplicationRecord
|
||||||
SERVER_TRANSFER_PROHIBITED, CLIENT_UPDATE_PROHIBITED, SERVER_UPDATE_PROHIBITED,
|
SERVER_TRANSFER_PROHIBITED, CLIENT_UPDATE_PROHIBITED, SERVER_UPDATE_PROHIBITED,
|
||||||
OK, PENDING_CREATE, PENDING_DELETE, PENDING_TRANSFER,
|
OK, PENDING_CREATE, PENDING_DELETE, PENDING_TRANSFER,
|
||||||
PENDING_UPDATE, LINKED
|
PENDING_UPDATE, LINKED
|
||||||
]
|
].freeze
|
||||||
|
|
||||||
CLIENT_STATUSES = [
|
CLIENT_STATUSES = [
|
||||||
CLIENT_DELETE_PROHIBITED, CLIENT_TRANSFER_PROHIBITED,
|
CLIENT_DELETE_PROHIBITED, CLIENT_TRANSFER_PROHIBITED,
|
||||||
CLIENT_UPDATE_PROHIBITED
|
CLIENT_UPDATE_PROHIBITED
|
||||||
]
|
].freeze
|
||||||
|
|
||||||
SERVER_STATUSES = [
|
SERVER_STATUSES = [
|
||||||
SERVER_UPDATE_PROHIBITED,
|
SERVER_UPDATE_PROHIBITED,
|
||||||
SERVER_DELETE_PROHIBITED,
|
SERVER_DELETE_PROHIBITED,
|
||||||
SERVER_TRANSFER_PROHIBITED
|
SERVER_TRANSFER_PROHIBITED,
|
||||||
]
|
].freeze
|
||||||
#
|
#
|
||||||
# END OF STATUSES
|
# END OF STATUSES
|
||||||
#
|
#
|
||||||
|
@ -355,7 +355,7 @@ class Contact < ApplicationRecord
|
||||||
@desc[dom.name][:roles] << :registrant
|
@desc[dom.name][:roles] << :registrant
|
||||||
end
|
end
|
||||||
|
|
||||||
domain_contacts.each do |dc|
|
domain_contacts.includes(:domain).each do |dc|
|
||||||
@desc[dc.domain.name] ||= { id: dc.domain.uuid, roles: [] }
|
@desc[dc.domain.name] ||= { id: dc.domain.uuid, roles: [] }
|
||||||
@desc[dc.domain.name][:roles] << dc.name.downcase.to_sym
|
@desc[dc.domain.name][:roles] << dc.name.downcase.to_sym
|
||||||
@desc[dc.domain.name] = @desc[dc.domain.name].compact
|
@desc[dc.domain.name] = @desc[dc.domain.name].compact
|
||||||
|
@ -383,6 +383,10 @@ class Contact < ApplicationRecord
|
||||||
"#{code} #{name}"
|
"#{code} #{name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def name_disclosed_by_registrar(reg_id)
|
||||||
|
registrar_id == reg_id ? name : 'N/A'
|
||||||
|
end
|
||||||
|
|
||||||
def strip_email
|
def strip_email
|
||||||
self.email = email.to_s.strip
|
self.email = email.to_s.strip
|
||||||
end
|
end
|
||||||
|
@ -405,7 +409,7 @@ class Contact < ApplicationRecord
|
||||||
|
|
||||||
# using small rails hack to generate outer join
|
# using small rails hack to generate outer join
|
||||||
domains = if sorts.first == 'registrar_name'.freeze
|
domains = if sorts.first == 'registrar_name'.freeze
|
||||||
domains.includes(:registrar).where.not(registrars: { id: nil })
|
domains.where.not(registrars: { id: nil })
|
||||||
.order("registrars.name #{order} NULLS LAST")
|
.order("registrars.name #{order} NULLS LAST")
|
||||||
else
|
else
|
||||||
domains.order("#{sort} #{order} NULLS LAST")
|
domains.order("#{sort} #{order} NULLS LAST")
|
||||||
|
@ -422,7 +426,6 @@ class Contact < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
domains.each { |d| d.roles = domain_c[d.id].uniq }
|
domains.each { |d| d.roles = domain_c[d.id].uniq }
|
||||||
|
|
||||||
domains
|
domains
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -438,18 +441,28 @@ class Contact < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def qualified_domain_ids(domain_filter)
|
def qualified_domain_ids(filters)
|
||||||
registrant_ids = registrant_domains.pluck(:id)
|
rant_domains = registrant_domains.map { |d| { id: d.id, type: ['Registrant'] } }
|
||||||
return registrant_ids if domain_filter == 'Registrant'
|
contact_domains = domain_contacts.map { |dc| { id: dc.domain_id, type: [dc.type] } }
|
||||||
|
grouped_domains = group_by_id_and_type(rant_domains + contact_domains)
|
||||||
|
return grouped_domains.keys if filters.nil? || filters == ''
|
||||||
|
|
||||||
if %w[AdminDomainContact TechDomainContact].include? domain_filter
|
# use domain_filters.sort == v.sort if should be exact match
|
||||||
DomainContact.select('domain_id').where(contact_id: id, type: domain_filter)
|
grouped_domains.reject { |_, v| ([].push(filters).flatten & v).empty? }.keys
|
||||||
else
|
|
||||||
(DomainContact.select('domain_id').where(contact_id: id).pluck(:domain_id) +
|
|
||||||
registrant_ids).uniq
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# def qualified_domain_ids(domain_filter)
|
||||||
|
# registrant_ids = registrant_domains.pluck(:id)
|
||||||
|
# return registrant_ids if domain_filter == 'Registrant'
|
||||||
|
|
||||||
|
# if %w[AdminDomainContact TechDomainContact].include? domain_filter
|
||||||
|
# DomainContact.where(contact_id: id, type: domain_filter).pluck(:domain_id)
|
||||||
|
# else
|
||||||
|
# (DomainContact.where(contact_id: id).pluck(:domain_id) +
|
||||||
|
# registrant_ids).uniq
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
def update_prohibited?
|
def update_prohibited?
|
||||||
(statuses & [
|
(statuses & [
|
||||||
CLIENT_UPDATE_PROHIBITED,
|
CLIENT_UPDATE_PROHIBITED,
|
||||||
|
@ -459,7 +472,7 @@ class Contact < ApplicationRecord
|
||||||
PENDING_CREATE,
|
PENDING_CREATE,
|
||||||
PENDING_TRANSFER,
|
PENDING_TRANSFER,
|
||||||
PENDING_UPDATE,
|
PENDING_UPDATE,
|
||||||
PENDING_DELETE
|
PENDING_DELETE,
|
||||||
]).present?
|
]).present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -590,4 +603,14 @@ class Contact < ApplicationRecord
|
||||||
def self.csv_header
|
def self.csv_header
|
||||||
['Name', 'ID', 'Ident', 'E-mail', 'Created at', 'Registrar', 'Phone']
|
['Name', 'ID', 'Ident', 'E-mail', 'Created at', 'Registrar', 'Phone']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def group_by_id_and_type(domains_hash_array)
|
||||||
|
domains_hash_array.group_by { |d| d[:id] }
|
||||||
|
.transform_values do |v|
|
||||||
|
v.each.with_object(:type)
|
||||||
|
.map(&:[]).flatten
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
1
app/models/contact_update_action.rb
Normal file
1
app/models/contact_update_action.rb
Normal file
|
@ -0,0 +1 @@
|
||||||
|
class ContactUpdateAction < Action; end
|
|
@ -33,6 +33,7 @@ class Deposit
|
||||||
|
|
||||||
def issue_prepayment_invoice
|
def issue_prepayment_invoice
|
||||||
return unless valid?
|
return unless valid?
|
||||||
|
|
||||||
registrar.issue_prepayment_invoice(amount, description)
|
registrar.issue_prepayment_invoice(amount, description)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,8 +31,8 @@ module Depp
|
||||||
|
|
||||||
def request(xml)
|
def request(xml)
|
||||||
Nokogiri::XML(server.request(xml)).remove_namespaces!
|
Nokogiri::XML(server.request(xml)).remove_namespaces!
|
||||||
rescue EppErrorResponse => e
|
rescue EppErrorResponse => e
|
||||||
Nokogiri::XML(e.response_xml.to_s).remove_namespaces!
|
Nokogiri::XML(e.response_xml.to_s).remove_namespaces!
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -4,10 +4,10 @@ class DomainTransfer < ApplicationRecord
|
||||||
belongs_to :old_registrar, class_name: 'Registrar'
|
belongs_to :old_registrar, class_name: 'Registrar'
|
||||||
belongs_to :new_registrar, class_name: 'Registrar'
|
belongs_to :new_registrar, class_name: 'Registrar'
|
||||||
|
|
||||||
PENDING = 'pending'
|
PENDING = 'pending'.freeze
|
||||||
CLIENT_APPROVED = 'clientApproved'
|
CLIENT_APPROVED = 'clientApproved'.freeze
|
||||||
CLIENT_REJECTED = 'clientRejected'
|
CLIENT_REJECTED = 'clientRejected'.freeze
|
||||||
SERVER_APPROVED = 'serverApproved'
|
SERVER_APPROVED = 'serverApproved'.freeze
|
||||||
|
|
||||||
before_create :set_wait_until
|
before_create :set_wait_until
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,13 @@ class Invoice < ApplicationRecord
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
ransacker :number_str do
|
||||||
|
Arel.sql(
|
||||||
|
"regexp_replace(
|
||||||
|
to_char(\"#{table_name}\".\"number\", '999999999999'), ' ', '', 'g')"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def receipt_date_status
|
def receipt_date_status
|
||||||
if paid?
|
if paid?
|
||||||
receipt_date
|
receipt_date
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
class Notification < ApplicationRecord
|
class Notification < ApplicationRecord
|
||||||
include Versions # version/notification_version.rb
|
include Versions # version/notification_version.rb
|
||||||
|
include EppErrors
|
||||||
|
|
||||||
belongs_to :registrar
|
belongs_to :registrar
|
||||||
belongs_to :action, optional: true
|
belongs_to :action, optional: true
|
||||||
|
|
|
@ -97,7 +97,7 @@ class Registrar < ApplicationRecord
|
||||||
description: 'prepayment',
|
description: 'prepayment',
|
||||||
unit: 'piece',
|
unit: 'piece',
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
price: amount
|
price: amount,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
@ -233,13 +233,9 @@ class Registrar < ApplicationRecord
|
||||||
def notify(action)
|
def notify(action)
|
||||||
text = I18n.t("notifications.texts.#{action.notification_key}", contact: action.contact&.code,
|
text = I18n.t("notifications.texts.#{action.notification_key}", contact: action.contact&.code,
|
||||||
count: action.subactions&.count)
|
count: action.subactions&.count)
|
||||||
if action.bulk_action?
|
notifications.create!(text: text, action_id: action.id,
|
||||||
notifications.create!(text: text, action_id: action.id,
|
attached_obj_type: 'ContactUpdateAction',
|
||||||
attached_obj_type: 'BulkAction',
|
attached_obj_id: action.id)
|
||||||
attached_obj_id: action.id)
|
|
||||||
else
|
|
||||||
notifications.create!(text: text)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def e_invoice_iban
|
def e_invoice_iban
|
||||||
|
|
|
@ -5,7 +5,7 @@ class TechDomainContact < DomainContact
|
||||||
skipped_domains = []
|
skipped_domains = []
|
||||||
tech_contacts = where(contact: current_contact)
|
tech_contacts = where(contact: current_contact)
|
||||||
|
|
||||||
tech_contacts.each do |tech_contact|
|
tech_contacts.includes(:domain).each do |tech_contact|
|
||||||
if irreplaceable?(tech_contact)
|
if irreplaceable?(tech_contact)
|
||||||
skipped_domains << tech_contact.domain.name
|
skipped_domains << tech_contact.domain.name
|
||||||
next
|
next
|
||||||
|
|
|
@ -16,6 +16,6 @@ class User < ApplicationRecord
|
||||||
identity_code = uid.slice(2..-1)
|
identity_code = uid.slice(2..-1)
|
||||||
# country_code = uid.slice(0..1)
|
# country_code = uid.slice(0..1)
|
||||||
|
|
||||||
find_by(identity_code: identity_code)
|
find_by(identity_code: identity_code, active: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,13 +17,13 @@ class Registrar::DomainListCsvPresenter
|
||||||
private
|
private
|
||||||
|
|
||||||
def header
|
def header
|
||||||
columns = %w(
|
columns = %w[
|
||||||
domain_name
|
domain_name
|
||||||
transfer_code
|
transfer_code
|
||||||
registrant_name
|
registrant_name
|
||||||
registrant_code
|
registrant_code
|
||||||
expire_time
|
expire_time
|
||||||
)
|
]
|
||||||
|
|
||||||
columns.map! { |column| view.t("registrar.domains.index.csv.#{column}") }
|
columns.map! { |column| view.t("registrar.domains.index.csv.#{column}") }
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ class Registrar::DomainListCsvPresenter
|
||||||
row[2] = domain.registrant.name
|
row[2] = domain.registrant.name
|
||||||
row[3] = domain.registrant.code
|
row[3] = domain.registrant.code
|
||||||
row[4] = domain.expire_date
|
row[4] = domain.expire_date
|
||||||
row
|
|
||||||
|
|
||||||
CSV::Row.new([], row)
|
CSV::Row.new([], row)
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,7 +15,7 @@ xml.epp_head do
|
||||||
xml.resData do
|
xml.resData do
|
||||||
xml << render('epp/domains/partials/transfer', builder: xml, dt: @object)
|
xml << render('epp/domains/partials/transfer', builder: xml, dt: @object)
|
||||||
end
|
end
|
||||||
when 'BulkAction'
|
when 'ContactUpdateAction'
|
||||||
xml.resData do
|
xml.resData do
|
||||||
xml << render(
|
xml << render(
|
||||||
'epp/contacts/partials/check',
|
'epp/contacts/partials/check',
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<%= f.label :valid_to_from, for: nil %>
|
<%= f.label :valid_to_gteq, for: nil %>
|
||||||
<%= f.search_field :valid_to_gteq, value: search_params[:valid_to_gteq],
|
<%= f.search_field :valid_to_gteq, value: search_params[:valid_to_gteq],
|
||||||
class: 'form-control js-datepicker',
|
class: 'form-control js-datepicker',
|
||||||
placeholder: t(:valid_to_from) %>
|
placeholder: t(:valid_to_from) %>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<%= f.label :valid_to_until, for: nil %>
|
<%= f.label :valid_to_lteq, for: nil %>
|
||||||
<%= f.search_field :valid_to_lteq, value: search_params[:valid_to_lteq],
|
<%= f.search_field :valid_to_lteq, value: search_params[:valid_to_lteq],
|
||||||
class: 'form-control js-datepicker',
|
class: 'form-control js-datepicker',
|
||||||
placeholder: t(:valid_to_until) %>
|
placeholder: t(:valid_to_until) %>
|
||||||
|
|
|
@ -27,10 +27,11 @@
|
||||||
= form_tag confirm_transfer_registrar_poll_path, class: 'js-transfer-form' do
|
= form_tag confirm_transfer_registrar_poll_path, class: 'js-transfer-form' do
|
||||||
= hidden_field_tag 'domain[name]', @data.css('name').text
|
= hidden_field_tag 'domain[name]', @data.css('name').text
|
||||||
|
|
||||||
- @data.css('trnData').children.each do |x|
|
- @data.css('trnData').children.each do |x|
|
||||||
- next if x.blank?
|
- next if x.blank?
|
||||||
%dt= t(x.name)
|
%dt= t(x.name)
|
||||||
%dd= x.text
|
%dd= x.text
|
||||||
|
|
||||||
- else
|
- else
|
||||||
.row
|
.row
|
||||||
.col-sm-12
|
.col-sm-12
|
||||||
|
|
25
config/initializers/arel.rb
Normal file
25
config/initializers/arel.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
require 'arel/nodes/binary'
|
||||||
|
require 'arel/predications'
|
||||||
|
require 'arel/visitors/postgresql'
|
||||||
|
|
||||||
|
module Arel
|
||||||
|
class Nodes::ContainsArray < Arel::Nodes::Binary
|
||||||
|
def operator
|
||||||
|
:"@>"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Visitors::PostgreSQL
|
||||||
|
private
|
||||||
|
|
||||||
|
def visit_Arel_Nodes_ContainsArray(o, collector)
|
||||||
|
infix_value o, collector, ' @> '
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Predications
|
||||||
|
def contains_array(other)
|
||||||
|
Nodes::ContainsArray.new self, Nodes.build_quoted(other, self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -15,62 +15,67 @@ host = ENV['tara_host']
|
||||||
identifier = ENV['tara_identifier']
|
identifier = ENV['tara_identifier']
|
||||||
secret = ENV['tara_secret']
|
secret = ENV['tara_secret']
|
||||||
redirect_uri = ENV['tara_redirect_uri']
|
redirect_uri = ENV['tara_redirect_uri']
|
||||||
|
authorization_endpoint = ENV['tara_authorization_endpoint']
|
||||||
|
token_endpoint = ENV['tara_token_endpoint']
|
||||||
|
jwks_uri = ENV['tara_jwks_uri']
|
||||||
|
scope = ENV['tara_scope']
|
||||||
|
|
||||||
registrant_identifier = ENV['tara_rant_identifier']
|
registrant_identifier = ENV['tara_rant_identifier']
|
||||||
registrant_secret = ENV['tara_rant_secret']
|
registrant_secret = ENV['tara_rant_secret']
|
||||||
registrant_redirect_uri = ENV['tara_rant_redirect_uri']
|
registrant_redirect_uri = ENV['tara_rant_redirect_uri']
|
||||||
|
|
||||||
Rails.application.config.middleware.use OmniAuth::Builder do
|
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||||
provider "tara", {
|
provider 'tara', {
|
||||||
callback_path: '/registrar/open_id/callback',
|
callback_path: '/registrar/open_id/callback',
|
||||||
name: 'tara',
|
name: 'tara',
|
||||||
scope: ['openid'],
|
scope: scope,
|
||||||
state: Proc.new{ SecureRandom.hex(10) },
|
# state: Proc.new{ SecureRandom.hex(10) },
|
||||||
client_signing_alg: :RS256,
|
client_signing_alg: :RS256,
|
||||||
client_jwk_signing_key: signing_keys,
|
client_jwk_signing_key: signing_keys,
|
||||||
send_scope_to_token_endpoint: false,
|
send_scope_to_token_endpoint: false,
|
||||||
send_nonce: true,
|
send_nonce: true,
|
||||||
issuer: issuer,
|
issuer: issuer,
|
||||||
|
discovery: true,
|
||||||
|
|
||||||
client_options: {
|
client_options: {
|
||||||
scheme: 'https',
|
scheme: 'https',
|
||||||
host: host,
|
host: host,
|
||||||
|
|
||||||
authorization_endpoint: '/oidc/authorize',
|
authorization_endpoint: authorization_endpoint,
|
||||||
token_endpoint: '/oidc/token',
|
token_endpoint: token_endpoint,
|
||||||
userinfo_endpoint: nil, # Not implemented
|
userinfo_endpoint: nil, # Not implemented
|
||||||
jwks_uri: '/oidc/jwks',
|
jwks_uri: jwks_uri,
|
||||||
|
|
||||||
# Registry
|
# Registry
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
secret: secret,
|
secret: secret,
|
||||||
redirect_uri: redirect_uri,
|
redirect_uri: redirect_uri,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "tara", {
|
provider 'tara', {
|
||||||
callback_path: '/registrant/open_id/callback',
|
callback_path: '/registrant/open_id/callback',
|
||||||
name: 'rant_tara',
|
name: 'rant_tara',
|
||||||
scope: ['openid'],
|
scope: ['openid'],
|
||||||
client_signing_alg: :RS256,
|
client_signing_alg: :RS256,
|
||||||
client_jwk_signing_key: signing_keys,
|
client_jwk_signing_key: signing_keys,
|
||||||
send_scope_to_token_endpoint: false,
|
send_scope_to_token_endpoint: false,
|
||||||
send_nonce: true,
|
send_nonce: true,
|
||||||
issuer: issuer,
|
issuer: issuer,
|
||||||
|
|
||||||
client_options: {
|
client_options: {
|
||||||
scheme: 'https',
|
scheme: 'https',
|
||||||
host: host,
|
host: host,
|
||||||
|
|
||||||
authorization_endpoint: '/oidc/authorize',
|
authorization_endpoint: '/oidc/authorize',
|
||||||
token_endpoint: '/oidc/token',
|
token_endpoint: '/oidc/token',
|
||||||
userinfo_endpoint: nil, # Not implemented
|
userinfo_endpoint: nil, # Not implemented
|
||||||
jwks_uri: '/oidc/jwks',
|
jwks_uri: '/oidc/jwks',
|
||||||
|
|
||||||
# Registry
|
# Registry
|
||||||
identifier: registrant_identifier,
|
identifier: registrant_identifier,
|
||||||
secret: registrant_secret,
|
secret: registrant_secret,
|
||||||
redirect_uri: registrant_redirect_uri,
|
redirect_uri: registrant_redirect_uri,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
7
config/initializers/ransack.rb
Normal file
7
config/initializers/ransack.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Ransack.configure do |config|
|
||||||
|
config.add_predicate 'contains_array',
|
||||||
|
arel_predicate: 'contains_array',
|
||||||
|
formatter: proc { |v| "{#{v}}" },
|
||||||
|
validator: proc { |v| v.present? },
|
||||||
|
type: :string
|
||||||
|
end
|
|
@ -101,6 +101,11 @@ en:
|
||||||
attributes:
|
attributes:
|
||||||
value:
|
value:
|
||||||
taken: 'Status already exists on this domain'
|
taken: 'Status already exists on this domain'
|
||||||
|
|
||||||
|
invoice:
|
||||||
|
attributes:
|
||||||
|
base:
|
||||||
|
invoice_status_prohibits_operation: 'Invoice status prohibits operation'
|
||||||
|
|
||||||
user:
|
user:
|
||||||
attributes:
|
attributes:
|
||||||
|
|
|
@ -71,12 +71,27 @@ Rails.application.routes.draw do
|
||||||
resources :contacts do
|
resources :contacts do
|
||||||
collection do
|
collection do
|
||||||
get 'check/:id', to: 'contacts#check'
|
get 'check/:id', to: 'contacts#check'
|
||||||
|
get 'search(/:id)', to: 'contacts#search'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :accounts do
|
resource :account, controller: :account, only: %i[index update] do
|
||||||
collection do
|
collection do
|
||||||
|
get '/', to: 'account#index'
|
||||||
get 'balance'
|
get 'balance'
|
||||||
|
get 'details'
|
||||||
|
post 'update_auto_reload_balance'
|
||||||
|
get 'disable_auto_reload_balance'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
resources :invoices, only: %i[index show] do
|
||||||
|
collection do
|
||||||
|
get ':id/download', to: 'invoices#download'
|
||||||
|
get ':id/cancel', to: 'invoices#cancel'
|
||||||
|
post 'add_credit'
|
||||||
|
end
|
||||||
|
member do
|
||||||
|
post 'send_to_recipient', to: 'invoices#send_to_recipient'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
resources :auctions, only: %i[index]
|
resources :auctions, only: %i[index]
|
||||||
|
@ -98,6 +113,13 @@ Rails.application.routes.draw do
|
||||||
put '/', to: 'nameservers#update'
|
put '/', to: 'nameservers#update'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
resources :summary, only: %i[index]
|
||||||
|
resources :auth, only: %i[index] do
|
||||||
|
collection do
|
||||||
|
post '/tara_callback', to: 'auth#tara_callback'
|
||||||
|
put '/switch_user', to: 'auth#switch_user'
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
resources :domains, constraints: { id: /.*/ } do
|
resources :domains, constraints: { id: /.*/ } do
|
||||||
resources :nameservers, only: %i[index create destroy], constraints: { id: /.*/ }, controller: 'domains/nameservers'
|
resources :nameservers, only: %i[index create destroy], constraints: { id: /.*/ }, controller: 'domains/nameservers'
|
||||||
|
@ -146,9 +168,9 @@ Rails.application.routes.draw do
|
||||||
namespace :accreditation_center do
|
namespace :accreditation_center do
|
||||||
# At the moment invoice_status endpoint returns only cancelled invoices. But in future logic of this enpoint can change.
|
# At the moment invoice_status endpoint returns only cancelled invoices. But in future logic of this enpoint can change.
|
||||||
# And it will need to return invoices of different statuses. I decided to leave the name of the endpoint "invoice_status"
|
# And it will need to return invoices of different statuses. I decided to leave the name of the endpoint "invoice_status"
|
||||||
resources :invoice_status, only: [ :index ]
|
resources :invoice_status, only: [:index]
|
||||||
resource :domains, only: [ :show ], param: :name
|
resource :domains, only: [:show], param: :name
|
||||||
resource :contacts, only: [ :show ], param: :id
|
resource :contacts, only: [:show], param: :id
|
||||||
# resource :auth, only: [ :index ]
|
# resource :auth, only: [ :index ]
|
||||||
get 'auth', to: 'auth#index'
|
get 'auth', to: 'auth#index'
|
||||||
end
|
end
|
||||||
|
@ -159,7 +181,7 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
match '*all', controller: 'cors', action: 'cors_preflight_check', via: [:options],
|
match '*all', controller: 'cors', action: 'cors_preflight_check', via: [:options],
|
||||||
as: 'cors_preflight_check'
|
as: 'cors_preflight_check'
|
||||||
end
|
end
|
||||||
|
|
||||||
# REGISTRAR ROUTES
|
# REGISTRAR ROUTES
|
||||||
|
|
|
@ -3,22 +3,32 @@ module Serializers
|
||||||
class Contact
|
class Contact
|
||||||
attr_reader :contact
|
attr_reader :contact
|
||||||
|
|
||||||
def initialize(contact, show_address:)
|
def initialize(contact, options = {})
|
||||||
@contact = contact
|
@contact = contact
|
||||||
@show_address = show_address
|
@show_address = options[:show_address]
|
||||||
|
@domain_params = options[:domain_params] || nil
|
||||||
|
@simplify = options[:simplify] || false
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_json(obj = contact)
|
def to_json(obj = contact)
|
||||||
json = { id: obj.code, name: obj.name, ident: ident,
|
return simple_object if @simplify
|
||||||
email: obj.email, phone: obj.phone,
|
|
||||||
auth_info: obj.auth_info, statuses: obj.statuses,
|
|
||||||
disclosed_attributes: obj.disclosed_attributes }
|
|
||||||
|
|
||||||
|
json = { id: obj.uuid, code: obj.code, name: obj.name, ident: ident,
|
||||||
|
email: obj.email, phone: obj.phone, created_at: obj.created_at,
|
||||||
|
auth_info: obj.auth_info, statuses: statuses,
|
||||||
|
disclosed_attributes: obj.disclosed_attributes, registrar: registrar }
|
||||||
json[:address] = address if @show_address
|
json[:address] = address if @show_address
|
||||||
|
if @domain_params
|
||||||
|
json[:domains] = domains
|
||||||
|
json[:domains_count] = obj.qualified_domain_ids(@domain_params[:domain_filter]).size
|
||||||
|
end
|
||||||
json
|
json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def registrar
|
||||||
|
contact.registrar.as_json(only: %i[name website])
|
||||||
|
end
|
||||||
|
|
||||||
def ident
|
def ident
|
||||||
{
|
{
|
||||||
code: contact.ident,
|
code: contact.ident,
|
||||||
|
@ -31,6 +41,34 @@ module Serializers
|
||||||
{ street: contact.street, zip: contact.zip, city: contact.city,
|
{ street: contact.street, zip: contact.zip, city: contact.city,
|
||||||
state: contact.state, country_code: contact.country_code }
|
state: contact.state, country_code: contact.country_code }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def domains
|
||||||
|
contact.all_domains(page: @domain_params[:page],
|
||||||
|
per: @domain_params[:per_page],
|
||||||
|
params: @domain_params)
|
||||||
|
.map do |d|
|
||||||
|
{ id: d.uuid, name: d.name, registrar: { name: d.registrar.name },
|
||||||
|
valid_to: d.valid_to, roles: d.roles }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def statuses
|
||||||
|
statuses_with_notes = contact.status_notes
|
||||||
|
contact.statuses.each do |status|
|
||||||
|
statuses_with_notes.merge!({ "#{status}": '' }) unless statuses_with_notes.key?(status)
|
||||||
|
end
|
||||||
|
statuses_with_notes
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def simple_object
|
||||||
|
{
|
||||||
|
id: contact.uuid,
|
||||||
|
code: contact.code,
|
||||||
|
name: contact.name,
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,19 +3,25 @@ module Serializers
|
||||||
class Domain
|
class Domain
|
||||||
attr_reader :domain
|
attr_reader :domain
|
||||||
|
|
||||||
def initialize(domain, sponsored: true)
|
def initialize(domain, sponsored: true, simplify: false)
|
||||||
@domain = domain
|
@domain = domain
|
||||||
@sponsored = sponsored
|
@sponsored = sponsored
|
||||||
|
@simplify = simplify
|
||||||
end
|
end
|
||||||
|
|
||||||
# rubocop:disable Metrics/AbcSize
|
# rubocop:disable Metrics/AbcSize
|
||||||
def to_json(obj = domain)
|
def to_json(obj = domain)
|
||||||
|
return simple_object if @simplify
|
||||||
|
|
||||||
json = {
|
json = {
|
||||||
name: obj.name, registrant: obj.registrant.code, created_at: obj.created_at,
|
id: obj.uuid, name: obj.name, registrant: registrant,
|
||||||
updated_at: obj.updated_at, expire_time: obj.expire_time, outzone_at: obj.outzone_at,
|
created_at: obj.created_at, updated_at: obj.updated_at,
|
||||||
delete_date: obj.delete_date, force_delete_date: obj.force_delete_date,
|
expire_time: obj.expire_time,
|
||||||
contacts: contacts, nameservers: nameservers, dnssec_keys: dnssec_keys,
|
outzone_at: obj.outzone_at, delete_date: obj.delete_date,
|
||||||
statuses: obj.status_notes, registrar: registrar
|
force_delete_date: obj.force_delete_date, contacts: contacts,
|
||||||
|
nameservers: nameservers, dnssec_keys: dnssec_keys,
|
||||||
|
statuses: statuses, registrar: registrar,
|
||||||
|
dispute: Dispute.active.exists?(domain_name: obj.name)
|
||||||
}
|
}
|
||||||
json[:transfer_code] = obj.auth_info if @sponsored
|
json[:transfer_code] = obj.auth_info if @sponsored
|
||||||
json
|
json
|
||||||
|
@ -23,22 +29,54 @@ module Serializers
|
||||||
# rubocop:enable Metrics/AbcSize
|
# rubocop:enable Metrics/AbcSize
|
||||||
|
|
||||||
def contacts
|
def contacts
|
||||||
domain.domain_contacts.map { |c| { code: c.contact.code, type: c.type } }
|
domain.domain_contacts.includes(:contact).map do |dc|
|
||||||
end
|
contact = dc.contact
|
||||||
|
{ code: contact.code, type: dc.type,
|
||||||
def nameservers
|
name: contact.name_disclosed_by_registrar(domain.registrar_id) }
|
||||||
domain.nameservers.map { |ns| { hostname: ns.hostname, ipv4: ns.ipv4, ipv6: ns.ipv6 } }
|
|
||||||
end
|
|
||||||
|
|
||||||
def dnssec_keys
|
|
||||||
domain.dnskeys.map do |nssec|
|
|
||||||
{ flags: nssec.flags, protocol: nssec.protocol, alg: nssec.alg,
|
|
||||||
public_key: nssec.public_key }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def nameservers
|
||||||
|
domain.nameservers.order(:created_at).as_json(only: %i[id hostname ipv4 ipv6])
|
||||||
|
end
|
||||||
|
|
||||||
|
def dnssec_keys
|
||||||
|
domain.dnskeys.order(:updated_at).as_json(only: %i[id flags protocol alg public_key])
|
||||||
|
end
|
||||||
|
|
||||||
def registrar
|
def registrar
|
||||||
{ name: domain.registrar.name, website: domain.registrar.website }
|
domain.registrar.as_json(only: %i[name website])
|
||||||
|
end
|
||||||
|
|
||||||
|
def registrant
|
||||||
|
rant = domain.registrant
|
||||||
|
{
|
||||||
|
id: rant.uuid,
|
||||||
|
name: rant.name,
|
||||||
|
code: rant.code,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def statuses
|
||||||
|
statuses_with_notes = domain.status_notes
|
||||||
|
domain.statuses.each do |status|
|
||||||
|
statuses_with_notes.merge!({ "#{status}": '' }) unless statuses_with_notes.key?(status)
|
||||||
|
end
|
||||||
|
statuses_with_notes
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def simple_object
|
||||||
|
json = {
|
||||||
|
id: domain.uuid,
|
||||||
|
name: domain.name,
|
||||||
|
expire_time: domain.expire_time,
|
||||||
|
registrant: registrant,
|
||||||
|
statuses: statuses,
|
||||||
|
}
|
||||||
|
json[:transfer_code] = domain.auth_info if @sponsored
|
||||||
|
json
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
85
lib/serializers/repp/invoice.rb
Normal file
85
lib/serializers/repp/invoice.rb
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
module Serializers
|
||||||
|
module Repp
|
||||||
|
class Invoice
|
||||||
|
attr_reader :invoice
|
||||||
|
|
||||||
|
def initialize(invoice, simplify: false)
|
||||||
|
@invoice = invoice
|
||||||
|
@simplify = simplify
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_json(obj = invoice)
|
||||||
|
return simple_object if @simplify
|
||||||
|
|
||||||
|
{
|
||||||
|
id: obj.id, issue_date: obj.issue_date, cancelled_at: obj.cancelled_at,
|
||||||
|
paid: obj.paid?, payable: obj.payable?, cancellable: invoice.cancellable?,
|
||||||
|
receipt_date: obj.receipt_date, payment_link: obj.payment_link,
|
||||||
|
number: obj.number, subtotal: obj.subtotal, vat_amount: obj.vat_amount,
|
||||||
|
vat_rate: obj.vat_rate, total: obj.total,
|
||||||
|
description: obj.description, reference_no: obj.reference_no,
|
||||||
|
created_at: obj.created_at, updated_at: obj.updated_at,
|
||||||
|
due_date: obj.due_date, currency: obj.currency,
|
||||||
|
seller: seller, buyer: buyer, items: items,
|
||||||
|
recipient: obj.buyer.billing_email
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def seller
|
||||||
|
{
|
||||||
|
name: invoice.seller_name,
|
||||||
|
reg_no: invoice.seller_reg_no,
|
||||||
|
iban: invoice.seller_iban,
|
||||||
|
bank: invoice.seller_bank,
|
||||||
|
swift: invoice.seller_swift,
|
||||||
|
vat_no: invoice.seller_vat_no,
|
||||||
|
address: invoice.seller_address,
|
||||||
|
country: invoice.seller_country.name,
|
||||||
|
phone: invoice.seller_phone,
|
||||||
|
url: invoice.seller_url,
|
||||||
|
email: invoice.seller_email,
|
||||||
|
contact_name: invoice.seller_contact_name,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def buyer
|
||||||
|
{
|
||||||
|
name: invoice.buyer_name,
|
||||||
|
reg_no: invoice.buyer_reg_no,
|
||||||
|
address: invoice.buyer_address,
|
||||||
|
country: invoice.buyer_country.name,
|
||||||
|
phone: invoice.buyer_phone,
|
||||||
|
url: invoice.buyer_url,
|
||||||
|
email: invoice.buyer_email,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def items
|
||||||
|
invoice.items.map do |item|
|
||||||
|
{ description: item.description, unit: item.unit,
|
||||||
|
quantity: item.quantity, price: item.price,
|
||||||
|
sum_without_vat: item.item_sum_without_vat,
|
||||||
|
vat_amount: item.vat_amount, total: item.total }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def simple_object
|
||||||
|
{
|
||||||
|
id: invoice.id,
|
||||||
|
number: invoice.number,
|
||||||
|
paid: invoice.paid?,
|
||||||
|
payable: invoice.payable?,
|
||||||
|
payment_link: invoice.payment_link,
|
||||||
|
receipt_date: invoice.receipt_date,
|
||||||
|
cancelled: invoice.cancelled?,
|
||||||
|
cancellable: invoice.cancellable?,
|
||||||
|
due_date: invoice.due_date,
|
||||||
|
total: invoice.total,
|
||||||
|
recipient: invoice.buyer.billing_email,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -56,7 +56,7 @@ class EppPollTest < EppTestCase
|
||||||
bulk_action = actions(:contacts_update_bulk_action)
|
bulk_action = actions(:contacts_update_bulk_action)
|
||||||
@notification.update!(action: bulk_action,
|
@notification.update!(action: bulk_action,
|
||||||
attached_obj_id: bulk_action.id,
|
attached_obj_id: bulk_action.id,
|
||||||
attached_obj_type: 'BulkAction')
|
attached_obj_type: 'ContactUpdateAction')
|
||||||
|
|
||||||
post epp_poll_path, params: { frame: request_req_xml },
|
post epp_poll_path, params: { frame: request_req_xml },
|
||||||
headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
|
headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
|
||||||
|
|
|
@ -11,7 +11,7 @@ class ReppV1BalanceTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_can_query_balance
|
def test_can_query_balance
|
||||||
get '/repp/v1/accounts/balance', headers: @auth_headers
|
get '/repp/v1/account/balance', headers: @auth_headers
|
||||||
json = JSON.parse(response.body, symbolize_names: true)
|
json = JSON.parse(response.body, symbolize_names: true)
|
||||||
|
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
|
@ -28,7 +28,7 @@ class ReppV1BalanceTest < ActionDispatch::IntegrationTest
|
||||||
started_from = "2010-07-05"
|
started_from = "2010-07-05"
|
||||||
end_to = DateTime.current.to_date.to_s(:db)
|
end_to = DateTime.current.to_date.to_s(:db)
|
||||||
|
|
||||||
get "/repp/v1/accounts/balance?detailed=true", headers: @auth_headers
|
get "/repp/v1/account/balance?detailed=true", headers: @auth_headers
|
||||||
json = JSON.parse(response.body, symbolize_names: true)
|
json = JSON.parse(response.body, symbolize_names: true)
|
||||||
|
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
|
@ -44,8 +44,8 @@ class ReppV1BalanceTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal @registrar.registrar.cash_account.account_activities.last.new_balance.to_s, entry[:balance]
|
assert_equal @registrar.registrar.cash_account.account_activities.last.new_balance.to_s, entry[:balance]
|
||||||
|
|
||||||
json[:data][:transactions].map do |trans|
|
json[:data][:transactions].map do |trans|
|
||||||
assert trans[:created_at].to_date.to_s(:db) >= started_from
|
assert trans[:created_at].to_date.to_s(:db) >= started_from
|
||||||
assert trans[:created_at].to_date.to_s(:db) >= end_to
|
assert trans[:created_at].to_date.to_s(:db) >= end_to
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -11,16 +11,16 @@ class ReppV1ContactsCreateTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
def test_creates_new_contact
|
def test_creates_new_contact
|
||||||
request_body = {
|
request_body = {
|
||||||
"contact": {
|
contact: {
|
||||||
"name": "Donald Trump",
|
name: 'Donald Trump',
|
||||||
"phone": "+372.51111112",
|
phone: '+372.51111112',
|
||||||
"email": "donald@trumptower.com",
|
email: 'donald@trumptower.com',
|
||||||
"ident": {
|
ident: {
|
||||||
"ident_type": "priv",
|
ident_type: 'priv',
|
||||||
"ident_country_code": "EE",
|
ident_country_code: 'EE',
|
||||||
"ident": "39708290069"
|
ident: '39708290069',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
post '/repp/v1/contacts', headers: @auth_headers, params: request_body
|
post '/repp/v1/contacts', headers: @auth_headers, params: request_body
|
||||||
|
@ -30,7 +30,7 @@ class ReppV1ContactsCreateTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal 1000, json[:code]
|
assert_equal 1000, json[:code]
|
||||||
assert_equal 'Command completed successfully', json[:message]
|
assert_equal 'Command completed successfully', json[:message]
|
||||||
|
|
||||||
contact = Contact.find_by(code: json[:data][:contact][:id])
|
contact = Contact.find_by(code: json[:data][:contact][:code])
|
||||||
assert contact.present?
|
assert contact.present?
|
||||||
|
|
||||||
assert_equal(request_body[:contact][:name], contact.name)
|
assert_equal(request_body[:contact][:name], contact.name)
|
||||||
|
@ -42,21 +42,21 @@ class ReppV1ContactsCreateTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_removes_postal_info_when_contact_created
|
def test_removes_postal_info_when_contact_created
|
||||||
request_body = {
|
request_body = {
|
||||||
"contact": {
|
contact: {
|
||||||
"name": "Donald Trump",
|
name: 'Donald Trump',
|
||||||
"phone": "+372.51111111",
|
phone: '+372.51111111',
|
||||||
"email": "donald@trump.com",
|
email: 'donald@trump.com',
|
||||||
"ident": {
|
ident: {
|
||||||
"ident_type": "priv",
|
ident_type: 'priv',
|
||||||
"ident_country_code": "EE",
|
ident_country_code: 'EE',
|
||||||
"ident": "39708290069"
|
ident: '39708290069',
|
||||||
},
|
},
|
||||||
"addr": {
|
addr: {
|
||||||
"city": "Tallinn",
|
city: 'Tallinn',
|
||||||
"street": "Wismari 13",
|
street: 'Wismari 13',
|
||||||
"zip": "12345",
|
zip: '12345',
|
||||||
"country_code": "EE"
|
country_code: 'EE',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ class ReppV1ContactsCreateTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal 1100, json[:code]
|
assert_equal 1100, json[:code]
|
||||||
assert_equal 'Command completed successfully; Postal address data discarded', json[:message]
|
assert_equal 'Command completed successfully; Postal address data discarded', json[:message]
|
||||||
|
|
||||||
contact = Contact.find_by(code: json[:data][:contact][:id])
|
contact = Contact.find_by(code: json[:data][:contact][:code])
|
||||||
assert contact.present?
|
assert contact.present?
|
||||||
|
|
||||||
assert_nil contact.city
|
assert_nil contact.city
|
||||||
|
@ -126,21 +126,21 @@ class ReppV1ContactsCreateTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_attaches_legaldoc_if_present
|
def test_attaches_legaldoc_if_present
|
||||||
request_body = {
|
request_body = {
|
||||||
"contact": {
|
contact: {
|
||||||
"name": "Donald Trump",
|
name: 'Donald Trump',
|
||||||
"phone": "+372.51111112",
|
phone: '+372.51111112',
|
||||||
"email": "donald@trumptower.com",
|
email: 'donald@trumptower.com',
|
||||||
"ident": {
|
ident: {
|
||||||
"ident_type": "priv",
|
ident_type: 'priv',
|
||||||
"ident_country_code": "EE",
|
ident_country_code: 'EE',
|
||||||
"ident": "39708290069"
|
ident: '39708290069',
|
||||||
|
},
|
||||||
|
legal_document: {
|
||||||
|
type: 'pdf',
|
||||||
|
body: ('test' * 2000).to_s,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"legal_document": {
|
|
||||||
"type": "pdf",
|
|
||||||
"body": "#{'test' * 2000}"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
post '/repp/v1/contacts', headers: @auth_headers, params: request_body
|
post '/repp/v1/contacts', headers: @auth_headers, params: request_body
|
||||||
|
@ -150,7 +150,7 @@ class ReppV1ContactsCreateTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal 1000, json[:code]
|
assert_equal 1000, json[:code]
|
||||||
assert_equal 'Command completed successfully', json[:message]
|
assert_equal 'Command completed successfully', json[:message]
|
||||||
|
|
||||||
contact = Contact.find_by(code: json[:data][:contact][:id])
|
contact = Contact.find_by(code: json[:data][:contact][:code])
|
||||||
assert contact.legal_documents.any?
|
assert contact.legal_documents.any?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,13 +12,13 @@ class ReppV1ContactsListTest < ActionDispatch::IntegrationTest
|
||||||
def test_returns_registrar_contacts
|
def test_returns_registrar_contacts
|
||||||
get repp_v1_contacts_path, headers: @auth_headers
|
get repp_v1_contacts_path, headers: @auth_headers
|
||||||
json = JSON.parse(response.body, symbolize_names: true)
|
json = JSON.parse(response.body, symbolize_names: true)
|
||||||
|
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
|
|
||||||
assert_equal @user.registrar.contacts.count, json[:total_number_of_records]
|
assert_equal @user.registrar.contacts.count, json[:data][:count]
|
||||||
assert_equal @user.registrar.contacts.count, json[:contacts].length
|
assert_equal @user.registrar.contacts.count, json[:data][:contacts].length
|
||||||
|
|
||||||
assert json[:contacts][0].is_a? String
|
assert json[:data][:contacts][0].is_a? String
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,10 +28,10 @@ class ReppV1ContactsListTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
|
|
||||||
assert_equal @user.registrar.contacts.count, json[:total_number_of_records]
|
assert_equal @user.registrar.contacts.count, json[:data][:count]
|
||||||
assert_equal @user.registrar.contacts.count, json[:contacts].length
|
assert_equal @user.registrar.contacts.count, json[:data][:contacts].length
|
||||||
|
|
||||||
assert json[:contacts][0].is_a? Hash
|
assert json[:data][:contacts][0].is_a? Hash
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_respects_limit
|
def test_respects_limit
|
||||||
|
@ -40,7 +40,7 @@ class ReppV1ContactsListTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
|
|
||||||
assert_equal 2, json[:contacts].length
|
assert_equal 2, json[:data][:contacts].length
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_respects_offset
|
def test_respects_offset
|
||||||
|
@ -50,6 +50,6 @@ class ReppV1ContactsListTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
|
|
||||||
assert_equal (@user.registrar.contacts.count - offset), json[:contacts].length
|
assert_equal (@user.registrar.contacts.count - offset), json[:data][:contacts].length
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,7 +28,7 @@ class ReppV1ContactsShowTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal 1000, json[:code]
|
assert_equal 1000, json[:code]
|
||||||
assert_equal 'Command completed successfully', json[:message]
|
assert_equal 'Command completed successfully', json[:message]
|
||||||
|
|
||||||
assert_equal contact.code, json[:data][:id]
|
assert_equal contact.code, json[:data][:contact][:code]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_can_not_access_out_of_scope_contacts
|
def test_can_not_access_out_of_scope_contacts
|
||||||
|
|
|
@ -24,14 +24,14 @@ class ReppV1ContactsUpdateTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal 1000, json[:code]
|
assert_equal 1000, json[:code]
|
||||||
assert_equal 'Command completed successfully', json[:message]
|
assert_equal 'Command completed successfully', json[:message]
|
||||||
|
|
||||||
contact = Contact.find_by(code: json[:data][:contact][:id])
|
contact = Contact.find_by(code: json[:data][:contact][:code])
|
||||||
assert contact.present?
|
assert contact.present?
|
||||||
|
|
||||||
assert_equal(request_body[:contact][:email], contact.email)
|
assert_equal(request_body[:contact][:email], contact.email)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_removes_postal_info_when_updated
|
def test_removes_postal_info_when_updated
|
||||||
request_body = {
|
request_body = {
|
||||||
"contact": {
|
"contact": {
|
||||||
"addr": {
|
"addr": {
|
||||||
"city": "Tallinn",
|
"city": "Tallinn",
|
||||||
|
@ -49,7 +49,7 @@ class ReppV1ContactsUpdateTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal 1100, json[:code]
|
assert_equal 1100, json[:code]
|
||||||
assert_equal 'Command completed successfully; Postal address data discarded', json[:message]
|
assert_equal 'Command completed successfully; Postal address data discarded', json[:message]
|
||||||
|
|
||||||
contact = Contact.find_by(code: json[:data][:contact][:id])
|
contact = Contact.find_by(code: json[:data][:contact][:code])
|
||||||
assert contact.present?
|
assert contact.present?
|
||||||
|
|
||||||
assert_nil contact.city
|
assert_nil contact.city
|
||||||
|
@ -81,14 +81,14 @@ class ReppV1ContactsUpdateTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_attaches_legaldoc_if_present
|
def test_attaches_legaldoc_if_present
|
||||||
request_body = {
|
request_body = {
|
||||||
"contact": {
|
contact: {
|
||||||
"email": "donaldtrump@yandex.ru"
|
email: 'donaldtrump@yandex.ru',
|
||||||
|
legal_document: {
|
||||||
|
type: 'pdf',
|
||||||
|
body: ('test' * 2000).to_s,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"legal_document": {
|
|
||||||
"type": "pdf",
|
|
||||||
"body": "#{'test' * 2000}"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
put "/repp/v1/contacts/#{@contact.code}", headers: @auth_headers, params: request_body
|
put "/repp/v1/contacts/#{@contact.code}", headers: @auth_headers, params: request_body
|
||||||
|
@ -103,9 +103,11 @@ class ReppV1ContactsUpdateTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_returns_error_if_ident_wrong_format
|
def test_returns_error_if_ident_wrong_format
|
||||||
request_body = {
|
request_body = {
|
||||||
"contact": {
|
contact: {
|
||||||
"ident": "123"
|
ident: {
|
||||||
|
ident: '123',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class ReppV1DomainsContactReplacementTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"current_contact_id": replaceable_contact.code,
|
"current_contact_id": replaceable_contact.code,
|
||||||
"new_contact_id": replacing_contact.code
|
"new_contact_id": replacing_contact.code,
|
||||||
}
|
}
|
||||||
|
|
||||||
patch '/repp/v1/domains/contacts', headers: @auth_headers, params: payload
|
patch '/repp/v1/domains/contacts', headers: @auth_headers, params: payload
|
||||||
|
@ -37,7 +37,7 @@ class ReppV1DomainsContactReplacementTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"current_contact_id": replaceable_contact.code,
|
"current_contact_id": replaceable_contact.code,
|
||||||
"new_contact_id": replacing_contact.code
|
"new_contact_id": replacing_contact.code,
|
||||||
}
|
}
|
||||||
|
|
||||||
patch '/repp/v1/domains/contacts', headers: @auth_headers, params: payload
|
patch '/repp/v1/domains/contacts', headers: @auth_headers, params: payload
|
||||||
|
@ -51,7 +51,7 @@ class ReppV1DomainsContactReplacementTest < ActionDispatch::IntegrationTest
|
||||||
def test_contact_codes_must_be_valid
|
def test_contact_codes_must_be_valid
|
||||||
payload = {
|
payload = {
|
||||||
"current_contact_id": 'dfgsdfg',
|
"current_contact_id": 'dfgsdfg',
|
||||||
"new_contact_id": 'vvv'
|
"new_contact_id": 'vvv',
|
||||||
}
|
}
|
||||||
|
|
||||||
patch '/repp/v1/domains/contacts', headers: @auth_headers, params: payload
|
patch '/repp/v1/domains/contacts', headers: @auth_headers, params: payload
|
||||||
|
@ -61,5 +61,4 @@ class ReppV1DomainsContactReplacementTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal 2303, json[:code]
|
assert_equal 2303, json[:code]
|
||||||
assert_equal 'Object does not exist', json[:message]
|
assert_equal 'Object does not exist', json[:message]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,9 +15,11 @@ class ReppV1DomainsDeleteTest < ActionDispatch::IntegrationTest
|
||||||
@auth_headers['Content-Type'] = 'application/json'
|
@auth_headers['Content-Type'] = 'application/json'
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
delete: {
|
domain: {
|
||||||
verified: false
|
delete: {
|
||||||
}
|
verified: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
delete "/repp/v1/domains/#{@domain.name}", headers: @auth_headers, params: payload.to_json
|
delete "/repp/v1/domains/#{@domain.name}", headers: @auth_headers, params: payload.to_json
|
||||||
|
@ -36,9 +38,11 @@ class ReppV1DomainsDeleteTest < ActionDispatch::IntegrationTest
|
||||||
@auth_headers['Content-Type'] = 'application/json'
|
@auth_headers['Content-Type'] = 'application/json'
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
delete: {
|
domain: {
|
||||||
verified: true
|
delete: {
|
||||||
}
|
verified: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
delete "/repp/v1/domains/#{@domain.name}", headers: @auth_headers, params: payload.to_json
|
delete "/repp/v1/domains/#{@domain.name}", headers: @auth_headers, params: payload.to_json
|
||||||
|
|
|
@ -15,7 +15,7 @@ class ReppV1DomainsListTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
|
|
||||||
assert_equal @user.registrar.domains.count, json[:data][:total_number_of_records]
|
assert_equal @user.registrar.domains.count, json[:data][:count]
|
||||||
assert_equal @user.registrar.domains.count, json[:data][:domains].length
|
assert_equal @user.registrar.domains.count, json[:data][:domains].length
|
||||||
|
|
||||||
assert json[:data][:domains][0].is_a? String
|
assert json[:data][:domains][0].is_a? String
|
||||||
|
@ -27,7 +27,7 @@ class ReppV1DomainsListTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
|
|
||||||
assert_equal @user.registrar.domains.count, json[:data][:total_number_of_records]
|
assert_equal @user.registrar.domains.count, json[:data][:count]
|
||||||
assert_equal @user.registrar.domains.count, json[:data][:domains].length
|
assert_equal @user.registrar.domains.count, json[:data][:domains].length
|
||||||
|
|
||||||
assert json[:data][:domains][0].is_a? Hash
|
assert json[:data][:domains][0].is_a? Hash
|
||||||
|
|
|
@ -18,7 +18,7 @@ class ReppV1DomainsRenewsTest < ActionDispatch::IntegrationTest
|
||||||
:prepare_renewed_expire_time).and_call_through
|
:prepare_renewed_expire_time).and_call_through
|
||||||
|
|
||||||
@auth_headers['Content-Type'] = 'application/json'
|
@auth_headers['Content-Type'] = 'application/json'
|
||||||
payload = { renew: { period: 1, period_unit: 'y', exp_date: original_valid_to } }
|
payload = { renews: { period: 1, period_unit: 'y', exp_date: original_valid_to } }
|
||||||
post "/repp/v1/domains/#{@domain.name}/renew", headers: @auth_headers, params: payload.to_json
|
post "/repp/v1/domains/#{@domain.name}/renew", headers: @auth_headers, params: payload.to_json
|
||||||
json = JSON.parse(response.body, symbolize_names: true)
|
json = JSON.parse(response.body, symbolize_names: true)
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class ReppV1DomainsRenewsTest < ActionDispatch::IntegrationTest
|
||||||
travel_to Time.zone.parse('2010-07-05')
|
travel_to Time.zone.parse('2010-07-05')
|
||||||
|
|
||||||
@auth_headers['Content-Type'] = 'application/json'
|
@auth_headers['Content-Type'] = 'application/json'
|
||||||
payload = { renew: { period: 10, period_unit: 'y', exp_date: original_valid_to } }
|
payload = { renews: { period: 10, period_unit: 'y', exp_date: original_valid_to } }
|
||||||
post "/repp/v1/domains/#{@domain.name}/renew", headers: @auth_headers, params: payload.to_json
|
post "/repp/v1/domains/#{@domain.name}/renew", headers: @auth_headers, params: payload.to_json
|
||||||
json = JSON.parse(response.body, symbolize_names: true)
|
json = JSON.parse(response.body, symbolize_names: true)
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ class ReppV1DomainsRenewsTest < ActionDispatch::IntegrationTest
|
||||||
one_year.reload
|
one_year.reload
|
||||||
|
|
||||||
@auth_headers['Content-Type'] = 'application/json'
|
@auth_headers['Content-Type'] = 'application/json'
|
||||||
payload = { renew: { period: 1, period_unit: 'y', exp_date: original_valid_to } }
|
payload = { renews: { period: 1, period_unit: 'y', exp_date: original_valid_to } }
|
||||||
post "/repp/v1/domains/#{@domain.name}/renew", headers: @auth_headers, params: payload.to_json
|
post "/repp/v1/domains/#{@domain.name}/renew", headers: @auth_headers, params: payload.to_json
|
||||||
json = JSON.parse(response.body, symbolize_names: true)
|
json = JSON.parse(response.body, symbolize_names: true)
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@ class ReppV1DomainsUpdateTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
domain: {
|
domain: {
|
||||||
auth_code: new_auth_code
|
auth_code: new_auth_code,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
put "/repp/v1/domains/#{@domain.name}", headers: @auth_headers, params: payload.to_json
|
put "/repp/v1/domains/#{@domain.name}", headers: @auth_headers, params: payload.to_json
|
||||||
|
@ -40,9 +40,9 @@ class ReppV1DomainsUpdateTest < ActionDispatch::IntegrationTest
|
||||||
payload = {
|
payload = {
|
||||||
domain: {
|
domain: {
|
||||||
registrant: {
|
registrant: {
|
||||||
code: new_registrant.code
|
code: new_registrant.code,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
put "/repp/v1/domains/#{@domain.name}", headers: @auth_headers, params: payload.to_json
|
put "/repp/v1/domains/#{@domain.name}", headers: @auth_headers, params: payload.to_json
|
||||||
|
@ -67,13 +67,14 @@ class ReppV1DomainsUpdateTest < ActionDispatch::IntegrationTest
|
||||||
domain: {
|
domain: {
|
||||||
registrant: {
|
registrant: {
|
||||||
code: new_registrant.code,
|
code: new_registrant.code,
|
||||||
verified: true
|
verified: true,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
put "/repp/v1/domains/#{@domain.name}", headers: @auth_headers, params: payload.to_json
|
put "/repp/v1/domains/#{@domain.name}", headers: @auth_headers, params: payload.to_json
|
||||||
@domain.reload
|
@domain.reload
|
||||||
|
|
||||||
json = JSON.parse(response.body, symbolize_names: true)
|
json = JSON.parse(response.body, symbolize_names: true)
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
assert_equal 1000, json[:code]
|
assert_equal 1000, json[:code]
|
||||||
|
|
|
@ -60,6 +60,8 @@ class RegistrantUserTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
bulk_action = @user.actions.where(operation: :bulk_update).last
|
bulk_action = @user.actions.where(operation: :bulk_update).last
|
||||||
|
single_action = @user.actions.find_by(operation: :update,
|
||||||
|
contact_id: contacts(:identical_to_william).id)
|
||||||
|
|
||||||
assert_equal 4, bulk_action.subactions.size
|
assert_equal 4, bulk_action.subactions.size
|
||||||
|
|
||||||
|
@ -67,14 +69,14 @@ class RegistrantUserTest < ActiveSupport::TestCase
|
||||||
notification = r.notifications.unread.order('created_at DESC').take
|
notification = r.notifications.unread.order('created_at DESC').take
|
||||||
if r == registrars(:bestnames)
|
if r == registrars(:bestnames)
|
||||||
assert_equal '4 contacts have been updated by registrant', notification.text
|
assert_equal '4 contacts have been updated by registrant', notification.text
|
||||||
assert_equal 'BulkAction', notification.attached_obj_type
|
assert_equal 'ContactUpdateAction', notification.attached_obj_type
|
||||||
assert_equal bulk_action.id, notification.attached_obj_id
|
assert_equal bulk_action.id, notification.attached_obj_id
|
||||||
assert_equal bulk_action.id, notification.action_id
|
assert_equal bulk_action.id, notification.action_id
|
||||||
else
|
else
|
||||||
assert_equal 'Contact william-002 has been updated by registrant', notification.text
|
assert_equal 'Contact william-002 has been updated by registrant', notification.text
|
||||||
refute notification.action_id
|
assert_equal 'ContactUpdateAction', notification.attached_obj_type
|
||||||
refute notification.attached_obj_id
|
assert_equal single_action.id, notification.attached_obj_id
|
||||||
refute notification.attached_obj_type
|
assert_equal single_action.id, notification.action_id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue