summaryrefslogtreecommitdiff
path: root/lib/gitlab/middleware/multipart.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/middleware/multipart.rb')
-rw-r--r--lib/gitlab/middleware/multipart.rb124
1 files changed, 26 insertions, 98 deletions
diff --git a/lib/gitlab/middleware/multipart.rb b/lib/gitlab/middleware/multipart.rb
index a6d8a778e05..79f1abe820f 100644
--- a/lib/gitlab/middleware/multipart.rb
+++ b/lib/gitlab/middleware/multipart.rb
@@ -41,7 +41,7 @@ module Gitlab
end
def with_open_files
- @rewritten_fields.each do |field, tmp_path|
+ @rewritten_fields.keys.each do |field|
raise "invalid field: #{field.inspect}" unless valid_field_name?(field)
parsed_field = Rack::Utils.parse_nested_query(field)
@@ -51,10 +51,10 @@ module Gitlab
if value.nil? # we have a top level param, eg. field = 'foo' and not 'foo[bar]'
raise "invalid field: #{field.inspect}" if field != key
- value = open_file(@request.params, key, tmp_path.presence)
+ value = open_file(extract_upload_params_from(@request.params, with_prefix: key))
@open_files << value
else
- value = decorate_params_value(value, @request.params[key], tmp_path.presence)
+ value = decorate_params_value(value, @request.params[key])
end
update_param(key, value)
@@ -67,12 +67,12 @@ module Gitlab
end
# This function calls itself recursively
- def decorate_params_value(path_hash, value_hash, path_override = nil)
- unless path_hash.is_a?(Hash) && path_hash.count == 1
- raise "invalid path: #{path_hash.inspect}"
+ def decorate_params_value(hash_path, value_hash)
+ unless hash_path.is_a?(Hash) && hash_path.count == 1
+ raise "invalid path: #{hash_path.inspect}"
end
- path_key, path_value = path_hash.first
+ path_key, path_value = hash_path.first
unless value_hash.is_a?(Hash) && value_hash[path_key]
raise "invalid value hash: #{value_hash.inspect}"
@@ -80,19 +80,19 @@ module Gitlab
case path_value
when nil
- value_hash[path_key] = open_file(value_hash.dig(path_key), '', path_override)
+ value_hash[path_key] = open_file(extract_upload_params_from(value_hash[path_key]))
@open_files << value_hash[path_key]
value_hash
when Hash
- decorate_params_value(path_value, value_hash[path_key], path_override)
+ decorate_params_value(path_value, value_hash[path_key])
value_hash
else
raise "unexpected path value: #{path_value.inspect}"
end
end
- def open_file(params, key, path_override = nil)
- ::UploadedFile.from_params(params, key, allowed_paths, path_override)
+ def open_file(params)
+ ::UploadedFile.from_params(params, allowed_paths)
end
# update_params ensures that both rails controllers and rack middleware can find
@@ -111,6 +111,20 @@ module Gitlab
private
+ def extract_upload_params_from(params, with_prefix: '')
+ param_key = "#{with_prefix}#{JWT_PARAM_SUFFIX}"
+ jwt_token = params[param_key]
+ raise "Empty JWT param: #{param_key}" if jwt_token.blank?
+
+ payload = Gitlab::Workhorse.decode_jwt(jwt_token).first
+ raise "Invalid JWT payload: not a Hash" unless payload.is_a?(Hash)
+
+ upload_params = payload.fetch(JWT_PARAM_FIXED_KEY, {})
+ raise "Empty params for: #{param_key}" if upload_params.empty?
+
+ upload_params
+ end
+
def valid_field_name?(name)
# length validation
return false if name.size >= REWRITTEN_FIELD_NAME_MAX_LENGTH
@@ -149,82 +163,6 @@ module Gitlab
end
end
- # TODO this class is meant to replace Handler when the feature flag
- # upload_middleware_jwt_params_handler is removed
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/233895#roll-out-steps
- class HandlerForJWTParams < Handler
- def with_open_files
- @rewritten_fields.keys.each do |field|
- raise "invalid field: #{field.inspect}" unless valid_field_name?(field)
-
- parsed_field = Rack::Utils.parse_nested_query(field)
- raise "unexpected field: #{field.inspect}" unless parsed_field.count == 1
-
- key, value = parsed_field.first
- if value.nil? # we have a top level param, eg. field = 'foo' and not 'foo[bar]'
- raise "invalid field: #{field.inspect}" if field != key
-
- value = open_file(extract_upload_params_from(@request.params, with_prefix: key))
- @open_files << value
- else
- value = decorate_params_value(value, @request.params[key])
- end
-
- update_param(key, value)
- end
-
- yield
- ensure
- @open_files.compact
- .each(&:close)
- end
-
- # This function calls itself recursively
- def decorate_params_value(hash_path, value_hash)
- unless hash_path.is_a?(Hash) && hash_path.count == 1
- raise "invalid path: #{hash_path.inspect}"
- end
-
- path_key, path_value = hash_path.first
-
- unless value_hash.is_a?(Hash) && value_hash[path_key]
- raise "invalid value hash: #{value_hash.inspect}"
- end
-
- case path_value
- when nil
- value_hash[path_key] = open_file(extract_upload_params_from(value_hash[path_key]))
- @open_files << value_hash[path_key]
- value_hash
- when Hash
- decorate_params_value(path_value, value_hash[path_key])
- value_hash
- else
- raise "unexpected path value: #{path_value.inspect}"
- end
- end
-
- def open_file(params)
- ::UploadedFile.from_params_without_field(params, allowed_paths)
- end
-
- private
-
- def extract_upload_params_from(params, with_prefix: '')
- param_key = "#{with_prefix}#{JWT_PARAM_SUFFIX}"
- jwt_token = params[param_key]
- raise "Empty JWT param: #{param_key}" if jwt_token.blank?
-
- payload = Gitlab::Workhorse.decode_jwt(jwt_token).first
- raise "Invalid JWT payload: not a Hash" unless payload.is_a?(Hash)
-
- upload_params = payload.fetch(JWT_PARAM_FIXED_KEY, {})
- raise "Empty params for: #{param_key}" if upload_params.empty?
-
- upload_params
- end
- end
-
def initialize(app)
@app = app
end
@@ -235,22 +173,12 @@ module Gitlab
message = ::Gitlab::Workhorse.decode_jwt(encoded_message)[0]
- handler_class.new(env, message).with_open_files do
+ ::Gitlab::Middleware::Multipart::Handler.new(env, message).with_open_files do
@app.call(env)
end
rescue UploadedFile::InvalidPathError => e
[400, { 'Content-Type' => 'text/plain' }, e.message]
end
-
- private
-
- def handler_class
- if Feature.enabled?(:upload_middleware_jwt_params_handler, default_enabled: true)
- ::Gitlab::Middleware::Multipart::HandlerForJWTParams
- else
- ::Gitlab::Middleware::Multipart::Handler
- end
- end
end
end
end