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!