diff options
Diffstat (limited to 'spec/lib/gitlab/rack_attack/request_spec.rb')
-rw-r--r-- | spec/lib/gitlab/rack_attack/request_spec.rb | 266 |
1 files changed, 263 insertions, 3 deletions
diff --git a/spec/lib/gitlab/rack_attack/request_spec.rb b/spec/lib/gitlab/rack_attack/request_spec.rb index ecdcc23e588..b8a26a64e5b 100644 --- a/spec/lib/gitlab/rack_attack/request_spec.rb +++ b/spec/lib/gitlab/rack_attack/request_spec.rb @@ -5,6 +5,20 @@ require 'spec_helper' RSpec.describe Gitlab::RackAttack::Request do using RSpec::Parameterized::TableSyntax + let(:path) { '/' } + let(:env) { {} } + let(:session) { {} } + let(:request) do + ::Rack::Attack::Request.new( + env.reverse_merge( + 'REQUEST_METHOD' => 'GET', + 'PATH_INFO' => Gitlab.config.gitlab.relative_url_root + path, + 'rack.input' => StringIO.new, + 'rack.session' => session + ) + ) + end + describe 'FILES_PATH_REGEX' do subject { described_class::FILES_PATH_REGEX } @@ -16,11 +30,249 @@ RSpec.describe Gitlab::RackAttack::Request do it { is_expected.not_to match('/api/v4/projects/some/nested/repo/repository/files/README') } end + describe '#api_request?' do + subject { request.api_request? } + + where(:path, :expected) do + '/' | false + '/groups' | false + '/foo/api' | false + + '/api' | true + '/api/v4/groups/1' | true + end + + with_them do + it { is_expected.to eq(expected) } + + context 'when the application is mounted at a relative URL' do + before do + stub_config_setting(relative_url_root: '/gitlab/root') + end + + it { is_expected.to eq(expected) } + end + end + end + + describe '#api_internal_request?' do + subject { request.api_internal_request? } + + where(:path, :expected) do + '/' | false + '/groups' | false + '/api' | false + '/api/v4/groups/1' | false + '/api/v4/internal' | false + '/foo/api/v4/internal' | false + + '/api/v4/internal/' | true + '/api/v4/internal/foo' | true + '/api/v1/internal/foo' | true + end + + with_them do + it { is_expected.to eq(expected) } + + context 'when the application is mounted at a relative URL' do + before do + stub_config_setting(relative_url_root: '/gitlab/root') + end + + it { is_expected.to eq(expected) } + end + end + end + + describe '#health_check_request?' do + subject { request.health_check_request? } + + where(:path, :expected) do + '/' | false + '/groups' | false + '/foo/-/health' | false + + '/-/health' | true + '/-/liveness' | true + '/-/readiness' | true + '/-/metrics' | true + '/-/health/foo' | true + '/-/liveness/foo' | true + '/-/readiness/foo' | true + '/-/metrics/foo' | true + end + + with_them do + it { is_expected.to eq(expected) } + + context 'when the application is mounted at a relative URL' do + before do + stub_config_setting(relative_url_root: '/gitlab/root') + end + + it { is_expected.to eq(expected) } + end + end + end + + describe '#container_registry_event?' do + subject { request.container_registry_event? } + + where(:path, :expected) do + '/' | false + '/groups' | false + '/api/v4/container_registry_event' | false + '/foo/api/v4/container_registry_event/' | false + + '/api/v4/container_registry_event/' | true + '/api/v4/container_registry_event/foo' | true + '/api/v1/container_registry_event/foo' | true + end + + with_them do + it { is_expected.to eq(expected) } + + context 'when the application is mounted at a relative URL' do + before do + stub_config_setting(relative_url_root: '/gitlab/root') + end + + it { is_expected.to eq(expected) } + end + end + end + + describe '#product_analytics_collector_request?' do + subject { request.product_analytics_collector_request? } + + where(:path, :expected) do + '/' | false + '/groups' | false + '/-/collector' | false + '/-/collector/foo' | false + '/foo/-/collector/i' | false + + '/-/collector/i' | true + '/-/collector/ifoo' | true + '/-/collector/i/foo' | true + end + + with_them do + it { is_expected.to eq(expected) } + + context 'when the application is mounted at a relative URL' do + before do + stub_config_setting(relative_url_root: '/gitlab/root') + end + + it { is_expected.to eq(expected) } + end + end + end + + describe '#should_be_skipped?' do + where( + api_internal_request: [true, false], + health_check_request: [true, false], + container_registry_event: [true, false] + ) + + with_them do + it 'returns true if any condition is true' do + allow(request).to receive(:api_internal_request?).and_return(api_internal_request) + allow(request).to receive(:health_check_request?).and_return(health_check_request) + allow(request).to receive(:container_registry_event?).and_return(container_registry_event) + + expect(request.should_be_skipped?).to be(api_internal_request || health_check_request || container_registry_event) + end + end + end + + describe '#web_request?' do + subject { request.web_request? } + + where(:path, :expected) do + '/' | true + '/groups' | true + '/foo/api' | true + + '/api' | false + '/api/v4/groups/1' | false + end + + with_them do + it { is_expected.to eq(expected) } + + context 'when the application is mounted at a relative URL' do + before do + stub_config_setting(relative_url_root: '/gitlab/root') + end + + it { is_expected.to eq(expected) } + end + end + end + + describe '#protected_path?' do + subject { request.protected_path? } + + before do + stub_application_setting(protected_paths: [ + '/protected', + '/secure' + ]) + end + + where(:path, :expected) do + '/' | false + '/groups' | false + '/foo/protected' | false + '/foo/secure' | false + + '/protected' | true + '/secure' | true + '/secure/' | true + '/secure/foo' | true + end + + with_them do + it { is_expected.to eq(expected) } + + context 'when the application is mounted at a relative URL' do + before do + stub_config_setting(relative_url_root: '/gitlab/root') + end + + it { is_expected.to eq(expected) } + end + end + end + + describe '#frontend_request?', :allow_forgery_protection do + subject { request.send(:frontend_request?) } + + let(:path) { '/' } + + # Define these as local variables so we can use them in the `where` block. + valid_token = SecureRandom.base64(ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH) + other_token = SecureRandom.base64(ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH) + + where(:session, :env, :expected) do + {} | {} | false # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands + {} | { 'HTTP_X_CSRF_TOKEN' => valid_token } | false + { _csrf_token: valid_token } | { 'HTTP_X_CSRF_TOKEN' => other_token } | false + { _csrf_token: valid_token } | { 'HTTP_X_CSRF_TOKEN' => valid_token } | true + end + + with_them do + it { is_expected.to eq(expected) } + end + end + describe '#deprecated_api_request?' do - let(:env) { { 'REQUEST_METHOD' => 'GET', 'rack.input' => StringIO.new, 'PATH_INFO' => path, 'QUERY_STRING' => query } } - let(:request) { ::Rack::Attack::Request.new(env) } + subject { request.send(:deprecated_api_request?) } - subject { !!request.__send__(:deprecated_api_request?) } + let(:env) { { 'QUERY_STRING' => query } } where(:path, :query, :expected) do '/' | '' | false @@ -42,6 +294,14 @@ RSpec.describe Gitlab::RackAttack::Request do with_them do it { is_expected.to eq(expected) } + + context 'when the application is mounted at a relative URL' do + before do + stub_config_setting(relative_url_root: '/gitlab/root') + end + + it { is_expected.to eq(expected) } + end end end end |