mirror of
https://github.com/internetee/registry.git
synced 2025-05-28 13:51:41 +02:00
Merge branch 'master' into domains-nested-refactor
Conflicts: config/locales/en.yml
This commit is contained in:
commit
08fb2966d4
93 changed files with 2356 additions and 1678 deletions
|
@ -12,10 +12,7 @@ class Admin::ApiUsersController < AdminController
|
|||
end
|
||||
|
||||
def create
|
||||
app = api_user_params
|
||||
app[:csr] = params[:api_user][:csr].open.read if params[:api_user][:csr]
|
||||
|
||||
@api_user = ApiUser.new(app)
|
||||
@api_user = ApiUser.new(api_user_params)
|
||||
|
||||
if @api_user.save
|
||||
flash[:notice] = I18n.t('record_created')
|
||||
|
@ -31,10 +28,7 @@ class Admin::ApiUsersController < AdminController
|
|||
def edit; end
|
||||
|
||||
def update
|
||||
app = api_user_params
|
||||
app[:csr] = params[:api_user][:csr].open.read if params[:api_user][:csr]
|
||||
|
||||
if @api_user.update(app)
|
||||
if @api_user.update(api_user_params)
|
||||
flash[:notice] = I18n.t('record_updated')
|
||||
redirect_to [:admin, @api_user]
|
||||
else
|
||||
|
@ -53,14 +47,6 @@ class Admin::ApiUsersController < AdminController
|
|||
end
|
||||
end
|
||||
|
||||
def download_csr
|
||||
send_data @api_user.csr, filename: "#{@api_user.username}.csr.pem"
|
||||
end
|
||||
|
||||
def download_crt
|
||||
send_data @api_user.crt, filename: "#{@api_user.username}.crt.pem"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_api_user
|
||||
|
@ -68,6 +54,6 @@ class Admin::ApiUsersController < AdminController
|
|||
end
|
||||
|
||||
def api_user_params
|
||||
params.require(:api_user).permit(:username, :password, :csr, :active, :registrar_id, :registrar_typeahead)
|
||||
params.require(:api_user).permit(:username, :password, :active, :registrar_id, :registrar_typeahead)
|
||||
end
|
||||
end
|
||||
|
|
68
app/controllers/admin/certificates_controller.rb
Normal file
68
app/controllers/admin/certificates_controller.rb
Normal file
|
@ -0,0 +1,68 @@
|
|||
class Admin::CertificatesController < AdminController
|
||||
load_and_authorize_resource
|
||||
before_action :set_certificate, :set_api_user, only: [:sign, :show, :download_csr, :download_crt, :revoke]
|
||||
|
||||
def show
|
||||
@csr = OpenSSL::X509::Request.new(@certificate.csr) if @certificate.csr
|
||||
@crt = OpenSSL::X509::Certificate.new(@certificate.crt) if @certificate.crt
|
||||
end
|
||||
|
||||
def new
|
||||
set_api_user
|
||||
@certificate = Certificate.new
|
||||
end
|
||||
|
||||
def create
|
||||
@api_user = ApiUser.find(params[:api_user_id])
|
||||
csr = certificate_params[:csr].open.read if certificate_params[:csr]
|
||||
|
||||
@certificate = @api_user.certificates.build(csr: csr)
|
||||
if @api_user.save
|
||||
flash[:notice] = I18n.t('record_created')
|
||||
redirect_to [:admin, @api_user, @certificate]
|
||||
else
|
||||
flash.now[:alert] = I18n.t('failed_to_create_record')
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def sign
|
||||
if @certificate.sign!
|
||||
flash[:notice] = I18n.t('record_updated')
|
||||
else
|
||||
flash[:alert] = I18n.t('failed_to_update_record')
|
||||
end
|
||||
redirect_to [:admin, @api_user, @certificate]
|
||||
end
|
||||
|
||||
def revoke
|
||||
if @certificate.revoke!
|
||||
flash[:notice] = I18n.t('record_updated')
|
||||
else
|
||||
flash[:alert] = I18n.t('failed_to_update_record')
|
||||
end
|
||||
redirect_to [:admin, @api_user, @certificate]
|
||||
end
|
||||
|
||||
def download_csr
|
||||
send_data @certificate.csr, filename: "#{@api_user.username}.csr.pem"
|
||||
end
|
||||
|
||||
def download_crt
|
||||
send_data @certificate.crt, filename: "#{@api_user.username}.crt.pem"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_certificate
|
||||
@certificate = Certificate.find(params[:id])
|
||||
end
|
||||
|
||||
def set_api_user
|
||||
@api_user = ApiUser.find(params[:api_user_id])
|
||||
end
|
||||
|
||||
def certificate_params
|
||||
params.require(:certificate).permit(:csr)
|
||||
end
|
||||
end
|
|
@ -1,4 +1,3 @@
|
|||
class AdminController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
check_authorization
|
||||
end
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
check_authorization unless: :devise_controller?
|
||||
|
||||
# Prevent CSRF attacks by raising an exception.
|
||||
# For APIs, you may want to use :null_session instead.
|
||||
protect_from_forgery with: :exception
|
||||
|
@ -9,8 +11,14 @@ class ApplicationController < ActionController::Base
|
|||
params[resource] &&= send(method) if respond_to?(method, true)
|
||||
end
|
||||
|
||||
rescue_from CanCan::AccessDenied do |exception|
|
||||
redirect_to admin_dashboard_path, alert: exception.message
|
||||
end
|
||||
|
||||
def after_sign_in_path_for(_resource)
|
||||
return session[:user_return_to].to_s if session[:user_return_to] && session[:user_return_to] != login_path
|
||||
if session[:user_return_to] && session[:user_return_to] != login_path
|
||||
return session[:user_return_to].to_s
|
||||
end
|
||||
admin_dashboard_path
|
||||
end
|
||||
|
||||
|
@ -34,9 +42,3 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
rescue_from CanCan::AccessDenied do |exception|
|
||||
redirect_to admin_dashboard_path, alert: exception.message
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,188 +1,125 @@
|
|||
class Epp::ContactsController < EppController
|
||||
helper WhodunnitHelper ## Refactor this?
|
||||
|
||||
def create
|
||||
@contact = Contact.new(contact_and_address_attributes)
|
||||
@contact.registrar = current_user.registrar
|
||||
render_epp_response '/epp/contacts/create' and return if @contact.save
|
||||
handle_errors(@contact)
|
||||
end
|
||||
|
||||
def update
|
||||
# FIXME: Update returns 2303 update multiple times
|
||||
code = params_hash['epp']['command']['update']['update'][:id]
|
||||
|
||||
@contact = Contact.where(code: code).first
|
||||
# if update_rights? && @contact.update_attributes(contact_and_address_attributes(:update))
|
||||
if owner? && @contact.update_attributes(contact_and_address_attributes(:update))
|
||||
render_epp_response 'epp/contacts/update'
|
||||
else
|
||||
contact_exists?(code)
|
||||
handle_errors(@contact) and return
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
def delete
|
||||
@contact = find_contact
|
||||
handle_errors(@contact) and return unless rights? # owner?
|
||||
handle_errors(@contact) and return unless @contact
|
||||
handle_errors(@contact) and return unless @contact.destroy_and_clean
|
||||
|
||||
render_epp_response '/epp/contacts/delete'
|
||||
end
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
|
||||
def check
|
||||
ph = params_hash['epp']['command']['check']['check']
|
||||
@contacts = Contact.check_availability(ph[:id])
|
||||
render_epp_response '/epp/contacts/check'
|
||||
end
|
||||
before_action :find_contact, only: [:info, :update, :delete]
|
||||
before_action :find_password, only: [:info, :update, :delete]
|
||||
|
||||
def info
|
||||
handle_errors(@contact) and return unless @contact && rights?
|
||||
# handle_errors(@contact) and return unless rights?
|
||||
@disclosure = ContactDisclosure.default_values.merge(@contact.disclosure.try(:as_hash) || {})
|
||||
@disclosure_policy = @contact.disclosure.try(:attributes_with_flag)
|
||||
@owner = owner?(false)
|
||||
# need to reload contact eagerly
|
||||
@contact = find_contact if @owner # for clarity, could just be true
|
||||
authorize! :info, @contact, @password
|
||||
render_epp_response 'epp/contacts/info'
|
||||
end
|
||||
|
||||
def check
|
||||
authorize! :check, Epp::Contact
|
||||
|
||||
ids = params[:parsed_frame].css('id').map(&:text)
|
||||
@results = Contact.check_availability(ids)
|
||||
render_epp_response '/epp/contacts/check'
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Epp::Contact
|
||||
@contact = Epp::Contact.new(params[:parsed_frame], current_user.registrar)
|
||||
|
||||
if @contact.save
|
||||
render_epp_response '/epp/contacts/create'
|
||||
else
|
||||
handle_errors(@contact)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, @contact, @password
|
||||
|
||||
if @contact.update_attributes(params[:parsed_frame])
|
||||
render_epp_response 'epp/contacts/update'
|
||||
else
|
||||
handle_errors(@contact)
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
authorize! :delete, @contact, @password
|
||||
|
||||
if @contact.destroy_and_clean
|
||||
render_epp_response '/epp/contacts/delete'
|
||||
else
|
||||
handle_errors(@contact)
|
||||
end
|
||||
end
|
||||
|
||||
def renew
|
||||
authorize! :renew, Epp::Contact
|
||||
epp_errors << { code: '2101', msg: t(:'errors.messages.unimplemented_command') }
|
||||
handle_errors
|
||||
end
|
||||
|
||||
## HELPER METHODS
|
||||
|
||||
private
|
||||
|
||||
## CREATE
|
||||
def validate_create
|
||||
@ph = params_hash['epp']['command']['create']['create']
|
||||
return false unless validate_params
|
||||
xml_attrs_present?(@ph, [%w(postalInfo name), %w(postalInfo addr city), %w(postalInfo addr cc),
|
||||
%w(ident), %w(voice), %w(email)])
|
||||
|
||||
epp_errors.empty?
|
||||
def find_password
|
||||
@password = params[:parsed_frame].css('authInfo pw').text
|
||||
end
|
||||
|
||||
## UPDATE
|
||||
def validate_updatezz
|
||||
@ph = params_hash['epp']['command']['update']['update']
|
||||
update_attrs_present?
|
||||
# xml_attrs_present?(@ph, [['id'], %w(authInfo pw)])
|
||||
xml_attrs_present?(@ph, [['id']])
|
||||
end
|
||||
|
||||
def contact_exists?(code)
|
||||
return true if @contact.is_a?(Contact)
|
||||
epp_errors << { code: '2303', msg: t('errors.messages.epp_obj_does_not_exist'),
|
||||
value: { obj: 'id', val: code } }
|
||||
end
|
||||
|
||||
def update_attrs_present?
|
||||
return true if params[:parsed_frame].css('add').present?
|
||||
return true if params[:parsed_frame].css('rem').present?
|
||||
return true if params[:parsed_frame].css('chg').present?
|
||||
epp_errors << { code: '2003', msg: I18n.t('errors.messages.required_parameter_missing', key: 'add, rem or chg') }
|
||||
end
|
||||
|
||||
## DELETE
|
||||
def validate_delete
|
||||
@ph = params_hash['epp']['command']['delete']['delete']
|
||||
xml_attrs_present?(@ph, [['id']])
|
||||
end
|
||||
|
||||
## check
|
||||
def validate_check
|
||||
@ph = params_hash['epp']['command']['check']['check']
|
||||
xml_attrs_present?(@ph, [['id']])
|
||||
end
|
||||
|
||||
## info
|
||||
def validate_info # and process
|
||||
@ph = params_hash['epp']['command']['info']['info']
|
||||
return false unless xml_attrs_present?(@ph, [['id']])
|
||||
@contact = find_contact
|
||||
return false unless @contact
|
||||
return true if current_user.registrar == @contact.registrar || xml_attrs_present?(@ph, [%w(authInfo pw)])
|
||||
false
|
||||
end
|
||||
|
||||
## SHARED
|
||||
|
||||
def find_contact
|
||||
contact = Contact.find_by(code: @ph[:id])
|
||||
unless contact
|
||||
epp_errors << { code: '2303',
|
||||
msg: t('errors.messages.epp_obj_does_not_exist'),
|
||||
value: { obj: 'id', val: @ph[:id] } }
|
||||
code = params[:parsed_frame].css('id').text.strip.downcase
|
||||
@contact = Epp::Contact.find_by(code: code)
|
||||
|
||||
if @contact.blank?
|
||||
epp_errors << {
|
||||
code: '2303',
|
||||
msg: t('errors.messages.epp_obj_does_not_exist'),
|
||||
value: { obj: 'id', val: code }
|
||||
}
|
||||
fail CanCan::AccessDenied
|
||||
end
|
||||
contact
|
||||
@contact
|
||||
end
|
||||
|
||||
def owner?(with_errors = true)
|
||||
return false unless find_contact
|
||||
return true if @contact.registrar == current_user.registrar
|
||||
return false unless with_errors
|
||||
epp_errors << { code: '2201', msg: t('errors.messages.epp_authorization_error') }
|
||||
false
|
||||
#
|
||||
# Validations
|
||||
#
|
||||
def validate_info
|
||||
@prefix = 'info > info >'
|
||||
requires 'id'
|
||||
end
|
||||
|
||||
def rights?
|
||||
pw = @ph.try(:[], :authInfo).try(:[], :pw)
|
||||
|
||||
return true if current_user.try(:registrar) == @contact.try(:registrar)
|
||||
return true if pw && @contact.auth_info_matches(pw) # @contact.try(:auth_info_matches, pw)
|
||||
|
||||
epp_errors << { code: '2200', msg: t('errors.messages.epp_authentication_error') }
|
||||
false
|
||||
def validate_check
|
||||
@prefix = 'check > check >'
|
||||
requires 'id'
|
||||
end
|
||||
|
||||
def update_rights?
|
||||
pw = @ph.try(:[], :authInfo).try(:[], :pw)
|
||||
return true if pw && @contact.auth_info_matches(pw)
|
||||
epp_errors << { code: '2200', msg: t('errors.messages.epp_authentication_error') }
|
||||
false
|
||||
end
|
||||
|
||||
def contact_and_address_attributes(type = :create)
|
||||
case type
|
||||
when :update
|
||||
# TODO: support for rem/add
|
||||
contact_hash = merge_attribute_hash(@ph[:chg], type).delete_if { |_k, v| v.empty? }
|
||||
else
|
||||
contact_hash = merge_attribute_hash(@ph, type)
|
||||
end
|
||||
contact_hash[:ident_type] = ident_type unless ident_type.nil?
|
||||
contact_hash
|
||||
end
|
||||
|
||||
def merge_attribute_hash(prms, type)
|
||||
contact_hash = Contact.extract_attributes(prms, type)
|
||||
contact_hash = contact_hash.merge(
|
||||
Address.extract_attributes((prms.try(:[], :postalInfo) || []))
|
||||
def validate_create
|
||||
@prefix = 'create > create >'
|
||||
requires(
|
||||
'postalInfo > name', 'postalInfo > addr > city',
|
||||
'postalInfo > addr > cc', 'ident', 'voice', 'email'
|
||||
)
|
||||
contact_hash[:disclosure_attributes] =
|
||||
ContactDisclosure.extract_attributes(params[:parsed_frame])
|
||||
|
||||
contact_hash
|
||||
ident = params[:parsed_frame].css('ident')
|
||||
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')
|
||||
}
|
||||
end
|
||||
@prefix = nil
|
||||
requires 'extension > extdata > legalDocument'
|
||||
end
|
||||
|
||||
def ident_type
|
||||
result = params[:parsed_frame].css('ident').first.try(:attributes).try(:[], 'type').try(:value)
|
||||
return nil unless result
|
||||
|
||||
Contact::IDENT_TYPES.any? { |type| return type if result.include?(type) }
|
||||
nil
|
||||
def validate_update
|
||||
@prefix = 'update > update >'
|
||||
if element_count('chg') == 0 && element_count('rem') == 0 && element_count('add') == 0
|
||||
epp_errors << {
|
||||
code: '2003',
|
||||
msg: I18n.t('errors.messages.required_parameter_missing', key: 'add, rem or chg')
|
||||
}
|
||||
end
|
||||
requires 'id', 'authInfo > pw'
|
||||
@prefix = nil
|
||||
requires 'extension > extdata > legalDocument'
|
||||
end
|
||||
|
||||
def validate_params
|
||||
return true if @ph
|
||||
epp_errors << { code: '2001', msg: t(:'errors.messages.epp_command_syntax_error') }
|
||||
false
|
||||
def validate_delete
|
||||
@prefix = 'delete > delete >'
|
||||
requires 'id', 'authInfo > pw'
|
||||
@prefix = nil
|
||||
requires 'extension > extdata > legalDocument'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Epp::DomainsController < EppController
|
||||
skip_authorization_check # TODO: remove it
|
||||
|
||||
def create
|
||||
@domain = Epp::EppDomain.new(domain_create_params)
|
||||
# @domain.parse_and_attach_domain_dependencies(params[:parsed_frame])
|
||||
|
@ -334,7 +336,7 @@ class Epp::DomainsController < EppController
|
|||
|
||||
return domain if domain.auth_info == params[:parsed_frame].css('authInfo pw').text
|
||||
|
||||
if (domain.registrar != current_user.registrar && secure[:secure] == true) &&
|
||||
if (domain.registrar != current_user.registrar) && secure[:secure] == true
|
||||
epp_errors << {
|
||||
code: '2302',
|
||||
msg: I18n.t('errors.messages.domain_exists_but_belongs_to_other_registrar'),
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Epp::ErrorsController < EppController
|
||||
skip_authorization_check # TODO: remove it
|
||||
|
||||
def error
|
||||
epp_errors << { code: params[:code], msg: params[:msg] }
|
||||
render_epp_response '/epp/error'
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Epp::KeyrelaysController < EppController
|
||||
skip_authorization_check # TODO: remove it
|
||||
|
||||
# rubocop: disable Metrics/PerceivedComplexity
|
||||
# rubocop: disable Metrics/CyclomaticComplexity
|
||||
def keyrelay
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Epp::PollsController < EppController
|
||||
skip_authorization_check # TODO: remove it
|
||||
|
||||
def poll
|
||||
req_poll if params[:parsed_frame].css('poll').first['op'] == 'req'
|
||||
ack_poll if params[:parsed_frame].css('poll').first['op'] == 'ack'
|
||||
|
@ -38,6 +40,6 @@ class Epp::PollsController < EppController
|
|||
private
|
||||
|
||||
def validate_poll
|
||||
requires_attribute 'poll', 'op', values: %(ack req)
|
||||
requires_attribute 'poll', 'op', values: %(ack req), allow_blank: true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,12 +1,24 @@
|
|||
class Epp::SessionsController < EppController
|
||||
skip_authorization_check only: [:hello, :login, :logout]
|
||||
|
||||
def hello
|
||||
render_epp_response('greeting')
|
||||
end
|
||||
|
||||
# rubocop: disable Metrics/PerceivedComplexity
|
||||
# rubocop: disable Metrics/CyclomaticComplexity
|
||||
def login
|
||||
@api_user = ApiUser.find_by(login_params)
|
||||
cert_valid = true
|
||||
if request.ip == ENV['webclient_ip']
|
||||
@api_user = ApiUser.find_by(login_params)
|
||||
else
|
||||
if request.env['HTTP_SSL_CLIENT_S_DN_CN'] != login_params[:username]
|
||||
cert_valid = false
|
||||
end
|
||||
@api_user = ApiUser.find_by(login_params)
|
||||
end
|
||||
|
||||
if @api_user.try(:active)
|
||||
if @api_user.try(:active) && cert_valid
|
||||
epp_session[:api_user_id] = @api_user.id
|
||||
render_epp_response('login_success')
|
||||
else
|
||||
|
@ -14,6 +26,8 @@ class Epp::SessionsController < EppController
|
|||
render_epp_response('login_fail')
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/PerceivedComplexity
|
||||
# rubocop: enable Metrics/CyclomaticComplexity
|
||||
|
||||
def logout
|
||||
@api_user = current_user # cache current_user for logging
|
||||
|
|
|
@ -1,10 +1,23 @@
|
|||
class EppController < ApplicationController
|
||||
layout false
|
||||
protect_from_forgery with: :null_session
|
||||
skip_before_action :verify_authenticity_token
|
||||
|
||||
before_action :generate_svtrid
|
||||
before_action :validate_request
|
||||
layout false
|
||||
helper_method :current_user
|
||||
|
||||
rescue_from CanCan::AccessDenied do |_exception|
|
||||
@errors ||= []
|
||||
if @errors.blank?
|
||||
@errors = [{
|
||||
msg: t('errors.messages.epp_authorization_error'),
|
||||
code: '2201'
|
||||
}]
|
||||
end
|
||||
render_epp_response '/epp/error'
|
||||
end
|
||||
|
||||
def generate_svtrid
|
||||
# rubocop: disable Style/VariableName
|
||||
@svTRID = "ccReg-#{format('%010d', rand(10**10))}"
|
||||
|
@ -84,15 +97,23 @@ class EppController < ApplicationController
|
|||
# TODO: Add possibility to pass validations / options in the method
|
||||
|
||||
def requires(*selectors)
|
||||
options = selectors.extract_options!
|
||||
allow_blank = options[:allow_blank] ||= false # allow_blank is false by default
|
||||
|
||||
el, missing = nil, nil
|
||||
selectors.each do |selector|
|
||||
full_selector = [@prefix, selector].compact.join(' ')
|
||||
attr = selector.split('>').last.strip.underscore
|
||||
el = params[:parsed_frame].css(full_selector).first
|
||||
|
||||
missing = el.nil?
|
||||
if allow_blank
|
||||
missing = el.nil?
|
||||
else
|
||||
missing = el.present? ? el.text.blank? : true
|
||||
end
|
||||
epp_errors << {
|
||||
code: '2003',
|
||||
msg: I18n.t('errors.messages.required_parameter_missing', key: full_selector)
|
||||
msg: I18n.t('errors.messages.required_parameter_missing', key: "#{full_selector} [#{attr}]")
|
||||
} if missing
|
||||
end
|
||||
|
||||
|
@ -105,7 +126,7 @@ class EppController < ApplicationController
|
|||
# requires_attribute 'transfer', 'op', values: %(approve, query, reject)
|
||||
|
||||
def requires_attribute(element_selector, attribute_selector, options)
|
||||
element = requires(element_selector)
|
||||
element = requires(element_selector, allow_blank: options[:allow_blank])
|
||||
return unless element
|
||||
|
||||
attribute = element[attribute_selector]
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class SessionsController < Devise::SessionsController
|
||||
skip_authorization_check
|
||||
|
||||
def create
|
||||
# TODO: Create ID Card login here:
|
||||
# this is just testing config
|
||||
|
|
|
@ -8,4 +8,13 @@ module ApplicationHelper
|
|||
return '' if unstable_env.nil?
|
||||
"background-image: url(#{image_path(unstable_env.to_s + '.png')});"
|
||||
end
|
||||
|
||||
def ident_indicator(contact)
|
||||
case contact.ident_type
|
||||
when 'birthday'
|
||||
"[#{contact.ident_type}]"
|
||||
else
|
||||
"[#{contact.ident_country_code} #{contact.ident_type}]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
module WhodunnitHelper
|
||||
def link_to_whodunnit(whodunnit)
|
||||
return nil unless whodunnit
|
||||
if whodunnit.include?('-ApiUser')
|
||||
user = ApiUser.find(whodunnit)
|
||||
return link_to(user.username, admin_epp_user_path(user))
|
||||
end
|
||||
user = AdminUser.find(whodunnit)
|
||||
return link_to(user.username, admin_user_path(user))
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
return nil
|
||||
end
|
||||
|
||||
def whodunnit_with_protocol(whodunnit)
|
||||
return nil unless whodunnit
|
||||
if whodunnit.include?('-ApiUser')
|
||||
user = ApiUser.find(whodunnit)
|
||||
return "#{user.username} (EPP)"
|
||||
end
|
||||
user = AdminUser.find(whodunnit)
|
||||
return user.username
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
return nil
|
||||
end
|
||||
end
|
|
@ -2,16 +2,31 @@ class Ability
|
|||
include CanCan::Ability
|
||||
|
||||
def initialize(user)
|
||||
alias_action :create, :read, :update, :destroy, to: :crud
|
||||
alias_action :show, :create, :update, :destroy, to: :crud
|
||||
|
||||
@user = user || AdminUser.new
|
||||
@user.roles.each { |role| send(role) } if @user.roles
|
||||
|
||||
return if @user.roles || @user.roles.any?
|
||||
case @user.class.to_s
|
||||
when 'AdminUser'
|
||||
@user.roles.each { |role| send(role) } if @user.roles
|
||||
when 'ApiUser'
|
||||
epp
|
||||
end
|
||||
|
||||
can :show, :dashboard
|
||||
end
|
||||
|
||||
def epp
|
||||
# Epp::Contact
|
||||
can(:info, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
||||
can(:check, Epp::Contact)
|
||||
can(:create, Epp::Contact)
|
||||
can(:update, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id && c.auth_info == pw }
|
||||
can(:delete, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id && c.auth_info == pw }
|
||||
can(:renew, Epp::Contact)
|
||||
can(:view_password, Epp::Contact) { |c| c.registrar_id == @user.registrar_id }
|
||||
end
|
||||
|
||||
def user
|
||||
can :show, :dashboard
|
||||
end
|
||||
|
@ -30,6 +45,7 @@ class Ability
|
|||
can :manage, DomainVersion
|
||||
can :manage, User
|
||||
can :manage, ApiUser
|
||||
can :manage, Certificate
|
||||
can :manage, Keyrelay
|
||||
can :manage, LegalDocument
|
||||
can :read, ApiLog::EppLog
|
||||
|
|
|
@ -5,14 +5,24 @@ class ApiUser < User
|
|||
# TODO: should have max request limit per day
|
||||
belongs_to :registrar
|
||||
has_many :contacts
|
||||
has_many :certificates
|
||||
|
||||
validates :username, :password, :registrar, presence: true
|
||||
validates :username, uniqueness: true
|
||||
|
||||
before_save :create_crt, if: -> (au) { au.csr_changed? }
|
||||
|
||||
attr_accessor :registrar_typeahead
|
||||
|
||||
def ability
|
||||
@ability ||= Ability.new(self)
|
||||
end
|
||||
delegate :can?, :cannot?, to: :ability
|
||||
|
||||
after_initialize :set_defaults
|
||||
def set_defaults
|
||||
return unless new_record?
|
||||
self.active = true unless active_changed?
|
||||
end
|
||||
|
||||
def registrar_typeahead
|
||||
@registrar_typeahead || registrar || nil
|
||||
end
|
||||
|
@ -24,28 +34,5 @@ class ApiUser < User
|
|||
def queued_messages
|
||||
registrar.messages.queued
|
||||
end
|
||||
|
||||
def create_crt
|
||||
csr_file = Tempfile.new('client_csr')
|
||||
csr_file.write(csr)
|
||||
csr_file.rewind
|
||||
|
||||
crt_file = Tempfile.new('client_crt')
|
||||
_out, err, _st = Open3.capture3("openssl ca -keyfile #{APP_CONFIG['ca_key_path']} \
|
||||
-cert #{APP_CONFIG['ca_cert_path']} \
|
||||
-extensions usr_cert -notext -md sha256 \
|
||||
-in #{csr_file.path} -out #{crt_file.path} -key '#{APP_CONFIG['ca_key_password']}' -batch")
|
||||
|
||||
if err.match(/Data Base Updated/)
|
||||
crt_file.rewind
|
||||
self.crt = crt_file.read
|
||||
return true
|
||||
else
|
||||
errors.add(:base, I18n.t('failed_to_create_certificate'))
|
||||
logger.error('FAILED TO CREATE CLIENT CERTIFICATE')
|
||||
logger.error(err)
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/ClassLength
|
||||
|
|
|
@ -32,10 +32,10 @@ class ApiUserDeprecated < ActiveRecord::Base
|
|||
csr_file.rewind
|
||||
|
||||
crt_file = Tempfile.new('client_crt')
|
||||
_out, err, _st = Open3.capture3("openssl ca -keyfile #{APP_CONFIG['ca_key_path']} \
|
||||
-cert #{APP_CONFIG['ca_cert_path']} \
|
||||
_out, err, _st = Open3.capture3("openssl ca -keyfile #{ENV['ca_key_path']} \
|
||||
-cert #{ENV['ca_cert_path']} \
|
||||
-extensions usr_cert -notext -md sha256 \
|
||||
-in #{csr_file.path} -out #{crt_file.path} -key '#{APP_CONFIG['ca_key_password']}' -batch")
|
||||
-in #{csr_file.path} -out #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch")
|
||||
|
||||
if err.match(/Data Base Updated/)
|
||||
crt_file.rewind
|
||||
|
|
88
app/models/certificate.rb
Normal file
88
app/models/certificate.rb
Normal file
|
@ -0,0 +1,88 @@
|
|||
class Certificate < ActiveRecord::Base
|
||||
include Versions
|
||||
|
||||
belongs_to :api_user
|
||||
|
||||
SIGNED = 'signed'
|
||||
UNSIGNED = 'unsigned'
|
||||
EXPIRED = 'expired'
|
||||
REVOKED = 'revoked'
|
||||
VALID = 'valid'
|
||||
|
||||
validates :csr, presence: true
|
||||
|
||||
def parsed_crt
|
||||
@p_crt ||= OpenSSL::X509::Certificate.new(crt) if crt
|
||||
end
|
||||
|
||||
def parsed_csr
|
||||
@p_csr ||= OpenSSL::X509::Request.new(csr) if csr
|
||||
end
|
||||
|
||||
def revoked?
|
||||
status == REVOKED
|
||||
end
|
||||
|
||||
def status
|
||||
return UNSIGNED if crt.blank?
|
||||
return @cached_status if @cached_status
|
||||
|
||||
@cached_status = SIGNED
|
||||
|
||||
if parsed_crt.not_before > Time.now.utc && parsed_crt.not_after < Time.now.utc
|
||||
@cached_status = EXPIRED
|
||||
end
|
||||
|
||||
crl = OpenSSL::X509::CRL.new(File.open(ENV['crl_path']).read)
|
||||
return @cached_status unless crl.revoked.map(&:serial).include?(parsed_crt.serial)
|
||||
|
||||
@cached_status = REVOKED
|
||||
end
|
||||
|
||||
def sign!
|
||||
csr_file = Tempfile.new('client_csr')
|
||||
csr_file.write(csr)
|
||||
csr_file.rewind
|
||||
|
||||
crt_file = Tempfile.new('client_crt')
|
||||
_out, err, _st = Open3.capture3("openssl ca -config #{ENV['openssl_config_path']} -keyfile #{ENV['ca_key_path']} \
|
||||
-cert #{ENV['ca_cert_path']} \
|
||||
-extensions usr_cert -notext -md sha256 \
|
||||
-in #{csr_file.path} -out #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch")
|
||||
|
||||
if err.match(/Data Base Updated/)
|
||||
crt_file.rewind
|
||||
self.crt = crt_file.read
|
||||
save!
|
||||
else
|
||||
errors.add(:base, I18n.t('failed_to_create_certificate'))
|
||||
logger.error('FAILED TO CREATE CLIENT CERTIFICATE')
|
||||
logger.error(err)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def revoke!
|
||||
crt_file = Tempfile.new('client_crt')
|
||||
crt_file.write(crt)
|
||||
crt_file.rewind
|
||||
|
||||
_out, err, _st = Open3.capture3("openssl ca -config #{ENV['openssl_config_path']} -keyfile #{ENV['ca_key_path']} \
|
||||
-cert #{ENV['ca_cert_path']} \
|
||||
-revoke #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch")
|
||||
|
||||
if err.match(/Data Base Updated/) || err.match(/ERROR:Already revoked/)
|
||||
save!
|
||||
@cached_status = REVOKED
|
||||
else
|
||||
errors.add(:base, I18n.t('failed_to_revoke_certificate'))
|
||||
logger.error('FAILED TO REVOKE CLIENT CERTIFICATE')
|
||||
logger.error(err)
|
||||
return false
|
||||
end
|
||||
|
||||
_out, _err, _st = Open3.capture3("openssl ca -config #{ENV['openssl_config_path']} -keyfile #{ENV['ca_key_path']} \
|
||||
-cert #{ENV['ca_cert_path']} \
|
||||
-gencrl -out #{ENV['crl_path']} -key '#{ENV['ca_key_password']}' -batch")
|
||||
end
|
||||
end
|
|
@ -3,42 +3,43 @@ module EppErrors
|
|||
|
||||
def construct_epp_errors
|
||||
epp_errors = []
|
||||
errors.messages.each do |key, values|
|
||||
key = key.to_s.split('.')[0].to_sym
|
||||
next if key == :epp_errors
|
||||
errors.messages.each do |attr, errors|
|
||||
attr = attr.to_s.split('.')[0].to_sym
|
||||
next if attr == :epp_errors
|
||||
|
||||
if self.class.reflect_on_association(key)
|
||||
epp_errors << collect_child_errors(key)
|
||||
if self.class.reflect_on_association(attr)
|
||||
epp_errors << collect_child_errors(attr)
|
||||
end
|
||||
|
||||
epp_errors << collect_parent_errors(values)
|
||||
epp_errors << collect_parent_errors(attr, errors)
|
||||
end
|
||||
|
||||
errors[:epp_errors] = epp_errors
|
||||
errors[:epp_errors].flatten!
|
||||
end
|
||||
|
||||
def collect_parent_errors(values)
|
||||
epp_errors = []
|
||||
values = [values] if values.is_a?(String)
|
||||
def collect_parent_errors(attr, errors)
|
||||
errors = [errors] if errors.is_a?(String)
|
||||
|
||||
values.each do |err|
|
||||
epp_errors = []
|
||||
errors.each do |err|
|
||||
code, value = find_epp_code_and_value(err)
|
||||
next unless code
|
||||
epp_errors << { code: code, msg: err, value: value }
|
||||
msg = attr.to_sym == :base ? err : "#{err} [#{attr}]"
|
||||
epp_errors << { code: code, msg: msg, value: value }
|
||||
end
|
||||
epp_errors
|
||||
end
|
||||
|
||||
def collect_child_errors(key)
|
||||
macro = self.class.reflect_on_association(key).macro
|
||||
def collect_child_errors(attr)
|
||||
macro = self.class.reflect_on_association(attr).macro
|
||||
multi = [:has_and_belongs_to_many, :has_many]
|
||||
# single = [:belongs_to, :has_one]
|
||||
|
||||
epp_errors = []
|
||||
send(key).each do |x|
|
||||
x.errors.messages.each do |_key, values|
|
||||
epp_errors << x.collect_parent_errors(values)
|
||||
send(attr).each do |x|
|
||||
x.errors.messages.each do |attribute, errors|
|
||||
epp_errors << x.collect_parent_errors(attribute, errors)
|
||||
end
|
||||
end if multi.include?(macro)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ module VersionSession
|
|||
before_save :add_session
|
||||
|
||||
def add_session
|
||||
self.session = PaperSession.session
|
||||
self.session = ::PaperSession.session
|
||||
true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,9 +28,9 @@ module Versions
|
|||
return nil if creator_str.blank?
|
||||
|
||||
if creator_str =~ /^\d-api-/
|
||||
ApiUser.find(creator_str)
|
||||
ApiUser.find_by(id: creator_str)
|
||||
else
|
||||
AdminUser.find(creator_str)
|
||||
AdminUser.find_by(id: creator_str)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -38,9 +38,9 @@ module Versions
|
|||
return nil if updator_str.blank?
|
||||
|
||||
if updator_str =~ /^\d-api-/
|
||||
ApiUser.find(updator_str)
|
||||
ApiUser.find_by(id: updator_str)
|
||||
else
|
||||
AdminUser.find(updator_str)
|
||||
AdminUser.find_by(id: updator_str)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
class Contact < ActiveRecord::Base
|
||||
include Versions # version/contact_version.rb
|
||||
include EppErrors
|
||||
|
||||
has_one :address, dependent: :destroy
|
||||
has_one :disclosure, class_name: 'ContactDisclosure', dependent: :destroy
|
||||
|
@ -8,45 +7,46 @@ class Contact < ActiveRecord::Base
|
|||
has_many :domain_contacts
|
||||
has_many :domains, through: :domain_contacts
|
||||
has_many :statuses, class_name: 'ContactStatus'
|
||||
has_many :legal_documents, as: :documentable
|
||||
|
||||
belongs_to :registrar
|
||||
|
||||
accepts_nested_attributes_for :address, :disclosure
|
||||
accepts_nested_attributes_for :address, :disclosure, :legal_documents
|
||||
|
||||
validates :name, :phone, :email, :ident, :address, :registrar, :ident_type, presence: true
|
||||
|
||||
# Phone nr validation is very minimam in order to support legacy requirements
|
||||
validates :phone, format: /\+[0-9]{1,3}\.[0-9]{1,14}?/
|
||||
validates :email, format: /@/
|
||||
validates :ident, format: /\d{4}-\d{2}-\d{2}/, if: proc { |c| c.ident_type == 'birthday' }
|
||||
validates :ident,
|
||||
format: { with: /\d{4}-\d{2}-\d{2}/, message: :invalid_birthday_format },
|
||||
if: proc { |c| c.ident_type == 'birthday' }
|
||||
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 }
|
||||
|
||||
validate :ident_must_be_valid
|
||||
validate :ident_valid_format?
|
||||
|
||||
validates :code, uniqueness: { message: :epp_id_taken }
|
||||
delegate :street, to: :address
|
||||
delegate :city, to: :address
|
||||
delegate :zip, to: :address
|
||||
delegate :state, to: :address
|
||||
delegate :country_code, to: :address
|
||||
delegate :country, to: :address
|
||||
|
||||
delegate :city, to: :address # , prefix: true
|
||||
delegate :street, to: :address # , prefix: true
|
||||
delegate :zip, to: :address # , prefix: true
|
||||
|
||||
# callbacks
|
||||
# TODO: remove old
|
||||
# after_commit :domains_snapshot
|
||||
# after_update :domains_snapshot
|
||||
# after_destroy :domains_snapshot
|
||||
before_validation :set_ident_country_code
|
||||
before_create :generate_code
|
||||
before_create :generate_auth_info
|
||||
after_create :ensure_disclosure
|
||||
|
||||
# scopes
|
||||
scope :current_registrars, ->(id) { where(registrar_id: id) }
|
||||
|
||||
IDENT_TYPE_ICO = 'ico'
|
||||
IDENT_TYPE_BIC = 'bic'
|
||||
IDENT_TYPES = [
|
||||
IDENT_TYPE_ICO, # Company registry code (or similar)
|
||||
'bic', # Business registry code
|
||||
IDENT_TYPE_BIC, # Company registry code (or similar)
|
||||
'priv', # National idendtification number
|
||||
'op', # Estonian ID, depricated
|
||||
'passport', # Passport number, depricated
|
||||
'birthday' # Birthday date
|
||||
]
|
||||
|
||||
|
@ -54,124 +54,10 @@ class Contact < ActiveRecord::Base
|
|||
CONTACT_TYPE_ADMIN = 'admin'
|
||||
CONTACT_TYPES = [CONTACT_TYPE_TECH, CONTACT_TYPE_ADMIN]
|
||||
|
||||
def ident_must_be_valid
|
||||
# TODO: Ident can also be passport number or company registry code.
|
||||
# so have to make changes to validations (and doc/schema) accordingly
|
||||
return true unless ident.present? && ident_type.present? && ident_type == 'op'
|
||||
code = Isikukood.new(ident)
|
||||
errors.add(:ident, 'bad format') unless code.valid?
|
||||
end
|
||||
|
||||
def ensure_disclosure
|
||||
create_disclosure! unless disclosure
|
||||
end
|
||||
|
||||
# TODO: remove old
|
||||
# def domains_snapshot
|
||||
# (domains + domains_owned).uniq.each do |domain|
|
||||
# next unless domain.is_a?(Domain)
|
||||
# # next if domain.versions.last == domain.create_snapshot
|
||||
# domain.create_version # Method from paper_trail
|
||||
# end
|
||||
# end
|
||||
|
||||
def juridical?
|
||||
ident_type == IDENT_TYPE_ICO
|
||||
end
|
||||
|
||||
def citizen?
|
||||
ident_type != IDENT_TYPE_ICO
|
||||
end
|
||||
|
||||
def cr_id
|
||||
# created_by ? created_by.username : nil
|
||||
end
|
||||
|
||||
def up_id
|
||||
# updated_by ? updated_by.username : nil
|
||||
end
|
||||
|
||||
def auth_info_matches(pw)
|
||||
auth_info == pw
|
||||
end
|
||||
|
||||
# generate random id for contact
|
||||
def generate_code
|
||||
self.code = SecureRandom.hex(4)
|
||||
end
|
||||
|
||||
def generate_auth_info
|
||||
self.auth_info = SecureRandom.hex(16)
|
||||
end
|
||||
|
||||
# Find a way to use self.domains with contact
|
||||
def domains_owned
|
||||
Domain.where(owner_contact_id: id)
|
||||
end
|
||||
|
||||
def relations_with_domain?
|
||||
return true if domain_contacts.present? || domains_owned.present?
|
||||
false
|
||||
end
|
||||
|
||||
# should use only in transaction
|
||||
def destroy_and_clean
|
||||
if relations_with_domain?
|
||||
errors.add(:domains, :exist)
|
||||
return false
|
||||
end
|
||||
destroy
|
||||
end
|
||||
|
||||
def epp_code_map # rubocop:disable Metrics/MethodLength
|
||||
{
|
||||
'2302' => [ # Object exists
|
||||
[:code, :epp_id_taken]
|
||||
],
|
||||
'2305' => [ # Association exists
|
||||
[:domains, :exist]
|
||||
],
|
||||
'2005' => [ # Value syntax error
|
||||
[:phone, :invalid],
|
||||
[:email, :invalid],
|
||||
[:ident, :invalid]
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
# TODO: remove old
|
||||
# for archiving
|
||||
# def snapshot
|
||||
# {
|
||||
# name: name,
|
||||
# phone: phone,
|
||||
# code: code,
|
||||
# ident: ident,
|
||||
# email: email
|
||||
# }
|
||||
# end
|
||||
|
||||
class << self
|
||||
# non-EPP
|
||||
|
||||
# EPP
|
||||
def extract_attributes(ph, _type = :create)
|
||||
ph[:postalInfo] = ph[:postalInfo].first if ph[:postalInfo].is_a?(Array)
|
||||
contact_hash = {
|
||||
phone: ph[:voice],
|
||||
ident: ph[:ident],
|
||||
ident_type: ph[:ident_type],
|
||||
email: ph[:email],
|
||||
fax: ph[:fax],
|
||||
name: ph[:postalInfo].try(:[], :name),
|
||||
org_name: ph[:postalInfo].try(:[], :org)
|
||||
}
|
||||
# contact_hash[:auth_info] = ph[:authInfo][:pw] if type == :create
|
||||
contact_hash.delete_if { |_k, v| v.nil? }
|
||||
def search_by_query(query)
|
||||
res = search(code_cont: query).result
|
||||
res.reduce([]) { |o, v| o << { id: v[:id], display_key: "#{v.name} (#{v.code})" } }
|
||||
end
|
||||
|
||||
def check_availability(codes)
|
||||
|
@ -188,10 +74,84 @@ class Contact < ActiveRecord::Base
|
|||
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
def search_by_query(query)
|
||||
res = search(code_cont: query).result
|
||||
res.reduce([]) { |o, v| o << { id: v[:id], display_key: "#{v.name} (#{v.code})" } }
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
def ident_valid_format?
|
||||
case ident_type
|
||||
when 'priv'
|
||||
case ident_country_code
|
||||
when 'EE'
|
||||
code = Isikukood.new(ident)
|
||||
errors.add(:ident, :invalid_EE_identity_format) unless code.valid?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_disclosure
|
||||
create_disclosure! unless disclosure
|
||||
end
|
||||
|
||||
def bic?
|
||||
ident_type == IDENT_TYPE_BIC
|
||||
end
|
||||
|
||||
def priv?
|
||||
ident_type != IDENT_TYPE_BIC
|
||||
end
|
||||
|
||||
def generate_code
|
||||
self.code = SecureRandom.hex(4) if code.blank?
|
||||
end
|
||||
|
||||
def generate_auth_info
|
||||
return if @generate_auth_info_disabled
|
||||
self.auth_info = SecureRandom.hex(16)
|
||||
end
|
||||
|
||||
def disable_generate_auth_info! # needed for testing
|
||||
@generate_auth_info_disabled = true
|
||||
end
|
||||
|
||||
def auth_info=(pw)
|
||||
self[:auth_info] = pw if new_record?
|
||||
end
|
||||
|
||||
def code=(code)
|
||||
self[:code] = code if new_record?
|
||||
end
|
||||
|
||||
# Find a way to use self.domains with contact
|
||||
def domains_owned
|
||||
Domain.where(owner_contact_id: id)
|
||||
end
|
||||
|
||||
def relations_with_domain?
|
||||
return true if domain_contacts.present? || domains_owned.present?
|
||||
false
|
||||
end
|
||||
|
||||
# TODO: refactor, it should not allow to destroy with normal destroy,
|
||||
# no need separate method
|
||||
# should use only in transaction
|
||||
def destroy_and_clean
|
||||
if relations_with_domain?
|
||||
errors.add(:domains, :exist)
|
||||
return false
|
||||
end
|
||||
destroy
|
||||
end
|
||||
|
||||
def set_ident_country_code
|
||||
return true unless ident_country_code_changed? && ident_country_code.present?
|
||||
code = Country.new(ident_country_code)
|
||||
if code
|
||||
self.ident_country_code = code.alpha2
|
||||
else
|
||||
errors.add(:ident_country_code, 'is not following ISO_3166-1 alpha 2 format')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -85,9 +85,9 @@ class Dnskey < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def generate_ds_key_tag
|
||||
public_key.gsub!(' ', '')
|
||||
pk = public_key.gsub(' ', '')
|
||||
wire_format = [flags, protocol, alg].pack('S!>CC')
|
||||
wire_format += Base64.decode64(public_key)
|
||||
wire_format += Base64.decode64(pk)
|
||||
|
||||
c = 0
|
||||
wire_format.each_byte.with_index do |b, i|
|
||||
|
|
|
@ -20,8 +20,6 @@ class Domain < ActiveRecord::Base
|
|||
-> { where(domain_contacts: { contact_type: DomainContact::ADMIN }) },
|
||||
through: :domain_contacts, source: :contact
|
||||
|
||||
# TODO: remove old
|
||||
# has_many :nameservers, dependent: :delete_all, after_add: :track_nameserver_add
|
||||
has_many :nameservers, dependent: :delete_all
|
||||
|
||||
accepts_nested_attributes_for :nameservers, allow_destroy: true,
|
||||
|
@ -43,11 +41,11 @@ class Domain < ActiveRecord::Base
|
|||
has_many :legal_documents, as: :documentable
|
||||
accepts_nested_attributes_for :legal_documents, reject_if: proc { |attrs| attrs[:body].blank? }
|
||||
|
||||
delegate :code, to: :owner_contact, prefix: true
|
||||
delegate :code, to: :owner_contact, prefix: true
|
||||
delegate :email, to: :owner_contact, prefix: true
|
||||
delegate :ident, to: :owner_contact, prefix: true
|
||||
delegate :phone, to: :owner_contact, prefix: true
|
||||
delegate :name, to: :registrar, prefix: true
|
||||
delegate :name, to: :registrar, prefix: true
|
||||
|
||||
before_create :generate_auth_info
|
||||
before_create :set_validity_dates
|
||||
|
@ -118,11 +116,6 @@ class Domain < ActiveRecord::Base
|
|||
|
||||
attr_accessor :owner_contact_typeahead, :update_me
|
||||
|
||||
# TODO: remove old
|
||||
# archiving
|
||||
# if proc works only on changes on domain sadly
|
||||
# has_paper_trail class_name: 'DomainVersion', meta: { snapshot: :create_snapshot }, if: proc(&:new_version)
|
||||
|
||||
def tech_domain_contacts
|
||||
domain_contacts.select { |x| x.contact_type == DomainContact::TECH }
|
||||
end
|
||||
|
@ -131,52 +124,6 @@ class Domain < ActiveRecord::Base
|
|||
domain_contacts.select { |x| x.contact_type == DomainContact::ADMIN }
|
||||
end
|
||||
|
||||
# TODO: remove old
|
||||
# def new_version
|
||||
# return false if versions.try(:last).try(:snapshot) == create_snapshot
|
||||
# true
|
||||
# end
|
||||
|
||||
# TODO: remove old
|
||||
# def create_version
|
||||
# return true unless PaperTrail.enabled?
|
||||
# return true unless valid?
|
||||
# touch_with_version if new_version
|
||||
# end
|
||||
|
||||
# TODO: remove old
|
||||
# def track_nameserver_add(_nameserver)
|
||||
# return true if versions.count == 0
|
||||
# return true unless valid? && new_version
|
||||
|
||||
# touch_with_version
|
||||
# end
|
||||
|
||||
# TODO: remove old
|
||||
# def create_snapshot
|
||||
# oc = owner_contact.snapshot if owner_contact.is_a?(Contact)
|
||||
# {
|
||||
# owner_contact: oc,
|
||||
# tech_contacts: tech_contacts.map(&:snapshot),
|
||||
# admin_contacts: admin_contacts.map(&:snapshot),
|
||||
# nameservers: nameservers.map(&:snapshot),
|
||||
# domain: make_snapshot
|
||||
# }.to_yaml
|
||||
# end
|
||||
|
||||
# TODO: remove old
|
||||
# def make_snapshot
|
||||
# {
|
||||
# name: name,
|
||||
# status: status,
|
||||
# period: period,
|
||||
# period_unit: period_unit,
|
||||
# registrar_id: registrar.try(:id),
|
||||
# valid_to: valid_to,
|
||||
# valid_from: valid_from
|
||||
# }
|
||||
# end
|
||||
|
||||
def name=(value)
|
||||
value.strip!
|
||||
value.downcase!
|
||||
|
@ -265,7 +212,7 @@ class Domain < ActiveRecord::Base
|
|||
attach_contact(DomainContact::TECH, owner_contact)
|
||||
end
|
||||
|
||||
return unless admin_domain_contacts.count.zero? && owner_contact.citizen?
|
||||
return unless admin_domain_contacts.count.zero? && owner_contact.priv?
|
||||
attach_contact(DomainContact::ADMIN, owner_contact)
|
||||
end
|
||||
|
||||
|
@ -305,36 +252,36 @@ class Domain < ActiveRecord::Base
|
|||
# rubocop:disable Metrics/MethodLength
|
||||
def update_whois_body
|
||||
self.whois_body = <<-EOS
|
||||
This Whois Server contains information on
|
||||
Estonian Top Level Domain ee TLD
|
||||
This Whois Server contains information on
|
||||
Estonian Top Level Domain ee TLD
|
||||
|
||||
domain: #{name}
|
||||
registrar: #{registrar}
|
||||
status:
|
||||
registered:
|
||||
changed: #{updated_at.to_s(:db)}
|
||||
expire:
|
||||
outzone:
|
||||
delete:
|
||||
domain: #{name}
|
||||
registrar: #{registrar}
|
||||
status:
|
||||
registered:
|
||||
changed: #{updated_at.to_s(:db)}
|
||||
expire:
|
||||
outzone:
|
||||
delete:
|
||||
|
||||
contact
|
||||
name:
|
||||
e-mail:
|
||||
registrar:
|
||||
created:
|
||||
contact
|
||||
name:
|
||||
e-mail:
|
||||
registrar:
|
||||
created:
|
||||
|
||||
contact:
|
||||
contact:
|
||||
|
||||
nsset:
|
||||
nserver:
|
||||
nsset:
|
||||
nserver:
|
||||
|
||||
registrar:
|
||||
org:
|
||||
url:
|
||||
phone:
|
||||
address:
|
||||
created:
|
||||
changed:
|
||||
registrar:
|
||||
org:
|
||||
url:
|
||||
phone:
|
||||
address:
|
||||
created:
|
||||
changed:
|
||||
EOS
|
||||
end
|
||||
# rubocop:enabled Metrics/MethodLength
|
||||
|
|
102
app/models/epp/contact.rb
Normal file
102
app/models/epp/contact.rb
Normal file
|
@ -0,0 +1,102 @@
|
|||
# rubocop: disable Metrics/ClassLength
|
||||
class Epp::Contact < Contact
|
||||
include EppErrors
|
||||
|
||||
# disable STI, there is type column present
|
||||
self.inheritance_column = :sti_disabled
|
||||
|
||||
class << self
|
||||
# rubocop: disable Metrics/PerceivedComplexity
|
||||
# rubocop: disable Metrics/CyclomaticComplexity
|
||||
# rubocop: disable Metrics/MethodLength
|
||||
def attrs_from(frame)
|
||||
f = frame
|
||||
at = {}.with_indifferent_access
|
||||
at[:name] = f.css('postalInfo name').text if f.css('postalInfo name').present?
|
||||
at[:org_name] = f.css('postalInfo org').text if f.css('postalInfo org').present?
|
||||
at[:email] = f.css('email').text if f.css('email').present?
|
||||
at[:fax] = f.css('fax').text if f.css('fax').present?
|
||||
at[:phone] = f.css('voice').text if f.css('voice').present?
|
||||
at[:auth_info] = f.css('authInfo pw').text if f.css('authInfo pw').present?
|
||||
|
||||
if f.css('ident').present? && f.css('ident').attr('type').present?
|
||||
at[:ident] = f.css('ident').text
|
||||
at[:ident_type] = f.css('ident').attr('type').try(:text)
|
||||
at[:ident_country_code] = f.css('ident').attr('cc').try(:text)
|
||||
end
|
||||
|
||||
at[:address_attributes] = {}.with_indifferent_access
|
||||
sat = at[:address_attributes]
|
||||
sat[:city] = f.css('postalInfo addr city').text if f.css('postalInfo addr city').present?
|
||||
sat[:zip] = f.css('postalInfo addr pc').text if f.css('postalInfo addr pc').present?
|
||||
sat[:street] = f.css('postalInfo addr street').text if f.css('postalInfo addr street').present?
|
||||
sat[:state] = f.css('postalInfo addr sp').text if f.css('postalInfo addr sp').present?
|
||||
sat[:country_code] = f.css('postalInfo addr cc').text if f.css('postalInfo addr cc').present?
|
||||
at.delete(:address_attributes) if at[:address_attributes].blank?
|
||||
|
||||
legal_frame = f.css('legalDocument').first
|
||||
if legal_frame.present?
|
||||
at[:legal_documents_attributes] = legal_document_attrs(legal_frame)
|
||||
end
|
||||
|
||||
at
|
||||
end
|
||||
# rubocop: enable Metrics/MethodLength
|
||||
# rubocop: enable Metrics/PerceivedComplexity
|
||||
# rubocop: enable Metrics/CyclomaticComplexity
|
||||
|
||||
def new(frame, registrar)
|
||||
return super if frame.blank?
|
||||
|
||||
custom_code =
|
||||
if frame.css('id').present?
|
||||
"#{registrar.code}:#{frame.css('id').text.parameterize}"
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
super(
|
||||
attrs_from(frame).merge(
|
||||
code: custom_code,
|
||||
registrar: registrar
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def legal_document_attrs(legal_frame)
|
||||
[{
|
||||
body: legal_frame.text,
|
||||
document_type: legal_frame['type']
|
||||
}]
|
||||
end
|
||||
end
|
||||
|
||||
def epp_code_map # rubocop:disable Metrics/MethodLength
|
||||
{
|
||||
'2302' => [ # Object exists
|
||||
[:code, :epp_id_taken]
|
||||
],
|
||||
'2305' => [ # Association exists
|
||||
[:domains, :exist]
|
||||
],
|
||||
'2005' => [ # Value syntax error
|
||||
[:phone, :invalid],
|
||||
[:email, :invalid],
|
||||
[:ident, :invalid],
|
||||
[:ident, :invalid_EE_identity_format],
|
||||
[:ident, :invalid_birthday_format]
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def update_attributes(frame)
|
||||
return super if frame.blank?
|
||||
at = {}.with_indifferent_access
|
||||
at.deep_merge!(self.class.attrs_from(frame.css('chg')))
|
||||
legal_frame = frame.css('legalDocument').first
|
||||
at[:legal_documents_attributes] = self.class.legal_document_attrs(legal_frame)
|
||||
|
||||
super(at)
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/ClassLength
|
|
@ -146,7 +146,7 @@ class Epp::EppDomain < Domain
|
|||
next
|
||||
end
|
||||
|
||||
if k == :admin && contact.juridical?
|
||||
if k == :admin && contact.bic?
|
||||
add_epp_error('2306', 'contact', x[:contact], [:domain_contacts, :admin_contact_can_be_only_citizen])
|
||||
next
|
||||
end
|
||||
|
|
|
@ -9,10 +9,18 @@ class Registrar < ActiveRecord::Base
|
|||
|
||||
validates :name, :reg_no, :country_code, :email, presence: true
|
||||
validates :name, :reg_no, uniqueness: true
|
||||
validate :set_code, if: :new_record?
|
||||
after_save :touch_domains_version
|
||||
|
||||
validates :email, :billing_email, format: /@/, allow_blank: true
|
||||
|
||||
class << self
|
||||
def search_by_query(query)
|
||||
res = search(name_or_reg_no_cont: query).result
|
||||
res.reduce([]) { |o, v| o << { id: v[:id], display_key: "#{v[:name]} (#{v[:reg_no]})" } }
|
||||
end
|
||||
end
|
||||
|
||||
def domain_transfers
|
||||
at = DomainTransfer.arel_table
|
||||
DomainTransfer.where(
|
||||
|
@ -23,7 +31,7 @@ class Registrar < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def address
|
||||
[street, city, state, zip].reject(&:empty?).compact.join(', ')
|
||||
[street, city, state, zip].reject(&:blank?).compact.join(', ')
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -34,10 +42,23 @@ class Registrar < ActiveRecord::Base
|
|||
Country.new(country_code)
|
||||
end
|
||||
|
||||
class << self
|
||||
def search_by_query(query)
|
||||
res = search(name_or_reg_no_cont: query).result
|
||||
res.reduce([]) { |o, v| o << { id: v[:id], display_key: "#{v[:name]} (#{v[:reg_no]})" } }
|
||||
def code=(code)
|
||||
self[:code] = code if new_record?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_code
|
||||
return false if name.blank?
|
||||
new_code = name.parameterize
|
||||
|
||||
# ensure code is always uniq automatically for a new record
|
||||
seq = 1
|
||||
while self.class.find_by_code(new_code)
|
||||
new_code += seq.to_s
|
||||
seq += 1
|
||||
end
|
||||
|
||||
self.code = new_code
|
||||
end
|
||||
end
|
||||
|
|
4
app/models/version/certificate_version.rb
Normal file
4
app/models/version/certificate_version.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
class CertificateVersion < PaperTrail::Version
|
||||
self.table_name = :log_certificates
|
||||
self.sequence_name = :log_certificates_id_seq
|
||||
end
|
|
@ -18,7 +18,7 @@ class ZonefileSetting < ActiveRecord::Base
|
|||
"select generate_zonefile('#{origin}')"
|
||||
)[0]['generate_zonefile']
|
||||
|
||||
File.open("#{APP_CONFIG['zonefile_export_dir']}/#{filename}", 'w') { |f| f.write(zf) }
|
||||
File.open("#{ENV['zonefile_export_dir']}/#{filename}", 'w') { |f| f.write(zf) }
|
||||
|
||||
STDOUT << "#{Time.now.utc} - Successfully generated zonefile #{filename}\n"
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
%hr
|
||||
|
||||
.row
|
||||
.col-md-6
|
||||
.col-md-12
|
||||
.form-group
|
||||
= f.label :username
|
||||
= f.text_field(:username, class: 'form-control')
|
||||
|
@ -26,11 +26,6 @@
|
|||
%label{for: 'api_user_active'}
|
||||
= f.check_box(:active)
|
||||
= t('active')
|
||||
|
||||
.col-md-6.text-left
|
||||
.form-group
|
||||
= f.label :csr, t('certificate_signing_req')
|
||||
= f.file_field :csr
|
||||
%hr
|
||||
.row
|
||||
.col-md-12.text-right
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
- if @api_user.errors.any?
|
||||
%hr
|
||||
.row
|
||||
.col-md-6
|
||||
.col-md-12
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
%h3.panel-title= t('general')
|
||||
|
@ -29,21 +29,24 @@
|
|||
|
||||
%dt= t('active')
|
||||
%dd= @api_user.active
|
||||
|
||||
.col-md-6
|
||||
.row
|
||||
.col-md-12
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
%h3.panel-title= t('certificates')
|
||||
.panel-body
|
||||
%dl.dl-horizontal
|
||||
%dt= t('csr')
|
||||
- if @api_user.csr
|
||||
%dd= link_to(t('download'), download_csr_admin_api_user_path)
|
||||
- else
|
||||
%dd -
|
||||
.panel-heading.clearfix
|
||||
.pull-left
|
||||
= t('certificates')
|
||||
.pull-right
|
||||
= link_to(t('upload_csr'), new_admin_api_user_certificate_path(@api_user), class: 'btn btn-primary btn-xs')
|
||||
|
||||
%dt= t('crt')
|
||||
- if @api_user.csr
|
||||
%dd= link_to(t('download'), download_crt_admin_api_user_path)
|
||||
- else
|
||||
%dd -
|
||||
.table-responsive
|
||||
%table.table.table-hover.table-bordered.table-condensed
|
||||
%thead
|
||||
%tr
|
||||
%th{class: 'col-xs-10'}= t('subject')
|
||||
%th{class: 'col-xs-2'}= t('status')
|
||||
%tbody
|
||||
- @api_user.certificates.each do |x|
|
||||
- if x.csr
|
||||
%tr
|
||||
%td= link_to(x.parsed_csr.try(:subject), admin_api_user_certificate_path(@api_user, x))
|
||||
%td= x.status
|
||||
|
|
20
app/views/admin/certificates/new.haml
Normal file
20
app/views/admin/certificates/new.haml
Normal file
|
@ -0,0 +1,20 @@
|
|||
%h2= t('upload_csr')
|
||||
%hr
|
||||
= form_for([:admin, @api_user, @certificate], multipart: true) do |f|
|
||||
- if @certificate.errors.any?
|
||||
- @certificate.errors.each do |attr, err|
|
||||
= err
|
||||
%br
|
||||
- if @certificate.errors.any?
|
||||
%hr
|
||||
|
||||
.row
|
||||
.col-md-12.text-left
|
||||
.form-group
|
||||
= f.label :csr, t('certificate_signing_req')
|
||||
= f.file_field :csr
|
||||
%hr
|
||||
.row
|
||||
.col-md-12.text-right
|
||||
= button_tag(t('save'), class: 'btn btn-primary')
|
||||
|
75
app/views/admin/certificates/show.haml
Normal file
75
app/views/admin/certificates/show.haml
Normal file
|
@ -0,0 +1,75 @@
|
|||
.row
|
||||
.col-sm-6
|
||||
%h2.text-center-xs
|
||||
= t('certificates')
|
||||
.col-sm-6
|
||||
%h2.text-right.text-center-xs
|
||||
= link_to(t('back_to_api_user'), [:admin, @api_user], class: 'btn btn-default')
|
||||
|
||||
%hr
|
||||
- if @certificate.errors.any?
|
||||
- @certificate.errors.each do |attr, err|
|
||||
= err
|
||||
%br
|
||||
- if @certificate.errors.any?
|
||||
%hr
|
||||
.row
|
||||
.col-md-12
|
||||
.panel.panel-default
|
||||
.panel-heading.clearfix
|
||||
.pull-left
|
||||
= t('csr')
|
||||
.pull-right
|
||||
= link_to(t('download'), download_csr_admin_api_user_certificate_path(@api_user, @certificate), class: 'btn btn-default btn-xs')
|
||||
- unless @crt
|
||||
= link_to(t('sign_this_request'), sign_admin_api_user_certificate_path(@api_user, @certificate), method: :post, class: 'btn btn-primary btn-xs')
|
||||
|
||||
.panel-body
|
||||
%dl.dl-horizontal
|
||||
%dt= t('version')
|
||||
%dd= @csr.version
|
||||
|
||||
%dt= t('subject')
|
||||
%dd= @csr.subject
|
||||
|
||||
%dt= t('signature_algorithm')
|
||||
%dd= @csr.signature_algorithm
|
||||
|
||||
- if @crt
|
||||
.row
|
||||
.col-md-12
|
||||
.panel.panel-default
|
||||
.panel-heading.clearfix
|
||||
.pull-left
|
||||
= t('crt') unless @certificate.revoked?
|
||||
= t('crt_revoked') if @certificate.revoked?
|
||||
.pull-right
|
||||
= link_to(t('download'), download_crt_admin_api_user_certificate_path(@api_user, @certificate), class: 'btn btn-default btn-xs')
|
||||
- unless @certificate.revoked?
|
||||
= link_to(t('revoke_this_certificate'), revoke_admin_api_user_certificate_path(@api_user, @certificate), method: :post, class: 'btn btn-primary btn-xs')
|
||||
- if @crt
|
||||
.panel-body
|
||||
%dl.dl-horizontal
|
||||
%dt= t('version')
|
||||
%dd= @crt.version
|
||||
|
||||
%dt= t('serial_number')
|
||||
%dd= @crt.serial
|
||||
|
||||
%dt= t('signature_algorithm')
|
||||
%dd= @crt.signature_algorithm
|
||||
|
||||
%dt= t('issuer')
|
||||
%dd= @crt.issuer
|
||||
|
||||
%dt= t('valid_from')
|
||||
%dd= @crt.not_before
|
||||
|
||||
%dt= t('valid_to')
|
||||
%dd= @crt.not_after
|
||||
|
||||
%dt= t('subject')
|
||||
%dd= @crt.subject
|
||||
|
||||
%dt= t('extensions')
|
||||
%dd= @crt.extensions.map(&:to_s).join('<br>').html_safe
|
|
@ -22,20 +22,20 @@
|
|||
%thead
|
||||
%tr
|
||||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'name', t('name'))
|
||||
= sort_link(@q, 'name', t(:name))
|
||||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'code', t('code'))
|
||||
= sort_link(@q, 'ident', t(:identity))
|
||||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'ident', t('identity_code'))
|
||||
= sort_link(@q, 'email', t(:email))
|
||||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'email', t('email'))
|
||||
= sort_link(@q, 'code', t(:code))
|
||||
%tbody
|
||||
- @contacts.each do |x|
|
||||
- @contacts.each do |contact|
|
||||
%tr
|
||||
%td= link_to(x, admin_contact_path(x))
|
||||
%td= x.code
|
||||
%td= x.ident
|
||||
%td= x.email
|
||||
%td= link_to(contact, admin_contact_path(contact))
|
||||
%td= "#{contact.ident} #{ident_indicator(contact)}"
|
||||
%td= contact.email
|
||||
%td= contact.code
|
||||
.row
|
||||
.col-md-12
|
||||
= paginate @contacts
|
||||
|
|
|
@ -1,28 +1,24 @@
|
|||
.panel.panel-default
|
||||
.panel-heading
|
||||
%h3.panel-title= t('address')
|
||||
%h3.panel-title= t(:address)
|
||||
.panel-body
|
||||
- unless @contact.address.nil?
|
||||
%dl.dl-horizontal
|
||||
%dt= t('country')
|
||||
%dd= @contact.address.country
|
||||
- if @contact.bic?
|
||||
%dt= t(:org_name)
|
||||
%dd= @contact.org_name
|
||||
|
||||
%dt= t('city')
|
||||
%dd= @contact.address.city
|
||||
%dt= t(:street)
|
||||
%dd= @contact.street
|
||||
|
||||
%dt= t('street')
|
||||
%dd= @contact.address.street
|
||||
%dt= t(:city)
|
||||
%dd= @contact.city
|
||||
|
||||
- if @contact.address.street2
|
||||
%dt= t('street')
|
||||
%dd= @contact.address.street2
|
||||
%dt= t(:zip)
|
||||
%dd= @contact.zip
|
||||
|
||||
- if @contact.address.street3
|
||||
%dt= t('street')
|
||||
%dd= @contact.address.street3
|
||||
|
||||
|
||||
|
||||
%dt= t('zip')
|
||||
%dd= @contact.address.zip
|
||||
%dt= t(:state)
|
||||
%dd= @contact.state
|
||||
|
||||
%dt= t(:country)
|
||||
%dd= @contact.country
|
||||
|
|
|
@ -3,30 +3,25 @@
|
|||
%h3.panel-title= t('general')
|
||||
.panel-body
|
||||
%dl.dl-horizontal
|
||||
%dt= t('name')
|
||||
%dd= @contact.name
|
||||
%dt= t(:ident)
|
||||
%dd= "#{@contact.ident} #{ident_indicator(@contact)}"
|
||||
|
||||
%dt= t('org_name')
|
||||
%dd= @contact.org_name
|
||||
%br
|
||||
|
||||
%dt= t('code')
|
||||
%dd= @contact.code
|
||||
|
||||
%dt= t('ident')
|
||||
%dd= @contact.ident
|
||||
|
||||
%dt= t('ident_type')
|
||||
%dd= @contact.ident_type
|
||||
|
||||
%dt= t('email')
|
||||
%dt= t(:email)
|
||||
%dd= @contact.email
|
||||
|
||||
%dt= t('phone')
|
||||
%dt= t(:phone)
|
||||
%dd= @contact.phone
|
||||
|
||||
- if @contact.fax
|
||||
%dt= t('fax')
|
||||
%dt= t(:fax)
|
||||
%dd= @contact.fax
|
||||
|
||||
%br
|
||||
|
||||
%dt= t(:code)
|
||||
%dd= @contact.code
|
||||
|
||||
%dt= t('password')
|
||||
%dd= @contact.auth_info
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
.row
|
||||
.col-sm-12
|
||||
%h2.text-center-xs
|
||||
= "#{t('contact_details')}"
|
||||
= @contact.name
|
||||
%hr
|
||||
.row
|
||||
.col-md-6= render 'admin/contacts/partials/general'
|
||||
.col-md-6= render 'admin/contacts/partials/address'
|
||||
.row
|
||||
.col-md-12= render 'admin/contacts/partials/domains'
|
||||
.row
|
||||
.col-md-12
|
||||
= render 'admin/domains/partials/legal_documents', legal_documents: @contact.legal_documents
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
%th{class: 'col-xs-8'}= t('created_at')
|
||||
%th{class: 'col-xs-4'}= t('type')
|
||||
%tbody
|
||||
- @domain.legal_documents.each do |x|
|
||||
- legal_documents.each do |x|
|
||||
%tr
|
||||
%td= link_to(x.created_at, [:admin, x])
|
||||
%td= x.document_type
|
||||
|
|
|
@ -24,4 +24,5 @@
|
|||
.row
|
||||
.col-md-12= render 'admin/domains/partials/keyrelays'
|
||||
.row
|
||||
.col-md-12= render 'admin/domains/partials/legal_documents'
|
||||
.col-md-12
|
||||
= render 'admin/domains/partials/legal_documents', legal_documents: @domain.legal_documents
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
address = @contact.address
|
||||
xml.tag!('contact:postalInfo', type: 'int') do
|
||||
xml.tag!('contact:name', @contact.name) if @disclosure.try(:[], :name) || @owner
|
||||
xml.tag!('contact:org', @contact.org_name) if @disclosure.try(:[], :org_name) || @owner
|
||||
if @disclosure.try(:addr) || @owner
|
||||
xml.tag!('contact:name', @contact.name) #if @disclosure.try(:[], :name) || @owner
|
||||
xml.tag!('contact:org', @contact.org_name) #if @disclosure.try(:[], :org_name) || @owner
|
||||
# if @disclosure.try(:addr) || @owner
|
||||
xml.tag!('contact:addr') do
|
||||
xml.tag!('contact:street', address.street) if address
|
||||
xml.tag!('contact:cc', address.country_code) unless address.country_code.nil?
|
||||
xml.tag!('contact:city', address.city) if address
|
||||
xml.tag!('contact:street', @contact.street)
|
||||
xml.tag!('contact:city', @contact.city)
|
||||
xml.tag!('contact:pc', @contact.zip)
|
||||
xml.tag!('contact:sp', @contact.state)
|
||||
xml.tag!('contact:cc', @contact.country_code)
|
||||
end
|
||||
end
|
||||
# end
|
||||
end
|
||||
|
||||
|
|
|
@ -6,11 +6,10 @@ xml.epp_head do
|
|||
|
||||
xml.resData do
|
||||
xml.tag!('contact:chkData', 'xmlns:contact' => 'urn:ietf:params:xml:ns:contact-1.0') do
|
||||
#xml.tag!('contact:id', @contact.code)
|
||||
@contacts.each do |contact|
|
||||
@results.each do |result|
|
||||
xml.tag!('contact:cd') do
|
||||
xml.tag! "contact:id", contact[:code], avail: contact[:avail]
|
||||
xml.tag!('contact:reason', contact[:reason]) unless contact[:avail] == 1
|
||||
xml.tag! "contact:id", result[:code], avail: result[:avail]
|
||||
xml.tag!('contact:reason', result[:reason]) unless result[:avail] == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,9 +8,9 @@ xml.epp_head do
|
|||
xml.tag!('contact:chkData', 'xmlns:contact' => 'urn:ietf:params:xml:ns:contact-1.0') do
|
||||
xml.tag!('contact:id', @contact.code)
|
||||
xml << render('/epp/contacts/postal_info')
|
||||
xml.tag!('contact:voice', @contact.phone) if @disclosure.try(:phone) || @owner
|
||||
xml.tag!('contact:fax', @contact.fax) if @disclosure.try(:fax) || @owner
|
||||
xml.tag!('contact:email', @contact.email) if @disclosure.try(:email) || @owner
|
||||
xml.tag!('contact:voice', @contact.phone) #if @disclosure.try(:phone) || @owner
|
||||
xml.tag!('contact:fax', @contact.fax) #if @disclosure.try(:fax) || @owner
|
||||
xml.tag!('contact:email', @contact.email) #if @disclosure.try(:email) || @owner
|
||||
xml.tag!('contact:clID', @contact.registrar.try(:name))
|
||||
xml.tag!('contact:crID', @contact.creator.try(:registrar))
|
||||
xml.tag!('contact:crDate', @contact.created_at)
|
||||
|
@ -18,18 +18,17 @@ xml.epp_head do
|
|||
xml.tag!('contact:upID', @contact.updator.try(:registrar))
|
||||
xml.tag!('contact:upDate', @contact.updated_at)
|
||||
end
|
||||
xml.tag!('contact:ident', @contact.ident, type: @contact.ident_type)
|
||||
xml.tag!('contact:trDate', '123') if false
|
||||
if @owner
|
||||
xml.tag!('contact:ident', @contact.ident, type: @contact.ident_type, cc: @contact.ident_country_code)
|
||||
# xml.tag!('contact:trDate', '123') if false
|
||||
if can? :view_password, @contact
|
||||
xml.tag!('contact:authInfo') do
|
||||
xml.tag!('contact:pw', @contact.auth_info) # Doc says we have to return this but is it necessary?
|
||||
xml.tag!('contact:pw', @contact.auth_info)
|
||||
end
|
||||
end
|
||||
# statuses
|
||||
@contact.statuses.each do |cs|
|
||||
xml.tag!('contact:status', s: cs.value)
|
||||
@contact.statuses.each do |status|
|
||||
xml.tag!('contact:status', s: status.value)
|
||||
end
|
||||
xml << render('/epp/contacts/disclosure_policy')
|
||||
# xml << render('/epp/contacts/disclosure_policy')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
= link_to admin_dashboard_path, class: 'navbar-brand' do
|
||||
= APP_CONFIG['app_name']
|
||||
= ENV['app_name']
|
||||
- if unstable_env.present?
|
||||
.text-center
|
||||
%small{style: 'color: #0074B3;'}= unstable_env
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue