diff --git a/app/controllers/concerns/epp/common.rb b/app/controllers/concerns/epp/common.rb index d43b82190..f5cb2e33e 100644 --- a/app/controllers/concerns/epp/common.rb +++ b/app/controllers/concerns/epp/common.rb @@ -63,6 +63,19 @@ module Epp::Common @errors += obj.errors[:epp_errors] end + def epp_request_valid?(*selectors) + selectors.each do |selector| + el = parsed_frame.css(selector).first + next unless el + epp_errors << { + code: '2003', + msg: I18n.t('errors.messages.required_parameter_missing', key: el.name) + } unless el.text.present? + end + + epp_errors.empty? + end + def xml_attrs_present?(ph, attributes) attributes.each do |x| epp_errors << { diff --git a/app/helpers/epp/keyrelay_helper.rb b/app/helpers/epp/keyrelay_helper.rb index f1b12ae5c..f879621f4 100644 --- a/app/helpers/epp/keyrelay_helper.rb +++ b/app/helpers/epp/keyrelay_helper.rb @@ -1,30 +1,54 @@ module Epp::KeyrelayHelper + # rubocop: disable Metrics/PerceivedComplexity + # rubocop: disable Metrics/CyclomaticComplexity + def keyrelay - domain = Domain.find_by(name: parsed_frame.css('name').text) + handle_errors and return unless validate_keyrelay_request - abs_datetime = parsed_frame.css('absolute').text - abs_datetime = abs_datetime.to_date if abs_datetime + @domain = find_domain - kr = domain.keyrelays.create( - domain: domain, - pa_date: Time.now, - key_data_flags: parsed_frame.css('flags').text, - key_data_protocol: parsed_frame.css('protocol').text, - key_data_alg: parsed_frame.css('alg').text, - key_data_public_key: parsed_frame.css('pubKey').text, - auth_info_pw: parsed_frame.css('pw').text, - expiry_relative: parsed_frame.css('relative').text, - expiry_absolute: abs_datetime, - requester: current_epp_user.registrar, - accepter: domain.registrar - ) - - domain.registrar.messages.create( - body: 'Key Relay action completed successfully.', - attached_obj_type: kr.class.to_s, - attached_obj_id: kr.id - ) + handle_errors(@domain) and return unless @domain + handle_errors(@domain) and return unless @domain.authenticate(parsed_frame.css('pw').text) + handle_errors(@domain) and return unless @domain.keyrelay(parsed_frame, current_epp_user.registrar) render '/epp/shared/success' end + # rubocop: enable Metrics/PerceivedComplexity + # rubocop: enable Metrics/CyclomaticComplexity + + private + + def validate_keyrelay_request + epp_request_valid?('pubKey', 'flags', 'protocol', 'algorithm', 'name', 'pw') + + if parsed_frame.css('relative').text.present? && parsed_frame.css('absolute').text.present? + epp_errors << { + code: '2003', + msg: I18n.t('only_one_parameter_allowed', param_1: 'relative', param_2: 'absolute') + } + elsif parsed_frame.css('relative').text.empty? && parsed_frame.css('absolute').text.empty? + epp_errors << { + code: '2003', + msg: I18n.t('required_parameter_missing_choice', param_1: 'relative', param_2: 'absolute') + } + end + + epp_errors.empty? + end + + def find_domain + domain_name = 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 + + domain + end end diff --git a/app/models/epp/epp_domain.rb b/app/models/epp/epp_domain.rb index a7f27314d..ea768824a 100644 --- a/app/models/epp/epp_domain.rb +++ b/app/models/epp/epp_domain.rb @@ -357,6 +357,38 @@ class Epp::EppDomain < Domain save(validate: false) end + def keyrelay(parsed_frame, requester) + if registrar == requester + errors.add(:base, :domain_already_belongs_to_the_querying_registrar) and return false + end + + abs_datetime = parsed_frame.css('absolute').text + abs_datetime = abs_datetime.to_date if abs_datetime + + transaction do + kr = keyrelays.create( + pa_date: Time.now, + key_data_flags: parsed_frame.css('flags').text, + key_data_protocol: parsed_frame.css('protocol').text, + key_data_alg: parsed_frame.css('alg').text, + key_data_public_key: parsed_frame.css('pubKey').text, + auth_info_pw: parsed_frame.css('pw').text, + expiry_relative: parsed_frame.css('relative').text, + expiry_absolute: abs_datetime, + requester: requester, + accepter: registrar + ) + + registrar.messages.create( + body: 'Key Relay action completed successfully.', + attached_obj_type: kr.class.to_s, + attached_obj_id: kr.id + ) + + kr + end + end + ### VALIDATIONS ### def validate_exp_dates(cur_exp_date) diff --git a/config/locales/en.yml b/config/locales/en.yml index 2d785280d..41f08825b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -426,3 +426,5 @@ en: host_obj_is_not_allowed: 'hostObj object is not allowed' generate_zonefile: 'Generate zonefile' zonefile: 'Zonefile' + only_one_parameter_allowed: 'Only one parameter allowed: %{param_1} or %{param_2}' + required_parameter_missing_choice: 'Required parameter missing: %{param_1} or %{param_2}' diff --git a/spec/epp/keyrelay_spec.rb b/spec/epp/keyrelay_spec.rb index 50696b120..bcdcddd6b 100644 --- a/spec/epp/keyrelay_spec.rb +++ b/spec/epp/keyrelay_spec.rb @@ -39,6 +39,5 @@ describe 'EPP Keyrelay', epp: true do expect(zone.messages.queued.count).to eq(1) end - end end