Merge branch 'users-refocator and contact refactor'

This commit is contained in:
Priit Tark 2015-02-17 09:13:18 +02:00
commit 8a2c4c97ea
63 changed files with 853 additions and 1117 deletions

View file

@ -3,11 +3,11 @@ group :red_green_refactor, halt_on_fail: true do
# be sure you have apache2 configured to
# accept EPP request on port 701, what proxy to 8989.
# port and environment is just for correct notification, all is overwritten by CLI
guard :rails, port: 8989, environment: 'test' do
# guard :rails, port: 8989, environment: 'test', CLI: 'RAILS_ENV=test unicorn -p 8989' do
watch('Gemfile.lock')
watch(%r{^(config|lib)/.*})
end
# guard :rails, port: 8989, environment: 'test' do
# # guard :rails, port: 8989, environment: 'test', CLI: 'RAILS_ENV=test unicorn -p 8989' do
# watch('Gemfile.lock')
# watch(%r{^(config|lib)/.*})
# end
guard :rspec, cmd: 'spring rspec', notification: false do
watch(%r{^spec/.+_spec\.rb$})

View file

@ -4,11 +4,11 @@ module Repp
prefix :repp
http_basic do |username, password|
@current_api_user ||= ApiUser.find_by(username: username, password: password)
@current_user ||= ApiUser.find_by(username: username, password: password)
end
helpers do
attr_reader :current_api_user
attr_reader :current_user
end
after do
@ -18,8 +18,8 @@ module Repp
request_params: request.params.except('route_info').to_json,
response: @response.to_json,
response_code: status,
api_user_name: current_api_user.try(:username),
api_user_registrar: current_api_user.try(:registrar).try(:to_s),
api_user_name: current_user.try(:username),
api_user_registrar: current_user.try(:registrar).try(:to_s),
ip: request.ip
})
end

View file

@ -5,7 +5,7 @@ module Repp
resource :contacts do
desc 'Return list of contact'
get '/' do
contacts = current_api_user.registrar.contacts.page(params[:page])
contacts = current_user.registrar.contacts.page(params[:page])
@response = {
contacts: contacts,
total_pages: contacts.total_pages

View file

@ -5,7 +5,7 @@ module Repp
resource :domains do
desc 'Return list of domains'
get '/' do
domains = current_api_user.registrar.domains.page(params[:page])
domains = current_user.registrar.domains.page(params[:page])
@response = {
domains: domains,
total_pages: domains.total_pages

View file

@ -1,22 +1,22 @@
class Admin::UsersController < AdminController
class Admin::AdminUsersController < AdminController
load_and_authorize_resource
before_action :set_user, only: [:show, :edit, :update, :destroy]
def index
@q = User.search(params[:q])
@users = @q.result.page(params[:page])
@q = AdminUser.search(params[:q])
@admin_users = @q.result.page(params[:page])
end
def new
@user = User.new
@admin_user = AdminUser.new
end
def create
@user = User.new(user_params)
@admin_user = AdminUser.new(admin_user_params)
if @user.save
if @admin_user.save
flash[:notice] = I18n.t('record_created')
redirect_to [:admin, @user]
redirect_to [:admin, @admin_user]
else
flash.now[:alert] = I18n.t('failed_to_create_record')
render 'new'
@ -28,9 +28,9 @@ class Admin::UsersController < AdminController
def edit; end
def update
if @user.update(user_params)
if @admin_user.update(admin_user_params)
flash[:notice] = I18n.t('record_updated')
redirect_to [:admin, @user]
redirect_to [:admin, @admin_user]
else
flash.now[:alert] = I18n.t('failed_to_update_record')
render 'edit'
@ -38,7 +38,7 @@ class Admin::UsersController < AdminController
end
def destroy
if @user.destroy
if @admin_user.destroy
flash[:notice] = I18n.t('record_deleted')
redirect_to admin_users_path
else
@ -50,10 +50,10 @@ class Admin::UsersController < AdminController
private
def set_user
@user = User.find(params[:id])
@admin_user = AdminUser.find(params[:id])
end
def user_params
params.require(:user).permit(:username, :password, :identity_code, :email, :country_code, { roles: [] })
def admin_user_params
params.require(:admin_user).permit(:username, :password, :identity_code, :email, :country_code, { roles: [] })
end
end

View file

@ -1,4 +1,3 @@
class AdminController < ApplicationController
before_action :authenticate_user!
check_authorization
end

View file

@ -1,4 +1,6 @@
class ApplicationController < ActionController::Base
check_authorization
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
@ -9,16 +11,22 @@ 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
def user_for_paper_trail
if defined?(current_api_user) && current_api_user.present?
# Most of the time it's not loaded in correct time because PaperTrail before filter kicks in
# before current_api_user is defined. PaperTrail is triggered also at current_api_user
api_user_log_str(current_api_user)
if defined?(current_user) && current_user.present?
# Most of the time it's not loaded in correct time because PaperTrail before filter kicks in
# before current_user is defined. PaperTrail is triggered also at current_user
api_user_log_str(current_user)
elsif current_user.present?
"#{current_user.id}-#{current_user.username}"
else
@ -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

View file

@ -5,9 +5,9 @@ module Shared::UserStamper
# return false if obj.nil? || !obj.has_attribute?(:created_by_id && :updated_by_id)
# if obj.new_record?
# obj.created_by_id = current_api_user.id
# obj.created_by_id = current_user.id
# else
# obj.updated_by_id = current_api_user.id
# obj.updated_by_id = current_user.id
# end
# true

View file

@ -1,188 +1,120 @@
class Epp::ContactsController < EppController
helper WhodunnitHelper ## Refactor this?
def create
@contact = Contact.new(contact_and_address_attributes)
@contact.registrar = current_api_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])
@contact.registrar = 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_api_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_api_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_api_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
@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

View file

@ -1,4 +1,6 @@
class Epp::DomainsController < EppController
skip_authorization_check # TODO: remove it
def create
@domain = Epp::EppDomain.new(domain_create_params)
@ -176,7 +178,7 @@ class Epp::DomainsController < EppController
{
name: name,
registrar_id: current_api_user.registrar.try(:id),
registrar_id: current_user.registrar.try(:id),
registered_at: Time.now,
period: (period.to_i == 0) ? 1 : period.to_i,
period_unit: Epp::EppDomain.parse_period_unit_from_frame(params[:parsed_frame]) || 'y'
@ -187,7 +189,7 @@ class Epp::DomainsController < EppController
res = {}
res[:pw] = params[:parsed_frame].css('pw').first.try(:text)
res[:action] = params[:parsed_frame].css('transfer').first[:op]
res[:current_user] = current_api_user
res[:current_user] = current_user
res
end
@ -206,7 +208,7 @@ class Epp::DomainsController < EppController
return domain if domain.auth_info == params[:parsed_frame].css('authInfo pw').text
if (domain.registrar != current_api_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'),

View file

@ -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'

View file

@ -1,4 +1,6 @@
class Epp::KeyrelaysController < EppController
skip_authorization_check # TODO: remove it
# rubocop: disable Metrics/PerceivedComplexity
# rubocop: disable Metrics/CyclomaticComplexity
def keyrelay
@ -6,7 +8,7 @@ class Epp::KeyrelaysController < EppController
handle_errors(@domain) and return unless @domain
handle_errors(@domain) and return unless @domain.authenticate(params[:parsed_frame].css('pw').text)
handle_errors(@domain) and return unless @domain.keyrelay(params[:parsed_frame], current_api_user.registrar)
handle_errors(@domain) and return unless @domain.keyrelay(params[:parsed_frame], current_user.registrar)
render_epp_response '/epp/shared/success'
end

View file

@ -1,11 +1,13 @@
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'
end
def req_poll
@message = current_api_user.queued_messages.last
@message = current_user.queued_messages.last
render_epp_response 'epp/poll/poll_no_messages' and return unless @message
if @message.attached_obj_type && @message.attached_obj_id
@ -20,7 +22,7 @@ class Epp::PollsController < EppController
end
def ack_poll
@message = current_api_user.queued_messages.find_by(id: params[:parsed_frame].css('poll').first['msgID'])
@message = current_user.queued_messages.find_by(id: params[:parsed_frame].css('poll').first['msgID'])
unless @message
epp_errors << {
@ -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

View file

@ -1,4 +1,6 @@
class Epp::SessionsController < EppController
skip_authorization_check only: [:hello, :login, :logout]
def hello
render_epp_response('greeting')
end
@ -16,7 +18,7 @@ class Epp::SessionsController < EppController
end
def logout
@api_user = current_api_user # cache current_api_user for logging
@api_user = current_user # cache current_user for logging
epp_session[:api_user_id] = nil
response.headers['X-EPP-Returncode'] = '1500'
render_epp_response('logout')

View file

@ -1,9 +1,22 @@
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_api_user
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
@ -21,13 +34,13 @@ class EppController < ApplicationController
EppSession.find_or_initialize_by(session_id: cookie['session'])
end
def current_api_user
@current_api_user ||= ApiUser.find_by_id(epp_session[:api_user_id])
def current_user
@current_user ||= ApiUser.find_by_id(epp_session[:api_user_id])
# by default PaperTrail uses before filter and at that
# time current_api_user is not yet present
::PaperTrail.whodunnit = api_user_log_str(@current_api_user)
# time current_user is not yet present
::PaperTrail.whodunnit = api_user_log_str(@current_user)
::PaperSession.session = epp_session.session_id if epp_session.session_id.present?
@current_api_user
@current_user
end
# ERROR + RESPONSE HANDLING
@ -84,12 +97,19 @@ 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(' ')
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)
@ -105,7 +125,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]
@ -203,8 +223,8 @@ class EppController < ApplicationController
request_successful: epp_errors.empty?,
request_object: params[:epp_object_type],
response: @response,
api_user_name: api_user_log_str(@api_user || current_api_user),
api_user_registrar: @api_user.try(:registrar).try(:to_s) || current_api_user.try(:registrar).try(:to_s),
api_user_name: api_user_log_str(@api_user || current_user),
api_user_registrar: @api_user.try(:registrar).try(:to_s) || current_user.try(:registrar).try(:to_s),
ip: request.ip
})
end

View file

@ -1,10 +1,12 @@
class SessionsController < Devise::SessionsController
skip_authorization_check only: [:login, :create]
def create
# TODO: Create ID Card login here:
# this is just testing config
# if Rails.env.development? || Rails.env.test?
@user = User.first if params[:user1]
@user = User.second if params[:user2]
@user = AdminUser.first if params[:user1]
@user = AdminUser.second if params[:user2]
return redirect_to :back, alert: 'No user' if @user.blank?

View file

@ -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 = User.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 = User.find(whodunnit)
return user.username
rescue ActiveRecord::RecordNotFound
return nil
end
end

View file

@ -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 || User.new
@user.roles.each { |role| send(role) } if @user.roles
return if @user.roles || @user.roles.any?
@user = user || AdminUser.new
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

31
app/models/admin_user.rb Normal file
View file

@ -0,0 +1,31 @@
class AdminUser < User
# TODO: Foreign user will get email with activation link,email,temp-password.
# After activisation, system should require to change temp password.
# TODO: Estonian id validation
validates :username, :password, :country_code, presence: true
validates :identity_code, uniqueness: true, allow_blank: true
validates :identity_code, presence: true, if: -> { country_code == 'EE' }
validates :email, presence: true, if: -> { country_code != 'EE' }
validate :validate_identity_code
belongs_to :country_deprecated, foreign_key: :country_id
ROLES = %w(user customer_service admin)
def to_s
username
end
def country
Country.new(country_code)
end
private
def validate_identity_code
return unless identity_code.present?
code = Isikukood.new(identity_code)
errors.add(:identity_code, :invalid) unless code.valid?
end
end

View file

@ -1,8 +1,7 @@
require 'open3'
# rubocop: disable Metrics/ClassLength
class ApiUser < ActiveRecord::Base
include Versions # version/api_user_version.rb
class ApiUser < User
# TODO: should have max request limit per day
belongs_to :registrar
has_many :contacts
@ -14,6 +13,11 @@ class ApiUser < ActiveRecord::Base
attr_accessor :registrar_typeahead
def ability
@ability ||= Ability.new(self)
end
delegate :can?, :cannot?, to: :ability
def registrar_typeahead
@registrar_typeahead || registrar || nil
end

View file

@ -0,0 +1,52 @@
require 'open3'
# rubocop: disable Metrics/ClassLength
class ApiUserDeprecated < ActiveRecord::Base
self.table_name = "api_users"
# TODO: should have max request limit per day
belongs_to :registrar
has_many :contacts
validates :username, :password, :registrar, presence: true
validates :username, uniqueness: true
before_save :create_crt, if: -> (au) { au.csr_changed? }
attr_accessor :registrar_typeahead
def registrar_typeahead
@registrar_typeahead || registrar || nil
end
def to_s
username
end
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

View file

@ -5,7 +5,7 @@ module VersionSession
before_save :add_session
def add_session
self.session = PaperSession.session
self.session = ::PaperSession.session
true
end
end

View file

@ -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
User.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
User.find(updator_str)
AdminUser.find_by(id: updator_str)
end
end

View file

@ -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,10 +7,11 @@ 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
@ -19,25 +19,20 @@ class Contact < ActiveRecord::Base
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' }
validate :ident_must_be_valid
validates :code, uniqueness: { message: :epp_id_taken }
delegate :city, to: :address # , prefix: true
delegate :street, to: :address # , prefix: true
delegate :zip, to: :address # , prefix: true
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
# callbacks
# TODO: remove old
# after_commit :domains_snapshot
# after_update :domains_snapshot
# after_destroy :domains_snapshot
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'
@ -54,6 +49,32 @@ class Contact < ActiveRecord::Base
CONTACT_TYPE_ADMIN = 'admin'
CONTACT_TYPES = [CONTACT_TYPE_TECH, CONTACT_TYPE_ADMIN]
class << self
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)
codes = [codes] if codes.is_a?(String)
res = []
codes.each do |x|
if Contact.find_by(code: x)
res << { code: x, avail: 0, reason: 'in use' }
else
res << { code: x, avail: 1 }
end
end
res
end
end
def to_s
name
end
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
@ -66,15 +87,6 @@ class Contact < ActiveRecord::Base
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
@ -83,18 +95,6 @@ class Contact < ActiveRecord::Base
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)
@ -114,6 +114,8 @@ class Contact < ActiveRecord::Base
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?
@ -122,76 +124,4 @@ class Contact < ActiveRecord::Base
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? }
end
def check_availability(codes)
codes = [codes] if codes.is_a?(String)
res = []
codes.each do |x|
if Contact.find_by(code: x)
res << { code: x, avail: 0, reason: 'in use' }
else
res << { code: x, avail: 1 }
end
end
res
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})" } }
end
end
end

View file

@ -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,
@ -42,11 +40,11 @@ class Domain < ActiveRecord::Base
has_many :legal_documents, as: :documentable
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
@ -117,11 +115,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
@ -130,52 +123,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!
@ -304,36 +251,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

81
app/models/epp/contact.rb Normal file
View file

@ -0,0 +1,81 @@
# 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').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?
legald = f.css('legalDocument').first
if legald.present?
at[:legal_documents_attributes] = {}.with_indifferent_access
lat = at[:legal_documents_attributes]
lat[0] = {}.with_indifferent_access
lat[0][:document_type] = legald['type']
lat[0][:body] = legald.text
at.delete(:legal_documents_attributes) if at[:legal_documents_attributes].blank?
end
at
end
# rubocop: enable Metrics/MethodLength
# rubocop: enable Metrics/PerceivedComplexity
# rubocop: enable Metrics/CyclomaticComplexity
def new(frame)
return super if frame.blank?
super(attrs_from(frame))
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]
]
}
end
def update_attributes(frame)
return super if frame.blank?
at = {}.with_indifferent_access
at.deep_merge!(self.class.attrs_from(frame.css('chg')))
super(at)
end
end
# rubocop: enable Metrics/ClassLength

View file

@ -1,35 +1,4 @@
class User < ActiveRecord::Base
include Versions # version/user_version.rb
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :trackable, :timeoutable
# TODO: Foreign user will get email with activation link,email,temp-password.
# After activisation, system should require to change temp password.
# TODO: Estonian id validation
validates :username, :password, :country_code, presence: true
validates :identity_code, uniqueness: true, allow_blank: true
validates :identity_code, presence: true, if: -> { country_code == 'EE' }
validates :email, presence: true, if: -> { country_code != 'EE' }
validate :validate_identity_code
belongs_to :country_deprecated, foreign_key: :country_id
ROLES = %w(user customer_service admin)
def to_s
username
end
def country
Country.new(country_code)
end
private
def validate_identity_code
return unless identity_code.present?
code = Isikukood.new(identity_code)
errors.add(:identity_code, :invalid) unless code.valid?
end
end

View file

@ -1,9 +1,9 @@
= form_for([:admin, @user]) do |f|
- if @user.errors.any?
- @user.errors.each do |attr, err|
= form_for([:admin, @admin_user]) do |f|
- if @admin_user.errors.any?
- @admin_user.errors.each do |attr, err|
= err
%br
- if @user.errors.any?
- if @admin_user.errors.any?
%hr
.row
@ -27,7 +27,7 @@
= f.text_field(:email, class: 'form-control')
.form-group
= f.label :role
= select_tag 'user[roles][]', options_for_select(User::ROLES.map {|x| [t(x), x] }, @user.roles.try(:first)), class: 'form-control selectize'
= select_tag 'admin_user[roles][]', options_for_select(AdminUser::ROLES.map {|x| [t(x), x] }, @admin_user.roles.try(:first)), class: 'form-control selectize'
%hr
.row

View file

@ -4,6 +4,6 @@
= "#{t('edit_user')}"
.col-sm-6
%h2.text-right.text-center-xs
= link_to(t('back_to_user'), [:admin, @user], class: 'btn btn-default')
= link_to(t('back_to_user'), [:admin, @admin_user], class: 'btn btn-default')
%hr
= render 'form'

View file

@ -1,9 +1,9 @@
.row
.col-sm-6
%h2.text-center-xs= t('users')
%h2.text-center-xs= t('admin_users')
.col-sm-6
%h2.text-right.text-center-xs
= link_to(t('create_new_user'), new_admin_user_path, class: 'btn btn-primary')
= link_to(t('create_new_user'), new_admin_admin_user_path, class: 'btn btn-primary')
%hr
.row
.col-md-12
@ -20,7 +20,7 @@
%th{class: 'col-xs-2'}
= sort_link(@q, 'role', t('role'))
%tbody
- @users.each do |x|
- @admin_users.each do |x|
%tr
%td= link_to(x, [:admin, x])
%td= x.email
@ -31,4 +31,4 @@
%td
.row
.col-md-12
= paginate @users
= paginate @admin_users

View file

@ -4,15 +4,15 @@
= "#{t('user_details')}"
.col-sm-6
%h2.text-right.text-center-xs
= link_to(t('edit'), edit_admin_user_path(@user), class: 'btn btn-primary')
= link_to(t('delete'), admin_user_path(@user), method: :delete, data: { confirm: t('are_you_sure') }, class: 'btn btn-danger')
= link_to(t('edit'), edit_admin_admin_user_path(@admin_user), class: 'btn btn-primary')
= link_to(t('delete'), admin_admin_user_path(@admin_user), method: :delete, data: { confirm: t('are_you_sure') }, class: 'btn btn-danger')
%hr
- if @user.errors.any?
- @user.errors.each do |attr, err|
- if @admin_user.errors.any?
- @admin_user.errors.each do |attr, err|
= err
%br
- if @user.errors.any?
- if @admin_user.errors.any?
%hr
.row
.col-md-6
@ -22,13 +22,13 @@
.panel-body
%dl.dl-horizontal
%dt= t('username')
%dd= @user.username
%dd= @admin_user.username
%dt= t('password')
%dd= @user.password
%dd= @admin_user.password
%dt= t('identity_code')
%dd= @user.identity_code
%dd= @admin_user.identity_code
.col-md-6
.panel.panel-default
@ -37,10 +37,10 @@
.panel-body
%dl.dl-horizontal
%dt= t('email')
%dd= @user.email
%dd= @admin_user.email
%dt= t('role')
- if @user.roles
%dd= t(@user.roles.first)
- if @admin_user.roles
%dd= t(@admin_user.roles.first)
- else
%dd

View file

@ -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|
%tr
%td= link_to(x, admin_contact_path(x))
%td= x.code
%td= x.ident
%td= x.email
%td= x.code
.row
.col-md-12
= paginate @contacts

View file

@ -4,25 +4,17 @@
.panel-body
- unless @contact.address.nil?
%dl.dl-horizontal
%dt= t('country')
%dd= @contact.address.country
%dt= t('street')
%dd= @contact.street
%dt= t('city')
%dd= @contact.address.city
%dt= t('street')
%dd= @contact.address.street
- if @contact.address.street2
%dt= t('street')
%dd= @contact.address.street2
- if @contact.address.street3
%dt= t('street')
%dd= @contact.address.street3
%dd= @contact.city
%dt= t('zip')
%dd= @contact.address.zip
%dd= @contact.zip
%dt= t('state')
%dd= @contact.state
%dt= t('country')
%dd= @contact.country

View file

@ -3,30 +3,28 @@
%h3.panel-title= t('general')
.panel-body
%dl.dl-horizontal
%dt= t('name')
%dd= @contact.name
%dt= t(:ident)
%dd= @contact.ident + ' [' + @contact.ident_type + ']'
%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
%dt= t(:org_name)
%dd= @contact.org_name
- 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)
@ -19,17 +19,16 @@ xml.epp_head do
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: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

View file

@ -4,7 +4,7 @@ xml.epp_head do
xml.msg 'Command completed successfully'
end
xml.tag!('msgQ', 'count' => current_api_user.queued_messages.count, 'id' => @message.id)
xml.tag!('msgQ', 'count' => current_user.queued_messages.count, 'id' => @message.id)
xml << render('/epp/shared/trID')
end

View file

@ -10,7 +10,7 @@ xml.epp(
xml.msg 'Command completed successfully; ack to dequeue'
end
xml.tag!('msgQ', 'count' => current_api_user.queued_messages.count, 'id' => @message.id) do
xml.tag!('msgQ', 'count' => current_user.queued_messages.count, 'id' => @message.id) do
xml.qDate @message.created_at
xml.msg @message.body
end

View file

@ -4,7 +4,7 @@ xml.epp_head do
xml.msg 'Command completed successfully; ack to dequeue'
end
xml.tag!('msgQ', 'count' => current_api_user.queued_messages.count, 'id' => @message.id) do
xml.tag!('msgQ', 'count' => current_user.queued_messages.count, 'id' => @message.id) do
xml.qDate @message.created_at
xml.msg @message.body
end

View file

@ -52,7 +52,7 @@
%li.divider
%li.dropdown-header= t('users')
%li= link_to t(:admin_users), admin_users_path
%li= link_to t(:admin_users), admin_admin_users_path
%li= link_to t(:api_users), admin_api_users_path
%ul.nav.navbar-nav.navbar-right

View file

@ -1,24 +1,3 @@
# Files in the config/locales directory are used for internationalization
# and are automatically loaded by Rails. If you want to use locales other
# than English, add the necessary files in this directory.
#
# To use the locales, use `I18n.t`:
#
# I18n.t 'hello'
#
# In views, this is aliased to just `t`:
#
# <%= t('hello') %>
#
# To use a different locale, set it with `I18n.locale`:
#
# I18n.locale = :es
#
# This would use the information in config/locales/es.yml.
#
# To learn more, please read the Rails Internationalization guide
# available at http://guides.rubyonrails.org/i18n.html.
en:
views:
pagination:
@ -259,7 +238,6 @@ en:
unimplemented_command: 'Unimplemented command'
domain_exists_but_belongs_to_other_registrar: 'Domain exists but belongs to other registrar'
code: 'Code'
value: 'Value'
action: 'Action'
@ -321,7 +299,7 @@ en:
domain_status_prohibits_deleting: 'Domain status prohibits deleting'
domain_deleted: 'Domain deleted!'
failed_to_delete_domain: 'Failed to delete domain!'
email: 'Email'
email: 'E-mail'
fax: 'Fax'
contact_details: 'Contact details'
ident: 'Ident'
@ -330,8 +308,8 @@ en:
country: 'Country'
city: 'City'
street: 'Street'
zip: 'Zip'
org_name: 'Organisation name'
zip: 'Postcode'
org_name: 'Org name'
failed_to_add_domain: 'Failed to add domain!'
domain_added: 'Domain added!'
new_contact: 'New contact'
@ -501,3 +479,4 @@ en:
address_help: 'Street name, house no - apartment no, city, county, country, zip'
download: 'Download'
failed_to_create_certificate: 'Failed to create certificate!'
contact_code: Contact code

View file

@ -45,7 +45,7 @@ Rails.application.routes.draw do
end
end
resources :users
resources :admin_users
resources :api_users do
member do
get 'download_csr'

View file

@ -0,0 +1,5 @@
class AddStateToAddress < ActiveRecord::Migration
def change
add_column :addresses, :state, :string
end
end

View file

@ -0,0 +1,21 @@
class MergeApiUserAndUser < ActiveRecord::Migration
def change
add_column :users, :registrar_id, :integer
add_column :users, :active, :boolean, default: false
add_column :users, :csr, :text
add_column :users, :crt, :text
add_column :users, :type, :string
User.all.each do |x|
x.type = 'AdminUser'
x.save
end
ApiUserDeprecated.all.each do |x|
attrs = x.attributes
attrs.delete('id')
ApiUser.skip_callback(:save, :before, :create_crt)
ApiUser.create!(attrs)
end
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150212125339) do
ActiveRecord::Schema.define(version: 20150213104014) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -615,17 +615,22 @@ ActiveRecord::Schema.define(version: 20150212125339) do
t.datetime "created_at"
t.datetime "updated_at"
t.string "email"
t.integer "sign_in_count", default: 0, null: false
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.string "identity_code"
t.integer "country_id"
t.string "roles", array: true
t.string "roles", array: true
t.string "creator_str"
t.string "updator_str"
t.string "country_code"
t.integer "registrar_id"
t.boolean "active", default: false
t.text "csr"
t.text "crt"
t.string "type"
end
create_table "versions", force: :cascade do |t|

View file

@ -37,7 +37,7 @@ ApiUser.where(
registrar: registrar2
).first_or_create!
User.where(
AdminUser.where(
username: 'user1',
password: 'test1',
email: 'user1@example.ee',
@ -45,7 +45,7 @@ User.where(
country_code: 'EE'
).first_or_create!
User.where(
AdminUser.where(
username: 'user2',
password: 'test2',
email: 'user2@example.ee',
@ -53,7 +53,7 @@ User.where(
country_code: 'EE'
).first_or_create!
User.where(
AdminUser.where(
username: 'user3',
password: 'test3',
email: 'user3@example.ee',
@ -61,4 +61,4 @@ User.where(
country_code: 'EE'
).first_or_create!
User.update_all(roles: ['admin'])
AdminUser.update_all(roles: ['admin'])

View file

@ -30,12 +30,10 @@ Contact Mapping protocol short version:
"priv" # National idendtification number
"birthday" # Birthday date in format in DD-MM-YYYY
<extension> 1
<eis:extdata> 1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
<eis:legalDocument> 1 Base64 encoded document
<eis:extdata> 1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
<eis:legalDocument> 1 Base64 encoded document
Attribute: type="pdf/bdoc/ddoc/zip/rar/gz/tar/7z"
[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-create-command-successfully-creates-a-contact)
### Contact update
@ -65,9 +63,9 @@ Contact Mapping protocol short version:
<contact:authInfo> 0-1 Required if registrar is not the owner of the contact.
<contact:pw> 1 Contact password. Attribute: roid="String"
<extension> 0-1
<eis:extdata> 0-1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
<eis:legalDocument> 0-1 Base64 encoded document.
Attribute: type="pdf/bdoc/ddoc/zip/rar/gz/tar/7z"
<eis:extdata> 0-1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
<eis:legalDocument> 0-1 Base64 encoded document.
Attribute: type="pdf/bdoc/ddoc/zip/rar/gz/tar/7z"
[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-update-command-is-succesful)
@ -82,10 +80,10 @@ Contact Mapping protocol short version:
<contact:authInfo> 0-1 Required if registrar is not the owner of the contact.
<contact:pw> 1 Contact password. Attribute: roid="String"
<extension> 1
<eis:extdata> 1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
<eis:legalDocument> 1 Base64 encoded document.
<eis:extdata> 1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
<eis:legalDocument> 1 Base64 encoded document.
Attribute: type="pdf/bdoc/ddoc/zip/rar/gz/tar/7z"
<clTRID> 0-1 Client transaction id
<clTRID> 0-1 Client transaction id
[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-delete-command-deletes-contact)

View file

@ -15,6 +15,14 @@ describe 'EPP Contact', epp: true do
Contact.skip_callback(:create, :before, :generate_code)
Contact.skip_callback(:create, :before, :generate_auth_info)
@contact = Fabricate(:contact, registrar: @registrar1)
@legal_document = {
legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==',
attrs: { type: 'pdf' }
}
}
end
after :all do
@ -24,26 +32,40 @@ describe 'EPP Contact', epp: true do
context 'with valid user' do
context 'create command' do
it 'fails if request xml is missing' do
xml = @epp_xml.create
response = epp_plain_request(xml, :xml)
response[:results][0][:msg].should == 'Command syntax error'
response[:results][0][:result_code].should == '2001'
response[:results].count.should == 1
def create_request(overwrites = {})
defaults = {
postalInfo: {
name: { value: 'John Doe' },
addr: {
street: { value: '123 Example' },
city: { value: 'Tallinn' },
cc: { value: 'EE' }
}
},
voice: { value: '+372.1234567' },
email: { value: 'test@example.example' },
ident: { value: '37605030299', attrs: { type: 'priv' } }
}
create_xml = @epp_xml.create(defaults.deep_merge(overwrites), @legal_document)
epp_plain_request(create_xml, :xml)
end
it 'fails if request xml is missing' do
xml = @epp_xml.create(
postalInfo: { addr: { value: nil } }
)
response = epp_plain_request(xml, :xml)
response[:results][0][:msg].should == 'Required parameter missing: name'
response[:results][1][:msg].should == 'Required parameter missing: city'
response[:results][2][:msg].should == 'Required parameter missing: cc'
response[:results][3][:msg].should == 'Required parameter missing: ident'
response[:results][4][:msg].should == 'Required parameter missing: voice'
response[:results][5][:msg].should == 'Required parameter missing: email'
response = epp_plain_request(@epp_xml.create, :xml)
response[:results][0][:msg].should ==
'Required parameter missing: create > create > postalInfo > name'
response[:results][1][:msg].should ==
'Required parameter missing: create > create > postalInfo > addr > city'
response[:results][2][:msg].should ==
'Required parameter missing: create > create > postalInfo > addr > cc'
response[:results][3][:msg].should ==
'Required parameter missing: create > create > ident'
response[:results][4][:msg].should ==
'Required parameter missing: create > create > voice'
response[:results][5][:msg].should ==
'Required parameter missing: create > create > email'
response[:results][6][:msg].should ==
'Required parameter missing: extension > extdata > legalDocument'
response[:results][0][:result_code].should == '2003'
response[:results][1][:result_code].should == '2003'
@ -51,19 +73,13 @@ describe 'EPP Contact', epp: true do
response[:results][3][:result_code].should == '2003'
response[:results][4][:result_code].should == '2003'
response[:results][5][:result_code].should == '2003'
response[:results][6][:result_code].should == '2003'
response[:results].count.should == 6
end
it 'successfully saves ident type' do
xml = { ident: { value: '1990-22-12', attrs: { type: 'birthday' } } }
epp_plain_request(create_contact_xml(xml), :xml)
Contact.last.ident_type.should == 'birthday'
response[:results].count.should == 7
end
it 'successfully creates a contact' do
response = epp_plain_request(create_contact_xml, :xml)
response = create_request
response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000'
@ -71,10 +87,10 @@ describe 'EPP Contact', epp: true do
@contact = Contact.last
@contact.registrar.should == @registrar1
# registrar1.api_users.should include(@contact.created_by)
# @contact.updated_by_id.should == nil
@registrar1.api_users.should include(@contact.creator)
@contact.ident.should == '37605030299'
@contact.address.street.should == '123 Example'
@contact.legal_documents.count.should == 1
log = ApiLog::EppLog.last
log.request_command.should == 'create'
@ -84,8 +100,19 @@ describe 'EPP Contact', epp: true do
log.api_user_registrar.should == 'registrar1'
end
it 'successfully saves ident type' do
response = create_request(
{ ident: { value: '1990-22-12', attrs: { type: 'birthday' } } }
)
response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000'
Contact.last.ident_type.should == 'birthday'
end
it 'successfully adds registrar' do
response = epp_plain_request(create_contact_xml, :xml)
response = create_request
response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000'
@ -94,7 +121,7 @@ describe 'EPP Contact', epp: true do
end
it 'returns result data upon success' do
response = epp_plain_request(create_contact_xml, :xml)
response = create_request
response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000'
@ -106,52 +133,6 @@ describe 'EPP Contact', epp: true do
# 5 seconds for what-ever weird lag reasons might happen
cr_date.text.to_time.should be_within(5).of(Time.now)
end
it 'creates disclosure data' do
xml = {
disclose: { value: {
voice: { value: '' },
addr: { value: '' },
name: { value: '' },
org_name: { value: '' },
email: { value: '' },
fax: { value: '' }
}, attrs: { flag: '1' }
}
}
response = epp_plain_request(create_contact_xml(xml), :xml)
response[:result_code].should == '1000'
@contact = Contact.last
@contact.disclosure.name.should == true
@contact.disclosure.org_name.should == true
@contact.disclosure.phone.should == true
@contact.disclosure.fax.should == true
@contact.disclosure.email.should == true
@contact.disclosure.address.should == true
end
it 'creates disclosure data merging with defaults' do
xml = {
disclose: { value: {
voice: { value: '' },
addr: { value: '' }
}, attrs: { flag: '1' }
}
}
response = epp_plain_request(create_contact_xml(xml), :xml)
response[:result_code].should == '1000'
@contact = Contact.last
@contact.disclosure.name.should == nil
@contact.disclosure.org_name.should == nil
@contact.disclosure.phone.should == true
@contact.disclosure.fax.should == nil
@contact.disclosure.email.should == nil
@contact.disclosure.address.should == true
end
end
context 'update command' do
@ -167,130 +148,167 @@ describe 'EPP Contact', epp: true do
)
end
it 'fails if request is invalid' do
xml = @epp_xml.update
response = epp_plain_request(xml, :xml) # epp_request('contacts/update_missing_attr.xml')
def update_request(overwrites = {})
defaults = {
id: { value: 'asd123123er' },
authInfo: { pw: { value: 'password' } },
chg: {
postalInfo: {
name: { value: 'John Doe Edited' }
},
voice: { value: '+372.7654321' },
email: { value: 'edited@example.example' },
disclose: {
value: {
voice: { value: '' },
email: { value: '' }
}, attrs: { flag: '0' }
}
}
}
update_xml = @epp_xml.update(defaults.deep_merge(overwrites), @legal_document)
epp_plain_request(update_xml, :xml)
end
it 'fails if request is invalid' do
response = epp_plain_request(@epp_xml.update, :xml)
response[:results][0][:msg].should ==
'Required parameter missing: add, rem or chg'
response[:results][0][:result_code].should == '2003'
response[:results][0][:msg].should == 'Required parameter missing: add, rem or chg'
response[:results][1][:msg].should ==
'Required parameter missing: update > update > id'
response[:results][1][:result_code].should == '2003'
response[:results][1][:msg].should == 'Required parameter missing: id'
response[:results].count.should == 2
response[:results][2][:msg].should ==
'Required parameter missing: update > update > authInfo > pw'
response[:results][2][:result_code].should == '2003'
response[:results][3][:msg].should ==
'Required parameter missing: extension > extdata > legalDocument'
response[:results][3][:result_code].should == '2003'
response[:results].count.should == 4
end
it 'returns error if obj doesnt exist' do
response = update_request({ id: { value: 'not-exists' } })
response[:msg].should == 'Object does not exist'
response[:result_code].should == '2303'
response[:results].count.should == 1
end
it 'is succesful' do
response = update_request({ id: { value: 'sh8013' } })
response[:msg].should == 'Command completed successfully'
@contact.reload
@contact.name.should == 'John Doe Edited'
@contact.email.should == 'edited@example.example'
end
it 'fails with wrong authentication info' do
login_as :registrar2 do
response = epp_plain_request(update_contact_xml({ id: { value: 'sh8013' } }), :xml)
expect(response[:msg]).to eq('Authorization error')
expect(response[:result_code]).to eq('2201')
response = update_request({ id: { value: 'sh8013' } })
response[:msg].should == 'Authorization error'
response[:result_code].should == '2201'
end
end
it 'is succesful' do
response = epp_plain_request(update_contact_xml({ id: { value: 'sh8013' } }), :xml)
response[:msg].should == 'Command completed successfully'
@contact.reload
@contact.name.should == 'John Doe Edited'
@contact.email.should == 'edited@example.example'
end
it 'returns phone and email error' do
xml = {
response = update_request({
id: { value: 'sh8013' },
chg: {
voice: { value: '123213' },
email: { value: 'aaa' }
email: { value: 'wrong' }
}
}
response = epp_plain_request(update_contact_xml(xml), :xml)
})
response[:results][0][:msg].should == 'Phone nr is invalid'
response[:results][0][:result_code].should == '2005'
response[:results][1][:msg].should == 'Email is invalid'
response[:results][1][:result_code].should == '2005'
end
it 'updates disclosure items' do
Fabricate(
:contact,
code: 'sh8013disclosure',
auth_info: '2fooBAR',
registrar: @registrar1,
# created_by_id: ApiUser.first.id,
disclosure: Fabricate(:contact_disclosure, phone: true, email: true))
xml = {
id: { value: 'sh8013disclosure' },
authInfo: { pw: { value: '2fooBAR' } }
}
@response = epp_plain_request(update_contact_xml(xml), :xml)
@response[:results][0][:msg].should == 'Command completed successfully'
@response[:results][0][:result_code].should == '1000'
Contact.last.disclosure.phone.should == false
Contact.last.disclosure.email.should == false
end
end
context 'delete command' do
it 'fails if request is invalid' do
xml = @epp_xml.delete({ uid: { value: '23123' } })
response = epp_plain_request(xml, :xml)
before do
@contact = Fabricate(:contact, registrar: @registrar1)
end
response[:results][0][:msg].should == 'Required parameter missing: id'
def delete_request(overwrites = {})
defaults = {
id: { value: @contact.code },
authInfo: { pw: { value: @contact.auth_info } }
}
delete_xml = @epp_xml.delete(defaults.deep_merge(overwrites), @legal_document)
epp_plain_request(delete_xml, :xml)
end
it 'fails if request is invalid' do
response = epp_plain_request(@epp_xml.delete, :xml)
response[:results][0][:msg].should ==
'Required parameter missing: delete > delete > id'
response[:results][0][:result_code].should == '2003'
response[:results][1][:msg].should ==
'Required parameter missing: delete > delete > authInfo > pw'
response[:results][1][:result_code].should == '2003'
response[:results][2][:msg].should ==
'Required parameter missing: extension > extdata > legalDocument'
response[:results][2][:result_code].should == '2003'
response[:results].count.should == 3
end
it 'returns error if obj doesnt exist' do
response = delete_request({ id: { value: 'not-exists' } })
response[:msg].should == 'Object does not exist'
response[:result_code].should == '2303'
response[:results].count.should == 1
end
it 'deletes contact' do
@contact_deleted =
# Fabricate(:contact, code: 'dwa1234', created_by_id: ApiUser.first.id, registrar: registrar1)
Fabricate(:contact, code: 'dwa1234', registrar: @registrar1)
response = epp_plain_request(delete_contact_xml({ id: { value: 'dwa1234' } }), :xml)
response = delete_request
response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000'
response[:clTRID].should == 'ABC-12345'
Contact.find_by_id(@contact_deleted.id).should == nil
end
it 'returns error if obj doesnt exist' do
response = epp_plain_request(delete_contact_xml, :xml)
response[:msg].should == 'Object does not exist'
response[:result_code].should == '2303'
Contact.find_by_id(@contact.id).should == nil
end
it 'fails if contact has associated domain' do
Fabricate(
:domain,
registrar: @registrar1,
owner_contact: Fabricate(
:contact,
code: 'dwa1234',
# created_by_id: registrar1.id,
registrar: @registrar1)
)
Domain.last.owner_contact.address.present?.should == true
response = epp_plain_request(delete_contact_xml({ id: { value: 'dwa1234' } }), :xml)
@domain = Fabricate(:domain, registrar: @registrar1, owner_contact: @contact)
@domain.owner_contact.address.present?.should == true
response = delete_request
response[:msg].should == 'Object association prohibits operation'
response[:result_code].should == '2305'
response[:results].count.should == 1
Domain.last.owner_contact.present?.should == true
@domain.owner_contact.present?.should == true
end
it 'fails with wrong authentication info' do
login_as :registrar2 do
response = delete_request
response[:msg].should == 'Authorization error'
response[:result_code].should == '2201'
response[:results].count.should == 1
end
end
end
context 'check command' do
it 'fails if request is invalid' do
xml = @epp_xml.check({ uid: { value: '123asde' } })
response = epp_plain_request(xml, :xml)
def check_request(overwrites = {})
defaults = {
id: { value: @contact.code },
authInfo: { pw: { value: @contact.auth_info } }
}
xml = @epp_xml.check(defaults.deep_merge(overwrites))
epp_plain_request(xml, :xml)
end
response[:results][0][:msg].should == 'Required parameter missing: id'
it 'fails if request is invalid' do
response = epp_plain_request(@epp_xml.check, :xml)
response[:results][0][:msg].should == 'Required parameter missing: check > check > id'
response[:results][0][:result_code].should == '2003'
response[:results].count.should == 1
end
@ -312,132 +330,74 @@ describe 'EPP Contact', epp: true do
end
end
# context 'info command' do
# before :all do
# @registrar1_contact = Fabricate(:contact, code: 'info-4444', registrar: @registrar1,
# name: 'Johnny Awesome', address: Fabricate(:address))
# end
context 'info command' do
before :all do
@registrar1_contact = Fabricate(
:contact, code: 'info-4444', registrar: @registrar1,
name: 'Johnny Awesome', address: Fabricate(:address))
end
# fit 'return info about contact' do
# login_as :registrar2 do
# xml = @epp_xml.info(id: { value: @registrar1_contact.code })
# response = epp_plain_request(xml, :xml)
# response[:msg].should == 'Command completed successfully'
# response[:result_code].should == '1000'
def info_request(overwrites = {})
defaults = {
id: { value: @contact.code },
authInfo: { pw: { value: @contact.auth_info } }
}
xml = @epp_xml.info(defaults.deep_merge(overwrites))
epp_plain_request(xml, :xml)
end
# contact = response[:parsed].css('resData chkData')
# contact.css('name').first.text.should == 'Johnny Awesome'
# end
# end
it 'fails if request invalid' do
response = epp_plain_request(@epp_xml.info, :xml)
response[:results][0][:msg].should ==
'Required parameter missing: info > info > id'
response[:results][0][:result_code].should == '2003'
response[:results].count.should == 1
end
# it 'fails if request invalid' do
# response = epp_plain_request(@epp_xml.info({ wrongid: { value: '123123' } }), :xml)
# response[:results][0][:msg].should == 'Required parameter missing: id'
# response[:results][0][:result_code].should == '2003'
# response[:results].count.should == 1
# end
it 'returns error when object does not exist' do
response = info_request({ id: { value: 'no-contact' } })
response[:msg].should == 'Object does not exist'
response[:result_code].should == '2303'
response[:results][0][:value].should == 'no-contact'
response[:results].count.should == 1
end
# it 'returns error when object does not exist' do
# response = epp_plain_request(info_contact_xml({ id: { value: 'no-contact' } }), :xml)
# response[:msg].should == 'Object does not exist'
# response[:result_code].should == '2303'
# response[:results][0][:value].should == 'no-contact'
# end
it 'return info about contact' do
response = info_request({ id: { value: @registrar1_contact.code } })
response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000'
# # it 'returns auth error for non-owner with wrong password' do
# # @contact = Fabricate(:contact,
# # registrar: registrar2, code: 'info-4444', name: 'Johnny Awesome', auth_info: 'asde',
# # address: Fabricate(:address), disclosure: Fabricate(:contact_disclosure, name: false))
contact = response[:parsed].css('resData chkData')
contact.css('name').first.text.should == 'Johnny Awesome'
end
# # xml = @epp_xml.info({ id: { value: @contact.code }, authInfo: { pw: { value: 'asdesde' } } })
# # response = epp_plain_request(xml, :xml, :registrar1)
it 'returns no authorization error for wrong password when owner' do
response = info_request({ authInfo: { pw: { value: 'wrong-pw' } } })
# # expect(response[:result_code]).to eq('2200')
# # expect(response[:msg]).to eq('Authentication error')
# # end
response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000'
response[:results].count.should == 1
end
# context 'about disclose' do
# it 'discloses items with wrong password when queried by owner' do
# @contact = Fabricate(:contact,
# registrar: registrar1, code: 'info-4444',
# name: 'Johnny Awesome', auth_info: 'asde',
# address: Fabricate(:address), disclosure: Fabricate(:contact_disclosure, name: false))
it 'returns no authorization error for wrong user but correct pw' do
login_as :registrar2 do
response = info_request
# xml = @epp_xml.info({ id: { value: @contact.code } })
# login_as :registrar1 do
# response = epp_plain_request(xml, :xml)
# contact = response[:parsed].css('resData chkData')
response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000'
response[:results].count.should == 1
end
end
# expect(response[:result_code]).to eq('1000')
# expect(response[:msg]).to eq('Command completed successfully')
# expect(contact.css('name').first.text).to eq('Johnny Awesome')
# end
# end
# it 'doesn\'t disclose items to non-owner with right password' do
# @contact = Fabricate(:contact, registrar: registrar2, code: 'info-4444',
# name: 'Johnny Awesome', auth_info: 'password',
# address: Fabricate(:address), disclosure: Fabricate(:contact_disclosure, name: false))
# xml = @epp_xml.info({ id: { value: @contact.code }, authInfo: { pw: { value: 'password' } } })
# response = epp_plain_request(xml, :xml, :registrar1)
# contact = response[:parsed].css('resData chkData')
# expect(response[:result_code]).to eq('1000')
# expect(response[:msg]).to eq('Command completed successfully')
# expect(contact.css('chkData postalInfo name').first).to eq(nil)
# end
# it 'discloses items to owner' do
# @contact = Fabricate(:contact, registrar: registrar1, code: 'info-4444', name: 'Johnny Awesome',
# auth_info: 'password',
# address: Fabricate(:address), disclosure: Fabricate(:contact_disclosure, name: false))
# xml = @epp_xml.info({ id: { value: @contact.code } })
# response = epp_plain_request(xml, :xml, :registrar1)
# contact = response[:parsed].css('resData chkData')
# expect(response[:result_code]).to eq('1000')
# expect(response[:msg]).to eq('Command completed successfully')
# expect(contact.css('name').first.text).to eq('Johnny Awesome')
# end
# it 'doesn\'t disclose private elements' do
# Fabricate(:contact, code: 'info-4444', auth_info: '2fooBAR', registrar: registrar2,
# disclosure: Fabricate(:contact_disclosure, name: true, email: false, phone: false))
# xml = @epp_xml.info({ id: { value: 'info-4444' }, authInfo: { pw: { value: '2fooBAR' } } })
# response = epp_plain_request(xml, :xml, :registrar1)
# contact = response[:parsed].css('resData chkData')
# expect(response[:result_code]).to eq('1000')
# expect(contact.css('chkData phone')).to eq(contact.css('chkData disclose phone'))
# expect(contact.css('chkData phone').count).to eq(1)
# expect(contact.css('chkData email')).to eq(contact.css('chkData disclose email'))
# expect(contact.css('chkData email').count).to eq(1)
# expect(contact.css('postalInfo name').present?).to be(true)
# end
# end
# it 'does not display unassociated object without password' do
# xml = @epp_xml.info(id: { value: @registrar1_contact.code })
# response = epp_plain_request(xml, :xml, :registrar2)
# expect(response[:result_code]).to eq('2003')
# expect(response[:msg]).to eq('Required parameter missing: pw')
# end
# it 'does not display unassociated object with wrong password' do
# login_as :registrar2
# xml = @epp_xml.info(id: { value: @registrar1_contact.code },
# authInfo: { pw: { value: 'wrong-pw' } })
# response = epp_plain_request(xml, :xml)
# response[:msg].should == 'Authentication error'
# response[:result_code].should == '2200'
# end
# end
it 'returns authorization error for wrong user and wrong pw' do
login_as :registrar2 do
response = info_request({ authInfo: { pw: { value: 'wrong-pw' } } })
response[:msg].should == 'Authorization error'
response[:result_code].should == '2201'
response[:results].count.should == 1
end
end
end
context 'renew command' do
it 'returns 2101-unimplemented command' do
@ -448,4 +408,20 @@ describe 'EPP Contact', epp: true do
end
end
end
def check_multiple_contacts_xml
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<check>
<contact:check
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
<contact:id>check-1234</contact:id>
<contact:id>check-4321</contact:id>
</contact:check>
</check>
<clTRID>ABC-12345</clTRID>
</command>
</epp>'
end
end

View file

@ -206,8 +206,16 @@ describe 'EPP Domain', epp: true do
it 'does not create domain without nameservers' do
xml = domain_create_xml(ns: [])
response = epp_plain_request(xml, :xml)
response[:result_code].should == '2003'
response[:msg].should == 'Required parameter missing: create > create > ns > hostAttr'
response[:results][0][:msg].should ==
'Required parameter missing: create > create > ns'
response[:results][0][:result_code].should == '2003'
response[:results][1][:msg].should ==
'Required parameter missing: create > create > ns > hostAttr'
response[:results][1][:result_code].should == '2003'
response[:results].count.should == 2
end
it 'does not create domain with too many nameservers' do
@ -294,8 +302,8 @@ describe 'EPP Domain', epp: true do
xml = domain_create_xml(period_value: 365, period_unit: 'd')
response = epp_plain_request(xml, :xml)
response[:result_code].should == '1000'
response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000'
Domain.first.valid_to.should == Date.today + 1.year
end

View file

@ -1,6 +1,6 @@
# currently identity code generation not implemented,
# currently identity code generation not implemented,
# thus default user is FI for a while
Fabricator(:user) do
Fabricator(:admin_user) do
username 'gitlab'
password 'ghyt9e4fu'
email 'info@gitlab.eu'
@ -8,7 +8,7 @@ Fabricator(:user) do
roles ['admin']
end
Fabricator(:ee_user, from: :user) do
Fabricator(:ee_user, from: :admin_user) do
identity_code "45002036517"
country_code 'EE'
roles ['admin']

View file

@ -1,5 +1,5 @@
Fabricator(:domain) do
name { "#{Faker::Internet.domain_word}.ee" }
name { "fabricate_name#{rand(1_000_000)}.ee" }
valid_to Date.new(2014, 8, 7)
period 1
period_unit 'y'

View file

@ -1,7 +1,7 @@
require 'rails_helper'
feature 'Setting management', type: :feature do
let(:user) { Fabricate(:user, username: 'user1', identity_code: '37810013087') }
let(:user) { Fabricate(:admin_user, username: 'user1', identity_code: '37810013087') }
background { create_settings }

View file

@ -1,10 +1,10 @@
require 'rails_helper'
require 'cancan/matchers'
describe User do
describe AdminUser do
context 'with invalid attribute' do
before :all do
@user = User.new
@user = AdminUser.new
end
it 'should not be valid' do
@ -24,7 +24,7 @@ describe User do
context 'with valid attributes' do
before :all do
@user = Fabricate(:user)
@user = Fabricate(:admin_user)
end
it 'should be valid' do
@ -33,7 +33,7 @@ describe User do
end
# it 'should be valid twice' do
# @user = Fabricate(:user)
# @user = Fabricate(:admin_user)
# @user.valid?
# @user.errors.full_messages.should match_array([])
# end
@ -54,7 +54,7 @@ describe User do
# let(:user) { nil }
# context 'when user is admin' do
# let(:user) { Fabricate(:user) }
# let(:user) { Fabricate(:admin_user) }
# it { should be_able_to(:manage, Domain.new) }
# it { should be_able_to(:manage, Contact.new) }

View file

@ -1,91 +0,0 @@
require 'rails_helper'
describe ContactDisclosure do
it { should belong_to(:contact) }
context 'about class' do
it 'should have versioning enabled?' do
ContactDisclosure.paper_trail_enabled_for_model?.should == true
end
it 'should have custom log prexied table name for versions table' do
ContactDisclosureVersion.table_name.should == 'log_contact_disclosures'
end
end
context 'with invalid attribute' do
before :all do
@contact_disclosure = ContactDisclosure.new
end
it 'should not be valid' do
@contact_disclosure.valid?
@contact_disclosure.errors.full_messages.should match_array([
])
end
it 'should not have any versions' do
@contact_disclosure.versions.should == []
end
end
context 'with valid attributes' do
before :all do
@contact_disclosure = Fabricate(:contact_disclosure)
end
it 'should be valid' do
@contact_disclosure.valid?
@contact_disclosure.errors.full_messages.should match_array([])
end
it 'should be valid twice' do
@contact_disclosure = Fabricate(:contact_disclosure)
@contact_disclosure.valid?
@contact_disclosure.errors.full_messages.should match_array([])
end
it 'should have one version' do
with_versioning do
@contact_disclosure.versions.should == []
@contact_disclosure.name = false
@contact_disclosure.save
@contact_disclosure.errors.full_messages.should match_array([])
@contact_disclosure.versions.size.should == 1
end
end
end
end
describe '.extract_attributes' do
it 'should return empty hash for empty arguments' do
result = ContactDisclosure.extract_attributes(Nokogiri::XML::Document.new)
expect(result).to eq({})
end
it 'should return empty hash if no disclosure' do
parsed_frame = Nokogiri::XML(create_contact_xml).remove_namespaces!
result = ContactDisclosure.extract_attributes(parsed_frame)
expect(result).to eq({})
end
# TODO: remodel create contact xml to support disclosure
it 'should return disclosure has if disclosure' do
epp_xml = EppXml::Contact.new
xml = epp_xml.create(
{
disclose: { value: {
voice: { value: '' },
addr: { value: '' },
name: { value: '' },
org_name: { value: '' },
email: { value: '' },
fax: { value: '' }
}, attrs: { flag: '0' }
} })
parsed_frame = Nokogiri::XML(xml).remove_namespaces!
result = ContactDisclosure.extract_attributes(parsed_frame)
expect(result).to eq({ phone: '0', email: '0', fax: '0', address: '0', name: '0', org_name: '0' })
end
end

View file

@ -39,11 +39,11 @@ describe Contact do
end
it 'should not have creator' do
@contact.cr_id.should == nil
@contact.creator.should == nil
end
it 'should not have updater' do
@contact.up_id.should == nil
@contact.updator.should == nil
end
it 'phone should return false' do
@ -179,57 +179,18 @@ describe Contact do
end
context 'with creator' do
before :all do
# @contact.created_by = @api_user
end
# TODO: change cr_id to something else
it 'should return username of creator' do
# @contact.cr_id.should == 'gitlab'
end
end
context 'with updater' do
before :all do
# @contact.updated_by = @api_user
# @contact.creator_str.should == 'gitlab'
end
# TODO: change up_id to something else
it 'should return username of updater' do
# @contact.up_id.should == 'gitlab'
# @contact.updator.should == 'gitlab'
end
end
end
end
end
# TODO: investigate it a bit more
# describe Contact, '#relations_with_domain?' do
# context 'with relation' do
# before :all do
# create_settings
# Fabricate(:domain)
# @contact = Fabricate(:contact)
# end
# it 'should have relation with domain' do
# @contact.relations_with_domain?.should == true
# end
# end
# end
describe Contact, '.extract_params' do
it 'returns params hash'do
ph = { id: '123123', email: 'jdoe@example.com', authInfo: { pw: 'asde' },
postalInfo: { name: 'fred', addr: { cc: 'EE' } } }
Contact.extract_attributes(ph).should == {
name: 'fred',
email: 'jdoe@example.com'
}
end
end
describe Contact, '.check_availability' do
before do
Fabricate(:contact, code: 'asd12')

View file

@ -73,14 +73,14 @@ describe Domain do
it 'should return api_creator when created by api user' do
with_versioning do
@user = Fabricate(:user)
@user = Fabricate(:admin_user)
@api_user = Fabricate(:api_user)
@user.id.should == 1
@api_user.id.should == 1
::PaperTrail.whodunnit = '1-api-testuser'
@api_user.id.should == 2
::PaperTrail.whodunnit = '2-api-testuser'
@domain = Fabricate(:domain)
@domain.creator_str.should == '1-api-testuser'
@domain.creator_str.should == '2-api-testuser'
@domain.creator.should == @api_user
@domain.creator.should_not == @user
@ -89,14 +89,14 @@ describe Domain do
it 'should return api_creator when created by api user' do
with_versioning do
@user = Fabricate(:user)
@user = Fabricate(:admin_user)
@api_user = Fabricate(:api_user)
@user.id.should == 2
@api_user.id.should == 2
::PaperTrail.whodunnit = '2-testuser'
@user.id.should == 3
@api_user.id.should == 4
::PaperTrail.whodunnit = '3-testuser'
@domain = Fabricate(:domain)
@domain.creator_str.should == '2-testuser'
@domain.creator_str.should == '3-testuser'
@domain.creator.should == @user
@domain.creator.should_not == @api_user

View file

@ -112,7 +112,7 @@ module Epp
end
def next_domain_name
"example#{@uniq_no.call}.ee"
"example#{rand(100000000)}.ee"
end
### REQUEST TEMPLATES ###

View file

@ -1,87 +0,0 @@
module EppContactXmlHelper
def create_contact_xml(xml_params = {})
defaults = {
postalInfo: {
name: { value: 'John Doe' },
addr: {
street: { value: '123 Example' },
city: { value: 'Tallinn' },
cc: { value: 'EE' }
}
},
voice: { value: '+372.1234567' },
email: { value: 'test@example.example' },
ident: { value: '37605030299', attrs: { type: 'op' } }
}
xml_params = defaults.deep_merge(xml_params)
epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
epp_xml.create(xml_params)
end
def update_contact_xml(xml_params = {})
defaults = {
id: { value: 'asd123123er' },
authInfo: { pw: { value: 'password' } },
chg: {
postalInfo: {
name: { value: 'John Doe Edited' }
},
voice: { value: '+372.7654321' },
email: { value: 'edited@example.example' },
disclose: {
value: {
voice: { value: '' },
email: { value: '' }
}, attrs: { flag: '0' }
}
}
}
xml_params = defaults.deep_merge(xml_params)
epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
epp_xml.update(xml_params)
end
def delete_contact_xml(xml_params = {})
defaults = { id: { value: 'sh8012' } }
xml_params = defaults.deep_merge(xml_params)
epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
epp_xml.delete(xml_params)
end
def info_contact_xml(xml_params = {})
defaults = { id: { value: 'sh8012' }, authInfo: { pw: { value: 'password' } } }
xml_params = defaults.deep_merge(xml_params)
epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
epp_xml.info(xml_params)
end
def check_contact_xml(xml_params = {})
defaults = {
id: { value: 'ad123c3' }
}
xml_params = defaults.deep_merge(xml_params)
epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
epp_xml.check(xml_params)
end
def check_multiple_contacts_xml
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<check>
<contact:check
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
<contact:id>check-1234</contact:id>
<contact:id>check-4321</contact:id>
</contact:check>
</check>
<clTRID>ABC-12345</clTRID>
</command>
</epp>'
end
end
RSpec.configure do |c|
c.include EppContactXmlHelper
end