committee 1.14.1 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5fcb82a192f894e1baec1dcab89f081782d222f
|
4
|
+
data.tar.gz: 54d056b8be5b297b6a524166363f955db7a1bd15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f22924efd2696d884eb499978cdb2a9f6e81ead9d25dacbe3ea331b9fb4d771886a4ccea1926fe2d09256886433a451fdbe25ef47cbe8d4c80a07a4157e0b9bc
|
7
|
+
data.tar.gz: db8d1aa50e4f4fa854bda1d5484df09e7262801bd845195c1340a718fc6d0792666360698ea2fe8722f1c57a287fcfb4b1f0258706032f47a2ef7cceaffd7df9
|
data/lib/committee.rb
CHANGED
@@ -3,6 +3,7 @@ require "json_schema"
|
|
3
3
|
require "rack"
|
4
4
|
|
5
5
|
require_relative "committee/errors"
|
6
|
+
require_relative "committee/query_params_coercer"
|
6
7
|
require_relative "committee/request_unpacker"
|
7
8
|
require_relative "committee/request_validator"
|
8
9
|
require_relative "committee/response_generator"
|
@@ -2,17 +2,29 @@ module Committee::Middleware
|
|
2
2
|
class RequestValidation < Base
|
3
3
|
def initialize(app, options={})
|
4
4
|
super
|
5
|
-
@allow_form_params
|
6
|
-
@allow_query_params
|
7
|
-
@check_content_type
|
8
|
-
@optimistic_json
|
9
|
-
@
|
5
|
+
@allow_form_params = options.fetch(:allow_form_params, true)
|
6
|
+
@allow_query_params = options.fetch(:allow_query_params, true)
|
7
|
+
@check_content_type = options.fetch(:check_content_type, true)
|
8
|
+
@optimistic_json = options.fetch(:optimistic_json, false)
|
9
|
+
@coerce_query_params = options.fetch(:coerce_query_params, false)
|
10
|
+
@strict = options[:strict]
|
10
11
|
|
11
12
|
# deprecated
|
12
13
|
@allow_extra = options[:allow_extra]
|
13
14
|
end
|
14
15
|
|
15
16
|
def handle(request)
|
17
|
+
link = @router.find_request_link(request)
|
18
|
+
|
19
|
+
if link && @coerce_query_params && !request.GET.nil? && !link.schema.nil?
|
20
|
+
request.env["rack.request.query_hash"].merge!(
|
21
|
+
Committee::QueryParamsCoercer.new(
|
22
|
+
request.GET,
|
23
|
+
link.schema
|
24
|
+
).call
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
16
28
|
request.env[@params_key] = Committee::RequestUnpacker.new(
|
17
29
|
request,
|
18
30
|
allow_form_params: @allow_form_params,
|
@@ -20,7 +32,7 @@ module Committee::Middleware
|
|
20
32
|
optimistic_json: @optimistic_json
|
21
33
|
).call
|
22
34
|
|
23
|
-
if link
|
35
|
+
if link
|
24
36
|
validator = Committee::RequestValidator.new(link, check_content_type: @check_content_type)
|
25
37
|
validator.call(request, request.env[@params_key])
|
26
38
|
@app.call(request.env)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Attempts to coerce params given in the query hash (which are all strings) into
|
2
|
+
# the types specified by the schema.
|
3
|
+
# Currently supported types: null, integer, number and boolean.
|
4
|
+
# +call+ returns a hash of all params which could be coerced - coercion errors
|
5
|
+
# are simply ignored and expected to be handled later by schema validation.
|
6
|
+
module Committee
|
7
|
+
class QueryParamsCoercer
|
8
|
+
def initialize(query_hash, schema)
|
9
|
+
@query_hash = query_hash
|
10
|
+
@schema = schema
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
coerced = {}
|
15
|
+
@schema.properties.each do |k, s|
|
16
|
+
original_val = @query_hash[k]
|
17
|
+
unless original_val.nil?
|
18
|
+
s.type.each do |to_type|
|
19
|
+
case to_type
|
20
|
+
when "null"
|
21
|
+
coerced[k] = nil if original_val.empty?
|
22
|
+
when "integer"
|
23
|
+
begin
|
24
|
+
coerced[k] = Integer(original_val)
|
25
|
+
rescue ArgumentError => e
|
26
|
+
raise e unless e.message =~ /invalid value for Integer/
|
27
|
+
end
|
28
|
+
when "number"
|
29
|
+
begin
|
30
|
+
coerced[k] = Float(original_val)
|
31
|
+
rescue ArgumentError => e
|
32
|
+
raise e unless e.message =~ /invalid value for Float/
|
33
|
+
end
|
34
|
+
when "boolean"
|
35
|
+
coerced[k] = true if original_val == "true"
|
36
|
+
coerced[k] = false if original_val == "false"
|
37
|
+
end
|
38
|
+
break if coerced.key?(k)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
coerced
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -94,6 +94,21 @@ describe Committee::Middleware::RequestValidation do
|
|
94
94
|
assert_equal 200, last_response.status
|
95
95
|
end
|
96
96
|
|
97
|
+
it "optionally coerces query params" do
|
98
|
+
@app = new_rack_app(coerce_query_params: true)
|
99
|
+
header "Content-Type", "application/json"
|
100
|
+
get "/search/apps", {"per_page" => "10", "query" => "cloudnasium"}
|
101
|
+
assert_equal 200, last_response.status
|
102
|
+
end
|
103
|
+
|
104
|
+
it "still raises an error if query param coercion is not possible" do
|
105
|
+
@app = new_rack_app(coerce_query_params: true)
|
106
|
+
header "Content-Type", "application/json"
|
107
|
+
get "/search/apps", {"per_page" => "foo", "query" => "cloudnasium"}
|
108
|
+
assert_equal 400, last_response.status
|
109
|
+
assert_match /invalid request/i, last_response.body
|
110
|
+
end
|
111
|
+
|
97
112
|
private
|
98
113
|
|
99
114
|
def new_rack_app(options = {})
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
describe Committee::QueryParamsCoercer do
|
4
|
+
before do
|
5
|
+
@schema =
|
6
|
+
JsonSchema.parse!(JSON.parse(File.read("./test/data/schema.json")))
|
7
|
+
@schema.expand_references!
|
8
|
+
# GET /search/apps
|
9
|
+
@link = @link = @schema.properties["app"].links[5]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "doesn't coerce params not in the schema" do
|
13
|
+
data = {"owner" => "admin"}
|
14
|
+
assert_equal({}, call(data))
|
15
|
+
end
|
16
|
+
|
17
|
+
it "skips values for string param" do
|
18
|
+
data = {"name" => "foo"}
|
19
|
+
assert_equal({}, call(data))
|
20
|
+
end
|
21
|
+
|
22
|
+
it "coerces valid values for boolean param" do
|
23
|
+
data = {"deleted" => "true"}
|
24
|
+
assert_equal({"deleted" => true}, call(data))
|
25
|
+
data = {"deleted" => "false"}
|
26
|
+
assert_equal({"deleted" => false}, call(data))
|
27
|
+
end
|
28
|
+
|
29
|
+
it "skips invalid values for boolean param" do
|
30
|
+
data = {"deleted" => "foo"}
|
31
|
+
assert_equal({}, call(data))
|
32
|
+
end
|
33
|
+
|
34
|
+
it "coerces valid values for integer param" do
|
35
|
+
data = {"per_page" => "3"}
|
36
|
+
assert_equal({"per_page" => 3}, call(data))
|
37
|
+
end
|
38
|
+
|
39
|
+
it "skips invalid values for integer param" do
|
40
|
+
data = {"per_page" => "3.5"}
|
41
|
+
assert_equal({}, call(data))
|
42
|
+
data = {"per_page" => "false"}
|
43
|
+
assert_equal({}, call(data))
|
44
|
+
data = {"per_page" => ""}
|
45
|
+
assert_equal({}, call(data))
|
46
|
+
end
|
47
|
+
|
48
|
+
it "coerces valid values for number param" do
|
49
|
+
data = {"threshold" => "3"}
|
50
|
+
assert_equal({"threshold" => 3.0}, call(data))
|
51
|
+
data = {"threshold" => "3.5"}
|
52
|
+
assert_equal({"threshold" => 3.5}, call(data))
|
53
|
+
end
|
54
|
+
|
55
|
+
it "skips invalid values for number param" do
|
56
|
+
data = {"threshold" => "false"}
|
57
|
+
assert_equal({}, call(data))
|
58
|
+
end
|
59
|
+
|
60
|
+
it "coerces valid values for null param" do
|
61
|
+
data = {"threshold" => ""}
|
62
|
+
assert_equal({"threshold" => nil}, call(data))
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def call(data)
|
68
|
+
Committee::QueryParamsCoercer.new(data, @link.schema).call
|
69
|
+
end
|
70
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: committee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandur
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-09-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json_schema
|
@@ -117,6 +117,7 @@ files:
|
|
117
117
|
- lib/committee/middleware/request_validation.rb
|
118
118
|
- lib/committee/middleware/response_validation.rb
|
119
119
|
- lib/committee/middleware/stub.rb
|
120
|
+
- lib/committee/query_params_coercer.rb
|
120
121
|
- lib/committee/request_unpacker.rb
|
121
122
|
- lib/committee/request_validator.rb
|
122
123
|
- lib/committee/response_generator.rb
|
@@ -128,6 +129,7 @@ files:
|
|
128
129
|
- test/middleware/request_validation_test.rb
|
129
130
|
- test/middleware/response_validation_test.rb
|
130
131
|
- test/middleware/stub_test.rb
|
132
|
+
- test/query_params_coercer_test.rb
|
131
133
|
- test/request_unpacker_test.rb
|
132
134
|
- test/request_validator_test.rb
|
133
135
|
- test/response_generator_test.rb
|