Commit bbfce29b authored by Lin Jen-Shin's avatar Lin Jen-Shin

Use a controller to hold request values

So that we don't need to hold env after the request.
This makes it much harder to test, especially Rails session is
acting weirdly, so we need `dig('flash', 'flashes', 'alert')`
to dig the actual flash value.
parent d4d564c8
......@@ -5,15 +5,13 @@ module Gitlab
APPLICATION_JSON = 'application/json'.freeze
API_VERSIONS = (3..4)
def initialize(app)
class Controller
def initialize(app, env)
@app = app
@whitelisted = internal_routes
end
def call(env)
@env = env
@route_hash = nil
end
def call
if disallowed_request? && Gitlab::Database.read_only?
Rails.logger.debug('GitLab ReadOnly: preventing possible non read-only operation')
error_message = 'You cannot do writing operations on a read-only GitLab instance'
......@@ -28,17 +26,14 @@ module Gitlab
end
end
@app.call(env).tap { @env = nil }
@app.call(@env)
end
private
def internal_routes
API_VERSIONS.flat_map { |version| "api/v#{version}/internal" }
end
def disallowed_request?
DISALLOWED_METHODS.include?(@env['REQUEST_METHOD']) && !whitelisted_routes
DISALLOWED_METHODS.include?(@env['REQUEST_METHOD']) &&
!whitelisted_routes
end
def json_request?
......@@ -66,7 +61,7 @@ module Gitlab
end
def whitelisted_routes
grack_route || @whitelisted.any? { |path| request.path.include?(path) } || lfs_route || sidekiq_route
grack_route || ReadOnly.internal_routes.any? { |path| request.path.include?(path) } || lfs_route || sidekiq_route
end
def sidekiq_route
......@@ -87,5 +82,19 @@ module Gitlab
route_hash[:controller] == 'projects/lfs_api' && route_hash[:action] == 'batch'
end
end
def self.internal_routes
@internal_routes ||=
API_VERSIONS.map { |version| "api/v#{version}/internal" }
end
def initialize(app)
@app = app
end
def call(env)
Controller.new(@app, env).call
end
end
end
end
......@@ -11,8 +11,10 @@ describe Gitlab::Middleware::ReadOnly do
RSpec::Matchers.define :disallow_request do
match do |middleware|
flash = middleware.send(:rack_flash)
flash['alert'] && flash['alert'].include?('You cannot do writing operations')
alert = middleware.env['rack.session'].to_hash
.dig('flash', 'flashes', 'alert')
alert&.include?('You cannot do writing operations')
end
end
......@@ -34,7 +36,22 @@ describe Gitlab::Middleware::ReadOnly do
rack.to_app
end
subject { described_class.new(fake_app) }
let(:observe_env) do
Module.new do
attr_reader :env
def call(env)
@env = env
super
end
end
end
subject do
app = described_class.new(fake_app)
app.extend(observe_env)
app
end
let(:request) { Rack::MockRequest.new(rack_stack) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment