From aaa0e89cfe10fead458f1b6999e385861b04e95c Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Wed, 23 Nov 2022 12:41:00 +0200 Subject: [PATCH] Added xml epp console required endpoints and sample xml files --- app/controllers/concerns/epp_requestable.rb | 57 +++++++++++++++++++ .../v1/registrar/xml_console_controller.rb | 55 ++++++++++++++++++ app/models/domain.rb | 1 - .../epp/sample_requests/contact/check.xml | 12 ++++ .../contact/check_multiple.xml | 14 +++++ .../epp/sample_requests/contact/create.xml | 32 +++++++++++ .../epp/sample_requests/contact/delete.xml | 22 +++++++ .../epp/sample_requests/contact/info.xml | 14 +++++ .../sample_requests/contact/update_chg.xml | 36 ++++++++++++ .../epp/sample_requests/domain/check.xml | 12 ++++ .../sample_requests/domain/client_hold.xml | 15 +++++ .../epp/sample_requests/domain/create.xml | 42 ++++++++++++++ .../epp/sample_requests/domain/delete.xml | 19 +++++++ app/views/epp/sample_requests/domain/info.xml | 15 +++++ .../epp/sample_requests/domain/renew.xml | 14 +++++ .../epp/sample_requests/domain/transfer.xml | 22 +++++++ .../epp/sample_requests/domain/update.xml | 54 ++++++++++++++++++ app/views/epp/sample_requests/poll/poll.xml | 7 +++ config/application.yml.sample | 7 +++ config/locales/en.yml | 3 + config/routes.rb | 11 +++- 21 files changed, 460 insertions(+), 4 deletions(-) create mode 100644 app/controllers/concerns/epp_requestable.rb create mode 100644 app/controllers/repp/v1/registrar/xml_console_controller.rb create mode 100644 app/views/epp/sample_requests/contact/check.xml create mode 100644 app/views/epp/sample_requests/contact/check_multiple.xml create mode 100644 app/views/epp/sample_requests/contact/create.xml create mode 100644 app/views/epp/sample_requests/contact/delete.xml create mode 100644 app/views/epp/sample_requests/contact/info.xml create mode 100644 app/views/epp/sample_requests/contact/update_chg.xml create mode 100644 app/views/epp/sample_requests/domain/check.xml create mode 100644 app/views/epp/sample_requests/domain/client_hold.xml create mode 100644 app/views/epp/sample_requests/domain/create.xml create mode 100644 app/views/epp/sample_requests/domain/delete.xml create mode 100644 app/views/epp/sample_requests/domain/info.xml create mode 100644 app/views/epp/sample_requests/domain/renew.xml create mode 100644 app/views/epp/sample_requests/domain/transfer.xml create mode 100644 app/views/epp/sample_requests/domain/update.xml create mode 100644 app/views/epp/sample_requests/poll/poll.xml diff --git a/app/controllers/concerns/epp_requestable.rb b/app/controllers/concerns/epp_requestable.rb new file mode 100644 index 000000000..8243bfa40 --- /dev/null +++ b/app/controllers/concerns/epp_requestable.rb @@ -0,0 +1,57 @@ +module EppRequestable + extend ActiveSupport::Concern + + included do + before_action :validate_epp_user, only: :create + end + + def create + result = server.request(request_params[:payload]) + render_success(data: { xml: result }) + rescue StandardError + handle_non_epp_errors(nil, I18n.t('errors.messages.epp_conn_error')) + end + + private + + def validate_epp_user + tag = current_user.username + password = current_user.plain_text_password + res = server.open_connection + unless Nokogiri::XML(res).css('greeting') + server.close_connection # just in case + handle_non_epp_errors(nil, I18n.t('errors.messages.failed_epp_conn')) + return + end + + ex = EppXml::Session.new(cl_trid_prefix: tag) + xml = ex.login(clID: { value: tag }, pw: { value: password }) + res = server.send_request(xml) + + if Nokogiri::XML(res).css('result').first['code'] != '1000' + handle_non_epp_errors(nil, Nokogiri::XML(res).css('result').text) + end + + server.close_connection + rescue OpenSSL::SSL::SSLError => e + Rails.logger.error "INVALID CERT: #{e}" + Rails.logger.error "INVALID CERT DEBUG INFO: epp_hostname: #{ENV['epp_hostname']}," \ + "port: #{ENV['epp_port']}, cert_path: #{ENV['cert_path']}, key_path: #{ENV['key_path']}" + handle_non_epp_errors(nil, I18n.t('errors.messages.invalid_cert')) + end + + def server + client_cert = File.read(ENV['cert_path']) + client_key = File.read(ENV['key_path']) + port = ENV['epp_port'] || 700 + @server ||= Epp::Server.new({ server: ENV['epp_hostname'], tag: current_user.username, + password: current_user.plain_text_password, + port: port, + cert: OpenSSL::X509::Certificate.new(client_cert), + key: OpenSSL::PKey::RSA.new(client_key) }) + end + + def request_params + params.require(:xml_console).permit(:payload) + end +end \ No newline at end of file diff --git a/app/controllers/repp/v1/registrar/xml_console_controller.rb b/app/controllers/repp/v1/registrar/xml_console_controller.rb new file mode 100644 index 000000000..f5d42423b --- /dev/null +++ b/app/controllers/repp/v1/registrar/xml_console_controller.rb @@ -0,0 +1,55 @@ +module Repp + module V1 + module Registrar + class XmlConsoleController < BaseController + include EppRequestable + + PREFS = %w[ + domain-ee + contact-ee + eis + epp-ee + ].freeze + + def load_xml + cl_trid = "#{current_user.username}-#{Time.zone.now.to_i}" + xml_dir_path = Rails.root.join('app/views/epp/sample_requests').to_s + xml = File.read("#{xml_dir_path}/#{params[:obj]}/#{params[:epp_action]}.xml") + xml = prepare_payload(xml, cl_trid) + + render_success(data: { xml: xml }) + end + + private + + def prepare_payload(xml, cl_trid) + PREFS.map do |pref| + xml = load_schema_by_prefix(pref, xml) + end + + xml.gsub!('ABC-12345', "#{cl_trid}") + xml + end + + def load_schema_by_prefix(pref, xml) + case pref + when 'epp-ee' + insert_prefix_and_version(xml, pref, '1.0') + when 'eis' + insert_prefix_and_version(xml, pref, '1.0') + when 'contact-ee' + insert_prefix_and_version(xml, pref, '1.1') + else + insert_prefix_and_version(xml, pref, '1.2') + end + end + + def insert_prefix_and_version(xml, pref, version) + xml.gsub!("\"#{pref}\"", + "\"#{Xsd::Schema.filename(for_prefix: pref.to_s, for_version: version)}\"") + xml + end + end + end + end +end \ No newline at end of file diff --git a/app/models/domain.rb b/app/models/domain.rb index 2c2b363fa..f770b623f 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -65,7 +65,6 @@ class Domain < ApplicationRecord statuses.include? DomainStatus::SERVER_REGISTRANT_CHANGE_PROHIBITED end - # NB! contacts, admin_contacts, tech_contacts are empty for a new record has_many :domain_contacts, dependent: :destroy has_many :contacts, through: :domain_contacts, source: :contact diff --git a/app/views/epp/sample_requests/contact/check.xml b/app/views/epp/sample_requests/contact/check.xml new file mode 100644 index 000000000..f4c10d8bd --- /dev/null +++ b/app/views/epp/sample_requests/contact/check.xml @@ -0,0 +1,12 @@ + + + + + + sh8013 + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/contact/check_multiple.xml b/app/views/epp/sample_requests/contact/check_multiple.xml new file mode 100644 index 000000000..bdcff03dd --- /dev/null +++ b/app/views/epp/sample_requests/contact/check_multiple.xml @@ -0,0 +1,14 @@ + + + + + + sh8013 + sh13 + vsdfvq + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/contact/create.xml b/app/views/epp/sample_requests/contact/create.xml new file mode 100644 index 000000000..fc60b8311 --- /dev/null +++ b/app/views/epp/sample_requests/contact/create.xml @@ -0,0 +1,32 @@ + + + + + + + Sillius Soddus + + 123 Example Dr. + Suite 100 + + Megaton + F3 + 201-33 + EE + + + +372.1234567 + example@test.example + + + + + 123 + + dGVzdCBmYWlsCg== + + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/contact/delete.xml b/app/views/epp/sample_requests/contact/delete.xml new file mode 100644 index 000000000..28b50af64 --- /dev/null +++ b/app/views/epp/sample_requests/contact/delete.xml @@ -0,0 +1,22 @@ + + + + + + sh8013 + + wrong-one + + + + + + + dGVzdCBmYWlsCg== + + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/contact/info.xml b/app/views/epp/sample_requests/contact/info.xml new file mode 100644 index 000000000..44e5d5a1e --- /dev/null +++ b/app/views/epp/sample_requests/contact/info.xml @@ -0,0 +1,14 @@ + + + + + + sh8013 + + Aas34fq + + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/contact/update_chg.xml b/app/views/epp/sample_requests/contact/update_chg.xml new file mode 100644 index 000000000..61ea43202 --- /dev/null +++ b/app/views/epp/sample_requests/contact/update_chg.xml @@ -0,0 +1,36 @@ + + + + + + sh8013 + + + John Doe + + 123 Example Dr. + Suite 100 + Dulles + VA + 20166-6503 + EE + + + +123.7035555555 + jdoe@example.com + + 2fooBAR + + + + + + + + dGVzdCBmYWlsCg== + + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/domain/check.xml b/app/views/epp/sample_requests/domain/check.xml new file mode 100644 index 000000000..06492bcfe --- /dev/null +++ b/app/views/epp/sample_requests/domain/check.xml @@ -0,0 +1,12 @@ + + + + + + example.ee + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/domain/client_hold.xml b/app/views/epp/sample_requests/domain/client_hold.xml new file mode 100644 index 000000000..68f0b778e --- /dev/null +++ b/app/views/epp/sample_requests/domain/client_hold.xml @@ -0,0 +1,15 @@ + + + + + + example.ee + + + + + + timo-1579351654 + + diff --git a/app/views/epp/sample_requests/domain/create.xml b/app/views/epp/sample_requests/domain/create.xml new file mode 100644 index 000000000..f57fcfe30 --- /dev/null +++ b/app/views/epp/sample_requests/domain/create.xml @@ -0,0 +1,42 @@ + + + + + + example.ee + 1 + + + ns1.example.net + + + ns2.example.net + 192.0.2.2 + 1080:0:0:0:8:800:200C:417A + + + jd1234 + sh8013 + sh8013 + sh801333 + + + + + + 257 + 3 + 8 + AwEAAddt2AkLfYGKgiEZB5SmIF8EvrjxNMH6HtxWEA4RJ9Ao6LCWheg8 + + + + + dGVzdCBmYWlsCg== + + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/domain/delete.xml b/app/views/epp/sample_requests/domain/delete.xml new file mode 100644 index 000000000..f47bb79eb --- /dev/null +++ b/app/views/epp/sample_requests/domain/delete.xml @@ -0,0 +1,19 @@ + + + + + + example.ee + + + + + + dGVzdCBmYWlsCg== + + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/domain/info.xml b/app/views/epp/sample_requests/domain/info.xml new file mode 100644 index 000000000..210396c3b --- /dev/null +++ b/app/views/epp/sample_requests/domain/info.xml @@ -0,0 +1,15 @@ + + + + + + example.ee + + 2fooBAR + + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/domain/renew.xml b/app/views/epp/sample_requests/domain/renew.xml new file mode 100644 index 000000000..6ef479468 --- /dev/null +++ b/app/views/epp/sample_requests/domain/renew.xml @@ -0,0 +1,14 @@ + + + + + + example.ee + 2014-08-07 + 1 + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/domain/transfer.xml b/app/views/epp/sample_requests/domain/transfer.xml new file mode 100644 index 000000000..f6ee87b79 --- /dev/null +++ b/app/views/epp/sample_requests/domain/transfer.xml @@ -0,0 +1,22 @@ + + + + + + example.ee + + 2BARfoo + + + + + + + dGVzdCBmYWlsCg== + + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/domain/update.xml b/app/views/epp/sample_requests/domain/update.xml new file mode 100644 index 000000000..c087245e7 --- /dev/null +++ b/app/views/epp/sample_requests/domain/update.xml @@ -0,0 +1,54 @@ + + + + + + example.ee + + + + ns1.example.com + + + ns2.example.com + + + mak21 + + + + + ns1.example.net + + + mak21 + + + mak21 + + newpw + + + + + + + + + 257 + 3 + 8 + 700b97b591ed27ec2590d19f06f88bba700b97b591ed27ec2590d19f + + + + + + dGVzdCBmYWlsCg== + + + + ABC-12345 + + diff --git a/app/views/epp/sample_requests/poll/poll.xml b/app/views/epp/sample_requests/poll/poll.xml new file mode 100644 index 000000000..5ffed010e --- /dev/null +++ b/app/views/epp/sample_requests/poll/poll.xml @@ -0,0 +1,7 @@ + + + + + ABC-12345 + + diff --git a/config/application.yml.sample b/config/application.yml.sample index dffeea5be..61bf6f223 100644 --- a/config/application.yml.sample +++ b/config/application.yml.sample @@ -61,6 +61,13 @@ contact_org_enabled: 'false' # System default for legal document types is: pdf,asice,sce,asics,scs,adoc,edoc,bdoc,ddoc,zip,rar,gz,tar,7z,odt,doc,docx # legal_document_types: "pdf,asice,sce,asics,scs,adoc,edoc,bdoc,ddoc,zip,rar,gz,tar,7z,odt,doc,docx" +# +# REGISTRAR configuration +# +epp_port: '700' +cert_path: '/opt/ca/certs/webclient.crt.pem' +key_path: '/opt/ca/private/webclient.key.pem' +epp_hostname: 'epp_proxy' repp_url: 'http://epp:3000/repp/v1/' # Estonian Company Register diff --git a/config/locales/en.yml b/config/locales/en.yml index d42efd0a5..7a6fa2eb9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -187,6 +187,9 @@ en: required_ident_attribute_missing: "Required ident attribute missing: %{key}" invalid_iso31661_alpha2: does not conform to ISO 3166-1 alpha-2 standard invalid_iso8601_date: has invalid date format YYYY-MM-DD (ISO 8601) + invalid_cert: 'Invalid certificate' + failed_epp_conn: 'Failed to open connection to EPP server!' + epp_conn_error: 'CONNECTION ERROR - Is the EPP server running?' code: 'Code' action: 'Action' diff --git a/config/routes.rb b/config/routes.rb index 21fc16224..d8d52f322 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -106,7 +106,7 @@ Rails.application.routes.draw do end end namespace :registrar do - resources :notifications, only: [:index, :show, :update] do + resources :notifications, only: %i[index show update] do collection do get '/all_notifications', to: 'notifications#all_notifications' end @@ -128,6 +128,11 @@ Rails.application.routes.draw do post '/tara_callback', to: 'auth#tara_callback' end end + resource :xml_console, controller: 'xml_console', only: %i[create] do + collection do + get 'load_xml' + end + end end resources :domains, constraints: { id: /.*/ } do resources :nameservers, only: %i[index create destroy], constraints: { id: /.*/ }, controller: 'domains/nameservers' @@ -136,8 +141,8 @@ Rails.application.routes.draw do resources :renew, only: %i[create], constraints: { id: /.*/ }, controller: 'domains/renews' resources :transfer, only: %i[create], constraints: { id: /.*/ }, controller: 'domains/transfers' resources :statuses, only: %i[update destroy], constraints: { id: /.*/ }, controller: 'domains/statuses' - match "dnssec", to: "domains/dnssec#destroy", via: "delete", defaults: { id: nil } - match "contacts", to: "domains/contacts#destroy", via: "delete", defaults: { id: nil } + match 'dnssec', to: 'domains/dnssec#destroy', via: 'delete', defaults: { id: nil } + match 'contacts', to: 'domains/contacts#destroy', via: 'delete', defaults: { id: nil } collection do get ':id/transfer_info', to: 'domains#transfer_info', constraints: { id: /.*/ } post 'transfer', to: 'domains#transfer'