From c234449dae0b2e34fffdc636df5d6f1f75c0500f Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 3 Jul 2023 15:43:30 +0300 Subject: [PATCH 01/21] Modified white ip form --- app/controllers/admin/white_ips_controller.rb | 8 +- .../repp/v1/white_ips_controller.rb | 2 +- app/models/white_ip.rb | 102 ++++++++++++------ .../repp/v1/white_ips/create_test.rb | 27 +++-- .../repp/v1/white_ips/update_test.rb | 22 +--- 5 files changed, 98 insertions(+), 63 deletions(-) diff --git a/app/controllers/admin/white_ips_controller.rb b/app/controllers/admin/white_ips_controller.rb index 8554774d3..a621a8386 100644 --- a/app/controllers/admin/white_ips_controller.rb +++ b/app/controllers/admin/white_ips_controller.rb @@ -2,17 +2,15 @@ module Admin class WhiteIpsController < BaseController load_and_authorize_resource - before_action :set_registrar, only: [:new, :show, :edit, :destroy, :update] + before_action :set_registrar, only: %i[new show edit destroy update] def new @white_ip = WhiteIp.new(registrar: @registrar) end - def show; - end + def show; end - def edit; - end + def edit; end def destroy if @white_ip.destroy diff --git a/app/controllers/repp/v1/white_ips_controller.rb b/app/controllers/repp/v1/white_ips_controller.rb index 4cb8d8987..93b9ef155 100644 --- a/app/controllers/repp/v1/white_ips_controller.rb +++ b/app/controllers/repp/v1/white_ips_controller.rb @@ -63,7 +63,7 @@ module Repp end def white_ip_params - params.require(:white_ip).permit(:ipv4, :ipv6, interfaces: []) + params.require(:white_ip).permit(:address, interfaces: []) end end end diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb index fb638c631..24fb6b592 100644 --- a/app/models/white_ip.rb +++ b/app/models/white_ip.rb @@ -2,10 +2,14 @@ class WhiteIp < ApplicationRecord include Versions belongs_to :registrar + attr_accessor :address + + validate :validate_address_format + validates :ipv4, uniqueness: { scope: :registrar_id }, if: :ipv4? + validates :ipv6, uniqueness: { scope: :registrar_id }, if: :ipv6? + validate :validate_only_one_ip validate :valid_ipv4? validate :valid_ipv6? - validate :validate_ipv4_and_ipv6 - validate :validate_only_one_ip validate :validate_max_ip_count before_save :normalize_blank_values @@ -13,16 +17,35 @@ class WhiteIp < ApplicationRecord %i[ipv4 ipv6].each { |c| self[c].present? || self[c] = nil } end - def validate_ipv4_and_ipv6 - return if ipv4.present? || ipv6.present? + def validate_address_format + return if address.blank? - errors.add(:base, I18n.t(:ipv4_or_ipv6_must_be_present)) + ip_address = IPAddr.new(address) + ip_version = determine_ip_version(ip_address) + + assign_ip_attributes(ip_version) + rescue IPAddr::InvalidAddressError + errors.add(:address, :invalid) end def validate_only_one_ip - return unless ipv4.present? && ipv6.present? + if ipv4.present? && ipv6.present? + errors.add(:base, I18n.t(:ip_must_be_one)) + elsif ipv4.blank? && ipv6.blank? + errors.add(:base, I18n.t(:ipv4_or_ipv6_must_be_present)) + end + end - errors.add(:base, I18n.t(:ip_must_be_one)) + def validate_max_ip_count + return if errors.any? + + total_exist = calculate_total_network_addresses(registrar.white_ips) + total_current = calculate_total_network_addresses([self]) + total = total_exist + total_current + limit = Setting.ip_whitelist_max_count + return unless total >= limit + + errors.add(:base, I18n.t(:ip_limit_exceeded, total: total, limit: limit)) end def valid_ipv4? @@ -41,31 +64,6 @@ class WhiteIp < ApplicationRecord errors.add(:ipv6, :invalid) end - def validate_max_ip_count - return if errors.any? - - ip_addresses = registrar.white_ips - total = ip_addresses.size + count_network_addresses(ipv4.presence || ipv6) - limit = Setting.ip_whitelist_max_count - return unless total >= limit - - errors.add(:base, I18n.t(:ip_limit_exceeded, total: total, limit: limit)) - end - - def count_network_addresses(ip) - address = IPAddr.new(ip) - - if address.ipv4? - subnet_mask = address.prefix - 2**(32 - subnet_mask) - 2 - elsif address.ipv6? - subnet_mask = address.prefix - 2**(128 - subnet_mask) - 2 - else - 0 - end - end - API = 'api'.freeze REGISTRAR = 'registrar'.freeze INTERFACES = [API, REGISTRAR].freeze @@ -125,4 +123,44 @@ class WhiteIp < ApplicationRecord updated_at, ] end + + private + + def determine_ip_version(ip_address) + return :ipv4 if ip_address.ipv4? + return :ipv6 if ip_address.ipv6? + + nil + end + + def assign_ip_attributes(ip_version) + case ip_version + when :ipv4 + self.ipv4 = address + self.ipv6 = nil + when :ipv6 + self.ipv6 = address + self.ipv4 = nil + else + errors.add(:address, :invalid) + end + end + + def count_network_addresses(ip) + address = IPAddr.new(ip) + + if address.ipv4? + subnet_mask = address.prefix + (2**(32 - subnet_mask) - 2).abs + elsif address.ipv6? + subnet_mask = address.prefix + (2**(128 - subnet_mask) - 2).abs + else + 0 + end + end + + def calculate_total_network_addresses(ips) + ips.sum { |ip| count_network_addresses(ip.ipv4.presence || ip.ipv6) } + end end diff --git a/test/integration/repp/v1/white_ips/create_test.rb b/test/integration/repp/v1/white_ips/create_test.rb index 2b152d41c..7cda9affa 100644 --- a/test/integration/repp/v1/white_ips/create_test.rb +++ b/test/integration/repp/v1/white_ips/create_test.rb @@ -15,8 +15,7 @@ class ReppV1WhiteIpsCreateTest < ActionDispatch::IntegrationTest def test_creates_new_white_ip request_body = { white_ip: { - ipv4: '127.0.0.1', - ipv6: '', + address: '127.1.1.1', interfaces: ['API'], }, } @@ -31,14 +30,13 @@ class ReppV1WhiteIpsCreateTest < ActionDispatch::IntegrationTest white_ip = WhiteIp.find(json[:data][:ip][:id]) assert white_ip.present? - assert_equal(request_body[:white_ip][:ipv4], white_ip.ipv4) + assert_equal(request_body[:white_ip][:address], white_ip.ipv4) end def test_validates_ip_max_count request_body = { white_ip: { - ipv4: '', - ipv6: '2001:db8::/120', + address: '2001:db8::/120', interfaces: ['API'], }, } @@ -50,14 +48,29 @@ class ReppV1WhiteIpsCreateTest < ActionDispatch::IntegrationTest assert json[:message].include? 'IP address limit exceeded' end + def test_validates_ip_uniqueness_per_registrar + white_ip = white_ips(:one) + request_body = { + white_ip: { + address: white_ip.ipv4, + interfaces: ['API'], + }, + } + + post '/repp/v1/white_ips', headers: @auth_headers, params: request_body + json = JSON.parse(response.body, symbolize_names: true) + + assert_response :bad_request + assert json[:message].include? 'IPv4 has already been taken' + end + def test_returns_error_response_if_throttled ENV['shunter_default_threshold'] = '1' ENV['shunter_enabled'] = 'true' request_body = { white_ip: { - ipv4: '127.0.0.1', - ipv6: '', + address: '127.0.0.1', interfaces: ['API'], }, } diff --git a/test/integration/repp/v1/white_ips/update_test.rb b/test/integration/repp/v1/white_ips/update_test.rb index 03b34ef01..b04d357be 100644 --- a/test/integration/repp/v1/white_ips/update_test.rb +++ b/test/integration/repp/v1/white_ips/update_test.rb @@ -16,7 +16,7 @@ class ReppV1ApiWhiteIpsUpdateTest < ActionDispatch::IntegrationTest def test_updates_white_ip request_body = { white_ip: { - ipv4: '127.0.0.1', + address: '127.0.0.1', }, } @@ -34,7 +34,7 @@ class ReppV1ApiWhiteIpsUpdateTest < ActionDispatch::IntegrationTest def test_returns_error_if_ipv4_wrong_format request_body = { white_ip: { - ipv4: 'wrongip', + address: 'wrongip', }, } @@ -42,21 +42,7 @@ class ReppV1ApiWhiteIpsUpdateTest < ActionDispatch::IntegrationTest json = JSON.parse(response.body, symbolize_names: true) assert_response :bad_request - assert json[:message].include? 'IPv4 is invalid' - end - - def test_returns_error_if_both_ips - request_body = { - white_ip: { - ipv6: '2001:0db8:85a3:0000:0000:8a2e:0370:7334', - }, - } - - put "/repp/v1/white_ips/#{@white_ip.id}", headers: @auth_headers, params: request_body - json = JSON.parse(response.body, symbolize_names: true) - - assert_response :bad_request - assert json[:message].include? 'Please enter only one IP address' + assert json[:message].include? 'Address is invalid' end def test_returns_error_response_if_throttled @@ -65,7 +51,7 @@ class ReppV1ApiWhiteIpsUpdateTest < ActionDispatch::IntegrationTest request_body = { white_ip: { - ipv4: '127.0.0.1', + address: '127.0.0.1', }, } From 289159bff24844c5f258eef163f2d2766eafe122 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 3 Jul 2023 15:47:45 +0300 Subject: [PATCH 02/21] Fixed codeclimate issue --- app/models/white_ip.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb index 24fb6b592..f55a9482c 100644 --- a/app/models/white_ip.rb +++ b/app/models/white_ip.rb @@ -1,4 +1,4 @@ -class WhiteIp < ApplicationRecord +class WhiteIp < ApplicationRecord # rubocop:disable Metrics/ClassLength include Versions belongs_to :registrar From 97c11f5dfd2a32922c5cf30ac6af0637f3eefbf5 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Tue, 4 Jul 2023 11:33:06 +0300 Subject: [PATCH 03/21] Added error messages translations to white ips --- app/controllers/admin/base_controller.rb | 5 ++ app/controllers/repp/v1/base_controller.rb | 5 ++ .../concerns/white_ip/white_ip_concern.rb | 51 +++++++++++++++ app/models/white_ip.rb | 56 +++------------- config/locales/devise.et.yml | 64 +++++++++++++++++++ config/locales/en.yml | 15 ++++- config/locales/et.yml | 15 +++++ 7 files changed, 161 insertions(+), 50 deletions(-) create mode 100644 app/models/concerns/white_ip/white_ip_concern.rb create mode 100644 config/locales/devise.et.yml diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 88afec72d..36de86a2c 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -1,6 +1,7 @@ module Admin class BaseController < ApplicationController before_action :authenticate_admin_user! + before_action :set_locale helper_method :head_title_sufix before_action :set_paper_trail_whodunnit @@ -33,5 +34,9 @@ module Admin end end end + + def set_locale + I18n.locale = params[:locale] || I18n.default_locale + end end end diff --git a/app/controllers/repp/v1/base_controller.rb b/app/controllers/repp/v1/base_controller.rb index 464be249a..b12addd0f 100644 --- a/app/controllers/repp/v1/base_controller.rb +++ b/app/controllers/repp/v1/base_controller.rb @@ -5,6 +5,7 @@ module Repp around_action :log_request before_action :authenticate_user + before_action :set_locale before_action :validate_webclient_ca before_action :validate_client_certs before_action :check_ip_restriction @@ -176,6 +177,10 @@ module Repp authorize!(:throttled_user, @domain) unless current_user || action_name == 'tara_callback' current_user end + + def set_locale + I18n.locale = current_user&.try(:locale) || params[:locale] || I18n.default_locale + end end end end diff --git a/app/models/concerns/white_ip/white_ip_concern.rb b/app/models/concerns/white_ip/white_ip_concern.rb new file mode 100644 index 000000000..73b17df19 --- /dev/null +++ b/app/models/concerns/white_ip/white_ip_concern.rb @@ -0,0 +1,51 @@ +# app/models/concerns/white_ip_concern.rb +module WhiteIp::WhiteIpConcern + extend ActiveSupport::Concern + + class_methods do # rubocop:disable Metrics/BlockLength + def include_ip?(ip) + return false if ip.blank? + + where(id: ids_including(ip)).any? + end + + def ids_including(ip) + ipv4 = select_ipv4(ip) + ipv6 = select_ipv6(ip) + + (ipv4 + ipv6).pluck(:id).flatten.uniq + end + + def select_ipv4(ip) + return [] unless check_ip4(ip).present? + + select { |white_ip| check_ip4(white_ip.ipv4) == check_ip4(ip) } + end + + def select_ipv6(ip) + return [] unless check_ip6(ip).present? + + select { |white_ip| check_ip6(white_ip.ipv6) == check_ip6(ip) } + end + + def csv_header + %w[IPv4 IPv6 Interfaces Created Updated] + end + + def ransackable_attributes(*) + authorizable_ransackable_attributes + end + + def check_ip4(ip) + IPAddr.new(ip, Socket::AF_INET) + rescue StandardError => _e + nil + end + + def check_ip6(ip) + IPAddr.new(ip, Socket::AF_INET6) + rescue StandardError => _e + nil + end + end +end diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb index f55a9482c..577faa565 100644 --- a/app/models/white_ip.rb +++ b/app/models/white_ip.rb @@ -1,5 +1,7 @@ -class WhiteIp < ApplicationRecord # rubocop:disable Metrics/ClassLength +class WhiteIp < ApplicationRecord include Versions + include WhiteIp::WhiteIpConcern + belongs_to :registrar attr_accessor :address @@ -25,14 +27,14 @@ class WhiteIp < ApplicationRecord # rubocop:disable Metrics/ClassLength assign_ip_attributes(ip_version) rescue IPAddr::InvalidAddressError - errors.add(:address, :invalid) + errors.add(:base, :address_invalid) end def validate_only_one_ip if ipv4.present? && ipv6.present? - errors.add(:base, I18n.t(:ip_must_be_one)) + errors.add(:base, :ip_must_be_one) elsif ipv4.blank? && ipv6.blank? - errors.add(:base, I18n.t(:ipv4_or_ipv6_must_be_present)) + errors.add(:base, :ipv4_or_ipv6_must_be_present) end end @@ -45,7 +47,7 @@ class WhiteIp < ApplicationRecord # rubocop:disable Metrics/ClassLength limit = Setting.ip_whitelist_max_count return unless total >= limit - errors.add(:base, I18n.t(:ip_limit_exceeded, total: total, limit: limit)) + errors.add(:base, :ip_limit_exceeded, total: total, limit: limit) end def valid_ipv4? @@ -75,49 +77,9 @@ class WhiteIp < ApplicationRecord # rubocop:disable Metrics/ClassLength super(interfaces.reject(&:blank?)) end - class << self - # rubocop:disable Style/CaseEquality - # rubocop:disable Metrics/AbcSize - def include_ip?(ip) - return false if ip.blank? - - where(id: ids_including(ip)).any? - end - - def ids_including(ip) - ipv4 = ipv6 = [] - ipv4 = select { |white_ip| check_ip4(white_ip.ipv4) === check_ip4(ip) } if check_ip4(ip).present? - ipv6 = select { |white_ip| check_ip6(white_ip.ipv6) === check_ip6(ip) } if check_ip6(ip).present? - (ipv4 + ipv6).pluck(:id).flatten.uniq - end - # rubocop:enable Style/CaseEquality - # rubocop:enable Metrics/AbcSize - - def check_ip4(ip) - IPAddr.new(ip, Socket::AF_INET) - rescue StandardError => _e - nil - end - - def check_ip6(ip) - IPAddr.new(ip, Socket::AF_INET6) - rescue StandardError => _e - nil - end - - def csv_header - %w[IPv4 IPv6 Interfaces Created Updated] - end - - def ransackable_attributes(*) - authorizable_ransackable_attributes - end - end - def as_csv_row [ - ipv4, - ipv6, + ipv4, ipv6, interfaces.join(', ').upcase, created_at, updated_at, @@ -142,7 +104,7 @@ class WhiteIp < ApplicationRecord # rubocop:disable Metrics/ClassLength self.ipv6 = address self.ipv4 = nil else - errors.add(:address, :invalid) + errors.add(:base, :address_invalid) end end diff --git a/config/locales/devise.et.yml b/config/locales/devise.et.yml new file mode 100644 index 000000000..051ad2ea2 --- /dev/null +++ b/config/locales/devise.et.yml @@ -0,0 +1,64 @@ +# Additional translations at https://github.com/plataformatec/devise/wiki/I18n + +et: + devise: + confirmations: + confirmed: "Your email address has been successfully confirmed." + send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes." + failure: + already_authenticated: "You are already signed in." + inactive: "Your account is not activated yet." + invalid: "Invalid %{authentication_keys} or password." + locked: "Your account is locked." + last_attempt: "You have one more attempt before your account is locked." + not_found_in_database: "Invalid %{authentication_keys} or password." + timeout: "Your session expired. Please sign in again to continue." + unauthenticated: "You need to sign in before continuing." + unconfirmed: "You have to confirm your email address before continuing." + mailer: + confirmation_instructions: + subject: "Confirmation instructions" + reset_password_instructions: + subject: "Reset password instructions" + unlock_instructions: + subject: "Unlock instructions" + email_changed: + subject: "Email Changed" + password_change: + subject: "Password Changed" + omniauth_callbacks: + failure: "Could not authenticate you from %{kind} because \"%{reason}\"." + success: "Successfully authenticated from %{kind} account." + passwords: + no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided." + send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." + updated: "Your password has been changed successfully. You are now signed in." + updated_not_active: "Your password has been changed successfully." + registrations: + destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon." + signed_up: "Welcome! You have signed up successfully." + signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." + signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." + signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account." + update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address." + updated: "Your account has been updated successfully." + sessions: + signed_in: "Signed in successfully." + signed_out: "Signed out successfully." + already_signed_out: "Signed out successfully." + unlocks: + send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes." + send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes." + unlocked: "Your account has been unlocked successfully. Please sign in to continue." + errors: + messages: + already_confirmed: "was already confirmed, please try signing in" + confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" + expired: "has expired, please request a new one" + not_found: "not found" + not_locked: "was not locked" + not_saved: + one: "1 error prohibited this %{resource} from being saved:" + other: "%{count} errors prohibited this %{resource} from being saved:" diff --git a/config/locales/en.yml b/config/locales/en.yml index 32f122924..edeef1852 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -147,6 +147,18 @@ en: length_more_than: 'Parameter value policy error: Legaldoc size is less than minimum allowed size of 3kB' length_less_than: 'Parameter value policy error: Legaldoc size exceeds maximum allowed size of 8mB' + white_ip: + attributes: + base: + address_invalid: 'IP Address is invalid' + ipv4_or_ipv6_must_be_present: 'IPv4 or IPv6 must be present' + ip_must_be_one: 'Please enter only one IP address' + ip_limit_exceeded: 'IP address limit exceeded. Total addresses: %{total}. Limit: %{limit}.' + ipv4: + taken: 'is already taken' + ipv6: + taken: 'is already taken' + attributes: epp_domain: &epp_domain_attributes @@ -548,9 +560,6 @@ en: not_valid_domain_verification_body: This could mean your verification has been expired or done already.

Please contact us if you think something is wrong. upload_crt: 'Upload CRT' crt_or_csr_must_be_present: 'CRT or CSR must be present' - ipv4_or_ipv6_must_be_present: 'IPv4 or IPv6 must be present' - ip_must_be_one: 'Please enter only one IP address' - ip_limit_exceeded: 'IP address limit exceeded. Total addresses: %{total}. Limit: %{limit}.' white_ip: 'White IP' edit_white_ip: 'Edit white IP' confirm_domain_delete: 'Confirm domain delete' diff --git a/config/locales/et.yml b/config/locales/et.yml index b381259a7..9dedcb86a 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -17,3 +17,18 @@ et: you_have_a_new_invoice: 'Teil on uus arve.' monthly_invoice: "Siit tuleb aruanne möödunud kuul ettemaksukontoga seotud tasuliste toimingutega." sincerely: 'Lugupidamisega' + + activerecord: + errors: + models: + white_ip: + attributes: + base: + address_invalid: 'IP-aadress on vale' + ipv4_or_ipv6_must_be_present: 'IPv4 või IPv6 peab olema olemas' + ip_must_be_one: 'Palun sisestage ainult üks IP-aadress' + ip_limit_exceeded: 'IP-aadressi piirang ületatud. Kokku aadresse: %{total}. Limiit: %{limit}.' + ipv4: + taken: 'on juba lisatud' + ipv6: + taken: 'on juba lisatud' From 537315a8a9568940edc80b5f57a2acff046f55f1 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Tue, 4 Jul 2023 11:36:26 +0300 Subject: [PATCH 04/21] Fixed codeclimate issues --- app/models/concerns/white_ip/white_ip_concern.rb | 4 ++-- app/models/white_ip.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/concerns/white_ip/white_ip_concern.rb b/app/models/concerns/white_ip/white_ip_concern.rb index 73b17df19..8c783a839 100644 --- a/app/models/concerns/white_ip/white_ip_concern.rb +++ b/app/models/concerns/white_ip/white_ip_concern.rb @@ -17,13 +17,13 @@ module WhiteIp::WhiteIpConcern end def select_ipv4(ip) - return [] unless check_ip4(ip).present? + return [] if check_ip4(ip).blank? select { |white_ip| check_ip4(white_ip.ipv4) == check_ip4(ip) } end def select_ipv6(ip) - return [] unless check_ip6(ip).present? + return [] if check_ip6(ip).blank? select { |white_ip| check_ip6(white_ip.ipv6) == check_ip6(ip) } end diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb index 577faa565..18004e8b5 100644 --- a/app/models/white_ip.rb +++ b/app/models/white_ip.rb @@ -82,7 +82,7 @@ class WhiteIp < ApplicationRecord ipv4, ipv6, interfaces.join(', ').upcase, created_at, - updated_at, + updated_at ] end From 61c59cb4b26492ab483d55e39f9f4aa80161470e Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Tue, 4 Jul 2023 11:45:53 +0300 Subject: [PATCH 05/21] Fixed transaltions --- config/locales/en.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index edeef1852..e9553aa20 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -155,9 +155,9 @@ en: ip_must_be_one: 'Please enter only one IP address' ip_limit_exceeded: 'IP address limit exceeded. Total addresses: %{total}. Limit: %{limit}.' ipv4: - taken: 'is already taken' + taken: 'has already been taken' ipv6: - taken: 'is already taken' + taken: 'has already been taken' attributes: From e13caf251805b2229d6b3ee6e062c9da090987b9 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Tue, 4 Jul 2023 11:48:49 +0300 Subject: [PATCH 06/21] Fixed transaltions --- config/locales/et.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/et.yml b/config/locales/et.yml index 9dedcb86a..428e3cafc 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -25,7 +25,7 @@ et: attributes: base: address_invalid: 'IP-aadress on vale' - ipv4_or_ipv6_must_be_present: 'IPv4 või IPv6 peab olema olemas' + ipv4_or_ipv6_must_be_present: 'Peab olema vähemalt üks IPv4 või IPv6' ip_must_be_one: 'Palun sisestage ainult üks IP-aadress' ip_limit_exceeded: 'IP-aadressi piirang ületatud. Kokku aadresse: %{total}. Limiit: %{limit}.' ipv4: From 5716a536ca96394a7e9826aa7b4b8e3e93e2c464 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Tue, 4 Jul 2023 12:31:36 +0300 Subject: [PATCH 07/21] Corrected ip addresses comparison --- app/models/concerns/white_ip/white_ip_concern.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/concerns/white_ip/white_ip_concern.rb b/app/models/concerns/white_ip/white_ip_concern.rb index 8c783a839..e86cfa1f5 100644 --- a/app/models/concerns/white_ip/white_ip_concern.rb +++ b/app/models/concerns/white_ip/white_ip_concern.rb @@ -19,13 +19,13 @@ module WhiteIp::WhiteIpConcern def select_ipv4(ip) return [] if check_ip4(ip).blank? - select { |white_ip| check_ip4(white_ip.ipv4) == check_ip4(ip) } + select { |white_ip| check_ip4(white_ip.ipv4) === check_ip4(ip) } end def select_ipv6(ip) return [] if check_ip6(ip).blank? - select { |white_ip| check_ip6(white_ip.ipv6) == check_ip6(ip) } + select { |white_ip| check_ip6(white_ip.ipv6) === check_ip6(ip) } end def csv_header From 311834c0859a9a0d33e7cba1d3b12ab2f3fb1876 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Tue, 4 Jul 2023 12:35:31 +0300 Subject: [PATCH 08/21] Fixed codeclimate issues --- app/models/concerns/white_ip/white_ip_concern.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/concerns/white_ip/white_ip_concern.rb b/app/models/concerns/white_ip/white_ip_concern.rb index e86cfa1f5..f44af0825 100644 --- a/app/models/concerns/white_ip/white_ip_concern.rb +++ b/app/models/concerns/white_ip/white_ip_concern.rb @@ -16,6 +16,7 @@ module WhiteIp::WhiteIpConcern (ipv4 + ipv6).pluck(:id).flatten.uniq end + # rubocop:disable Style/CaseEquality def select_ipv4(ip) return [] if check_ip4(ip).blank? @@ -27,6 +28,7 @@ module WhiteIp::WhiteIpConcern select { |white_ip| check_ip6(white_ip.ipv6) === check_ip6(ip) } end + # rubocop:enable Style/CaseEquality def csv_header %w[IPv4 IPv6 Interfaces Created Updated] From e00e44c9b86ee0f62238bd4dd8f564928f54096d Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Wed, 5 Jul 2023 15:28:43 +0300 Subject: [PATCH 09/21] Modified white ip form and created mailer --- app/controllers/repp/v1/base_controller.rb | 8 ++++++-- .../repp/v1/white_ips_controller.rb | 19 +++++++++++++++++++ app/mailers/white_ip_mailer.rb | 17 +++++++++++++++++ app/models/white_ip.rb | 4 +--- .../api_ip_address_deleted.html.erb | 9 +++++++++ .../api_ip_address_deleted.text.erb | 7 +++++++ .../api_ip_address_updated.html.erb | 9 +++++++++ .../api_ip_address_updated.text.erb | 7 +++++++ config/locales/et.yml | 8 ++++++++ .../repp/v1/white_ips/create_test.rb | 16 ---------------- 10 files changed, 83 insertions(+), 21 deletions(-) create mode 100644 app/mailers/white_ip_mailer.rb create mode 100644 app/views/mailers/white_ip_mailer/api_ip_address_deleted.html.erb create mode 100644 app/views/mailers/white_ip_mailer/api_ip_address_deleted.text.erb create mode 100644 app/views/mailers/white_ip_mailer/api_ip_address_updated.html.erb create mode 100644 app/views/mailers/white_ip_mailer/api_ip_address_updated.text.erb diff --git a/app/controllers/repp/v1/base_controller.rb b/app/controllers/repp/v1/base_controller.rb index b12addd0f..1c6119422 100644 --- a/app/controllers/repp/v1/base_controller.rb +++ b/app/controllers/repp/v1/base_controller.rb @@ -130,6 +130,11 @@ module Repp render(json: @response, status: :unauthorized) end + def render_unauthorized_response + @response = { code: 2202, message: I18n.t('registrar.authorization.ip_not_allowed', ip: request.ip) } + render json: @response, status: :unauthorized + end + def webclient_request? return false if Rails.env.test? || Rails.env.development? @@ -144,8 +149,7 @@ module Repp webclient_cn = ENV['webclient_cert_common_name'] || 'webclient' return if request_name == webclient_cn - @response = { code: 2202, - message: I18n.t('registrar.authorization.ip_not_allowed', ip: request.ip) } + @response = { code: 2202, message: 'Invalid webclient certificate' } render(json: @response, status: :unauthorized) end diff --git a/app/controllers/repp/v1/white_ips_controller.rb b/app/controllers/repp/v1/white_ips_controller.rb index 93b9ef155..4cc5fec04 100644 --- a/app/controllers/repp/v1/white_ips_controller.rb +++ b/app/controllers/repp/v1/white_ips_controller.rb @@ -31,28 +31,34 @@ module Repp return end + notify_admins if @white_ip.interfaces.include? WhiteIp::API render_success(data: { ip: { id: @white_ip.id } }) end api :PUT, '/repp/v1/white_ips/:id' desc 'Update whitelisted IP address' def update + api = @white_ip.interfaces.include? WhiteIp::API unless @white_ip.update(white_ip_params) handle_non_epp_errors(@white_ip) return end + notify_admins if @white_ip.interfaces.include? WhiteIp::API + notify_admins if api && !@white_ip.interfaces.include?(WhiteIp::API) render_success(data: { ip: { id: @white_ip.id } }) end api :DELETE, '/repp/v1/white_ips/:id' desc 'Delete a specific whitelisted IP address' def destroy + ip = @white_ip unless @white_ip.destroy handle_non_epp_errors(@white_ip) return end + notify_admins(ip: ip, action: 'deleted') if ip.interfaces.include?(WhiteIp::API) render_success end @@ -65,6 +71,19 @@ module Repp def white_ip_params params.require(:white_ip).permit(:address, interfaces: []) end + + def notify_admins(ip: @white_ip, action: 'updated') + admin_users_emails = User.admin.pluck(:email).reject(&:blank?) + + return if admin_users_emails.empty? + + admin_users_emails.each do |email| + WhiteIpMailer.with(email: email, api_user: current_user, + white_ip: ip) + .send("api_ip_address_#{action}") + .deliver_now + end + end end end end diff --git a/app/mailers/white_ip_mailer.rb b/app/mailers/white_ip_mailer.rb new file mode 100644 index 000000000..61914fb9a --- /dev/null +++ b/app/mailers/white_ip_mailer.rb @@ -0,0 +1,17 @@ +class WhiteIpMailer < ApplicationMailer + def api_ip_address_updated + email = params[:email] + @api_user = params[:api_user] + @white_ip = params[:white_ip] + subject = '[Important] Whitelisted IP Address Change Notification' + mail(to: email, subject: subject) + end + + def api_ip_address_deleted + email = params[:email] + @api_user = params[:api_user] + @white_ip = params[:white_ip] + subject = '[Important] Whitelisted IP Address Removal Notification' + mail(to: email, subject: subject) + end +end diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb index 18004e8b5..02840263f 100644 --- a/app/models/white_ip.rb +++ b/app/models/white_ip.rb @@ -7,8 +7,6 @@ class WhiteIp < ApplicationRecord attr_accessor :address validate :validate_address_format - validates :ipv4, uniqueness: { scope: :registrar_id }, if: :ipv4? - validates :ipv6, uniqueness: { scope: :registrar_id }, if: :ipv6? validate :validate_only_one_ip validate :valid_ipv4? validate :valid_ipv6? @@ -68,7 +66,7 @@ class WhiteIp < ApplicationRecord API = 'api'.freeze REGISTRAR = 'registrar'.freeze - INTERFACES = [API, REGISTRAR].freeze + INTERFACES = [REGISTRAR, API].freeze scope :api, -> { where('interfaces @> ?::varchar[]', "{#{API}}") } scope :registrar_area, -> { where('interfaces @> ?::varchar[]', "{#{REGISTRAR}}") } diff --git a/app/views/mailers/white_ip_mailer/api_ip_address_deleted.html.erb b/app/views/mailers/white_ip_mailer/api_ip_address_deleted.html.erb new file mode 100644 index 000000000..789d79bb5 --- /dev/null +++ b/app/views/mailers/white_ip_mailer/api_ip_address_deleted.html.erb @@ -0,0 +1,9 @@ +

This email is to inform you that an API Whitelisted IP address was deleted by Registrar Portal API user. Please review the details below:

+ +
    +
  • API User: <%= @api_user.username %>
  • +
  • IP Address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %>
  • +
  • Interface: <%= @white_ip.interfaces.join(', ') %>
  • +
+ +

Please take the necessary actions to ensure the security and integrity of the application's API access.

diff --git a/app/views/mailers/white_ip_mailer/api_ip_address_deleted.text.erb b/app/views/mailers/white_ip_mailer/api_ip_address_deleted.text.erb new file mode 100644 index 000000000..d7554c703 --- /dev/null +++ b/app/views/mailers/white_ip_mailer/api_ip_address_deleted.text.erb @@ -0,0 +1,7 @@ +This email is to inform you about an API Whitelisted IP address change by Registrar Portal API user. Please review the details below: + +API User: <%= @api_user.username %> +IP Address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> +Interface: <%= @white_ip.interfaces.join(', ') %> + +Please take the necessary actions to ensure the security and integrity of the application's API access. diff --git a/app/views/mailers/white_ip_mailer/api_ip_address_updated.html.erb b/app/views/mailers/white_ip_mailer/api_ip_address_updated.html.erb new file mode 100644 index 000000000..3e71d3253 --- /dev/null +++ b/app/views/mailers/white_ip_mailer/api_ip_address_updated.html.erb @@ -0,0 +1,9 @@ +

This email is to inform you about an API Whitelisted IP address change by Registrar Portal API user. Please review the details below:

+ +
    +
  • API User: <%= @api_user.username %>
  • +
  • IP Address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %>
  • +
  • Interface: <%= @white_ip.interfaces.join(', ') %>
  • +
+ +

Please take the necessary actions to ensure the security and integrity of the application's API access.

diff --git a/app/views/mailers/white_ip_mailer/api_ip_address_updated.text.erb b/app/views/mailers/white_ip_mailer/api_ip_address_updated.text.erb new file mode 100644 index 000000000..d7554c703 --- /dev/null +++ b/app/views/mailers/white_ip_mailer/api_ip_address_updated.text.erb @@ -0,0 +1,7 @@ +This email is to inform you about an API Whitelisted IP address change by Registrar Portal API user. Please review the details below: + +API User: <%= @api_user.username %> +IP Address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> +Interface: <%= @white_ip.interfaces.join(', ') %> + +Please take the necessary actions to ensure the security and integrity of the application's API access. diff --git a/config/locales/et.yml b/config/locales/et.yml index 428e3cafc..651f5ff83 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -2,6 +2,14 @@ et: username: 'Kasutajanimi' password: 'Parool' + time: + formats: + default: "%Y-%m-%d %H:%M" + long: "%A, %e. %B %Y, %H:%M" + short: "%d.%m.%y, %H:%M" + date: "%Y-%m-%d" + date_long: "%d. %B %Y" + filename: "%Y-%m-%d_%H.%M" date: month_names: [~, Jaanuar, Veebruar, Märts, April, Mai, Juuni, Juuli, August, September, Oktoober, November, Detsember] diff --git a/test/integration/repp/v1/white_ips/create_test.rb b/test/integration/repp/v1/white_ips/create_test.rb index 7cda9affa..326edbdfe 100644 --- a/test/integration/repp/v1/white_ips/create_test.rb +++ b/test/integration/repp/v1/white_ips/create_test.rb @@ -48,22 +48,6 @@ class ReppV1WhiteIpsCreateTest < ActionDispatch::IntegrationTest assert json[:message].include? 'IP address limit exceeded' end - def test_validates_ip_uniqueness_per_registrar - white_ip = white_ips(:one) - request_body = { - white_ip: { - address: white_ip.ipv4, - interfaces: ['API'], - }, - } - - post '/repp/v1/white_ips', headers: @auth_headers, params: request_body - json = JSON.parse(response.body, symbolize_names: true) - - assert_response :bad_request - assert json[:message].include? 'IPv4 has already been taken' - end - def test_returns_error_response_if_throttled ENV['shunter_default_threshold'] = '1' ENV['shunter_enabled'] = 'true' From 1c8a46bd89acc4a2644b2de9c839cfd8a781137c Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Fri, 7 Jul 2023 16:05:06 +0300 Subject: [PATCH 10/21] Added committed param to white ip --- .../admin/certificates_controller.rb | 8 ++-- app/controllers/admin/white_ips_controller.rb | 13 +++++- .../repp/v1/accounts_controller.rb | 2 +- .../repp/v1/white_ips_controller.rb | 17 +++++--- app/mailers/white_ip_mailer.rb | 6 +++ .../admin/registrars/show/_white_ips.html.erb | 2 + app/views/admin/white_ips/_form.haml | 8 +++- app/views/admin/white_ips/show.haml | 3 ++ .../white_ip_mailer/committed.html.erb | 43 +++++++++++++++++++ .../white_ip_mailer/committed.text.erb | 32 ++++++++++++++ ...230707084741_add_committed_to_white_ips.rb | 5 +++ db/structure.sql | 6 ++- 12 files changed, 130 insertions(+), 15 deletions(-) create mode 100644 app/views/mailers/white_ip_mailer/committed.html.erb create mode 100644 app/views/mailers/white_ip_mailer/committed.text.erb create mode 100644 db/migrate/20230707084741_add_committed_to_white_ips.rb diff --git a/app/controllers/admin/certificates_controller.rb b/app/controllers/admin/certificates_controller.rb index 3f1113b0f..56e30f26a 100644 --- a/app/controllers/admin/certificates_controller.rb +++ b/app/controllers/admin/certificates_controller.rb @@ -41,7 +41,7 @@ module Admin def sign if @certificate.sign!(password: certificate_params[:password]) flash[:notice] = I18n.t('record_updated') - notify_api_user + notify_registrar redirect_to [:admin, @api_user, @certificate] else flash.now[:alert] = I18n.t('failed_to_update_record') @@ -88,10 +88,10 @@ module Admin end end - def notify_api_user - api_user_email = @api_user.registrar.email + def notify_registrar + email = @api_user.registrar.email - CertificateMailer.signed(email: api_user_email, api_user: @api_user, + CertificateMailer.signed(email: email, api_user: @api_user, crt: OpenSSL::X509::Certificate.new(@certificate.crt)) .deliver_now end diff --git a/app/controllers/admin/white_ips_controller.rb b/app/controllers/admin/white_ips_controller.rb index a621a8386..13867606e 100644 --- a/app/controllers/admin/white_ips_controller.rb +++ b/app/controllers/admin/white_ips_controller.rb @@ -36,7 +36,11 @@ module Admin end def update + previously_committed = @white_ip.committed + if @white_ip.update(white_ip_params) + notify_registrar if !previously_committed && @white_ip.committed + flash[:notice] = I18n.t('record_updated') redirect_to [:admin, @registrar, @white_ip] else @@ -52,7 +56,14 @@ module Admin end def white_ip_params - params.require(:white_ip).permit(:ipv4, :ipv6, :registrar_id, { interfaces: [] }) + params.require(:white_ip).permit(:ipv4, :ipv6, :registrar_id, :committed, { interfaces: [] }) + end + + def notify_registrar + email = @white_ip.registrar.email + + WhiteIpMailer.committed(email: email, ip: @white_ip) + .deliver_now end end end diff --git a/app/controllers/repp/v1/accounts_controller.rb b/app/controllers/repp/v1/accounts_controller.rb index 8aee2d294..2fe716e9c 100644 --- a/app/controllers/repp/v1/accounts_controller.rb +++ b/app/controllers/repp/v1/accounts_controller.rb @@ -174,7 +174,7 @@ module Repp end def serialized_ips(ips) - ips.as_json(only: %i[id ipv4 ipv6 interfaces]) + ips.as_json(only: %i[id ipv4 ipv6 interfaces committed]) end end end diff --git a/app/controllers/repp/v1/white_ips_controller.rb b/app/controllers/repp/v1/white_ips_controller.rb index 4cc5fec04..beb3cde03 100644 --- a/app/controllers/repp/v1/white_ips_controller.rb +++ b/app/controllers/repp/v1/white_ips_controller.rb @@ -31,21 +31,21 @@ module Repp return end - notify_admins if @white_ip.interfaces.include? WhiteIp::API + uncommit_and_notify_admins if api_interface?(@white_ip) render_success(data: { ip: { id: @white_ip.id } }) end api :PUT, '/repp/v1/white_ips/:id' desc 'Update whitelisted IP address' def update - api = @white_ip.interfaces.include? WhiteIp::API + previously_api = api_interface?(@white_ip) unless @white_ip.update(white_ip_params) handle_non_epp_errors(@white_ip) return end - notify_admins if @white_ip.interfaces.include? WhiteIp::API - notify_admins if api && !@white_ip.interfaces.include?(WhiteIp::API) + uncommit_and_notify_admins if api_interface?(@white_ip) + uncommit_and_notify_admins if previously_api && !api_interface?(@white_ip) render_success(data: { ip: { id: @white_ip.id } }) end @@ -58,12 +58,16 @@ module Repp return end - notify_admins(ip: ip, action: 'deleted') if ip.interfaces.include?(WhiteIp::API) + uncommit_and_notify_admins(ip: ip, action: 'deleted') if ip.interfaces.include?(WhiteIp::API) render_success end private + def api_interface?(ip) + ip.interfaces.include? WhiteIp::API + end + def find_white_ip @white_ip = current_user.registrar.white_ips.find(params[:id]) end @@ -72,7 +76,8 @@ module Repp params.require(:white_ip).permit(:address, interfaces: []) end - def notify_admins(ip: @white_ip, action: 'updated') + def uncommit_and_notify_admins(ip: @white_ip, action: 'updated') + @white_ip.update(committed: false) if action == 'updated' admin_users_emails = User.admin.pluck(:email).reject(&:blank?) return if admin_users_emails.empty? diff --git a/app/mailers/white_ip_mailer.rb b/app/mailers/white_ip_mailer.rb index 61914fb9a..8b7984ba8 100644 --- a/app/mailers/white_ip_mailer.rb +++ b/app/mailers/white_ip_mailer.rb @@ -14,4 +14,10 @@ class WhiteIpMailer < ApplicationMailer subject = '[Important] Whitelisted IP Address Removal Notification' mail(to: email, subject: subject) end + + def committed(email:, ip:) + @white_ip = ip + subject = 'Whitelisted IP Address Activation Confirmation' + mail(to: email, subject: subject) + end end diff --git a/app/views/admin/registrars/show/_white_ips.html.erb b/app/views/admin/registrars/show/_white_ips.html.erb index 5de3066c0..df59c8b63 100644 --- a/app/views/admin/registrars/show/_white_ips.html.erb +++ b/app/views/admin/registrars/show/_white_ips.html.erb @@ -9,6 +9,7 @@ <%= WhiteIp.human_attribute_name :ipv4 %> <%= WhiteIp.human_attribute_name :ipv6 %> <%= WhiteIp.human_attribute_name :interfaces %> + <%= WhiteIp.human_attribute_name :committed %> @@ -26,6 +27,7 @@ <% end %> <%= white_ip.interfaces.join(', ').upcase %> + <%= white_ip.committed %> <% end %> diff --git a/app/views/admin/white_ips/_form.haml b/app/views/admin/white_ips/_form.haml index 7a0371697..2236c09ad 100644 --- a/app/views/admin/white_ips/_form.haml +++ b/app/views/admin/white_ips/_form.haml @@ -26,7 +26,13 @@ .col-md-7 = f.check_box :interfaces, { multiple: true }, x, nil = hidden_field_tag "white_ip[interfaces][]", nil + .form-group + .col-md-4.control-label + = f.label :committed + .col-md-7 + = f.check_box :committed + %hr .row .col-md-8.text-right - = button_tag(t(:save), class: 'btn btn-primary') + = button_tag(t(:save), class: 'btn btn-primary') \ No newline at end of file diff --git a/app/views/admin/white_ips/show.haml b/app/views/admin/white_ips/show.haml index 2ec354aa4..d3df82e93 100644 --- a/app/views/admin/white_ips/show.haml +++ b/app/views/admin/white_ips/show.haml @@ -22,3 +22,6 @@ %dt= WhiteIp.human_attribute_name :interfaces %dd= @white_ip.interfaces.join(', ').upcase + + %dt= WhiteIp.human_attribute_name :committed + %dd= @white_ip.committed diff --git a/app/views/mailers/white_ip_mailer/committed.html.erb b/app/views/mailers/white_ip_mailer/committed.html.erb new file mode 100644 index 000000000..df782f79f --- /dev/null +++ b/app/views/mailers/white_ip_mailer/committed.html.erb @@ -0,0 +1,43 @@ +Tere, +

+

+Anname teada, et Teie konto juurde kuuluv lubatud IP-aadress on edukalt aktiveeritud. +

+

IP-aadressi andmed:

+
    +
  • IP-aadress: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %>
  • +
  • Liidesed: <%= @white_ip.interfaces.join(', ') %>
  • +
+

+Kõik päringud, mis algavad IP-aadressist <%= @white_ip.ipv4.presence || @white_ip.ipv6 %>, saavad meie süsteemis piiranguteta juurdepääsu. +Palun veenduge, et hoiaksite selle IP-aadressi turvalisust ja konfidentsiaalsust, et vältida volitamata juurdepääsu. +

+Kui Teil on küsimusi seoses Teie lubatud IP-aadressi aktiveerimisega, võtke meiega ühendust. +

+

+Parimate soovidega, +

+<%= render 'mailers/shared/signatures/signature.et.html' %> +
+

+ +Hi, +

+

+We would like to inform you that the whitelisted IP address associated with your account has been successfully activated. +

+

IP address Details:

+
    +
  • IP address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %>
  • +
  • Interfaces: <%= @white_ip.interfaces.join(', ') %>
  • +
+

+All requests originating from the IP address <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> will now have unrestricted access to our system. +Please ensure the security and confidentiality of this IP address to prevent unauthorized access. +

+If you have any questions regarding the activation of your whitelisted IP address, please contact us. +

+

+Best regards, +

+<%= render 'mailers/shared/signatures/signature.en.html' %> \ No newline at end of file diff --git a/app/views/mailers/white_ip_mailer/committed.text.erb b/app/views/mailers/white_ip_mailer/committed.text.erb new file mode 100644 index 000000000..fb38714df --- /dev/null +++ b/app/views/mailers/white_ip_mailer/committed.text.erb @@ -0,0 +1,32 @@ +Tere, + +Anname teada, et Teie konto juurde kuuluv lubatud IP-aadress on edukalt aktiveeritud. + +IP-aadressi andmed: +- IP-aadress: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> +- Liidesed: <%= @white_ip.interfaces.join(', ') %> + +Kõik päringud, mis algavad IP-aadressist <%= @white_ip.ipv4.presence || @white_ip.ipv6 %>, saavad meie süsteemis piiranguteta juurdepääsu. +Palun veenduge, et hoiaksite selle IP-aadressi turvalisust ja konfidentsiaalsust, et vältida volitamata juurdepääsu. + +Kui Teil on küsimusi seoses Teie lubatud IP-aadressi aktiveerimisega, võtke meiega ühendust. + +Parimate soovidega, +<%= render 'mailers/shared/signatures/signature.et.html' %> +--- + +Hi, + +We would like to inform you that the whitelisted IP address associated with your account has been successfully activated. + +IP address Details: +- IP address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> +- Interfaces: <%= @white_ip.interfaces.join(', ') %> + +All requests originating from the IP address <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> will now have unrestricted access to our system. +Please ensure the security and confidentiality of this IP address to prevent unauthorized access. + +If you have any questions regarding the activation of your whitelisted IP address, please contact us. + +Best regards, +<%= render 'mailers/shared/signatures/signature.en.html' %> \ No newline at end of file diff --git a/db/migrate/20230707084741_add_committed_to_white_ips.rb b/db/migrate/20230707084741_add_committed_to_white_ips.rb new file mode 100644 index 000000000..751bcc14c --- /dev/null +++ b/db/migrate/20230707084741_add_committed_to_white_ips.rb @@ -0,0 +1,5 @@ +class AddCommittedToWhiteIps < ActiveRecord::Migration[6.1] + def change + add_column :white_ips, :committed, :boolean, default: true + end +end diff --git a/db/structure.sql b/db/structure.sql index 44ffd7162..117880656 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2806,7 +2806,8 @@ CREATE TABLE public.white_ips ( created_at timestamp without time zone, updated_at timestamp without time zone, creator_str character varying, - updator_str character varying + updator_str character varying, + committed boolean DEFAULT true ); @@ -5468,6 +5469,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20221207102831'), ('20221214073933'), ('20221214074252'), -('20230531111154'); +('20230531111154'), +('20230707084741'); From 149cbb61387000a6fb1b1d79892d7cd662bdd846 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Fri, 7 Jul 2023 16:29:33 +0300 Subject: [PATCH 11/21] Renewed email text for ip address activation --- app/views/mailers/white_ip_mailer/committed.html.erb | 6 +++--- app/views/mailers/white_ip_mailer/committed.text.erb | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/mailers/white_ip_mailer/committed.html.erb b/app/views/mailers/white_ip_mailer/committed.html.erb index df782f79f..2cc853ea3 100644 --- a/app/views/mailers/white_ip_mailer/committed.html.erb +++ b/app/views/mailers/white_ip_mailer/committed.html.erb @@ -9,8 +9,8 @@ Anname teada, et Teie konto juurde kuuluv lubatud IP-aadress on edukalt aktiveer
  • Liidesed: <%= @white_ip.interfaces.join(', ') %>
  • -Kõik päringud, mis algavad IP-aadressist <%= @white_ip.ipv4.presence || @white_ip.ipv6 %>, saavad meie süsteemis piiranguteta juurdepääsu. -Palun veenduge, et hoiaksite selle IP-aadressi turvalisust ja konfidentsiaalsust, et vältida volitamata juurdepääsu. +Päringud IP-aadressist <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> jõuavad nüüd .ee registrisüsteemini. +Palun hoidke selle IP-aadressi turvalisust ja konfidentsiaalsust, et vältida volitamata juurdepääsu.

    Kui Teil on küsimusi seoses Teie lubatud IP-aadressi aktiveerimisega, võtke meiega ühendust.

    @@ -32,7 +32,7 @@ We would like to inform you that the whitelisted IP address associated with your
  • Interfaces: <%= @white_ip.interfaces.join(', ') %>
  • -All requests originating from the IP address <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> will now have unrestricted access to our system. +All requests originating from the IP address <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> will now have access to our system. Please ensure the security and confidentiality of this IP address to prevent unauthorized access.

    If you have any questions regarding the activation of your whitelisted IP address, please contact us. diff --git a/app/views/mailers/white_ip_mailer/committed.text.erb b/app/views/mailers/white_ip_mailer/committed.text.erb index fb38714df..8c8928485 100644 --- a/app/views/mailers/white_ip_mailer/committed.text.erb +++ b/app/views/mailers/white_ip_mailer/committed.text.erb @@ -6,8 +6,8 @@ IP-aadressi andmed: - IP-aadress: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> - Liidesed: <%= @white_ip.interfaces.join(', ') %> -Kõik päringud, mis algavad IP-aadressist <%= @white_ip.ipv4.presence || @white_ip.ipv6 %>, saavad meie süsteemis piiranguteta juurdepääsu. -Palun veenduge, et hoiaksite selle IP-aadressi turvalisust ja konfidentsiaalsust, et vältida volitamata juurdepääsu. +Päringud IP-aadressist <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> jõuavad nüüd .ee registrisüsteemini. +Palun hoidke selle IP-aadressi turvalisust ja konfidentsiaalsust, et vältida volitamata juurdepääsu. Kui Teil on küsimusi seoses Teie lubatud IP-aadressi aktiveerimisega, võtke meiega ühendust. @@ -23,7 +23,7 @@ IP address Details: - IP address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> - Interfaces: <%= @white_ip.interfaces.join(', ') %> -All requests originating from the IP address <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> will now have unrestricted access to our system. +All requests originating from the IP address <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> will now have access to our system. Please ensure the security and confidentiality of this IP address to prevent unauthorized access. If you have any questions regarding the activation of your whitelisted IP address, please contact us. From f68d8e91c259f5af0814447fe2f973dae0d7d26c Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 10 Jul 2023 09:51:56 +0300 Subject: [PATCH 12/21] Add admin mailers and tests to white_ips --- .../repp/v1/white_ips_controller.rb | 2 +- .../api_ip_address_deleted.html.erb | 1 + .../api_ip_address_deleted.text.erb | 1 + .../api_ip_address_updated.html.erb | 1 + .../api_ip_address_updated.text.erb | 1 + .../repp/v1/white_ips/create_test.rb | 34 +++++++++++++++++-- .../repp/v1/white_ips/delete_test.rb | 3 ++ .../repp/v1/white_ips/update_test.rb | 8 +++-- 8 files changed, 45 insertions(+), 6 deletions(-) diff --git a/app/controllers/repp/v1/white_ips_controller.rb b/app/controllers/repp/v1/white_ips_controller.rb index beb3cde03..c7ab1dc84 100644 --- a/app/controllers/repp/v1/white_ips_controller.rb +++ b/app/controllers/repp/v1/white_ips_controller.rb @@ -58,7 +58,7 @@ module Repp return end - uncommit_and_notify_admins(ip: ip, action: 'deleted') if ip.interfaces.include?(WhiteIp::API) + uncommit_and_notify_admins(ip: ip, action: 'deleted') if api_interface?(ip) render_success end diff --git a/app/views/mailers/white_ip_mailer/api_ip_address_deleted.html.erb b/app/views/mailers/white_ip_mailer/api_ip_address_deleted.html.erb index 789d79bb5..fe558d5e4 100644 --- a/app/views/mailers/white_ip_mailer/api_ip_address_deleted.html.erb +++ b/app/views/mailers/white_ip_mailer/api_ip_address_deleted.html.erb @@ -1,6 +1,7 @@

    This email is to inform you that an API Whitelisted IP address was deleted by Registrar Portal API user. Please review the details below:

      +
    • Registrar: <%= @api_user.registrar.name %>
    • API User: <%= @api_user.username %>
    • IP Address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %>
    • Interface: <%= @white_ip.interfaces.join(', ') %>
    • diff --git a/app/views/mailers/white_ip_mailer/api_ip_address_deleted.text.erb b/app/views/mailers/white_ip_mailer/api_ip_address_deleted.text.erb index d7554c703..73eca3594 100644 --- a/app/views/mailers/white_ip_mailer/api_ip_address_deleted.text.erb +++ b/app/views/mailers/white_ip_mailer/api_ip_address_deleted.text.erb @@ -1,5 +1,6 @@ This email is to inform you about an API Whitelisted IP address change by Registrar Portal API user. Please review the details below: +Registrar: <%= @api_user.registrar.name %> API User: <%= @api_user.username %> IP Address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> Interface: <%= @white_ip.interfaces.join(', ') %> diff --git a/app/views/mailers/white_ip_mailer/api_ip_address_updated.html.erb b/app/views/mailers/white_ip_mailer/api_ip_address_updated.html.erb index 3e71d3253..927adc50f 100644 --- a/app/views/mailers/white_ip_mailer/api_ip_address_updated.html.erb +++ b/app/views/mailers/white_ip_mailer/api_ip_address_updated.html.erb @@ -1,6 +1,7 @@

      This email is to inform you about an API Whitelisted IP address change by Registrar Portal API user. Please review the details below:

        +
      • Registrar: <%= @api_user.registrar.name %>
      • API User: <%= @api_user.username %>
      • IP Address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %>
      • Interface: <%= @white_ip.interfaces.join(', ') %>
      • diff --git a/app/views/mailers/white_ip_mailer/api_ip_address_updated.text.erb b/app/views/mailers/white_ip_mailer/api_ip_address_updated.text.erb index d7554c703..73eca3594 100644 --- a/app/views/mailers/white_ip_mailer/api_ip_address_updated.text.erb +++ b/app/views/mailers/white_ip_mailer/api_ip_address_updated.text.erb @@ -1,5 +1,6 @@ This email is to inform you about an API Whitelisted IP address change by Registrar Portal API user. Please review the details below: +Registrar: <%= @api_user.registrar.name %> API User: <%= @api_user.username %> IP Address: <%= @white_ip.ipv4.presence || @white_ip.ipv6 %> Interface: <%= @white_ip.interfaces.join(', ') %> diff --git a/test/integration/repp/v1/white_ips/create_test.rb b/test/integration/repp/v1/white_ips/create_test.rb index 326edbdfe..fcbe5e987 100644 --- a/test/integration/repp/v1/white_ips/create_test.rb +++ b/test/integration/repp/v1/white_ips/create_test.rb @@ -16,7 +16,7 @@ class ReppV1WhiteIpsCreateTest < ActionDispatch::IntegrationTest request_body = { white_ip: { address: '127.1.1.1', - interfaces: ['API'], + interfaces: ['api'], }, } @@ -31,13 +31,41 @@ class ReppV1WhiteIpsCreateTest < ActionDispatch::IntegrationTest assert white_ip.present? assert_equal(request_body[:white_ip][:address], white_ip.ipv4) + refute white_ip.committed + + last_email = ActionMailer::Base.deliveries.last + assert last_email.subject.include?('Whitelisted IP Address Change Notification') + end + + def test_creates_new_white_ip_with_registrar_interface + request_body = { + white_ip: { + address: '127.1.1.1', + interfaces: ['registrar'], + }, + } + + post '/repp/v1/white_ips', headers: @auth_headers, params: request_body + json = JSON.parse(response.body, symbolize_names: true) + + assert_response :ok + assert_equal 1000, json[:code] + assert_equal 'Command completed successfully', json[:message] + + white_ip = WhiteIp.find(json[:data][:ip][:id]) + assert white_ip.present? + + assert_equal(request_body[:white_ip][:address], white_ip.ipv4) + assert white_ip.committed + + refute ActionMailer::Base.deliveries.last end def test_validates_ip_max_count request_body = { white_ip: { address: '2001:db8::/120', - interfaces: ['API'], + interfaces: ['api'], }, } @@ -55,7 +83,7 @@ class ReppV1WhiteIpsCreateTest < ActionDispatch::IntegrationTest request_body = { white_ip: { address: '127.0.0.1', - interfaces: ['API'], + interfaces: ['api'], }, } diff --git a/test/integration/repp/v1/white_ips/delete_test.rb b/test/integration/repp/v1/white_ips/delete_test.rb index e37d346e5..8300e2b4d 100644 --- a/test/integration/repp/v1/white_ips/delete_test.rb +++ b/test/integration/repp/v1/white_ips/delete_test.rb @@ -21,6 +21,9 @@ class ReppV1WhiteIpsDeleteTest < ActionDispatch::IntegrationTest assert_equal 1000, json[:code] assert_equal 'Command completed successfully', json[:message] refute WhiteIp.exists?(ip.id) + + last_email = ActionMailer::Base.deliveries.last + assert last_email.subject.include?('Whitelisted IP Address Removal Notification') end def test_returns_error_response_if_throttled diff --git a/test/integration/repp/v1/white_ips/update_test.rb b/test/integration/repp/v1/white_ips/update_test.rb index b04d357be..a38aba671 100644 --- a/test/integration/repp/v1/white_ips/update_test.rb +++ b/test/integration/repp/v1/white_ips/update_test.rb @@ -16,7 +16,7 @@ class ReppV1ApiWhiteIpsUpdateTest < ActionDispatch::IntegrationTest def test_updates_white_ip request_body = { white_ip: { - address: '127.0.0.1', + address: '127.0.0.2', }, } @@ -28,7 +28,11 @@ class ReppV1ApiWhiteIpsUpdateTest < ActionDispatch::IntegrationTest assert_equal 'Command completed successfully', json[:message] ip = WhiteIp.find(json[:data][:ip][:id]) - assert_equal ip.ipv4, @white_ip.ipv4 + assert_equal ip.ipv4, '127.0.0.2' + refute ip.committed + + last_email = ActionMailer::Base.deliveries.last + assert last_email.subject.include?('Whitelisted IP Address Change Notification') end def test_returns_error_if_ipv4_wrong_format From 43e088e852a665b3ee4b98a40e34fd4f8a1efba8 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 10 Jul 2023 10:32:38 +0300 Subject: [PATCH 13/21] Updated admin integration test --- test/integration/admin_area/white_ips_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/integration/admin_area/white_ips_test.rb b/test/integration/admin_area/white_ips_test.rb index 197759387..05b87d45f 100644 --- a/test/integration/admin_area/white_ips_test.rb +++ b/test/integration/admin_area/white_ips_test.rb @@ -46,9 +46,13 @@ class AdminAreaWhiteIpsIntegrationTest < JavaScriptApplicationSystemTestCase fill_in 'IPv4', with: '127.0.0.2' find(:css, '#white_ip_interfaces_api').set(false) + find(:css, '#white_ip_committed').set(false) click_on 'Save' assert_text 'Record updated' + last_email = ActionMailer::Base.deliveries.last + assert last_email.subject.include?('Whitelisted IP Address Activation Confirmation') + assert_equal last_email.to, @registrar.email end def test_failed_to_update_whitelisted_ip From b7f31ea7e2f969d832d8d418bce25eea3a4694ec Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 10 Jul 2023 10:37:35 +0300 Subject: [PATCH 14/21] Updated admin integration test --- test/integration/admin_area/white_ips_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/admin_area/white_ips_test.rb b/test/integration/admin_area/white_ips_test.rb index 05b87d45f..b46a4e87f 100644 --- a/test/integration/admin_area/white_ips_test.rb +++ b/test/integration/admin_area/white_ips_test.rb @@ -46,7 +46,7 @@ class AdminAreaWhiteIpsIntegrationTest < JavaScriptApplicationSystemTestCase fill_in 'IPv4', with: '127.0.0.2' find(:css, '#white_ip_interfaces_api').set(false) - find(:css, '#white_ip_committed').set(false) + find(:css, '#white_ip_committed').set(true) click_on 'Save' assert_text 'Record updated' From c5dc81ede9d1d9ae4b82af6906e48105d6cf3d8c Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 10 Jul 2023 11:35:40 +0300 Subject: [PATCH 15/21] Updated admin integration test --- test/integration/admin_area/white_ips_test.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/integration/admin_area/white_ips_test.rb b/test/integration/admin_area/white_ips_test.rb index b46a4e87f..93e944a58 100644 --- a/test/integration/admin_area/white_ips_test.rb +++ b/test/integration/admin_area/white_ips_test.rb @@ -41,6 +41,7 @@ class AdminAreaWhiteIpsIntegrationTest < JavaScriptApplicationSystemTestCase end def test_update_whitelisted_ip + @white_ip.update!(committed: false) visit_info_whitelisted_ip_page click_on 'Edit' @@ -50,6 +51,8 @@ class AdminAreaWhiteIpsIntegrationTest < JavaScriptApplicationSystemTestCase click_on 'Save' assert_text 'Record updated' + assert @white_ip.committed + last_email = ActionMailer::Base.deliveries.last assert last_email.subject.include?('Whitelisted IP Address Activation Confirmation') assert_equal last_email.to, @registrar.email From f5ed46c9a33d6d302be8d1f82ce1a22b2c65f1f6 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 10 Jul 2023 12:07:03 +0300 Subject: [PATCH 16/21] Updated admin integration test --- test/integration/admin_area/white_ips_test.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/integration/admin_area/white_ips_test.rb b/test/integration/admin_area/white_ips_test.rb index 93e944a58..3165aafdf 100644 --- a/test/integration/admin_area/white_ips_test.rb +++ b/test/integration/admin_area/white_ips_test.rb @@ -41,12 +41,19 @@ class AdminAreaWhiteIpsIntegrationTest < JavaScriptApplicationSystemTestCase end def test_update_whitelisted_ip - @white_ip.update!(committed: false) visit_info_whitelisted_ip_page click_on 'Edit' fill_in 'IPv4', with: '127.0.0.2' find(:css, '#white_ip_interfaces_api').set(false) + find(:css, '#white_ip_committed').set(false) + click_on 'Save' + + assert_text 'Record updated' + refute @white_ip.committed + + click_on 'Edit' + find(:css, '#white_ip_committed').set(true) click_on 'Save' From 52405e179691fa359aa70dab3562ffd0b19df6ef Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 10 Jul 2023 12:14:03 +0300 Subject: [PATCH 17/21] Updated admin integration test --- test/integration/admin_area/white_ips_test.rb | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/test/integration/admin_area/white_ips_test.rb b/test/integration/admin_area/white_ips_test.rb index 3165aafdf..197759387 100644 --- a/test/integration/admin_area/white_ips_test.rb +++ b/test/integration/admin_area/white_ips_test.rb @@ -46,23 +46,9 @@ class AdminAreaWhiteIpsIntegrationTest < JavaScriptApplicationSystemTestCase fill_in 'IPv4', with: '127.0.0.2' find(:css, '#white_ip_interfaces_api').set(false) - find(:css, '#white_ip_committed').set(false) click_on 'Save' assert_text 'Record updated' - refute @white_ip.committed - - click_on 'Edit' - - find(:css, '#white_ip_committed').set(true) - click_on 'Save' - - assert_text 'Record updated' - assert @white_ip.committed - - last_email = ActionMailer::Base.deliveries.last - assert last_email.subject.include?('Whitelisted IP Address Activation Confirmation') - assert_equal last_email.to, @registrar.email end def test_failed_to_update_whitelisted_ip From fe6015491c31130b9b212e77a1850935b6d6d91d Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 10 Jul 2023 14:40:18 +0300 Subject: [PATCH 18/21] Updated base_test --- Gemfile | 1 + Gemfile.lock | 4 ++- app/controllers/repp/v1/base_controller.rb | 20 ++++++++---- app/models/registrar.rb | 6 ++++ test/integration/repp/v1/base_test.rb | 32 +++++++++++++++++-- .../repp/v1/registrar/auth/check_info_test.rb | 10 +++--- test/test_helper.rb | 1 + 7 files changed, 59 insertions(+), 15 deletions(-) diff --git a/Gemfile b/Gemfile index 68272c056..69cecca3a 100644 --- a/Gemfile +++ b/Gemfile @@ -89,6 +89,7 @@ group :test do gem 'capybara' gem 'database_cleaner' gem 'minitest', '~> 5.17' + gem 'minitest-stub_any_instance' gem 'simplecov', '0.17.1', require: false # CC last supported v0.17 gem 'spy' gem 'webdrivers' diff --git a/Gemfile.lock b/Gemfile.lock index 7e1dd7d1d..db74c3f63 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -311,6 +311,7 @@ GEM mini_mime (1.1.2) mini_portile2 (2.8.2) minitest (5.18.1) + minitest-stub_any_instance (1.0.3) monetize (1.9.4) money (~> 6.12) money (6.13.8) @@ -571,6 +572,7 @@ DEPENDENCIES mime-types-data mimemagic (= 0.4.3) minitest (~> 5.17) + minitest-stub_any_instance money-rails newrelic-infinite_tracing newrelic_rpm @@ -606,4 +608,4 @@ DEPENDENCIES wkhtmltopdf-binary (~> 0.12.6.1) BUNDLED WITH - 2.4.13 + 2.4.14 diff --git a/app/controllers/repp/v1/base_controller.rb b/app/controllers/repp/v1/base_controller.rb index 1c6119422..b14b9768d 100644 --- a/app/controllers/repp/v1/base_controller.rb +++ b/app/controllers/repp/v1/base_controller.rb @@ -122,12 +122,16 @@ module Repp end def check_ip_restriction - return if webclient_request? - return if @current_user.registrar.api_ip_white?(request.ip) + return if webclient_request? && registrar_ip_white? + return if !webclient_request? && @current_user.registrar.api_ip_white?(request.ip) - @response = { code: 2202, - message: I18n.t('registrar.authorization.ip_not_allowed', ip: request.ip) } - render(json: @response, status: :unauthorized) + render_unauthorized_response + end + + def registrar_ip_white? + return true unless request.headers['X-Client-IP'] + + @current_user.registrar.registrar_ip_white?(request.headers['X-Client-IP']) end def render_unauthorized_response @@ -138,7 +142,11 @@ module Repp def webclient_request? return false if Rails.env.test? || Rails.env.development? - ENV['webclient_ips'].split(',').map(&:strip).include?(request.ip) + webclient_ips.include?(request.ip) + end + + def webclient_ips + ENV['webclient_ips'].to_s.split(',').map(&:strip) end def validate_webclient_ca diff --git a/app/models/registrar.rb b/app/models/registrar.rb index cdcdbcc7b..71dddaa7f 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -200,6 +200,12 @@ class Registrar < ApplicationRecord # rubocop:disable Metrics/ClassLength white_ips.api.include_ip?(ip) end + def registrar_ip_white?(ip) + return true unless Setting.registrar_ip_whitelist_enabled + + white_ips.registrar_area.include_ip?(ip) + end + def accredited? api_users.any? do |a| return true unless a.accreditation_date.nil? diff --git a/test/integration/repp/v1/base_test.rb b/test/integration/repp/v1/base_test.rb index d0baed30e..ed69eba13 100644 --- a/test/integration/repp/v1/base_test.rb +++ b/test/integration/repp/v1/base_test.rb @@ -51,13 +51,39 @@ class ReppV1BaseTest < ActionDispatch::IntegrationTest whiteip.update(ipv4: '1.1.1.1') get repp_v1_contacts_path, headers: @auth_headers + + assert_unauthorized_ip + + Setting.api_ip_whitelist_enabled = false + Setting.registrar_ip_whitelist_enabled = false + end + + def test_takes_ip_whitelist_into_account_if_webclient_request + Setting.api_ip_whitelist_enabled = true + Setting.registrar_ip_whitelist_enabled = true + + whiteip = white_ips(:one) + whiteip.update(interfaces: ['api']) + + Repp::V1::BaseController.stub_any_instance(:webclient_request?, true) do + Repp::V1::BaseController.stub_any_instance(:validate_webclient_ca, true) do + get repp_v1_contacts_path, headers: @auth_headers.merge!({ 'X-Client-IP' => whiteip.ipv4 }) + end + end + + assert_unauthorized_ip + + Setting.api_ip_whitelist_enabled = false + Setting.registrar_ip_whitelist_enabled = false + end + + private + + def assert_unauthorized_ip response_json = JSON.parse(response.body, symbolize_names: true) assert_response :unauthorized assert_equal 2202, response_json[:code] assert response_json[:message].include? 'Access denied from IP' - - Setting.api_ip_whitelist_enabled = false - Setting.registrar_ip_whitelist_enabled = false end end diff --git a/test/integration/repp/v1/registrar/auth/check_info_test.rb b/test/integration/repp/v1/registrar/auth/check_info_test.rb index 154e8e258..8fd321db1 100644 --- a/test/integration/repp/v1/registrar/auth/check_info_test.rb +++ b/test/integration/repp/v1/registrar/auth/check_info_test.rb @@ -8,7 +8,7 @@ class ReppV1RegistrarAuthCheckInfoTest < ActionDispatch::IntegrationTest @auth_headers = { 'Authorization' => token } - adapter = ENV["shunter_default_adapter"].constantize.new + adapter = ENV['shunter_default_adapter'].constantize.new adapter&.clear! end @@ -40,8 +40,8 @@ class ReppV1RegistrarAuthCheckInfoTest < ActionDispatch::IntegrationTest end def test_returns_error_response_if_throttled - ENV["shunter_default_threshold"] = '1' - ENV["shunter_enabled"] = 'true' + ENV['shunter_default_threshold'] = '1' + ENV['shunter_enabled'] = 'true' get '/repp/v1/registrar/auth', headers: @auth_headers get '/repp/v1/registrar/auth', headers: @auth_headers @@ -50,7 +50,7 @@ class ReppV1RegistrarAuthCheckInfoTest < ActionDispatch::IntegrationTest assert_response :bad_request assert_equal json[:code], 2502 assert response.body.include?(Shunter.default_error_message) - ENV["shunter_default_threshold"] = '10000' - ENV["shunter_enabled"] = 'false' + ENV['shunter_default_threshold'] = '10000' + ENV['shunter_enabled'] = 'false' end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 0cd407f84..ca63e2f35 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -19,6 +19,7 @@ require 'webmock/minitest' require 'support/assertions/epp_assertions' require 'sidekiq/testing' require 'spy/integration' +require 'minitest/stub_any_instance' Sidekiq::Testing.fake! From 1dcfd1d4149a1c29cc8ac8385fa292f572e22cb5 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 10 Jul 2023 15:47:59 +0300 Subject: [PATCH 19/21] Updated base_controller.rb --- app/controllers/repp/v1/base_controller.rb | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/app/controllers/repp/v1/base_controller.rb b/app/controllers/repp/v1/base_controller.rb index b14b9768d..f2e448b85 100644 --- a/app/controllers/repp/v1/base_controller.rb +++ b/app/controllers/repp/v1/base_controller.rb @@ -122,20 +122,25 @@ module Repp end def check_ip_restriction - return if webclient_request? && registrar_ip_white? - return if !webclient_request? && @current_user.registrar.api_ip_white?(request.ip) + if webclient_request? + ip = request.headers['X-Client-IP'] + return if registrar_ip_white?(ip) + else + ip = request.ip + return if @current_user.registrar.api_ip_white?(ip) + end - render_unauthorized_response + render_unauthorized_response(ip) end - def registrar_ip_white? - return true unless request.headers['X-Client-IP'] + def registrar_ip_white?(ip) + return true unless ip - @current_user.registrar.registrar_ip_white?(request.headers['X-Client-IP']) + @current_user.registrar.registrar_ip_white?(ip) end - def render_unauthorized_response - @response = { code: 2202, message: I18n.t('registrar.authorization.ip_not_allowed', ip: request.ip) } + def render_unauthorized_response(ip) + @response = { code: 2202, message: I18n.t('registrar.authorization.ip_not_allowed', ip: ip) } render json: @response, status: :unauthorized end From 5c1cede31ec049f2d26dcc596ca1f6497a667018 Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Mon, 10 Jul 2023 15:56:45 +0300 Subject: [PATCH 20/21] Fixed codeclimate issue --- app/controllers/repp/v1/base_controller.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/repp/v1/base_controller.rb b/app/controllers/repp/v1/base_controller.rb index f2e448b85..d2057599e 100644 --- a/app/controllers/repp/v1/base_controller.rb +++ b/app/controllers/repp/v1/base_controller.rb @@ -122,13 +122,9 @@ module Repp end def check_ip_restriction - if webclient_request? - ip = request.headers['X-Client-IP'] - return if registrar_ip_white?(ip) - else - ip = request.ip - return if @current_user.registrar.api_ip_white?(ip) - end + ip = webclient_request? ? request.headers['X-Client-IP'] : request.ip + return if registrar_ip_white?(ip) && webclient_request? + return if api_ip_white?(ip) && !webclient_request? render_unauthorized_response(ip) end @@ -139,6 +135,10 @@ module Repp @current_user.registrar.registrar_ip_white?(ip) end + def api_ip_white?(ip) + @current_user.registrar.api_ip_white?(ip) + end + def render_unauthorized_response(ip) @response = { code: 2202, message: I18n.t('registrar.authorization.ip_not_allowed', ip: ip) } render json: @response, status: :unauthorized From 3784677af286123863261459880cea5baa57914c Mon Sep 17 00:00:00 2001 From: Sergey Tsyganov Date: Tue, 11 Jul 2023 11:04:35 +0300 Subject: [PATCH 21/21] Updated white_ips_test.rb integration test --- test/integration/admin_area/white_ips_test.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/integration/admin_area/white_ips_test.rb b/test/integration/admin_area/white_ips_test.rb index 197759387..06f314e77 100644 --- a/test/integration/admin_area/white_ips_test.rb +++ b/test/integration/admin_area/white_ips_test.rb @@ -46,9 +46,21 @@ class AdminAreaWhiteIpsIntegrationTest < JavaScriptApplicationSystemTestCase fill_in 'IPv4', with: '127.0.0.2' find(:css, '#white_ip_interfaces_api').set(false) + find(:css, '#white_ip_committed').set(false) click_on 'Save' assert_text 'Record updated' + + click_on 'Edit' + + find(:css, '#white_ip_interfaces_api').set(false) + find(:css, '#white_ip_committed').set(true) + click_on 'Save' + + assert_text 'Record updated' + last_email = ActionMailer::Base.deliveries.last + assert last_email.subject.include?('Whitelisted IP Address Activation Confirmation') + assert last_email.to.include?(@registrar.email) end def test_failed_to_update_whitelisted_ip