diff --git a/app/controllers/concerns/epp/common.rb b/app/controllers/concerns/epp/common.rb index c7e138833..952cdd4ca 100644 --- a/app/controllers/concerns/epp/common.rb +++ b/app/controllers/concerns/epp/common.rb @@ -8,8 +8,8 @@ module Epp::Common included do protect_from_forgery with: :null_session - before_action :validate_request, only: [:proxy] - + before_action :validate_request + layout false helper_method :current_epp_user end @@ -108,7 +108,7 @@ module Epp::Common # rubocop: enable Style/PredicateName def validate_request - validation_method = "validate_#{OBJECT_TYPES[params_hash['epp']['xmlns:ns2']]}_#{params[:command]}_request" + validation_method = "validate_#{params[:action]}" return unless respond_to?(validation_method, true) handle_errors and return unless send(validation_method) end @@ -123,7 +123,7 @@ module Epp::Common request_object = OBJECT_TYPES[params_hash['epp']['xmlns:ns2']] if params[:frame] ApiLog::EppLog.create({ request: params[:raw_frame], - request_command: params[:command], + request_command: params[:action], request_successful: epp_errors.empty?, request_object: request_object, response: @response, diff --git a/app/controllers/epp/contacts_controller.rb b/app/controllers/epp/contacts_controller.rb new file mode 100644 index 000000000..ad46acc95 --- /dev/null +++ b/app/controllers/epp/contacts_controller.rb @@ -0,0 +1,9 @@ +class Epp::ContactsController < ApplicationController + protect_from_forgery with: :null_session + + def create + end + + def info + end +end diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb new file mode 100644 index 000000000..e66f455cc --- /dev/null +++ b/app/controllers/epp/domains_controller.rb @@ -0,0 +1,51 @@ +class Epp::DomainsController < ApplicationController + include Epp::Common + + def create + end + + def info + @domain = find_domain + handle_errors(@domain) and return unless @domain + render_epp_response '/epp/domains/info' + end + + def check + names = params[:parsed_frame].css('name').map(&:text) + @domains = Epp::EppDomain.check_availability(names) + render_epp_response '/epp/domains/check' + end + + private + + def validate_check + epp_request_valid?('name') + end + + def find_domain(secure = { secure: true }) + domain_name = params[:parsed_frame].css('name').text.strip.downcase + domain = Epp::EppDomain.find_by(name: domain_name) + + unless domain + epp_errors << { + code: '2303', + msg: I18n.t('errors.messages.epp_domain_not_found'), + value: { obj: 'name', val: domain_name } + } + return nil + end + + return domain if domain.auth_info == params[:parsed_frame].css('authInfo pw').text + + if (domain.registrar != current_epp_user.registrar && secure[:secure] == true) && + epp_errors << { + code: '2302', + msg: I18n.t('errors.messages.domain_exists_but_belongs_to_other_registrar'), + value: { obj: 'name', val: params[:parsed_frame].css('name').text.strip.downcase } + } + return nil + end + + domain + end +end diff --git a/config/application.rb b/config/application.rb index 8de7bca3d..bb5c0c8fc 100644 --- a/config/application.rb +++ b/config/application.rb @@ -30,9 +30,11 @@ module Registry config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb') config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')] - # Active Record used to suppresses errors raised within - # `after_rollback`/`after_commit` callbacks and only printed them to the logs. - # In the next version, these errors will no longer be suppressed. + config.autoload_paths << Rails.root.join('lib') + + # Active Record used to suppresses errors raised within + # `after_rollback`/`after_commit` callbacks and only printed them to the logs. + # In the next version, these errors will no longer be suppressed. # Instead, the errors will propagate normally just like in other Active Record callbacks. config.active_record.raise_in_transactional_callbacks = true diff --git a/config/routes.rb b/config/routes.rb index 8846b35b1..47cf3c287 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,32 @@ +class EppConstraint + OBJECT_TYPES = { + domain: { domain: 'urn:ietf:params:xml:ns:domain-1.0' }, + contact: { contact: 'urn:ietf:params:xml:ns:contact-1.0' } + } + + def initialize(type) + @type = type + end + + def matches?(request) + element = "//#{@type}:#{request.params[:action]}" + parsed_frame = Nokogiri::XML(request.params[:raw_frame]) + ret = parsed_frame.xpath("#{element}", OBJECT_TYPES[@type]).any? + request.params[:parsed_frame] = parsed_frame.remove_namespaces! if ret + ret + end +end + Rails.application.routes.draw do namespace(:epp) do + post 'command/info', to: 'domains#info', defaults: { format: :xml }, constraints: EppConstraint.new(:domain) + post 'command/info', to: 'contacts#info', defaults: { format: :xml }, constraints: EppConstraint.new(:contact) + + post 'command/check', to: 'domains#check', defaults: { format: :xml }, constraints: EppConstraint.new(:domain) + post 'command/check', to: 'contacts#check', defaults: { format: :xml }, constraints: EppConstraint.new(:contact) + match 'session/:command', to: 'sessions#proxy', defaults: { format: :xml }, via: [:get, :post] - match 'command/:command', to: 'commands#proxy', defaults: { format: :xml }, via: [:post, :get] + # match 'command/:command', to: 'commands#proxy', defaults: { format: :xml }, via: [:post, :get] get 'error/:command', to: 'errors#error', defaults: { format: :xml } end