committee 1.14.1 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
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
|