blob: 742a792a1af836ef95d1003a48acd724c7808116 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
require 'spec_helper'
describe Gitlab::Middleware::ReadOnly do
include Rack::Test::Methods
RSpec::Matchers.define :be_a_redirect do
match do |response|
response.status == 301
end
end
RSpec::Matchers.define :disallow_request do
match do |middleware|
flash = middleware.send(:rack_flash)
flash['alert'] && flash['alert'].include?('You cannot do writing operations')
end
end
RSpec::Matchers.define :disallow_request_in_json do
match do |response|
json_response = JSON.parse(response.body)
response.body.include?('You cannot do writing operations') && json_response.key?('message')
end
end
let(:rack_stack) do
rack = Rack::Builder.new do
use ActionDispatch::Session::CacheStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
end
rack.run(subject)
rack.to_app
end
subject { described_class.new(fake_app) }
let(:request) { Rack::MockRequest.new(rack_stack) }
context 'normal requests to a read-only Gitlab instance' do
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')
expect(response).to be_a_redirect
expect(subject).to disallow_request
end
it 'expects PUT requests to be disallowed' do
response = request.put('/test_request')
expect(response).to be_a_redirect
expect(subject).to disallow_request
end
it 'expects POST requests to be disallowed' do
response = request.post('/test_request')
expect(response).to be_a_redirect
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')
expect(response).to be_a_redirect
response = request.post("/api/#{API::API.version}/internal")
expect(response).not_to be_a_redirect
end
it 'expects DELETE requests to be disallowed' do
response = request.delete('/test_request')
expect(response).to be_a_redirect
expect(subject).to disallow_request
end
context 'whitelisted requests' do
it 'expects DELETE request to logout to be allowed' do
response = request.delete('/users/sign_out')
expect(response).not_to be_a_redirect
expect(subject).not_to disallow_request
end
it 'expects a POST internal request to be allowed' do
response = request.post("/api/#{API::API.version}/internal")
expect(response).not_to be_a_redirect
expect(subject).not_to disallow_request
end
it 'expects a POST LFS request to batch URL to be allowed' do
response = request.post('/root/rouge.git/info/lfs/objects/batch')
expect(response).not_to be_a_redirect
expect(subject).not_to disallow_request
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
|