Skip to content

Commit

Permalink
add request params key option
Browse files Browse the repository at this point in the history
  • Loading branch information
ota42y committed May 30, 2021
1 parent a57df65 commit 20de9ad
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 32 deletions.
1 change: 1 addition & 0 deletions lib/committee.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def self.warn_deprecated(message)
end
end

require_relative "committee/utils"
require_relative "committee/drivers"
require_relative "committee/errors"
require_relative "committee/middleware"
Expand Down
9 changes: 1 addition & 8 deletions lib/committee/request_unpacker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,13 @@
module Committee
class RequestUnpacker
class << self
# Creates a Hash with indifferent access.
#
# (Copied from Sinatra)
def indifferent_hash
Hash.new { |hash,key| hash[key.to_s] if Symbol === key }
end

# Enable string or symbol key access to the nested params hash.
#
# (Copied from Sinatra)
def indifferent_params(object)
case object
when Hash
new_hash = indifferent_hash
new_hash = Committee::Utils.indifferent_hash
object.each { |key, value| new_hash[key] = indifferent_params(value) }
new_hash
when Array
Expand Down
30 changes: 16 additions & 14 deletions lib/committee/schema_validator/hyper_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,8 @@ def initialize(router, request, validator_option)
end

def request_validate(request)
# Attempts to coerce parameters that appear in a link's URL to Ruby
# types that can be validated with a schema.
param_matches_hash = validator_option.coerce_path_params ? coerce_path_params : {}

# Attempts to coerce parameters that appear in a query string to Ruby
# types that can be validated with a schema.
coerce_query_params(request) if validator_option.coerce_query_params

request_unpack(request)

request.env[validator_option.params_key].merge!(param_matches_hash) if param_matches_hash

request_schema_validation(request)
parameter_coerce!(request, link, validator_option.params_key)
parameter_coerce!(request, link, "rack.request.query_hash") if link_exist? && !request.GET.nil? && !link.schema.nil?
Expand Down Expand Up @@ -53,7 +43,7 @@ def link_exist?
private

def coerce_path_params
return unless link_exist?
return {} unless link_exist?

Committee::SchemaValidator::HyperSchema::StringParamsCoercer.new(param_matches, link.schema, coerce_recursive: validator_option.coerce_recursive).call!
param_matches
Expand All @@ -74,13 +64,25 @@ def request_unpack(request)
optimistic_json: validator_option.optimistic_json,
)

request.env[validator_option.headers_key] = unpacker.unpack_headers(request)

# Attempts to coerce parameters that appear in a link's URL to Ruby
# types that can be validated with a schema.
param_matches_hash = validator_option.coerce_path_params ? coerce_path_params : {}

# Attempts to coerce parameters that appear in a query string to Ruby
# types that can be validated with a schema.
coerce_query_params(request) if validator_option.coerce_query_params

query_param = unpacker.unpack_query_params(request)
request_param, is_form_params = unpacker.unpack_request_params(request)

coerce_form_params(request_param) if validator_option.coerce_form_params && is_form_params
request.env[validator_option.params_key] = query_param.merge(request_param)
request.env[validator_option.request_body_hash_key] = request_param

request.env[validator_option.headers_key] = unpacker.unpack_headers(request)
request.env[validator_option.params_key] = Committee::Utils.indifferent_hash
request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(query_param))
request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(request_param))
request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(param_matches_hash))
end

def coerce_form_params(parameter)
Expand Down
20 changes: 11 additions & 9 deletions lib/committee/schema_validator/open_api_3.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@ def initialize(router, request, validator_option)
def request_validate(request)
return unless link_exist?

path_params = validator_option.coerce_path_params ? coerce_path_params : Committee::RequestUnpacker.indifferent_hash
request.env[validator_option.path_hash_key] = path_params

request_unpack(request)

request.env[validator_option.params_key]&.merge!(path_params) unless path_params.empty?

request_schema_validation(request)

copy_coerced_data_to_query_hash(request)
Expand Down Expand Up @@ -55,6 +49,7 @@ def link_exist?
attr_reader :validator_option

def coerce_path_params
return Committee::Utils.indifferent_hash unless validator_option.coerce_path_params
Committee::RequestUnpacker.indifferent_params(@operation_object.coerce_path_parameter(@validator_option))
end

Expand All @@ -77,11 +72,18 @@ def request_unpack(request)
optimistic_json: validator_option.optimistic_json,
)

query_param = unpacker.unpack_query_params(request)
request.env[validator_option.headers_key] = unpacker.unpack_headers(request)

request_param, is_form_params = unpacker.unpack_request_params(request)
request.env[validator_option.params_key] = query_param.merge(request_param)
request.env[validator_option.request_body_hash_key] = request_param
request.env[validator_option.path_hash_key] = coerce_path_params

request.env[validator_option.headers_key] = unpacker.unpack_headers(request)
query_param = unpacker.unpack_query_params(request)

request.env[validator_option.params_key] = Committee::Utils.indifferent_hash
request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(query_param))
request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(request.env[validator_option.request_body_hash_key]))
request.env[validator_option.params_key].merge!(Committee::Utils.deep_copy(request.env[validator_option.path_hash_key]))
end

def copy_coerced_data_to_query_hash(request)
Expand Down
2 changes: 2 additions & 0 deletions lib/committee/schema_validator/option.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Option
attr_reader :headers_key,
:params_key,
:query_hash_key,
:request_body_hash_key,
:path_hash_key,
:prefix

Expand All @@ -36,6 +37,7 @@ def initialize(options, schema, schema_type)
options.fetch(:query_hash_key)
end
@path_hash_key = options[:path_hash_key] || "committee.path_hash"
@request_body_hash_key = options[:request_body_hash_key] || "committee.request_body_hash"

@prefix = options[:prefix]

Expand Down
28 changes: 28 additions & 0 deletions lib/committee/utils.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

module Committee
module Utils
# Creates a Hash with indifferent access.
#
# (Copied from Sinatra)
def self.indifferent_hash
Hash.new { |hash,key| hash[key.to_s] if Symbol === key }
end

def self.deep_copy(from)
if from.is_a?(Hash)
h = Committee::Utils.indifferent_hash
from.each_pair do |k, v|
h[k] = deep_copy(v)
end
return h
end

if from.is_a?(Array)
return from.map{ |v| deep_copy(v) }
end

return from
end
end
end
16 changes: 16 additions & 0 deletions test/middleware/request_validation_open_api_3_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,22 @@ def app
assert_equal 204, last_response.status
end

it "corce string and save request body hash" do
@app = new_rack_app_with_lambda(lambda do |env|
assert_equal env['committee.params']['integer'], 21 # use path parameter
assert_equal env['committee.params'][:integer], 21
assert_equal env['committee.request_body_hash']['integer'], 42
assert_equal env['committee.request_body_hash'][:integer], 42
[204, {}, []]
end, schema: open_api_3_schema)

params = {integer: 42}

header "Content-Type", "application/json"
post '/parameter_option_test/21', JSON.generate(params)
assert_equal 204, last_response.status
end

it "unpacker test" do
@app = new_rack_app_with_lambda(lambda do |env|
assert_equal env['committee.params']['integer'], 42
Expand Down
3 changes: 2 additions & 1 deletion test/middleware/request_validation_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,10 @@ def app
assert_equal 200, last_response.status
end

it "aacorce form params" do
it "corce form params" do
check_parameter = lambda { |env|
assert_equal 3, env['committee.params']['age']
assert_equal 3, env['committee.request_body_hash']['age']
[200, {}, []]
}

Expand Down

0 comments on commit 20de9ad

Please sign in to comment.