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 ...@@ -5,15 +5,13 @@ module Gitlab
APPLICATION_JSON = 'application/json'.freeze APPLICATION_JSON = 'application/json'.freeze
API_VERSIONS = (3..4) API_VERSIONS = (3..4)
def initialize(app) class Controller
def initialize(app, env)
@app = app @app = app
@whitelisted = internal_routes
end
def call(env)
@env = env @env = env
@route_hash = nil end
def call
if disallowed_request? && Gitlab::Database.read_only? if disallowed_request? && Gitlab::Database.read_only?
Rails.logger.debug('GitLab ReadOnly: preventing possible non read-only operation') Rails.logger.debug('GitLab ReadOnly: preventing possible non read-only operation')
error_message = 'You cannot do writing operations on a read-only GitLab instance' error_message = 'You cannot do writing operations on a read-only GitLab instance'
...@@ -28,17 +26,14 @@ module Gitlab ...@@ -28,17 +26,14 @@ module Gitlab
end end
end end
@app.call(env).tap { @env = nil } @app.call(@env)
end end
private private
def internal_routes
API_VERSIONS.flat_map { |version| "api/v#{version}/internal" }
end
def disallowed_request? def disallowed_request?
DISALLOWED_METHODS.include?(@env['REQUEST_METHOD']) && !whitelisted_routes DISALLOWED_METHODS.include?(@env['REQUEST_METHOD']) &&
!whitelisted_routes
end end
def json_request? def json_request?
...@@ -66,7 +61,7 @@ module Gitlab ...@@ -66,7 +61,7 @@ module Gitlab
end end
def whitelisted_routes 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 end
def sidekiq_route def sidekiq_route
...@@ -87,5 +82,19 @@ module Gitlab ...@@ -87,5 +82,19 @@ module Gitlab
route_hash[:controller] == 'projects/lfs_api' && route_hash[:action] == 'batch' route_hash[:controller] == 'projects/lfs_api' && route_hash[:action] == 'batch'
end end
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
end end
...@@ -11,8 +11,10 @@ describe Gitlab::Middleware::ReadOnly do ...@@ -11,8 +11,10 @@ describe Gitlab::Middleware::ReadOnly do
RSpec::Matchers.define :disallow_request do RSpec::Matchers.define :disallow_request do
match do |middleware| match do |middleware|
flash = middleware.send(:rack_flash) alert = middleware.env['rack.session'].to_hash
flash['alert'] && flash['alert'].include?('You cannot do writing operations') .dig('flash', 'flashes', 'alert')
alert&.include?('You cannot do writing operations')
end end
end end
...@@ -34,7 +36,22 @@ describe Gitlab::Middleware::ReadOnly do ...@@ -34,7 +36,22 @@ describe Gitlab::Middleware::ReadOnly do
rack.to_app rack.to_app
end 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) } 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