2019-12-04 20:38:33 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
require 'spec_helper'
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
RSpec.describe Gitlab::Middleware::ReadOnly do
|
2018-03-17 18:26:18 +05:30
|
|
|
include Rack::Test::Methods
|
2018-11-08 19:23:39 +05:30
|
|
|
using RSpec::Parameterized::TableSyntax
|
2018-03-17 18:26:18 +05:30
|
|
|
|
|
|
|
let(:rack_stack) do
|
|
|
|
rack = Rack::Builder.new do
|
|
|
|
use ActionDispatch::Session::CacheStore
|
|
|
|
use ActionDispatch::Flash
|
|
|
|
end
|
|
|
|
|
|
|
|
rack.run(subject)
|
|
|
|
rack.to_app
|
|
|
|
end
|
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
let(:observe_env) do
|
|
|
|
Module.new do
|
|
|
|
attr_reader :env
|
|
|
|
|
|
|
|
def call(env)
|
|
|
|
@env = env
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
|
|
|
|
let(:request) { Rack::MockRequest.new(rack_stack) }
|
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
subject do
|
|
|
|
described_class.new(fake_app).tap do |app|
|
|
|
|
app.extend(observe_env)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-12-05 23:21:45 +05:30
|
|
|
context 'normal requests to a read-only GitLab instance' do
|
2018-03-17 18:26:18 +05:30
|
|
|
let(:fake_app) { lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ['OK']] } }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(Gitlab::Database).to receive(:read_only?) { true }
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects PATCH requests to be disallowed' do
|
|
|
|
response = request.patch('/test_request')
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
expect(response).to be_redirect
|
2018-03-17 18:26:18 +05:30
|
|
|
expect(subject).to disallow_request
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects PUT requests to be disallowed' do
|
|
|
|
response = request.put('/test_request')
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
expect(response).to be_redirect
|
2018-03-17 18:26:18 +05:30
|
|
|
expect(subject).to disallow_request
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects POST requests to be disallowed' do
|
|
|
|
response = request.post('/test_request')
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
expect(response).to be_redirect
|
2018-03-17 18:26:18 +05:30
|
|
|
expect(subject).to disallow_request
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects a internal POST request to be allowed after a disallowed request' do
|
|
|
|
response = request.post('/test_request')
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
expect(response).to be_redirect
|
2018-03-17 18:26:18 +05:30
|
|
|
|
|
|
|
response = request.post("/api/#{API::API.version}/internal")
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
expect(response).not_to be_redirect
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects DELETE requests to be disallowed' do
|
|
|
|
response = request.delete('/test_request')
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
expect(response).to be_redirect
|
2018-03-17 18:26:18 +05:30
|
|
|
expect(subject).to disallow_request
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects POST of new file that looks like an LFS batch url to be disallowed' do
|
|
|
|
expect(Rails.application.routes).to receive(:recognize_path).and_call_original
|
|
|
|
response = request.post('/root/gitlab-ce/new/master/app/info/lfs/objects/batch')
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
expect(response).to be_redirect
|
2018-03-17 18:26:18 +05:30
|
|
|
expect(subject).to disallow_request
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns last_vistited_url for disallowed request' do
|
|
|
|
response = request.post('/test_request')
|
|
|
|
|
|
|
|
expect(response.location).to eq 'http://localhost/'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'whitelisted requests' do
|
|
|
|
it 'expects a POST internal request to be allowed' do
|
|
|
|
expect(Rails.application.routes).not_to receive(:recognize_path)
|
|
|
|
response = request.post("/api/#{API::API.version}/internal")
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
expect(response).not_to be_redirect
|
2018-03-17 18:26:18 +05:30
|
|
|
expect(subject).not_to disallow_request
|
|
|
|
end
|
|
|
|
|
2019-12-21 20:55:43 +05:30
|
|
|
it 'expects a graphql request to be allowed' do
|
|
|
|
response = request.post("/api/graphql")
|
|
|
|
|
|
|
|
expect(response).not_to be_redirect
|
|
|
|
expect(subject).not_to disallow_request
|
|
|
|
end
|
|
|
|
|
2020-10-24 23:57:45 +05:30
|
|
|
context 'relative URL is configured' do
|
|
|
|
before do
|
|
|
|
stub_config_setting(relative_url_root: '/gitlab')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects a graphql request to be allowed' do
|
|
|
|
response = request.post("/gitlab/api/graphql")
|
|
|
|
|
|
|
|
expect(response).not_to be_redirect
|
|
|
|
expect(subject).not_to disallow_request
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-03-02 22:35:43 +05:30
|
|
|
context 'sidekiq admin requests' do
|
|
|
|
where(:mounted_at) do
|
|
|
|
[
|
|
|
|
'',
|
|
|
|
'/',
|
|
|
|
'/gitlab',
|
|
|
|
'/gitlab/',
|
|
|
|
'/gitlab/gitlab',
|
|
|
|
'/gitlab/gitlab/'
|
|
|
|
]
|
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
|
2019-03-02 22:35:43 +05:30
|
|
|
with_them do
|
|
|
|
before do
|
|
|
|
stub_config_setting(relative_url_root: mounted_at)
|
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
|
2019-03-02 22:35:43 +05:30
|
|
|
it 'allows requests' do
|
|
|
|
path = File.join(mounted_at, 'admin/sidekiq')
|
|
|
|
response = request.post(path)
|
2018-03-17 18:26:18 +05:30
|
|
|
|
2019-03-02 22:35:43 +05:30
|
|
|
expect(response).not_to be_redirect
|
|
|
|
expect(subject).not_to disallow_request
|
|
|
|
|
|
|
|
response = request.get(path)
|
|
|
|
|
|
|
|
expect(response).not_to be_redirect
|
|
|
|
expect(subject).not_to disallow_request
|
|
|
|
end
|
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
where(:description, :path) do
|
|
|
|
'LFS request to batch' | '/root/rouge.git/info/lfs/objects/batch'
|
|
|
|
'LFS request to locks verify' | '/root/rouge.git/info/lfs/locks/verify'
|
|
|
|
'LFS request to locks create' | '/root/rouge.git/info/lfs/locks'
|
|
|
|
'LFS request to locks unlock' | '/root/rouge.git/info/lfs/locks/1/unlock'
|
|
|
|
'request to git-upload-pack' | '/root/rouge.git/git-upload-pack'
|
|
|
|
'request to git-receive-pack' | '/root/rouge.git/git-receive-pack'
|
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
with_them do
|
|
|
|
it "expects a POST #{description} URL to be allowed" do
|
|
|
|
expect(Rails.application.routes).to receive(:recognize_path).and_call_original
|
|
|
|
response = request.post(path)
|
2018-03-17 18:26:18 +05:30
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
expect(response).not_to be_redirect
|
|
|
|
expect(subject).not_to disallow_request
|
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'json requests to a read-only GitLab instance' do
|
|
|
|
let(:fake_app) { lambda { |env| [200, { 'Content-Type' => 'application/json' }, ['OK']] } }
|
|
|
|
let(:content_json) { { 'CONTENT_TYPE' => 'application/json' } }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(Gitlab::Database).to receive(:read_only?) { true }
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects PATCH requests to be disallowed' do
|
|
|
|
response = request.patch('/test_request', content_json)
|
|
|
|
|
|
|
|
expect(response).to disallow_request_in_json
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects PUT requests to be disallowed' do
|
|
|
|
response = request.put('/test_request', content_json)
|
|
|
|
|
|
|
|
expect(response).to disallow_request_in_json
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects POST requests to be disallowed' do
|
|
|
|
response = request.post('/test_request', content_json)
|
|
|
|
|
|
|
|
expect(response).to disallow_request_in_json
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'expects DELETE requests to be disallowed' do
|
|
|
|
response = request.delete('/test_request', content_json)
|
|
|
|
|
|
|
|
expect(response).to disallow_request_in_json
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|