mirror of
https://github.com/internetee/registry.git
synced 2025-07-21 02:05:57 +02:00
Merge branch 'alpha' into staging
This commit is contained in:
commit
801b8bbb9c
80 changed files with 3151 additions and 1454 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,6 +9,7 @@ capybara-*.html
|
|||
/spec/tmp
|
||||
**.orig
|
||||
config/initializers/secret_token.rb
|
||||
config/deploy.rb
|
||||
config/secrets.yml
|
||||
config/database.yml
|
||||
/export
|
||||
|
|
|
@ -4,6 +4,7 @@ AllCops:
|
|||
Exclude:
|
||||
- 'Guardfile'
|
||||
# stuff generated by AR and rails
|
||||
- 'config/deploy-example.rb'
|
||||
- 'db/schema.rb'
|
||||
- 'db/schema-read-only.rb'
|
||||
- 'db/whois_schema.rb'
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
20.07.2015
|
||||
|
||||
* New syntax for setting webclient IP-s (see config/application-example.yml)
|
||||
* Example mina/deploy.rb renamed to mina/deploy-example.rb in order to not overwrite local deploy scripts
|
||||
|
||||
14.07.2015
|
||||
|
||||
|
|
|
@ -5,6 +5,11 @@ module Repp
|
|||
|
||||
http_basic do |username, password|
|
||||
@current_user ||= ApiUser.find_by(username: username, password: password)
|
||||
if @current_user
|
||||
true
|
||||
else
|
||||
error! I18n.t('api_user_not_found'), 401
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
|
|
|
@ -62,3 +62,6 @@ body > .container
|
|||
border: 1px solid #dddddd
|
||||
padding-left: 4px
|
||||
padding-right: 4px
|
||||
|
||||
.disabled-value
|
||||
padding-top: 8px
|
||||
|
|
|
@ -16,7 +16,18 @@ class Admin::BankStatementsController < AdminController
|
|||
end
|
||||
|
||||
def new
|
||||
@bank_statement = BankStatement.new
|
||||
@bank_statement = BankStatement.new(
|
||||
bank_code: Setting.registry_bank_code,
|
||||
iban: Setting.registry_iban
|
||||
)
|
||||
@invoice = Invoice.find_by(id: params[:invoice_id])
|
||||
@bank_transaction = @bank_statement.bank_transactions.build(
|
||||
description: @invoice.to_s,
|
||||
sum: @invoice.sum,
|
||||
reference_no: @invoice.reference_no,
|
||||
paid_at: Time.zone.now.to_date,
|
||||
currency: 'EUR'
|
||||
) if @invoice
|
||||
end
|
||||
|
||||
def create
|
||||
|
@ -69,6 +80,8 @@ class Admin::BankStatementsController < AdminController
|
|||
end
|
||||
|
||||
def bank_statement_params
|
||||
params.require(:bank_statement).permit(:th6_file, :bank_code, :iban)
|
||||
params.require(:bank_statement).permit(:th6_file, :bank_code, :iban, bank_transactions_attributes: [
|
||||
:description, :sum, :currency, :reference_no, :paid_at
|
||||
])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,9 +11,38 @@ class Admin::ContactsController < AdminController
|
|||
render json: Contact.search_by_query(params[:q])
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
cp = ignore_empty_statuses
|
||||
|
||||
if @contact.update(cp)
|
||||
flash[:notice] = I18n.t('contact_updated')
|
||||
redirect_to [:admin, @contact]
|
||||
else
|
||||
flash.now[:alert] = I18n.t('failed_to_update_contact')
|
||||
render 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_contact
|
||||
@contact = Contact.includes(domains: :registrar).find(params[:id])
|
||||
end
|
||||
|
||||
def contact_params
|
||||
if params[:contact]
|
||||
params.require(:contact).permit({ statuses: [], status_notes_array: [] })
|
||||
else
|
||||
{ statuses: [] }
|
||||
end
|
||||
end
|
||||
|
||||
def ignore_empty_statuses
|
||||
dp = contact_params
|
||||
dp[:statuses].reject!(&:blank?)
|
||||
dp
|
||||
end
|
||||
end
|
||||
|
|
|
@ -94,12 +94,26 @@ class Epp::ContactsController < EppController
|
|||
'postalInfo > addr > pc', 'postalInfo > addr > cc', 'voice', 'email'
|
||||
)
|
||||
ident = params[:parsed_frame].css('ident')
|
||||
|
||||
if ident.present? && ident.attr('type').blank?
|
||||
epp_errors << {
|
||||
code: '2003',
|
||||
msg: I18n.t('errors.messages.required_ident_attribute_missing', key: 'type')
|
||||
}
|
||||
end
|
||||
|
||||
if ident.present? && ident.text != 'birthday' && ident.attr('cc').blank?
|
||||
epp_errors << {
|
||||
code: '2003',
|
||||
msg: I18n.t('errors.messages.required_attribute_missing', key: 'ident country code missing')
|
||||
msg: I18n.t('errors.messages.required_ident_attribute_missing', key: 'cc')
|
||||
}
|
||||
end
|
||||
# if ident.present? && ident.attr('cc').blank?
|
||||
# epp_errors << {
|
||||
# code: '2003',
|
||||
# msg: I18n.t('errors.messages.required_ident_attribute_missing', key: 'cc')
|
||||
# }
|
||||
# end
|
||||
contact_org_disabled
|
||||
fax_disabled
|
||||
status_editing_disabled
|
||||
|
|
|
@ -25,6 +25,7 @@ class Epp::DomainsController < EppController
|
|||
@domain = Epp::Domain.new_from_epp(params[:parsed_frame], current_user)
|
||||
handle_errors(@domain) and return if @domain.errors.any?
|
||||
@domain.valid?
|
||||
@domain.errors.delete(:name_dirty) if @domain.errors[:puny_label].any?
|
||||
handle_errors(@domain) and return if @domain.errors.any?
|
||||
|
||||
handle_errors and return unless balance_ok?('create')
|
||||
|
@ -94,8 +95,9 @@ class Epp::DomainsController < EppController
|
|||
def renew
|
||||
authorize! :renew, @domain
|
||||
|
||||
period = params[:parsed_frame].css('period').text
|
||||
period_unit = params[:parsed_frame].css('period').first['unit']
|
||||
period_element = params[:parsed_frame].css('period').text
|
||||
period = (period_element.to_i == 0) ? 1 : period_element.to_i
|
||||
period_unit = Epp::Domain.parse_period_unit_from_frame(params[:parsed_frame]) || 'y'
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
success = @domain.renew(
|
||||
|
@ -129,10 +131,14 @@ class Epp::DomainsController < EppController
|
|||
|
||||
@domain_transfer = @domain.transfer(params[:parsed_frame], action, current_user)
|
||||
|
||||
if @domain.errors.empty? && @domain_transfer
|
||||
if @domain_transfer
|
||||
render_epp_response '/epp/domains/transfer'
|
||||
else
|
||||
handle_errors(@domain)
|
||||
epp_errors << {
|
||||
code: '2303',
|
||||
msg: I18n.t('no_transfers_found')
|
||||
}
|
||||
handle_errors
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -154,6 +160,8 @@ class Epp::DomainsController < EppController
|
|||
@prefix = nil
|
||||
requires 'extension > extdata > legalDocument'
|
||||
|
||||
optional_attribute 'period', 'unit', values: %w(d m y)
|
||||
|
||||
status_editing_disabled
|
||||
end
|
||||
|
||||
|
@ -182,7 +190,9 @@ class Epp::DomainsController < EppController
|
|||
|
||||
def validate_renew
|
||||
@prefix = 'renew > renew >'
|
||||
requires 'name', 'curExpDate', 'period'
|
||||
requires 'name', 'curExpDate'
|
||||
|
||||
optional_attribute 'period', 'unit', values: %w(d m y)
|
||||
end
|
||||
|
||||
def validate_transfer
|
||||
|
|
|
@ -18,42 +18,66 @@ class Epp::SessionsController < EppController
|
|||
client_md5 = Certificate.parse_md_from_string(request.env['HTTP_SSL_CLIENT_CERT'])
|
||||
server_md5 = Certificate.parse_md_from_string(File.read(ENV['cert_path']))
|
||||
if client_md5 != server_md5
|
||||
@msg = 'Authentication error; server closing connection (certificate is not valid)'
|
||||
epp_errors << {
|
||||
msg: 'Authentication error; server closing connection (certificate is not valid)',
|
||||
code: '2501'
|
||||
}
|
||||
|
||||
success = false
|
||||
end
|
||||
end
|
||||
|
||||
if !webclient_request && @api_user
|
||||
unless @api_user.api_pki_ok?(request.env['HTTP_SSL_CLIENT_CERT'], request.env['HTTP_SSL_CLIENT_S_DN_CN'])
|
||||
@msg = 'Authentication error; server closing connection (certificate is not valid)'
|
||||
epp_errors << {
|
||||
msg: 'Authentication error; server closing connection (certificate is not valid)',
|
||||
code: '2501'
|
||||
}
|
||||
|
||||
success = false
|
||||
end
|
||||
end
|
||||
|
||||
if success && !@api_user
|
||||
@msg = 'Authentication error; server closing connection (API user not found)'
|
||||
epp_errors << {
|
||||
msg: 'Authentication error; server closing connection (API user not found)',
|
||||
code: '2501'
|
||||
}
|
||||
|
||||
success = false
|
||||
end
|
||||
|
||||
if success && !@api_user.try(:active)
|
||||
@msg = 'Authentication error; server closing connection (API user is not active)'
|
||||
epp_errors << {
|
||||
msg: 'Authentication error; server closing connection (API user is not active)',
|
||||
code: '2501'
|
||||
}
|
||||
|
||||
success = false
|
||||
end
|
||||
|
||||
if success && !ip_white?
|
||||
@msg = 'Authentication error; server closing connection (IP is not whitelisted)'
|
||||
epp_errors << {
|
||||
msg: 'Authentication error; server closing connection (IP is not whitelisted)',
|
||||
code: '2501'
|
||||
}
|
||||
|
||||
success = false
|
||||
end
|
||||
|
||||
if success && !connection_limit_ok?
|
||||
@msg = 'Authentication error; server closing connection (connection limit reached)'
|
||||
epp_errors << {
|
||||
msg: 'Authentication error; server closing connection (connection limit reached)',
|
||||
code: '2501'
|
||||
}
|
||||
|
||||
success = false
|
||||
end
|
||||
|
||||
if success
|
||||
if parsed_frame.css('newPW').first
|
||||
unless @api_user.update(password: parsed_frame.css('newPW').first.text)
|
||||
response.headers['X-EPP-Returncode'] = '2200'
|
||||
response.headers['X-EPP-Returncode'] = '2500'
|
||||
handle_errors(@api_user) and return
|
||||
end
|
||||
end
|
||||
|
@ -62,8 +86,8 @@ class Epp::SessionsController < EppController
|
|||
epp_session.update_column(:registrar_id, @api_user.registrar_id)
|
||||
render_epp_response('login_success')
|
||||
else
|
||||
response.headers['X-EPP-Returncode'] = '2200'
|
||||
render_epp_response('login_fail')
|
||||
response.headers['X-EPP-Returncode'] = '2500'
|
||||
handle_errors
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/MethodLength
|
||||
|
|
|
@ -8,6 +8,18 @@ class EppController < ApplicationController
|
|||
before_action :latin_only
|
||||
before_action :validate_request
|
||||
before_action :update_epp_session
|
||||
|
||||
around_action :catch_epp_errors
|
||||
def catch_epp_errors
|
||||
err = catch(:epp_error) do
|
||||
yield
|
||||
nil
|
||||
end
|
||||
return unless err
|
||||
@errors = [err]
|
||||
handle_errors
|
||||
end
|
||||
|
||||
helper_method :current_user
|
||||
|
||||
rescue_from StandardError do |e|
|
||||
|
@ -28,9 +40,18 @@ class EppController < ApplicationController
|
|||
}]
|
||||
end
|
||||
|
||||
logger.error e.message
|
||||
logger.error e.backtrace.join("\n")
|
||||
# TODO: NOITFY AIRBRAKE / ERRBIT HERE
|
||||
if Rails.env.test? || Rails.env.development?
|
||||
# rubocop:disable Rails/Output
|
||||
puts e.backtrace.reverse.join("\n")
|
||||
puts "\nFROM-EPP-RESCUE: #{e.message}\n"
|
||||
# rubocop:enable Rails/Output
|
||||
else
|
||||
logger.error "FROM-EPP-RESCUE: #{e.message}"
|
||||
logger.error e.backtrace.join("\n")
|
||||
|
||||
# TODO: NOITFY AIRBRAKE / ERRBIT HERE
|
||||
NewRelic::Agent.notice_error(e)
|
||||
end
|
||||
end
|
||||
|
||||
render_epp_response '/epp/error'
|
||||
|
@ -102,7 +123,7 @@ class EppController < ApplicationController
|
|||
msg: 'handle_errors was executed when there were actually no errors'
|
||||
}
|
||||
# rubocop:disable Rails/Output
|
||||
puts obj.errors.full_messages if Rails.env.test?
|
||||
puts "FULL MESSAGE: #{obj.errors.full_messages} #{obj.errors.inspect}" if Rails.env.test?
|
||||
# rubocop: enable Rails/Output
|
||||
end
|
||||
|
||||
|
@ -125,8 +146,13 @@ class EppController < ApplicationController
|
|||
def latin_only
|
||||
return true if params['frame'].blank?
|
||||
return true if params['frame'].match(/\A[\p{Latin}\p{Z}\p{P}\p{S}\p{Cc}\p{Cf}\w_\'\+\-\.\(\)\/]*\Z/i)
|
||||
render_epp_response '/epp/latin_error'
|
||||
false
|
||||
|
||||
epp_errors << {
|
||||
msg: 'Parameter value policy error. Allowed only Latin characters.',
|
||||
code: '2306'
|
||||
}
|
||||
|
||||
handle_errors and return false
|
||||
end
|
||||
|
||||
# VALIDATION
|
||||
|
@ -212,11 +238,11 @@ class EppController < ApplicationController
|
|||
end
|
||||
|
||||
def optional_attribute(element_selector, attribute_selector, options)
|
||||
element = requires(element_selector, allow_blank: options[:allow_blank])
|
||||
full_selector = [@prefix, element_selector].compact.join(' ')
|
||||
element = params[:parsed_frame].css(full_selector).first
|
||||
return unless element
|
||||
|
||||
attribute = element[attribute_selector]
|
||||
|
||||
return if (attribute && options[:values].include?(attribute)) || !attribute
|
||||
|
||||
epp_errors << {
|
||||
|
|
|
@ -1,4 +1,25 @@
|
|||
class ApplicationMailer < ActionMailer::Base
|
||||
default from: 'noreply@internet.ee'
|
||||
layout 'mailer'
|
||||
|
||||
def whitelist_blocked?(emails)
|
||||
return false if Rails.env.production? || Rails.env.test?
|
||||
|
||||
emails = [emails] unless emails.is_a?(Array)
|
||||
emails = emails.flatten
|
||||
emails.each do |email|
|
||||
next unless TEST_EMAILS.include?(email)
|
||||
logger.warn "EMAIL SENDING WAS BLOCKED BY WHITELIST: #{email}"
|
||||
return true
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
# turn on delivery on specific (epp) request only, thus rake tasks does not deliver anything
|
||||
def delivery_off?(model)
|
||||
return false if model.deliver_emails == true
|
||||
logger.warn "EMAIL SENDING WAS NOT ACTIVATED " \
|
||||
"BY MODEL OBJECT: id ##{model.try(:id)} deliver_emails returned false"
|
||||
true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,23 +1,34 @@
|
|||
class ContactMailer < ApplicationMailer
|
||||
# rubocop: disable Metrics/CyclomaticComplexity
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def email_updated(contact)
|
||||
unless Rails.env.production?
|
||||
return unless TEST_EMAILS.include?(contact.email) || TEST_EMAILS.include?(contact.email_was)
|
||||
end
|
||||
|
||||
# turn on delivery on specific request only, thus rake tasks does not deliver anything
|
||||
return if contact.deliver_emails != true
|
||||
return if delivery_off?(contact)
|
||||
|
||||
@contact = contact
|
||||
|
||||
emails = []
|
||||
emails << [@contact.email, @contact.email_was] if @contact.registrant_domains.present?
|
||||
emails << @contact.domains.map(&:registrant_email) if @contact.domains.present?
|
||||
emails = emails.uniq
|
||||
|
||||
|
||||
return if whitelist_blocked?(emails)
|
||||
emails.each do |email|
|
||||
mail(to: email, subject: "#{I18n.t(:contact_email_update_subject)} [#{@contact.code}]")
|
||||
begin
|
||||
mail(to: email, subject: "#{I18n.t(:contact_email_update_subject)} [#{@contact.code}]")
|
||||
rescue EOFError,
|
||||
IOError,
|
||||
TimeoutError,
|
||||
Errno::ECONNRESET,
|
||||
Errno::ECONNABORTED,
|
||||
Errno::EPIPE,
|
||||
Errno::ETIMEDOUT,
|
||||
Net::SMTPAuthenticationError,
|
||||
Net::SMTPServerBusy,
|
||||
Net::SMTPFatalError,
|
||||
Net::SMTPSyntaxError,
|
||||
Net::SMTPUnknownError,
|
||||
OpenSSL::SSL::SSLError => e
|
||||
logger.warn "EMAIL SENDING FAILED: #{email}: #{e}"
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/CyclomaticComplexity
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
end
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
class DomainMailer < ApplicationMailer
|
||||
def registrant_pending_updated(domain)
|
||||
@domain = domain
|
||||
return if Rails.env.production? ? false : !TEST_EMAILS.include?(@domain.registrant_email)
|
||||
|
||||
# turn on delivery on specific EPP request only, thus rake tasks does not deliver anything
|
||||
return if @domain.deliver_emails != true
|
||||
return if delivery_off?(@domain)
|
||||
|
||||
if @domain.registrant_verification_token.blank?
|
||||
logger.warn "EMAIL NOT DELIVERED: registrant_verification_token is missing for #{@domain.name}"
|
||||
|
@ -21,27 +18,23 @@ class DomainMailer < ApplicationMailer
|
|||
confirm_path = "#{ENV['registrant_url']}/registrant/domain_update_confirms"
|
||||
@verification_url = "#{confirm_path}/#{@domain.id}?token=#{@domain.registrant_verification_token}"
|
||||
|
||||
return if whitelist_blocked?(@old_registrant.email)
|
||||
mail(to: @old_registrant.email,
|
||||
subject: "#{I18n.t(:domain_registrant_pending_updated_subject, name: @domain.name)} [#{@domain.name}]")
|
||||
end
|
||||
|
||||
def registrant_updated(domain)
|
||||
@domain = domain
|
||||
return if Rails.env.production? ? false : !TEST_EMAILS.include?(@domain.registrant_email)
|
||||
|
||||
# turn on delivery on specific EPP request only, thus rake tasks does not deliver anything
|
||||
return if @domain.deliver_emails != true
|
||||
return if delivery_off?(@domain)
|
||||
|
||||
return if whitelist_blocked?(@domain.registrant_email)
|
||||
mail(to: @domain.registrant_email,
|
||||
subject: "#{I18n.t(:domain_registrant_updated, name: @domain.name)} [#{@domain.name}]")
|
||||
end
|
||||
|
||||
def pending_deleted(domain)
|
||||
@domain = domain
|
||||
return if Rails.env.production? ? false : !TEST_EMAILS.include?(@domain.registrant_email)
|
||||
|
||||
# turn on delivery on specific EPP request only, thus rake tasks does not deliver anything
|
||||
return if @domain.deliver_emails != true
|
||||
return if delivery_off?(@domain)
|
||||
|
||||
if @domain.registrant_verification_token.blank?
|
||||
logger.warn "EMAIL NOT DELIVERED: registrant_verification_token is missing for #{@domain.name}"
|
||||
|
@ -58,6 +51,7 @@ class DomainMailer < ApplicationMailer
|
|||
confirm_path = "#{ENV['registrant_url']}/registrant/domain_delete_confirms"
|
||||
@verification_url = "#{confirm_path}/#{@domain.id}?token=#{@domain.registrant_verification_token}"
|
||||
|
||||
return if whitelist_blocked?(@old_registrant.email)
|
||||
mail(to: @old_registrant.email,
|
||||
subject: "#{I18n.t(:domain_pending_deleted_subject, name: @domain.name)} [#{@domain.name}]")
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class InvoiceMailer < ApplicationMailer
|
||||
def invoice_email(invoice, pdf)
|
||||
return if Rails.env.production? ? false : !TEST_EMAILS.include?(invoice.billing_email)
|
||||
return if whitelist_blocked?(invoice.billing_email)
|
||||
|
||||
@invoice = invoice
|
||||
attachments[invoice.pdf_name] = pdf
|
||||
|
|
|
@ -2,6 +2,8 @@ class BankStatement < ActiveRecord::Base
|
|||
include Versions
|
||||
has_many :bank_transactions
|
||||
|
||||
accepts_nested_attributes_for :bank_transactions
|
||||
|
||||
attr_accessor :th6_file
|
||||
|
||||
validates :bank_code, :iban, presence: true
|
||||
|
|
|
@ -141,7 +141,7 @@ class Certificate < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def update_id_crl
|
||||
STDOUT << "#{Time.zone.now.utc} - Updating ID CRL\n"
|
||||
STDOUT << "#{Time.zone.now.utc} - Updating ID CRL\n" unless Rails.env.test?
|
||||
|
||||
_out, _err, _st = Open3.capture3("
|
||||
mkdir -p #{ENV['crl_dir']}/crl-id-temp
|
||||
|
@ -169,11 +169,11 @@ class Certificate < ActiveRecord::Base
|
|||
rm -rf #{ENV['crl_dir']}/crl-id-temp
|
||||
")
|
||||
|
||||
STDOUT << "#{Time.zone.now.utc} - ID CRL updated\n"
|
||||
STDOUT << "#{Time.zone.now.utc} - ID CRL updated\n" unless Rails.env.test?
|
||||
end
|
||||
|
||||
def update_registry_crl
|
||||
STDOUT << "#{Time.zone.now.utc} - Updating registry CRL\n"
|
||||
STDOUT << "#{Time.zone.now.utc} - Updating registry CRL\n" unless Rails.env.test?
|
||||
|
||||
_out, _err, _st = Open3.capture3("
|
||||
mkdir -p #{ENV['crl_dir']}/crl-temp
|
||||
|
@ -192,13 +192,13 @@ class Certificate < ActiveRecord::Base
|
|||
rm -rf #{ENV['crl_dir']}/crl-temp
|
||||
")
|
||||
|
||||
STDOUT << "#{Time.zone.now.utc} - Registry CRL updated\n"
|
||||
STDOUT << "#{Time.zone.now.utc} - Registry CRL updated\n" unless Rails.env.test?
|
||||
end
|
||||
|
||||
def reload_apache
|
||||
STDOUT << "#{Time.zone.now.utc} - Reloading apache\n"
|
||||
STDOUT << "#{Time.zone.now.utc} - Reloading apache\n" unless Rails.env.test?
|
||||
_out, _err, _st = Open3.capture3("sudo /etc/init.d/apache2 reload")
|
||||
STDOUT << "#{Time.zone.now.utc} - Apache reloaded\n"
|
||||
STDOUT << "#{Time.zone.now.utc} - Apache reloaded\n" unless Rails.env.test?
|
||||
end
|
||||
|
||||
def parse_md_from_string(crt)
|
||||
|
|
|
@ -5,10 +5,12 @@ class Contact < ActiveRecord::Base
|
|||
belongs_to :registrar
|
||||
has_many :domain_contacts
|
||||
has_many :domains, through: :domain_contacts
|
||||
has_many :statuses, class_name: 'ContactStatus', dependent: :destroy
|
||||
has_many :legal_documents, as: :documentable
|
||||
has_many :registrant_domains, class_name: 'Domain', foreign_key: 'registrant_id' # when contant is registrant
|
||||
|
||||
# TODO: remove later
|
||||
has_many :depricated_statuses, class_name: 'DepricatedContactStatus', dependent: :destroy
|
||||
|
||||
accepts_nested_attributes_for :legal_documents
|
||||
|
||||
validates :name, :phone, :email, :ident, :ident_type,
|
||||
|
@ -23,9 +25,15 @@ class Contact < ActiveRecord::Base
|
|||
validates :ident_country_code, presence: true, if: proc { |c| %w(bic priv).include? c.ident_type }
|
||||
validates :code,
|
||||
uniqueness: { message: :epp_id_taken },
|
||||
format: { with: /\A[\w\-\:]*\Z/i },
|
||||
length: { maximum: 100 }
|
||||
format: { with: /\A[\w\-\:]*\Z/i, message: :invalid },
|
||||
length: { maximum: 100, message: :too_long_contact_code }
|
||||
validate :ident_valid_format?
|
||||
validate :uniq_statuses?
|
||||
|
||||
after_initialize do
|
||||
self.statuses = [] if statuses.nil?
|
||||
self.status_notes = {} if status_notes.nil?
|
||||
end
|
||||
|
||||
before_validation :set_ident_country_code
|
||||
before_validation :prefix_code
|
||||
|
@ -37,10 +45,10 @@ class Contact < ActiveRecord::Base
|
|||
ContactMailer.email_updated(self).deliver_now
|
||||
end
|
||||
|
||||
after_save :manage_statuses
|
||||
before_save :manage_statuses
|
||||
def manage_statuses
|
||||
ContactStatus.manage(statuses, self)
|
||||
statuses.reload
|
||||
manage_linked
|
||||
manage_ok
|
||||
end
|
||||
|
||||
scope :current_registrars, ->(id) { where(registrar_id: id) }
|
||||
|
@ -58,6 +66,79 @@ class Contact < ActiveRecord::Base
|
|||
|
||||
attr_accessor :deliver_emails
|
||||
|
||||
#
|
||||
# STATUSES
|
||||
#
|
||||
# Requests to delete the object MUST be rejected.
|
||||
CLIENT_DELETE_PROHIBITED = 'clientDeleteProhibited'
|
||||
SERVER_DELETE_PROHIBITED = 'serverDeleteProhibited'
|
||||
|
||||
# Requests to transfer the object MUST be rejected.
|
||||
CLIENT_TRANSFER_PROHIBITED = 'clientTransferProhibited'
|
||||
SERVER_TRANSFER_PROHIBITED = 'serverTransferProhibited'
|
||||
|
||||
# The contact object has at least one active association with
|
||||
# another object, such as a domain object. Servers SHOULD provide
|
||||
# services to determine existing object associations.
|
||||
# "linked" status MAY be combined with any status.
|
||||
LINKED = 'linked'
|
||||
|
||||
# This is the normal status value for an object that has no pending
|
||||
# operations or prohibitions. This value is set and removed by the
|
||||
# server as other status values are added or removed.
|
||||
# "ok" status MAY only be combined with "linked" status.
|
||||
OK = 'ok'
|
||||
|
||||
# Requests to update the object (other than to remove this status) MUST be rejected.
|
||||
CLIENT_UPDATE_PROHIBITED = 'clientUpdateProhibited'
|
||||
SERVER_UPDATE_PROHIBITED = 'serverUpdateProhibited'
|
||||
|
||||
# A transform command has been processed for the object, but the
|
||||
# action has not been completed by the server. Server operators can
|
||||
# delay action completion for a variety of reasons, such as to allow
|
||||
# for human review or third-party action. A transform command that
|
||||
# is processed, but whose requested action is pending, is noted with
|
||||
# response code 1001.
|
||||
# When the requested action has been completed, the pendingCreate,
|
||||
# pendingDelete, pendingTransfer, or pendingUpdate status value MUST be
|
||||
# removed. All clients involved in the transaction MUST be notified
|
||||
# using a service message that the action has been completed and that
|
||||
# the status of the object has changed.
|
||||
# The pendingCreate, pendingDelete, pendingTransfer, and pendingUpdate
|
||||
# status values MUST NOT be combined with each other.
|
||||
PENDING_CREATE = 'pendingCreate'
|
||||
# "pendingTransfer" status MUST NOT be combined with either
|
||||
# "clientTransferProhibited" or "serverTransferProhibited" status.
|
||||
PENDING_TRANSFER = 'pendingTransfer'
|
||||
# "pendingUpdate" status MUST NOT be combined with either
|
||||
# "clientUpdateProhibited" or "serverUpdateProhibited" status.
|
||||
PENDING_UPDATE = 'pendingUpdate'
|
||||
# "pendingDelete" MUST NOT be combined with either
|
||||
# "clientDeleteProhibited" or "serverDeleteProhibited" status.
|
||||
PENDING_DELETE = 'pendingDelete'
|
||||
|
||||
STATUSES = [
|
||||
CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED,
|
||||
CLIENT_TRANSFER_PROHIBITED,
|
||||
SERVER_TRANSFER_PROHIBITED, CLIENT_UPDATE_PROHIBITED, SERVER_UPDATE_PROHIBITED,
|
||||
OK, PENDING_CREATE, PENDING_DELETE, PENDING_TRANSFER,
|
||||
PENDING_UPDATE, LINKED
|
||||
]
|
||||
|
||||
CLIENT_STATUSES = [
|
||||
CLIENT_DELETE_PROHIBITED, CLIENT_TRANSFER_PROHIBITED,
|
||||
CLIENT_UPDATE_PROHIBITED
|
||||
]
|
||||
|
||||
SERVER_STATUSES = [
|
||||
SERVER_UPDATE_PROHIBITED,
|
||||
SERVER_DELETE_PROHIBITED,
|
||||
SERVER_TRANSFER_PROHIBITED
|
||||
]
|
||||
#
|
||||
# END OF STATUSES
|
||||
#
|
||||
|
||||
class << self
|
||||
def search_by_query(query)
|
||||
res = search(code_cont: query).result
|
||||
|
@ -83,6 +164,20 @@ class Contact < ActiveRecord::Base
|
|||
def privs
|
||||
where("ident_type = '#{PRIV}'")
|
||||
end
|
||||
|
||||
def admin_statuses
|
||||
[
|
||||
SERVER_UPDATE_PROHIBITED,
|
||||
SERVER_DELETE_PROHIBITED
|
||||
]
|
||||
end
|
||||
|
||||
def admin_statuses_map
|
||||
[
|
||||
['UpdateProhibited', SERVER_UPDATE_PROHIBITED],
|
||||
['DeleteProhibited', SERVER_DELETE_PROHIBITED]
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
def roid
|
||||
|
@ -104,6 +199,12 @@ class Contact < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def uniq_statuses?
|
||||
return true unless statuses.detect { |s| statuses.count(s) > 1 }
|
||||
errors.add(:statuses, :not_uniq)
|
||||
false
|
||||
end
|
||||
|
||||
def bic?
|
||||
ident_type == BIC
|
||||
end
|
||||
|
@ -206,4 +307,78 @@ class Contact < ActiveRecord::Base
|
|||
|
||||
@desc
|
||||
end
|
||||
|
||||
def status_notes_array=(notes)
|
||||
self.status_notes = {}
|
||||
notes ||= []
|
||||
statuses.each_with_index do |status,i|
|
||||
self.status_notes[status] = notes[i]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def manage_linked
|
||||
if domains.present?
|
||||
statuses << LINKED if statuses.detect { |s| s == LINKED }.blank?
|
||||
else
|
||||
statuses.delete_if { |s| s == LINKED }
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
def manage_ok
|
||||
return unset_ok unless valid?
|
||||
|
||||
case statuses.size
|
||||
when 0
|
||||
set_ok
|
||||
when 1
|
||||
set_ok if statuses == [LINKED]
|
||||
when 2
|
||||
return if statuses.sort == [LINKED, OK]
|
||||
unset_ok
|
||||
else
|
||||
unset_ok
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
|
||||
def unset_ok
|
||||
statuses.delete_if { |s| s == OK }
|
||||
end
|
||||
|
||||
def set_ok
|
||||
statuses << OK if statuses.detect { |s| s == OK }.blank?
|
||||
end
|
||||
|
||||
def linked?
|
||||
statuses.include?(LINKED)
|
||||
end
|
||||
|
||||
def update_prohibited?
|
||||
(statuses & [
|
||||
CLIENT_UPDATE_PROHIBITED,
|
||||
SERVER_UPDATE_PROHIBITED,
|
||||
CLIENT_TRANSFER_PROHIBITED,
|
||||
SERVER_TRANSFER_PROHIBITED,
|
||||
PENDING_CREATE,
|
||||
PENDING_TRANSFER,
|
||||
PENDING_UPDATE,
|
||||
PENDING_DELETE
|
||||
]).present?
|
||||
end
|
||||
|
||||
def delete_prohibited?
|
||||
(statuses & [
|
||||
CLIENT_DELETE_PROHIBITED,
|
||||
SERVER_DELETE_PROHIBITED,
|
||||
CLIENT_TRANSFER_PROHIBITED,
|
||||
SERVER_TRANSFER_PROHIBITED,
|
||||
PENDING_CREATE,
|
||||
PENDING_TRANSFER,
|
||||
PENDING_UPDATE,
|
||||
PENDING_DELETE
|
||||
]).present?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
class ContactStatus < ActiveRecord::Base
|
||||
include Versions # version/contact_status_version.rb
|
||||
include EppErrors
|
||||
|
||||
belongs_to :contact
|
||||
|
||||
# Requests to delete the object MUST be rejected.
|
||||
CLIENT_DELETE_PROHIBITED = 'clientDeleteProhibited'
|
||||
SERVER_DELETE_PROHIBITED = 'serverDeleteProhibited'
|
||||
|
||||
# Requests to transfer the object MUST be rejected.
|
||||
CLIENT_TRANSFER_PROHIBITED = 'clientTransferProhibited'
|
||||
SERVER_TRANSFER_PROHIBITED = 'serverTransferProhibited'
|
||||
|
||||
# The contact object has at least one active association with
|
||||
# another object, such as a domain object. Servers SHOULD provide
|
||||
# services to determine existing object associations.
|
||||
# "linked" status MAY be combined with any status.
|
||||
LINKED = 'linked'
|
||||
|
||||
# This is the normal status value for an object that has no pending
|
||||
# operations or prohibitions. This value is set and removed by the
|
||||
# server as other status values are added or removed.
|
||||
# "ok" status MAY only be combined with "linked" status.
|
||||
OK = 'ok'
|
||||
|
||||
# Requests to update the object (other than to remove this status) MUST be rejected.
|
||||
CLIENT_UPDATE_PROHIBITED = 'clientUpdateProhibited'
|
||||
SERVER_UPDATE_PROHIBITED = 'serverUpdateProhibited'
|
||||
|
||||
# A transform command has been processed for the object, but the
|
||||
# action has not been completed by the server. Server operators can
|
||||
# delay action completion for a variety of reasons, such as to allow
|
||||
# for human review or third-party action. A transform command that
|
||||
# is processed, but whose requested action is pending, is noted with
|
||||
# response code 1001.
|
||||
# When the requested action has been completed, the pendingCreate,
|
||||
# pendingDelete, pendingTransfer, or pendingUpdate status value MUST be
|
||||
# removed. All clients involved in the transaction MUST be notified
|
||||
# using a service message that the action has been completed and that
|
||||
# the status of the object has changed.
|
||||
# The pendingCreate, pendingDelete, pendingTransfer, and pendingUpdate
|
||||
# status values MUST NOT be combined with each other.
|
||||
PENDING_CREATE = 'pendingCreate'
|
||||
# "pendingTransfer" status MUST NOT be combined with either
|
||||
# "clientTransferProhibited" or "serverTransferProhibited" status.
|
||||
PENDING_TRANSFER = 'pendingTransfer'
|
||||
# "pendingUpdate" status MUST NOT be combined with either
|
||||
# "clientUpdateProhibited" or "serverUpdateProhibited" status.
|
||||
PENDING_UPDATE = 'pendingUpdate'
|
||||
# "pendingDelete" MUST NOT be combined with either
|
||||
# "clientDeleteProhibited" or "serverDeleteProhibited" status.
|
||||
PENDING_DELETE = 'pendingDelete'
|
||||
|
||||
STATUSES = [
|
||||
CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED,
|
||||
CLIENT_TRANSFER_PROHIBITED,
|
||||
SERVER_TRANSFER_PROHIBITED, CLIENT_UPDATE_PROHIBITED, SERVER_UPDATE_PROHIBITED,
|
||||
OK, PENDING_CREATE, PENDING_DELETE, PENDING_TRANSFER,
|
||||
PENDING_UPDATE, LINKED
|
||||
]
|
||||
|
||||
CLIENT_STATUSES = [
|
||||
CLIENT_DELETE_PROHIBITED, CLIENT_TRANSFER_PROHIBITED,
|
||||
CLIENT_UPDATE_PROHIBITED
|
||||
]
|
||||
|
||||
SERVER_STATUSES = [
|
||||
SERVER_DELETE_PROHIBITED, SERVER_TRANSFER_PROHIBITED,
|
||||
SERVER_UPDATE_PROHIBITED
|
||||
]
|
||||
|
||||
class << self
|
||||
def manage(statuses, contact)
|
||||
manage_linked(statuses, contact)
|
||||
manage_ok(statuses, contact)
|
||||
end
|
||||
|
||||
def manage_linked(statuses, contact)
|
||||
if contact.domains.present?
|
||||
create(value: LINKED, contact_id: contact.id) if statuses.select { |s| s.value == LINKED }.blank?
|
||||
else
|
||||
statuses.select { |s| s.value == LINKED }.each(&:destroy)
|
||||
end
|
||||
end
|
||||
|
||||
def manage_ok(statuses, contact)
|
||||
if statuses.present?
|
||||
if contact.valid?
|
||||
else
|
||||
statuses.select { |s| s.value == OK }.each(&:destroy)
|
||||
end
|
||||
else
|
||||
create(value: OK, contact_id: contact.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def epp_code_map
|
||||
{
|
||||
'2302' => [ # Object exists
|
||||
[:value, :taken, { value: { obj: 'status', val: value } }]
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def server_status?
|
||||
SERVER_STATUSES.include?(value)
|
||||
end
|
||||
|
||||
def client_status?
|
||||
CLIENT_STATUSES.include?(value)
|
||||
end
|
||||
|
||||
class << self
|
||||
def statuses_for_client
|
||||
CLIENT_STATUSES.map { |x| x.sub('client', '') }
|
||||
end
|
||||
|
||||
def statuses_for_admin
|
||||
SERVER_STATUSES.map { |x| x.sub('server', '') }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -136,13 +136,12 @@ module Depp
|
|||
end
|
||||
hash
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(attributes = {})
|
||||
super
|
||||
self.country_code = 'EE' if country_code.blank?
|
||||
self.ident_type = 'bic' if ident_type.blank?
|
||||
self.ident_country_code = 'EE' if ident_country_code.blank?
|
||||
def type_string(type_code)
|
||||
return '' if type_code.blank?
|
||||
t = SELECTION_TYPES.select { |tp| tp.second == type_code }
|
||||
t.try(:first).try(:first)
|
||||
end
|
||||
end
|
||||
|
||||
def save
|
||||
|
|
5
app/models/depricated_contact_status.rb
Normal file
5
app/models/depricated_contact_status.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class DepricatedContactStatus < ActiveRecord::Base
|
||||
self.table_name = :contact_statuses
|
||||
self.sequence_name = :contact_statuses_id_seq
|
||||
belongs_to :contact
|
||||
end
|
|
@ -54,9 +54,10 @@ class Domain < ActiveRecord::Base
|
|||
delegate :name, to: :registrar, prefix: true
|
||||
delegate :street, to: :registrar, prefix: true
|
||||
|
||||
after_initialize :init_default_values
|
||||
def init_default_values
|
||||
after_initialize do
|
||||
self.pending_json = {} if pending_json.blank?
|
||||
self.statuses = [] if statuses.nil?
|
||||
self.status_notes = {} if status_notes.nil?
|
||||
end
|
||||
|
||||
before_create :generate_auth_info
|
||||
|
@ -77,7 +78,6 @@ class Domain < ActiveRecord::Base
|
|||
end
|
||||
after_save :update_whois_record
|
||||
|
||||
after_initialize -> { self.statuses = [] if statuses.nil? }
|
||||
|
||||
after_create :update_reserved_domains
|
||||
def update_reserved_domains
|
||||
|
|
|
@ -4,6 +4,13 @@ class Epp::Contact < Contact
|
|||
# disable STI, there is type column present
|
||||
self.inheritance_column = :sti_disabled
|
||||
|
||||
before_validation :manage_permissions
|
||||
def manage_permissions
|
||||
return unless update_prohibited? || delete_prohibited?
|
||||
add_epp_error('2304', nil, nil, I18n.t(:object_status_prohibits_operation))
|
||||
false
|
||||
end
|
||||
|
||||
class << self
|
||||
# support legacy search
|
||||
def find_by_epp_code(code)
|
||||
|
@ -125,7 +132,9 @@ class Epp::Contact < Contact
|
|||
[:ident, :invalid],
|
||||
[:ident, :invalid_EE_identity_format],
|
||||
[:ident, :invalid_birthday_format],
|
||||
[:ident, :invalid_country_code]
|
||||
[:ident, :invalid_country_code],
|
||||
[:code, :invalid],
|
||||
[:code, :too_long_contact_code]
|
||||
],
|
||||
'2302' => [ # Object exists
|
||||
[:code, :epp_id_taken]
|
||||
|
|
|
@ -9,6 +9,21 @@ class Epp::Domain < Domain
|
|||
false
|
||||
end
|
||||
|
||||
before_validation :validate_contacts
|
||||
def validate_contacts
|
||||
return if contacts.map {|c| c.valid? }.all?
|
||||
add_epp_error('2304', nil, nil, I18n.t(:object_status_prohibits_operation))
|
||||
false
|
||||
end
|
||||
|
||||
before_save :update_contact_status
|
||||
def update_contact_status
|
||||
contacts.each do |c|
|
||||
next if c.linked?
|
||||
c.save(validate: false)
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
def new_from_epp(frame, current_user)
|
||||
domain = Epp::Domain.new
|
||||
|
@ -399,7 +414,7 @@ class Epp::Domain < Domain
|
|||
statuses.delete(DomainStatus::PENDING_UPDATE)
|
||||
|
||||
return unless update(frame, user, false)
|
||||
clean_pendings!
|
||||
clean_pendings!
|
||||
self.deliver_emails = true # turn on email delivery for epp
|
||||
DomainMailer.registrant_updated(self).deliver_now
|
||||
end
|
||||
|
@ -446,8 +461,8 @@ class Epp::Domain < Domain
|
|||
|
||||
p = self.class.convert_period_to_time(period, unit)
|
||||
self.valid_to = valid_to + p
|
||||
self.outzone_at = outzone_at + p
|
||||
self.delete_at = delete_at + p
|
||||
self.outzone_at = valid_to + Setting.expire_warning_period.days
|
||||
self.delete_at = outzone_at + Setting.redemption_grace_period.days
|
||||
self.period = period
|
||||
self.period_unit = unit
|
||||
|
||||
|
@ -473,7 +488,6 @@ class Epp::Domain < Domain
|
|||
when 'reject'
|
||||
return reject_transfer(frame, current_user) if pending_transfer
|
||||
end
|
||||
add_epp_error('2303', nil, nil, I18n.t('no_transfers_found'))
|
||||
end
|
||||
|
||||
# TODO: Eager load problems here. Investigate how it's possible not to query contact again
|
||||
|
@ -485,7 +499,7 @@ class Epp::Domain < Domain
|
|||
|
||||
def copy_and_transfer_contact(contact_id, registrar_id)
|
||||
c = Contact.find(contact_id) # n+1 workaround
|
||||
oc = c.deep_clone include: [:statuses]
|
||||
oc = c.deep_clone
|
||||
oc.code = nil
|
||||
oc.registrar_id = registrar_id
|
||||
oc.prefix_code
|
||||
|
@ -536,50 +550,48 @@ class Epp::Domain < Domain
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop: enable Metrics/PerceivedComplexity
|
||||
# rubocop: enable Metrics/CyclomaticComplexity
|
||||
|
||||
# rubocop: disable Metrics/MethodLength
|
||||
# rubocop: disable Metrics/AbcSize
|
||||
def query_transfer(frame, current_user)
|
||||
return false unless can_be_transferred_to?(current_user.registrar)
|
||||
unless can_be_transferred_to?(current_user.registrar)
|
||||
throw :epp_error, {
|
||||
code: '2002',
|
||||
msg: I18n.t(:domain_already_belongs_to_the_querying_registrar)
|
||||
}
|
||||
end
|
||||
|
||||
old_contact_codes = contacts.pluck(:code).sort.uniq
|
||||
old_registrant_code = registrant.code
|
||||
|
||||
transaction do
|
||||
begin
|
||||
dt = domain_transfers.create!(
|
||||
transfer_requested_at: Time.zone.now,
|
||||
transfer_to: current_user.registrar,
|
||||
transfer_from: registrar
|
||||
dt = domain_transfers.create!(
|
||||
transfer_requested_at: Time.zone.now,
|
||||
transfer_to: current_user.registrar,
|
||||
transfer_from: registrar
|
||||
)
|
||||
|
||||
if dt.pending?
|
||||
registrar.messages.create!(
|
||||
body: I18n.t('transfer_requested'),
|
||||
attached_obj_id: dt.id,
|
||||
attached_obj_type: dt.class.to_s
|
||||
)
|
||||
|
||||
if dt.pending?
|
||||
registrar.messages.create!(
|
||||
body: I18n.t('transfer_requested'),
|
||||
attached_obj_id: dt.id,
|
||||
attached_obj_type: dt.class.to_s
|
||||
)
|
||||
end
|
||||
|
||||
if dt.approved?
|
||||
transfer_contacts(current_user.registrar_id)
|
||||
dt.notify_losing_registrar(old_contact_codes, old_registrant_code)
|
||||
generate_auth_info
|
||||
self.registrar = current_user.registrar
|
||||
end
|
||||
|
||||
attach_legal_document(self.class.parse_legal_document_from_frame(frame))
|
||||
save!(validate: false)
|
||||
|
||||
return dt
|
||||
rescue => e
|
||||
add_epp_error('2306', nil, nil, I18n.t('action_failed_due_to_server_error'))
|
||||
logger.error('DOMAIN TRANSFER FAILED')
|
||||
logger.error(e)
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
|
||||
if dt.approved?
|
||||
transfer_contacts(current_user.registrar_id)
|
||||
dt.notify_losing_registrar(old_contact_codes, old_registrant_code)
|
||||
generate_auth_info
|
||||
self.registrar = current_user.registrar
|
||||
end
|
||||
|
||||
attach_legal_document(self.class.parse_legal_document_from_frame(frame))
|
||||
save!(validate: false)
|
||||
|
||||
return dt
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/AbcSize
|
||||
|
@ -588,27 +600,24 @@ class Epp::Domain < Domain
|
|||
def approve_transfer(frame, current_user)
|
||||
pt = pending_transfer
|
||||
if current_user.registrar != pt.transfer_from
|
||||
add_epp_error('2304', nil, nil, I18n.t('transfer_can_be_approved_only_by_current_registrar'))
|
||||
return false
|
||||
throw :epp_error, {
|
||||
msg: I18n.t('transfer_can_be_approved_only_by_current_registrar'),
|
||||
code: '2304'
|
||||
}
|
||||
end
|
||||
|
||||
transaction do
|
||||
begin
|
||||
pt.update!(
|
||||
status: DomainTransfer::CLIENT_APPROVED,
|
||||
transferred_at: Time.zone.now
|
||||
)
|
||||
pt.update!(
|
||||
status: DomainTransfer::CLIENT_APPROVED,
|
||||
transferred_at: Time.zone.now
|
||||
)
|
||||
|
||||
transfer_contacts(pt.transfer_to_id)
|
||||
generate_auth_info
|
||||
self.registrar = pt.transfer_to
|
||||
transfer_contacts(pt.transfer_to_id)
|
||||
generate_auth_info
|
||||
self.registrar = pt.transfer_to
|
||||
|
||||
attach_legal_document(self.class.parse_legal_document_from_frame(frame))
|
||||
save!(validate: false)
|
||||
rescue => _e
|
||||
add_epp_error('2306', nil, nil, I18n.t('action_failed_due_to_server_error'))
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
attach_legal_document(self.class.parse_legal_document_from_frame(frame))
|
||||
save!(validate: false)
|
||||
end
|
||||
|
||||
pt
|
||||
|
@ -617,22 +626,19 @@ class Epp::Domain < Domain
|
|||
def reject_transfer(frame, current_user)
|
||||
pt = pending_transfer
|
||||
if current_user.registrar != pt.transfer_from
|
||||
add_epp_error('2304', nil, nil, I18n.t('transfer_can_be_rejected_only_by_current_registrar'))
|
||||
return false
|
||||
throw :epp_error, {
|
||||
msg: I18n.t('transfer_can_be_rejected_only_by_current_registrar'),
|
||||
code: '2304'
|
||||
}
|
||||
end
|
||||
|
||||
transaction do
|
||||
begin
|
||||
pt.update!(
|
||||
status: DomainTransfer::CLIENT_REJECTED
|
||||
)
|
||||
pt.update!(
|
||||
status: DomainTransfer::CLIENT_REJECTED
|
||||
)
|
||||
|
||||
attach_legal_document(self.class.parse_legal_document_from_frame(frame))
|
||||
save!(validate: false)
|
||||
rescue => _e
|
||||
add_epp_error('2306', nil, nil, I18n.t('action_failed_due_to_server_error'))
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
attach_legal_document(self.class.parse_legal_document_from_frame(frame))
|
||||
save!(validate: false)
|
||||
end
|
||||
|
||||
pt
|
||||
|
@ -709,11 +715,7 @@ class Epp::Domain < Domain
|
|||
end
|
||||
|
||||
def can_be_transferred_to?(new_registrar)
|
||||
if new_registrar == registrar
|
||||
errors.add(:base, :domain_already_belongs_to_the_querying_registrar)
|
||||
return false
|
||||
end
|
||||
true
|
||||
new_registrar != registrar
|
||||
end
|
||||
|
||||
## SHARED
|
||||
|
|
|
@ -13,6 +13,35 @@
|
|||
= f.label :iban
|
||||
.col-md-8
|
||||
= f.text_field(:iban, class: 'form-control')
|
||||
|
||||
- if @invoice
|
||||
%hr
|
||||
%h4= t('bank_transaction')
|
||||
%hr
|
||||
= f.fields_for :bank_transactions, [@bank_transaction] do |x|
|
||||
.row
|
||||
.col-md-8
|
||||
.form-group
|
||||
= x.label :description, class: 'col-md-4 control-label required'
|
||||
.col-md-8
|
||||
= x.text_field(:description, class: 'form-control', required: true)
|
||||
.form-group
|
||||
= x.label :sum, class: 'col-md-4 control-label required'
|
||||
.col-md-8
|
||||
= x.text_field(:sum, class: 'form-control', required: true)
|
||||
.form-group
|
||||
= x.label :currency, class: 'col-md-4 control-label required'
|
||||
.col-md-8
|
||||
= x.text_field(:currency, class: 'form-control', required: true, readonly: true)
|
||||
.form-group
|
||||
= x.label :reference_no, class: 'col-md-4 control-label required'
|
||||
.col-md-8
|
||||
= x.text_field(:reference_no, class: 'form-control', required: true)
|
||||
.form-group
|
||||
= x.label :paid_at, class: 'col-md-4 control-label required'
|
||||
.col-md-8
|
||||
= x.text_field(:paid_at, class: 'form-control datepicker', required: true)
|
||||
|
||||
%hr
|
||||
.row
|
||||
.col-md-8.text-right
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
- content_for :actions do
|
||||
= link_to(t(:back), admin_bank_statement_path(@bank_statement), class: 'btn btn-default')
|
||||
- if @bank_statement.persisted?
|
||||
= link_to(t(:back), admin_bank_statement_path(@bank_statement), class: 'btn btn-default')
|
||||
|
||||
= render 'shared/title', name: t(:create_bank_transaction)
|
||||
|
||||
|
|
11
app/views/admin/contacts/_form.haml
Normal file
11
app/views/admin/contacts/_form.haml
Normal file
|
@ -0,0 +1,11 @@
|
|||
= form_for([:admin, contact], html: { class: 'form-horizontal' }) do |f|
|
||||
.errors
|
||||
= render 'shared/errors', object: contact
|
||||
.row
|
||||
.col-md-8
|
||||
.tab-content{style:'margin-top: 20px;'}
|
||||
#general-tab.tab-pane.active
|
||||
= render 'admin/contacts/form_partials/statuses', f: f
|
||||
.row
|
||||
.col-md-8.text-right
|
||||
= button_tag(t(:save), class: 'btn btn-primary')
|
6
app/views/admin/contacts/edit.haml
Normal file
6
app/views/admin/contacts/edit.haml
Normal file
|
@ -0,0 +1,6 @@
|
|||
- content_for :actions do
|
||||
= link_to(t(:add_new_status), '#', class: 'btn btn-primary js-add-contact-status')
|
||||
= link_to(t(:back_to_contact), [:admin, @contact], class: 'btn btn-default')
|
||||
= render 'shared/title', name: "#{t(:edit)}: #{@contact.name}"
|
||||
|
||||
= render 'form', contact: @contact
|
41
app/views/admin/contacts/form_partials/_statuses.haml
Normal file
41
app/views/admin/contacts/form_partials/_statuses.haml
Normal file
|
@ -0,0 +1,41 @@
|
|||
#js-contact-statuses
|
||||
- f.object.statuses.each do |s|
|
||||
- disabled = !Contact.admin_statuses.include?(s)
|
||||
- disabled_style = disabled ? 'display: none' : ''
|
||||
- delete_style = [Contact::OK, Contact::LINKED].include?(s) ? 'display: none' : ''
|
||||
|
||||
.panel.panel-default
|
||||
.panel-heading.clearfix
|
||||
.pull-left= t(:status)
|
||||
.pull-right
|
||||
= link_to(t(:delete), '#', class: 'btn btn-danger btn-xs js-destroy-status', style: delete_style)
|
||||
.panel-body
|
||||
.form-group
|
||||
= f.label 'status', class: 'col-md-2 control-label'
|
||||
.col-md-10
|
||||
.js-select{style: disabled_style}
|
||||
= select_tag 'contact[statuses][]',
|
||||
options_for_select(Contact::admin_statuses_map, s),
|
||||
include_blank: true, class: "form-control"
|
||||
- if disabled
|
||||
.disabled-value.js-disabled-value
|
||||
= s
|
||||
= hidden_field_tag 'contact[statuses][]', s, readonly: true
|
||||
.form-group
|
||||
= label_tag t(:notes), nil, class: 'col-md-2 control-label'
|
||||
.col-md-10
|
||||
- value = f.object.new_record? ? '' : f.object.status_notes[s]
|
||||
= text_field_tag 'contact[status_notes_array][]', value, class: 'form-control'
|
||||
|
||||
:coffee
|
||||
$("#js-contact-statuses").nestedAttributes
|
||||
bindAddTo: $(".js-add-contact-status")
|
||||
afterAdd: (el) ->
|
||||
if el.find('.js-disabled-value')
|
||||
el.find('.js-disabled-value').remove()
|
||||
el.find('.js-select').show()
|
||||
el.find('.js-destroy-status').show()
|
||||
|
||||
$(document).on 'click', '.js-destroy-status', (e) ->
|
||||
e.preventDefault()
|
||||
$(this).parents('.panel').remove()
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
%br
|
||||
|
||||
|
||||
%dt= t(:ident)
|
||||
%dd= ident_for(@contact)
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
%thead
|
||||
%tr
|
||||
%th{class: 'col-xs-6'}= t(:status)
|
||||
%th{class: 'col-xs-6'}= t(:description)
|
||||
%th{class: 'col-xs-6'}= t(:notes)
|
||||
%tbody
|
||||
- contact.statuses.each do |s|
|
||||
- contact.statuses.each do |status|
|
||||
%tr
|
||||
%td= s.value
|
||||
%td= s.description
|
||||
%td= status
|
||||
%td= contact.status_notes[status]
|
||||
|
||||
- if contact.errors.messages[:statuses]
|
||||
%tfoot
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
- content_for :actions do
|
||||
= link_to(t(:edit_statuses), edit_admin_contact_path(@contact), class: 'btn btn-primary')
|
||||
= render 'shared/title', name: @contact.name
|
||||
|
||||
.row
|
||||
|
|
|
@ -1,125 +1,126 @@
|
|||
- children = HashWithIndifferentAccess.new(version.children)
|
||||
- nameservers = children[:nameservers] || []
|
||||
- tech_contacts = children[:tech_contacts] || []
|
||||
- admin_contacts = children[:admin_contacts] || []
|
||||
- registrant = children[:registrant] || []
|
||||
- if version.present? && domain.present?
|
||||
- children = HashWithIndifferentAccess.new(version.children)
|
||||
- nameservers = children[:nameservers] || []
|
||||
- tech_contacts = children[:tech_contacts] || []
|
||||
- admin_contacts = children[:admin_contacts] || []
|
||||
- registrant = children[:registrant] || []
|
||||
|
||||
%td
|
||||
%p.nowrap
|
||||
= l(domain.updated_at, format: :short)
|
||||
= version.event
|
||||
%p.text-right
|
||||
= version.terminator
|
||||
%td
|
||||
%p.nowrap
|
||||
= l(domain.updated_at, format: :short)
|
||||
= version.event
|
||||
%p.text-right
|
||||
= version.terminator
|
||||
|
||||
%td
|
||||
%p
|
||||
= "#{domain.period}#{domain.period_unit}"
|
||||
= "#{l(domain.valid_from, format: :date)} - #{l(domain.valid_to, format: :date)}"
|
||||
%p
|
||||
= domain.status
|
||||
|
||||
%td
|
||||
- registrant.each do |oc|
|
||||
%td
|
||||
%p
|
||||
= oc[:name]
|
||||
= oc[:phone]
|
||||
= oc[:email]
|
||||
= "#{domain.period}#{domain.period_unit}"
|
||||
= "#{l(domain.valid_from, format: :date)} - #{l(domain.valid_to, format: :date)}"
|
||||
%p
|
||||
= oc[:code]
|
||||
= domain.status
|
||||
|
||||
%td
|
||||
- admin_contacts.each do |ac|
|
||||
%td
|
||||
- registrant.each do |oc|
|
||||
%p
|
||||
= oc[:name]
|
||||
= oc[:phone]
|
||||
= oc[:email]
|
||||
%p
|
||||
= oc[:code]
|
||||
|
||||
%td
|
||||
- admin_contacts.each do |ac|
|
||||
%p
|
||||
= ac[:name]
|
||||
= ac[:phone]
|
||||
= ac[:email]
|
||||
%p
|
||||
= ac[:code]
|
||||
|
||||
%td
|
||||
- tech_contacts.each do |tc|
|
||||
%p
|
||||
= tc[:name]
|
||||
= tc[:phone]
|
||||
= tc[:email]
|
||||
%p
|
||||
= tc[:code]
|
||||
|
||||
%td
|
||||
- nameservers.each do |ns|
|
||||
%p
|
||||
= ns[:hostname]
|
||||
%br
|
||||
= ns[:ipv4]
|
||||
= ns[:ipv6]
|
||||
|
||||
%td
|
||||
%p
|
||||
= ac[:name]
|
||||
= ac[:phone]
|
||||
= ac[:email]
|
||||
%p
|
||||
= ac[:code]
|
||||
= domain.registrar.name
|
||||
|
||||
%td
|
||||
- tech_contacts.each do |tc|
|
||||
%p
|
||||
= tc[:name]
|
||||
= tc[:phone]
|
||||
= tc[:email]
|
||||
%p
|
||||
= tc[:code]
|
||||
-# %td
|
||||
-# = version.children.inspect
|
||||
|
||||
%td
|
||||
- nameservers.each do |ns|
|
||||
%p
|
||||
= ns[:hostname]
|
||||
%br
|
||||
= ns[:ipv4]
|
||||
= ns[:ipv6]
|
||||
|
||||
%td
|
||||
%p
|
||||
= domain.registrar.name
|
||||
|
||||
-# %td
|
||||
-# = version.children.inspect
|
||||
|
||||
-# %td{ class: changes.include?(:domain) ? 'edit-highlight' : 'no-highlight' }
|
||||
-# - if children[:domain]
|
||||
-# %p{:style => "font-size:x-small;"}
|
||||
-# = children[:domain][:period]
|
||||
-# = children[:domain][:period_unit] if children[:domain][:period]
|
||||
-# - if children[:domain][:valid_to] && children[:domain][:valid_from]
|
||||
-# = ","
|
||||
-# = l(children[:domain][:valid_from], format: :date) + '-' + l(children[:domain][:valid_to], format: :date)
|
||||
-# - if children[:domain].try(:[], :registrar_id)
|
||||
-# = ","
|
||||
-# = Registrar.find(children[:domain][:registrar_id]).try(:name)
|
||||
-# - if children[:domain][:status]
|
||||
-# = ',' + children[:domain][:status]
|
||||
|
||||
|
||||
-# %td{ class: changes.include?(:registrant) ? 'edit-highlight' : 'no-highlight' }
|
||||
-# - if children[:registrant]
|
||||
-# %p{:style => "font-size:x-small;"}
|
||||
-# = children[:registrant][:name]
|
||||
-# = ","
|
||||
-# = children[:registrant][:phone]
|
||||
-# = ","
|
||||
-# = children[:registrant][:email]
|
||||
-# = ","
|
||||
-# = children[:registrant][:code]
|
||||
|
||||
-# %td{ class: changes.include?(:admin_contacts) ? 'edit-highlight' : 'no-highlight' }
|
||||
-# - if children[:admin_contacts]
|
||||
-# - children[:admin_contacts].each do |ac|
|
||||
-# %td{ class: changes.include?(:domain) ? 'edit-highlight' : 'no-highlight' }
|
||||
-# - if children[:domain]
|
||||
-# %p{:style => "font-size:x-small;"}
|
||||
-# = ac[:name]
|
||||
-# = ","
|
||||
-# = ac[:phone]
|
||||
-# = ","
|
||||
-# = ac[:email]
|
||||
-# = ","
|
||||
-# = ac[:code]
|
||||
-# = children[:domain][:period]
|
||||
-# = children[:domain][:period_unit] if children[:domain][:period]
|
||||
-# - if children[:domain][:valid_to] && children[:domain][:valid_from]
|
||||
-# = ","
|
||||
-# = l(children[:domain][:valid_from], format: :date) + '-' + l(children[:domain][:valid_to], format: :date)
|
||||
-# - if children[:domain].try(:[], :registrar_id)
|
||||
-# = ","
|
||||
-# = Registrar.find(children[:domain][:registrar_id]).try(:name)
|
||||
-# - if children[:domain][:status]
|
||||
-# = ',' + children[:domain][:status]
|
||||
|
||||
-# %td{ class: changes.include?(:tech_contacts) ? 'edit-highlight' : 'no-highlight' }
|
||||
-# - if children[:tech_contacts]
|
||||
-# - children[:tech_contacts].each do |tc|
|
||||
|
||||
-# %td{ class: changes.include?(:registrant) ? 'edit-highlight' : 'no-highlight' }
|
||||
-# - if children[:registrant]
|
||||
-# %p{:style => "font-size:x-small;"}
|
||||
-# = tc[:name]
|
||||
-# = children[:registrant][:name]
|
||||
-# = ","
|
||||
-# = tc[:phone]
|
||||
-# = children[:registrant][:phone]
|
||||
-# = ","
|
||||
-# = tc[:email]
|
||||
-# = children[:registrant][:email]
|
||||
-# = ","
|
||||
-# = tc[:code]
|
||||
-# = children[:registrant][:code]
|
||||
|
||||
-# %td{ class: changes.include?(:nameservers) ? 'edit-highlight' : 'no-highlight' }
|
||||
-# - if children[:nameservers]
|
||||
-# - children[:nameservers].each do |ns|
|
||||
-# %p{:style => "font-size:x-small;"}
|
||||
-# = ns[:hostname]
|
||||
-# = ","
|
||||
-# = ns[:ipv4] || ns[:ipv6]
|
||||
-# %td{ class: changes.include?(:admin_contacts) ? 'edit-highlight' : 'no-highlight' }
|
||||
-# - if children[:admin_contacts]
|
||||
-# - children[:admin_contacts].each do |ac|
|
||||
-# %p{:style => "font-size:x-small;"}
|
||||
-# = ac[:name]
|
||||
-# = ","
|
||||
-# = ac[:phone]
|
||||
-# = ","
|
||||
-# = ac[:email]
|
||||
-# = ","
|
||||
-# = ac[:code]
|
||||
|
||||
-# %td
|
||||
-# %p{ :style => 'font-size:x-small;' }
|
||||
-# = l(version.created_at, format: :short)
|
||||
-# = whodunnit_with_protocol(version.whodunnit)
|
||||
-# = version.event
|
||||
-# %td{ class: changes.include?(:tech_contacts) ? 'edit-highlight' : 'no-highlight' }
|
||||
-# - if children[:tech_contacts]
|
||||
-# - children[:tech_contacts].each do |tc|
|
||||
-# %p{:style => "font-size:x-small;"}
|
||||
-# = tc[:name]
|
||||
-# = ","
|
||||
-# = tc[:phone]
|
||||
-# = ","
|
||||
-# = tc[:email]
|
||||
-# = ","
|
||||
-# = tc[:code]
|
||||
|
||||
-# %td{ class: changes.include?(:nameservers) ? 'edit-highlight' : 'no-highlight' }
|
||||
-# - if children[:nameservers]
|
||||
-# - children[:nameservers].each do |ns|
|
||||
-# %p{:style => "font-size:x-small;"}
|
||||
-# = ns[:hostname]
|
||||
-# = ","
|
||||
-# = ns[:ipv4] || ns[:ipv6]
|
||||
|
||||
-# %td
|
||||
-# %p{ :style => 'font-size:x-small;' }
|
||||
-# = l(version.created_at, format: :short)
|
||||
-# = whodunnit_with_protocol(version.whodunnit)
|
||||
-# = version.event
|
||||
|
|
|
@ -10,7 +10,3 @@
|
|||
.row
|
||||
.col-md-8.text-right
|
||||
= button_tag(t(:save), class: 'btn btn-primary')
|
||||
|
||||
:coffee
|
||||
$ ->
|
||||
$("#tabs a:first").tab "show"
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
.row
|
||||
.col-sm-6
|
||||
.col-sm-4
|
||||
%h1.text-center-xs
|
||||
= @invoice
|
||||
.col-sm-6
|
||||
.col-sm-8
|
||||
%h1.text-right.text-center-xs
|
||||
- unless @invoice.binded?
|
||||
= link_to(t(:payment_received), new_admin_bank_statement_path(invoice_id: @invoice.id), class: 'btn btn-default')
|
||||
= link_to(t(:download), admin_invoice_download_pdf_path(@invoice), class: 'btn btn-default')
|
||||
= link_to(t(:forward), admin_invoice_forward_path(@invoice), class: 'btn btn-default')
|
||||
- if !@invoice.cancelled? && !@invoice.binded?
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
= render 'setting_row', var: :registry_vat_no
|
||||
= render 'setting_row', var: :registry_vat_prc
|
||||
= render 'setting_row', var: :registry_bank
|
||||
= render 'setting_row', var: :registry_bank_code
|
||||
= render 'setting_row', var: :registry_iban
|
||||
= render 'setting_row', var: :registry_swift
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ xml.epp_head do
|
|||
xml.tag!('contact:roid', @contact.roid)
|
||||
|
||||
@contact.statuses.each do |status|
|
||||
xml.tag!('contact:status', s: status.value)
|
||||
xml.tag!('contact:status', s: status)
|
||||
end
|
||||
|
||||
xml.tag!('contact:postalInfo', type: 'int') do
|
||||
|
|
|
@ -30,5 +30,7 @@
|
|||
.col-md-3.control-label
|
||||
= f.label :country_code, t(:country) + '*'
|
||||
.col-md-7
|
||||
= f.select :country_code,
|
||||
SortedCountry.all_options(f.object.country_code)
|
||||
- country_selected = f.object.persisted? ? f.object.country_code : 'EE'
|
||||
= f.select(:country_code, SortedCountry.all_options(country_selected),
|
||||
{ include_blank: true }, required: true)
|
||||
|
||||
|
|
|
@ -6,24 +6,41 @@
|
|||
.col-md-3.control-label
|
||||
= f.label :ident_country_code, t(:country) + '*'
|
||||
.col-md-7
|
||||
= f.select(:ident_country_code, SortedCountry.all_options(f.object.ident_country_code), {},
|
||||
class: 'js-ident-country-code', required: true, disabled: @contact.persisted?)
|
||||
- if @contact.persisted? && f.object.ident_country_code.present?
|
||||
.disabled-value
|
||||
= Country.new(f.object.ident_country_code).try(:to_s)
|
||||
= " [#{f.object.ident_country_code}]"
|
||||
- else
|
||||
- country_selected = @contact.persisted? ? '' : 'EE'
|
||||
= f.select(:ident_country_code, SortedCountry.all_options(country_selected), {},
|
||||
class: 'js-ident-country-code', required: true)
|
||||
|
||||
.form-group
|
||||
.col-md-3.control-label
|
||||
= f.label :ident_type, t(:type) + '*'
|
||||
.col-md-7
|
||||
= f.select(:ident_type, Depp::Contact::SELECTION_TYPES, { selected: f.object.ident_type },
|
||||
class: 'js-ident-type', required: true, disabled: @contact.persisted?)
|
||||
- if @contact.persisted? && f.object.ident_type.present?
|
||||
.disabled-value
|
||||
= Depp::Contact.type_string(f.object.ident_type)
|
||||
= " [#{f.object.ident_type}]"
|
||||
- else
|
||||
- type_selected = @contact.persisted? ? '' : 'bic'
|
||||
= f.select(:ident_type, Depp::Contact::SELECTION_TYPES,
|
||||
{ selected: type_selected },
|
||||
class: 'js-ident-type', required: true)
|
||||
|
||||
.form-group
|
||||
.col-md-3.control-label
|
||||
= f.label :ident, t(:ident) + '*'
|
||||
.col-md-7
|
||||
= f.text_field :ident, class: 'form-control', required: true, disabled: @contact.persisted?
|
||||
- tip_visibility = f.object.ident_type == 'birthday' ? '' : 'display: none'
|
||||
.js-ident-tip{ style: tip_visibility }
|
||||
= t(:birthday_format)
|
||||
- if f.object.ident.present?
|
||||
.disabled-value
|
||||
= f.object.ident
|
||||
- else
|
||||
= f.text_field :ident, class: 'form-control', required: true, disabled: @contact.persisted?
|
||||
- tip_visibility = f.object.ident_type == 'birthday' ? '' : 'display: none'
|
||||
.js-ident-tip{ style: tip_visibility }
|
||||
= t(:birthday_format)
|
||||
|
||||
.panel.panel-default
|
||||
.panel-heading.clearfix
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
- object.errors.each do |attr, err|
|
||||
- next if attr.match(/\./)
|
||||
- next if attr == :epp_errors
|
||||
= err
|
||||
= "#{attr.to_s.humanize} #{err}"
|
||||
%br
|
||||
|
|
|
@ -21,3 +21,20 @@ api_log_test:
|
|||
registrant_write_test:
|
||||
<<: *default
|
||||
database: registry_test
|
||||
|
||||
# only for testing assets
|
||||
production:
|
||||
<<: *default
|
||||
database: registry_test
|
||||
|
||||
whois_test:
|
||||
<<: *default
|
||||
database: registry_whois_test
|
||||
|
||||
api_log_test:
|
||||
<<: *default
|
||||
database: registry_api_log_test
|
||||
|
||||
registrant_write_test:
|
||||
<<: *default
|
||||
database: registry_test
|
||||
|
|
|
@ -11,7 +11,7 @@ require 'mina/rbenv' # for rbenv support. (http://rbenv.org)
|
|||
# branch - Branch name to deploy. (needed by mina/git)
|
||||
|
||||
# alpha branch, all interfaces unified
|
||||
set :domain, 'registry-st'
|
||||
set :domain, 'registry'
|
||||
set :deploy_to, '$HOME/registry'
|
||||
set :repository, 'https://github.com/domify/registry' # dev repo
|
||||
set :branch, 'master'
|
||||
|
@ -20,7 +20,7 @@ set :que_restart, true
|
|||
|
||||
# alpha branch, only use for heavy debugging
|
||||
task :epp do
|
||||
set :domain, 'registry-st'
|
||||
set :domain, 'registry'
|
||||
set :deploy_to, '$HOME/epp'
|
||||
set :repository, 'https://github.com/domify/registry' # dev repo
|
||||
set :branch, 'master'
|
||||
|
@ -30,7 +30,7 @@ end
|
|||
|
||||
# alpha branch, only use for heavy debugging
|
||||
task :registrar do
|
||||
set :domain, 'registry-st'
|
||||
set :domain, 'registry'
|
||||
set :deploy_to, '$HOME/registrar'
|
||||
set :repository, 'https://github.com/domify/registry' # dev repo
|
||||
set :branch, 'master'
|
||||
|
@ -40,7 +40,7 @@ end
|
|||
|
||||
# alpha branch, only use for heavy debugging
|
||||
task :registrant do
|
||||
set :domain, 'registry-st'
|
||||
set :domain, 'registryt'
|
||||
set :deploy_to, '$HOME/registrant'
|
||||
set :repository, 'https://github.com/domify/registry' # dev repo
|
||||
set :branch, 'master'
|
||||
|
@ -219,19 +219,6 @@ task deploy: :environment do
|
|||
end
|
||||
end
|
||||
|
||||
desc 'Rolls back the latest release'
|
||||
task rollback: :environment do
|
||||
queue! %(echo "-----> Rolling back to previous release for instance: #{domain}")
|
||||
queue %(ls "#{deploy_to}/releases" -Art | sort | tail -n 2 | head -n 1)
|
||||
queue! %(
|
||||
ls -Art "#{deploy_to}/releases" | sort | tail -n 2 | head -n 1 |
|
||||
xargs -I active ln -nfs "#{deploy_to}/releases/active" "#{deploy_to}/current"
|
||||
)
|
||||
to :launch do
|
||||
invoke :restart
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Loads current commit hash'
|
||||
task load_commit_hash: :environment do
|
||||
queue! %(
|
|
@ -44,7 +44,7 @@ Rails.application.configure do
|
|||
|
||||
# The available log levels are: :debug, :info, :warn, :error, :fatal, and :unknown,
|
||||
# corresponding to the log level numbers from 0 up to 5 respectively
|
||||
config.log_level = :fatal
|
||||
config.log_level = :info
|
||||
|
||||
# for finding database optimization
|
||||
config.after_initialize do
|
||||
|
|
|
@ -50,6 +50,7 @@ if con.present? && con.table_exists?('settings')
|
|||
Setting.save_default(:registry_vat_prc, 0.2)
|
||||
Setting.save_default(:registry_iban, 'EE557700771000598731')
|
||||
Setting.save_default(:registry_bank, 'LHV Pank')
|
||||
Setting.save_default(:registry_bank_code, '689')
|
||||
Setting.save_default(:registry_swift, 'LHVBEE22')
|
||||
Setting.save_default(:registry_invoice_contact, 'Martti Õigus')
|
||||
end
|
||||
|
|
|
@ -36,6 +36,7 @@ en:
|
|||
attributes:
|
||||
code:
|
||||
blank: "Required parameter missing - code"
|
||||
too_long_contact_code: "Contact code is too long, max 100 characters"
|
||||
name:
|
||||
blank: "Required parameter missing - name"
|
||||
phone:
|
||||
|
@ -51,6 +52,8 @@ en:
|
|||
invalid_country_code: "Ident country code is not valid, should be in ISO_3166-1 alpha 2 format"
|
||||
domains:
|
||||
exist: 'Object association prohibits operation'
|
||||
statuses:
|
||||
not_uniq: 'not uniq'
|
||||
|
||||
epp_domain: &epp_domain_ar_attributes
|
||||
attributes:
|
||||
|
@ -256,7 +259,7 @@ en:
|
|||
invalid_type: 'PostalInfo type is invalid'
|
||||
unimplemented_command: 'Unimplemented command'
|
||||
domain_exists_but_belongs_to_other_registrar: 'Domain exists but belongs to other registrar'
|
||||
required_attribute_missing: Required attributes missing
|
||||
required_ident_attribute_missing: "Required ident attribute missing: %{key}"
|
||||
|
||||
code: 'Code'
|
||||
value: 'Value'
|
||||
|
@ -869,4 +872,8 @@ en:
|
|||
reserved_pw: 'Reserved pw'
|
||||
no_transfers_found: 'No transfers found'
|
||||
parameter_value_range_error: 'Parameter value range error: %{key}'
|
||||
payment_received: 'Payment received'
|
||||
domain_registrant_updated: 'Domeeni %{name} registreerija vahetus teostatud / Registrant change of %{name} has been finished.'
|
||||
api_user_not_found: 'API user not found'
|
||||
domain_already_belongs_to_the_querying_registrar: 'Domain already belongs to the querying registrar'
|
||||
notes: Notes
|
||||
|
|
15
db/data/20150707103801_refactor_contact_statuses.rb
Normal file
15
db/data/20150707103801_refactor_contact_statuses.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
class RefactorContactStatuses < ActiveRecord::Migration
|
||||
def self.up
|
||||
Contact.find_each do |contact|
|
||||
statuses = []
|
||||
contact.depricated_statuses.each do |ds|
|
||||
statuses << ds.value
|
||||
end
|
||||
contact.update_column('statuses', statuses)
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
5
db/migrate/20150707103241_add_statuses_to_contact.rb
Normal file
5
db/migrate/20150707103241_add_statuses_to_contact.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AddStatusesToContact < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :contacts, :statuses, :string, array: true
|
||||
end
|
||||
end
|
|
@ -0,0 +1,6 @@
|
|||
class AddContactAndDomainStatusNotes < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :contacts, :status_notes, :hstore
|
||||
add_column :domains, :status_notes, :hstore
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150713113436) do
|
||||
ActiveRecord::Schema.define(version: 20150722071128) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -200,6 +200,7 @@ ActiveRecord::Schema.define(version: 20150713113436) do
|
|||
t.string "state"
|
||||
t.integer "legacy_id"
|
||||
t.string "statuses", array: true
|
||||
t.hstore "status_notes"
|
||||
end
|
||||
|
||||
add_index "contacts", ["code"], name: "index_contacts_on_code", using: :btree
|
||||
|
@ -215,12 +216,6 @@ ActiveRecord::Schema.define(version: 20150713113436) do
|
|||
t.string "updator_str"
|
||||
end
|
||||
|
||||
create_table "data_migrations", id: false, force: :cascade do |t|
|
||||
t.string "version", null: false
|
||||
end
|
||||
|
||||
add_index "data_migrations", ["version"], name: "unique_data_migrations", unique: true, using: :btree
|
||||
|
||||
create_table "delegation_signers", force: :cascade do |t|
|
||||
t.integer "domain_id"
|
||||
t.string "key_tag"
|
||||
|
@ -327,6 +322,7 @@ ActiveRecord::Schema.define(version: 20150713113436) do
|
|||
t.datetime "force_delete_at"
|
||||
t.string "statuses", array: true
|
||||
t.boolean "reserved", default: false
|
||||
t.hstore "status_notes"
|
||||
end
|
||||
|
||||
add_index "domains", ["delete_at"], name: "index_domains_on_delete_at", using: :btree
|
||||
|
|
|
@ -632,7 +632,8 @@ CREATE TABLE contacts (
|
|||
country_code character varying,
|
||||
state character varying,
|
||||
legacy_id integer,
|
||||
statuses character varying[]
|
||||
statuses character varying[],
|
||||
status_notes hstore
|
||||
);
|
||||
|
||||
|
||||
|
@ -689,15 +690,6 @@ CREATE SEQUENCE countries_id_seq
|
|||
ALTER SEQUENCE countries_id_seq OWNED BY countries.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: data_migrations; Type: TABLE; Schema: public; Owner: -; Tablespace:
|
||||
--
|
||||
|
||||
CREATE TABLE data_migrations (
|
||||
version character varying NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: delegation_signers; Type: TABLE; Schema: public; Owner: -; Tablespace:
|
||||
--
|
||||
|
@ -945,7 +937,8 @@ CREATE TABLE domains (
|
|||
pending_json json,
|
||||
force_delete_at timestamp without time zone,
|
||||
statuses character varying[],
|
||||
reserved boolean DEFAULT false
|
||||
reserved boolean DEFAULT false,
|
||||
status_notes hstore
|
||||
);
|
||||
|
||||
|
||||
|
@ -4519,13 +4512,6 @@ CREATE INDEX index_whois_records_on_domain_id ON whois_records USING btree (doma
|
|||
CREATE INDEX index_whois_records_on_registrar_id ON whois_records USING btree (registrar_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: unique_data_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace:
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX unique_data_migrations ON data_migrations USING btree (version);
|
||||
|
||||
|
||||
--
|
||||
-- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace:
|
||||
--
|
||||
|
@ -4861,10 +4847,6 @@ INSERT INTO schema_migrations (version) VALUES ('20150522164020');
|
|||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150525075550');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150601083516');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150601083800');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150603141054');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150603141549');
|
||||
|
@ -4873,12 +4855,8 @@ INSERT INTO schema_migrations (version) VALUES ('20150603211318');
|
|||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150603212659');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150609093515');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150609103333');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150610111019');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150610112238');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150610144547');
|
||||
|
@ -4887,8 +4865,6 @@ INSERT INTO schema_migrations (version) VALUES ('20150611124920');
|
|||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150612123111');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150612125720');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150701074344');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150703084632');
|
||||
|
@ -4897,8 +4873,6 @@ INSERT INTO schema_migrations (version) VALUES ('20150706091724');
|
|||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150707103241');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150707103801');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150707104937');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150707154543');
|
||||
|
@ -4907,3 +4881,5 @@ INSERT INTO schema_migrations (version) VALUES ('20150709092549');
|
|||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150713113436');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150722071128');
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ Deploy overview: (database schema should be loaded and seeds should be present)
|
|||
git clone git@github.com:internetee/registry.git
|
||||
cd registry
|
||||
rbenv local 2.2.2 # more info about rbenv at debian doc
|
||||
gem install mina
|
||||
gem install mina # or any other deployment tool
|
||||
cp config/deploy-example.rb config/deploy.rb # and edit it
|
||||
mina pr setup # one time, only creates missing directories
|
||||
ssh registry
|
||||
|
||||
|
@ -37,15 +38,17 @@ Deploy overview: (database schema should be loaded and seeds should be present)
|
|||
vi /etc/apache2/sites-enabled/epp.conf # add epp conf, restart apache
|
||||
exit
|
||||
# at your local machine
|
||||
mina pr deploy # this is command you use in every application code update
|
||||
mina pr deploy # for new update using mina tool as example
|
||||
|
||||
|
||||
|
||||
### Deploy script setup
|
||||
|
||||
We recommend [Mina](https://github.com/mina-deploy/mina) instead of Capistrano for deployment.
|
||||
We recommend [Mina](https://github.com/mina-deploy/mina) instead of Capistrano or other tools for deployment.
|
||||
|
||||
All deploy code locates at config/deploy.rb file.
|
||||
All deploy code locates at config/deploy.rb, please copy content from example file and edit it.
|
||||
|
||||
cp config/deploy-example.rb config/deploy.rb # and edit it
|
||||
|
||||
First add shortcuts to your local machine ssh config file,
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ After deploy, in rails console:
|
|||
|
||||
Certificate.update_crl
|
||||
|
||||
Update cron:
|
||||
Update cron (mina tool example, when installed correctly):
|
||||
|
||||
mina cron:setup
|
||||
|
||||
|
|
2028
doc/epp-examples.md
2028
doc/epp-examples.md
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,8 @@ Contact Mapping protocol short version:
|
|||
----------------------- ------- -----------------
|
||||
<create> 1
|
||||
<contact:create> 1 Attribute: xmlns:contact="https://raw.githubusercontent.com/internetee/registry/alpha/doc/schemas/contact-eis-1.0.xsd"
|
||||
<contact:id> 0-1 Contact id, optional, generated automatically if missing
|
||||
<contact:id> 0-1 Contact id, optional, string, no spaces, max 100 characters,
|
||||
generated automatically if missing
|
||||
<contact:postalInfo> 1 Postal information container
|
||||
<contact:name> 1 Full name of the contact
|
||||
<contact:org> 0 Org is not supported and must be blank or missing
|
||||
|
|
|
@ -18,6 +18,7 @@ Domain name mapping protocol short version:
|
|||
<domain:period> 0-1 Registration period for domain.
|
||||
Must add up to 1 / 2 / 3 years.
|
||||
Attribute: unit="y/m/d"
|
||||
Default is 1 year.
|
||||
<domain:registrant> 1 Contact reference to the registrant
|
||||
Attribute:
|
||||
"verified" # optional, allowed values 'yes', 'no'
|
||||
|
@ -129,8 +130,9 @@ Domain name mapping protocol short version:
|
|||
<domain:renew> 1 Attribute: xmlns:domain="https://raw.githubusercontent.com/internetee/registry/alpha/doc/schemas/domain-eis-1.0.xsd"
|
||||
<domain:name> 1 Domain name. Can contain unicode characters.
|
||||
<domain:curExpDate> 1 Current expiry date (ISO8601 format)
|
||||
<domain:period> 1 Registration period for domain.
|
||||
<domain:period> 0-1 Registration period for domain.
|
||||
Must add up to 1 / 2 / 3 years. Attribute: unit="y/m/d"
|
||||
Default value is 1 year.
|
||||
<extension> 0-1
|
||||
<eis:extdata> 0-1 Attribute: xmlns:eis="https://raw.githubusercontent.com/internetee/registry/alpha/doc/schemas/eis-1.0.xsd"
|
||||
<eis:legalDocument> 0-1 Base64 encoded document.
|
||||
|
|
|
@ -12,3 +12,7 @@ namespace :assets do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
task as: :environment do
|
||||
system('RAILS_ENV=production rake assets:precompile')
|
||||
end
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -176,6 +176,19 @@ describe 'EPP Contact', epp: true do
|
|||
response[:result_code].should == '2005'
|
||||
end
|
||||
|
||||
it 'should not strange characters in custom code' do
|
||||
response = create_request({ id: { value: '33&$@@' } })
|
||||
response[:msg].should == 'is invalid [code]'
|
||||
response[:result_code].should == '2005'
|
||||
end
|
||||
|
||||
it 'should not strange characters in custom code' do
|
||||
long_str = 'a' * 1000
|
||||
response = create_request({ id: { value: long_str } })
|
||||
response[:msg].should == 'Contact code is too long, max 100 characters [code]'
|
||||
response[:result_code].should == '2005'
|
||||
end
|
||||
|
||||
it 'should not saves ident type with wrong country code' do
|
||||
extension = {
|
||||
ident: {
|
||||
|
@ -189,6 +202,31 @@ describe 'EPP Contact', epp: true do
|
|||
response[:result_code].should == '2005'
|
||||
end
|
||||
|
||||
it 'should return country missing' do
|
||||
extension = {
|
||||
ident: {
|
||||
value: '1990-22-12',
|
||||
attrs: { type: 'birthday' }
|
||||
}
|
||||
}
|
||||
response = create_request({}, extension, validate_input: false)
|
||||
response[:msg].should ==
|
||||
'Required ident attribute missing: cc'
|
||||
response[:result_code].should == '2003'
|
||||
end
|
||||
|
||||
it 'should return country missing' do
|
||||
extension = {
|
||||
ident: {
|
||||
value: '1990-22-12'
|
||||
}
|
||||
}
|
||||
response = create_request({}, extension, validate_input: false)
|
||||
response[:msg].should ==
|
||||
'Required ident attribute missing: type'
|
||||
response[:result_code].should == '2003'
|
||||
end
|
||||
|
||||
it 'should add registrar prefix for code when legacy prefix present' do
|
||||
response = create_request({ id: { value: 'CID:FIRST0:abc:ABC:NEW:12345' } })
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
|
|
|
@ -435,6 +435,24 @@ describe 'EPP Domain', epp: true do
|
|||
a.activity_type = AccountActivity::CREATE
|
||||
end
|
||||
|
||||
it 'creates a domain without period' do
|
||||
old_balance = @registrar1.balance
|
||||
old_activities = @registrar1.cash_account.account_activities.count
|
||||
xml = domain_create_xml(period: nil)
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
Domain.last.valid_to.should be_within(60).of(1.years.since)
|
||||
@registrar1.balance.should be < old_balance
|
||||
@registrar1.cash_account.account_activities.count.should == old_activities + 1
|
||||
a = @registrar1.cash_account.account_activities.last
|
||||
a.description.should == "Create #{Domain.last.name}"
|
||||
a.sum.should == -BigDecimal.new('10.0')
|
||||
a.activity_type = AccountActivity::CREATE
|
||||
a.log_pricelist_id.should == @pricelist_reg_1_year.id
|
||||
end
|
||||
|
||||
it 'does not create a domain with invalid period' do
|
||||
old_balance = @registrar1.balance
|
||||
old_activities = @registrar1.cash_account.account_activities.count
|
||||
|
@ -450,6 +468,24 @@ describe 'EPP Domain', epp: true do
|
|||
@registrar1.cash_account.account_activities.count.should == old_activities
|
||||
end
|
||||
|
||||
it 'does not create a domain with invalid period unit' do
|
||||
xml = domain_create_xml({
|
||||
period: { value: '1', attrs: { unit: '' } }
|
||||
})
|
||||
|
||||
response = epp_plain_request(xml, validate_input: false)
|
||||
response[:results][0][:msg].should == 'Attribute is invalid: unit'
|
||||
response[:results][0][:result_code].should == '2306'
|
||||
|
||||
xml = domain_create_xml({
|
||||
period: { value: '1', attrs: { unit: 'bla' } }
|
||||
})
|
||||
|
||||
response = epp_plain_request(xml, validate_input: false)
|
||||
response[:results][0][:msg].should == 'Attribute is invalid: unit'
|
||||
response[:results][0][:result_code].should == '2306'
|
||||
end
|
||||
|
||||
it 'creates a domain with multiple dnskeys' do
|
||||
xml = domain_create_xml({}, {
|
||||
_anonymus: [
|
||||
|
@ -2185,16 +2221,14 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
### RENEW ###
|
||||
it 'renews a domain' do
|
||||
Setting.days_to_renew_domain_before_expire = 0
|
||||
old_balance = @registrar1.balance
|
||||
old_activities = @registrar1.cash_account.account_activities.count
|
||||
|
||||
domain.valid_to = Time.zone.now.to_date + 10.days
|
||||
domain.save
|
||||
|
||||
exp_date = domain.valid_to.to_date
|
||||
exp_date = domain.valid_to
|
||||
xml = @epp_xml.domain.renew(
|
||||
name: { value: domain.name },
|
||||
curExpDate: { value: exp_date.to_s },
|
||||
curExpDate: { value: exp_date.to_date.to_s },
|
||||
period: { value: '1', attrs: { unit: 'y' } }
|
||||
)
|
||||
|
||||
|
@ -2204,9 +2238,16 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
ex_date = response[:parsed].css('renData exDate').text
|
||||
name = response[:parsed].css('renData name').text
|
||||
ex_date.should == "#{(exp_date + 1.year)}T00:00:00Z"
|
||||
ex_date.should == "#{(exp_date + 1.year).to_s(:iso8601)}"
|
||||
name.should == domain.name
|
||||
|
||||
domain.reload
|
||||
domain.valid_to.should be_within(1).of(exp_date + 1.year)
|
||||
domain.outzone_at.should be_within(1).of(exp_date + 1.year + Setting.expire_warning_period.days)
|
||||
domain.delete_at.should be_within(1).of(
|
||||
exp_date + 1.year + Setting.expire_warning_period.days + Setting.redemption_grace_period.days
|
||||
)
|
||||
|
||||
@registrar1.balance.should == old_balance - 15.0
|
||||
@registrar1.cash_account.account_activities.count.should == old_activities + 1
|
||||
a = @registrar1.cash_account.account_activities.last
|
||||
|
@ -2214,6 +2255,93 @@ describe 'EPP Domain', epp: true do
|
|||
a.sum.should == -BigDecimal.new('15.0')
|
||||
a.activity_type = AccountActivity::RENEW
|
||||
a.log_pricelist_id.should == @pricelist_renew_1_year.id
|
||||
Setting.days_to_renew_domain_before_expire = 90
|
||||
end
|
||||
|
||||
it 'renews a domain when outzone_at or delete_at is nil for some reason' do
|
||||
Setting.days_to_renew_domain_before_expire = 0
|
||||
|
||||
domain.outzone_at = nil
|
||||
domain.delete_at = nil
|
||||
domain.save
|
||||
|
||||
exp_date = domain.valid_to
|
||||
xml = @epp_xml.domain.renew(
|
||||
name: { value: domain.name },
|
||||
curExpDate: { value: exp_date.to_date.to_s },
|
||||
period: { value: '1', attrs: { unit: 'y' } }
|
||||
)
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:results][0][:msg].should == 'Command completed successfully'
|
||||
response[:results][0][:result_code].should == '1000'
|
||||
|
||||
Setting.days_to_renew_domain_before_expire = 90
|
||||
end
|
||||
|
||||
it 'renews a domain with no period specified' do
|
||||
Setting.days_to_renew_domain_before_expire = 0
|
||||
old_balance = @registrar1.balance
|
||||
old_activities = @registrar1.cash_account.account_activities.count
|
||||
|
||||
exp_date = domain.valid_to
|
||||
xml = @epp_xml.domain.renew(
|
||||
name: { value: domain.name },
|
||||
curExpDate: { value: exp_date.to_date.to_s },
|
||||
period: nil
|
||||
)
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:results][0][:msg].should == 'Command completed successfully'
|
||||
response[:results][0][:result_code].should == '1000'
|
||||
|
||||
ex_date = response[:parsed].css('renData exDate').text
|
||||
name = response[:parsed].css('renData name').text
|
||||
ex_date.should == "#{(exp_date + 1.year).to_s(:iso8601)}"
|
||||
name.should == domain.name
|
||||
|
||||
domain.reload
|
||||
domain.valid_to.should be_within(1).of(exp_date + 1.year)
|
||||
domain.outzone_at.should be_within(1).of(exp_date + 1.year + Setting.expire_warning_period.days)
|
||||
domain.delete_at.should be_within(1).of(
|
||||
exp_date + 1.year + Setting.expire_warning_period.days + Setting.redemption_grace_period.days
|
||||
)
|
||||
|
||||
@registrar1.balance.should == old_balance - 15.0
|
||||
@registrar1.cash_account.account_activities.count.should == old_activities + 1
|
||||
a = @registrar1.cash_account.account_activities.last
|
||||
a.description.should == "Renew #{Domain.last.name}"
|
||||
a.sum.should == -BigDecimal.new('15.0')
|
||||
a.activity_type = AccountActivity::RENEW
|
||||
a.log_pricelist_id.should == @pricelist_renew_1_year.id
|
||||
Setting.days_to_renew_domain_before_expire = 90
|
||||
end
|
||||
|
||||
it 'does not renew domain with invalid period' do
|
||||
Setting.days_to_renew_domain_before_expire = 0
|
||||
|
||||
exp_date = domain.valid_to
|
||||
xml = @epp_xml.domain.renew(
|
||||
name: { value: domain.name },
|
||||
curExpDate: { value: exp_date.to_date.to_s },
|
||||
period: { value: '1', attrs: { unit: '' } }
|
||||
)
|
||||
|
||||
response = epp_plain_request(xml, validate_input: false)
|
||||
response[:results][0][:msg].should == 'Attribute is invalid: unit'
|
||||
response[:results][0][:result_code].should == '2306'
|
||||
|
||||
xml = @epp_xml.domain.renew(
|
||||
name: { value: domain.name },
|
||||
curExpDate: { value: exp_date.to_date.to_s },
|
||||
period: { value: '1', attrs: { unit: 'bla' } }
|
||||
)
|
||||
|
||||
response = epp_plain_request(xml, validate_input: false)
|
||||
response[:results][0][:msg].should == 'Attribute is invalid: unit'
|
||||
response[:results][0][:result_code].should == '2306'
|
||||
|
||||
Setting.days_to_renew_domain_before_expire = 90
|
||||
end
|
||||
|
||||
it 'renews a domain with 2 year period' do
|
||||
|
|
|
@ -28,6 +28,11 @@ describe 'EPP Session', epp: true do
|
|||
response[:msg].should == 'Authentication error; server closing connection (API user not found)'
|
||||
response[:result_code].should == '2501'
|
||||
response[:clTRID].should == 'ABC-12345'
|
||||
|
||||
log = ApiLog::EppLog.last
|
||||
log.request_command.should == 'login'
|
||||
log.request_successful.should == false
|
||||
log.api_user_name.should == 'api-public'
|
||||
end
|
||||
|
||||
it 'does not log in with inactive user' do
|
||||
|
@ -38,6 +43,11 @@ describe 'EPP Session', epp: true do
|
|||
response = epp_plain_request(inactive)
|
||||
response[:msg].should == 'Authentication error; server closing connection (API user is not active)'
|
||||
response[:result_code].should == '2501'
|
||||
|
||||
log = ApiLog::EppLog.last
|
||||
log.request_command.should == 'login'
|
||||
log.request_successful.should == false
|
||||
log.api_user_name.should == '2-api-inactive-user'
|
||||
end
|
||||
|
||||
it 'prohibits further actions unless logged in' do
|
||||
|
@ -61,6 +71,11 @@ describe 'EPP Session', epp: true do
|
|||
response[:msg].should == 'Parameter value policy error. Allowed only Latin characters.'
|
||||
response[:result_code].should == '2306'
|
||||
response[:clTRID].should == 'ABC-12345'
|
||||
|
||||
log = ApiLog::EppLog.last
|
||||
log.request_command.should == 'login'
|
||||
log.request_successful.should == false
|
||||
log.api_user_name.should == 'api-public'
|
||||
end
|
||||
|
||||
context 'with valid user' do
|
||||
|
|
|
@ -59,4 +59,52 @@ feature 'Invoice', type: :feature do
|
|||
response_headers['Content-Type'].should == 'application/pdf'
|
||||
response_headers['Content-Disposition'].should == "attachment; filename=\"#{@invoice.pdf_name}\""
|
||||
end
|
||||
|
||||
it 'should create bank statement and transaction for invoice' do
|
||||
r = Fabricate(:registrar, reference_no: 'RF7086666663')
|
||||
invoice = r.issue_prepayment_invoice(200, 'add some money')
|
||||
|
||||
visit '/admin/invoices'
|
||||
click_link invoice.to_s
|
||||
|
||||
page.should have_content('Unpaid')
|
||||
|
||||
click_link 'Payment received'
|
||||
|
||||
paid_at = Time.zone.now
|
||||
find_field('Bank code').value.should == '689'
|
||||
find_field('Iban').value.should == 'EE557700771000598731'
|
||||
find_field('Description').value.should == invoice.to_s
|
||||
find_field('Sum').value.should == invoice.sum.to_s
|
||||
find_field('Currency').value.should == 'EUR'
|
||||
find_field('Reference no').value.should == invoice.reference_no
|
||||
find_field('Paid at').value.should == paid_at.to_date.to_s
|
||||
|
||||
click_button 'Save'
|
||||
|
||||
page.should have_content('Record created')
|
||||
page.should have_content('689')
|
||||
page.should have_content('EE557700771000598731')
|
||||
page.should have_content('Not binded', count: 2)
|
||||
page.should have_content(invoice.sum.to_s)
|
||||
page.should have_content('EUR')
|
||||
|
||||
click_link 'Bind invoices'
|
||||
|
||||
page.should have_content('Invoices were fully binded')
|
||||
page.should have_content('Fully binded')
|
||||
page.should have_content('Binded')
|
||||
|
||||
click_link I18n.l(paid_at, format: :date_long)
|
||||
|
||||
page.should have_content('Binded')
|
||||
page.should have_content(invoice.to_s)
|
||||
page.should have_content(invoice.sum.to_s)
|
||||
page.should have_content(invoice.reference_no)
|
||||
page.should have_content(I18n.l(paid_at, format: :date_long))
|
||||
|
||||
click_link(invoice.to_s)
|
||||
page.should_not have_content('Unpaid')
|
||||
page.should_not have_content('Payment received')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -97,7 +97,13 @@ describe Contact do
|
|||
it 'should not accept long code' do
|
||||
@contact.code = 'verylongcode' * 100
|
||||
@contact.valid?
|
||||
@contact.errors[:code].should == ['is too long (maximum is 100 characters)']
|
||||
@contact.errors[:code].should == ['Contact code is too long, max 100 characters']
|
||||
end
|
||||
|
||||
it 'should not allow double status' do
|
||||
@contact.statuses = ['ok', 'ok']
|
||||
@contact.valid?
|
||||
@contact.errors[:statuses].should == ['not uniq']
|
||||
end
|
||||
|
||||
it 'should have no related domain descriptions' do
|
||||
|
@ -154,17 +160,36 @@ describe Contact do
|
|||
end
|
||||
|
||||
it 'should have ok status by default' do
|
||||
@contact.statuses.size.should == 1
|
||||
@contact.statuses.first.value.should == 'ok'
|
||||
@contact.statuses.should == %w(ok)
|
||||
end
|
||||
|
||||
it 'should not remove ok status after save' do
|
||||
@contact.statuses.should == %w(ok)
|
||||
@contact.save
|
||||
@contact.statuses.should == %w(ok)
|
||||
end
|
||||
|
||||
it 'should remove ok status when other non linked status present' do
|
||||
contact = Fabricate(:contact)
|
||||
contact.statuses = [Contact::SERVER_UPDATE_PROHIBITED]
|
||||
contact.statuses.should == [Contact::SERVER_UPDATE_PROHIBITED] # temp test
|
||||
contact.save
|
||||
contact.statuses.should == [Contact::SERVER_UPDATE_PROHIBITED]
|
||||
end
|
||||
|
||||
it 'should have linked status when domain' do
|
||||
@tech_domain_contact = Fabricate(:tech_domain_contact, contact_id: @contact.id)
|
||||
@domain = Fabricate(:domain, tech_domain_contacts: [@tech_domain_contact])
|
||||
contact = @domain.contacts.first
|
||||
contact.save
|
||||
contact = Fabricate(:contact)
|
||||
tech_domain_contact = Fabricate(:tech_domain_contact, contact_id: contact.id)
|
||||
contact.statuses.should == %w(ok)
|
||||
domain = Fabricate(:domain, tech_domain_contacts: [tech_domain_contact])
|
||||
|
||||
contact.statuses.map(&:value).sort.should == %w(linked ok)
|
||||
contact = domain.contacts.first
|
||||
contact.save
|
||||
contact.statuses.sort.should == %w(linked ok)
|
||||
|
||||
contact = domain.contacts.second
|
||||
contact.save
|
||||
contact.statuses.sort.should == %w(linked ok)
|
||||
end
|
||||
|
||||
it 'should not have linked status when no domain' do
|
||||
|
@ -173,11 +198,11 @@ describe Contact do
|
|||
contact = @domain.contacts.first
|
||||
contact.save
|
||||
|
||||
contact.statuses.map(&:value).sort.should == %w(linked ok)
|
||||
contact.statuses.sort.should == %w(linked ok)
|
||||
|
||||
contact.domains.first.destroy
|
||||
contact.reload
|
||||
contact.statuses.map(&:value).should == %w(ok)
|
||||
contact.statuses.should == %w(ok)
|
||||
end
|
||||
|
||||
it 'should have code' do
|
||||
|
@ -193,6 +218,15 @@ describe Contact do
|
|||
# contact.statuses.map(&:value).should == %w(ok linked)
|
||||
end
|
||||
|
||||
it 'should save status notes' do
|
||||
contact = Fabricate(:contact)
|
||||
contact.statuses = ['serverDeleteProhibited', 'serverUpdateProhibited']
|
||||
contact.status_notes_array = [nil, 'update manually turned off']
|
||||
contact.status_notes['serverDeleteProhibited'].should == nil
|
||||
contact.status_notes['serverUpdateProhibited'].should == 'update manually turned off'
|
||||
contact.status_notes['someotherstatus'].should == nil
|
||||
end
|
||||
|
||||
context 'as birthday' do
|
||||
before do
|
||||
@domain = Fabricate(:domain)
|
||||
|
|
|
@ -77,5 +77,14 @@ describe Repp::DomainV1 do
|
|||
|
||||
# TODO: Log failed API requests too
|
||||
end
|
||||
|
||||
it 'returns an error with invalid credentials' do
|
||||
invalid_user = OpenStruct.new(username: 'bla', password: 'blabala')
|
||||
get_with_auth '/repp/v1/domains', {}, invalid_user
|
||||
response.status.should == 401
|
||||
|
||||
body = JSON.parse(response.body)
|
||||
body['error'].should == 'API user not found'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue