committee 1.7.3 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/committee/middleware/request_validation.rb +2 -1
- data/lib/committee/request_unpacker.rb +5 -1
- data/lib/committee/request_validator.rb +10 -4
- data/lib/committee/response_validator.rb +2 -2
- data/test/middleware/request_validation_test.rb +10 -0
- data/test/request_unpacker_test.rb +10 -0
- data/test/request_validator_test.rb +16 -2
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 173ee1ad63a2f3bbd80eb012363b1825186ccf0c
|
4
|
+
data.tar.gz: aada311d9d39946ba34e456cf63d3505ff22558d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7d52505a1d958dfd6181834f790a5567a1d6b1f13a8e81f56b4bd7ae60aa83030bb1af920a2ed6cc090fc235f3bd5d683619af072bd94e89be6094486852edf
|
7
|
+
data.tar.gz: 67952f61e059649f6a55d06d92d39e49ec4476f4ffa40ec0e9f0b27c0cb74115c3666268f4927b73f75fac200cbd753cb8d653ba4d238ec712d370ce79320bff
|
@@ -4,6 +4,7 @@ module Committee::Middleware
|
|
4
4
|
super
|
5
5
|
@allow_form_params = options.fetch(:allow_form_params, true)
|
6
6
|
@allow_query_params = options.fetch(:allow_query_params, true)
|
7
|
+
@check_content_type = options.fetch(:check_content_type, true)
|
7
8
|
@optimistic_json = options.fetch(:optimistic_json, false)
|
8
9
|
@raise = options[:raise]
|
9
10
|
@strict = options[:strict]
|
@@ -21,7 +22,7 @@ module Committee::Middleware
|
|
21
22
|
).call
|
22
23
|
|
23
24
|
if link = @router.find_request_link(request)
|
24
|
-
validator = Committee::RequestValidator.new(link)
|
25
|
+
validator = Committee::RequestValidator.new(link, check_content_type: @check_content_type)
|
25
26
|
validator.call(request, request.env[@params_key])
|
26
27
|
@app.call(request.env)
|
27
28
|
elsif @strict
|
@@ -14,7 +14,11 @@ module Committee
|
|
14
14
|
params = if !@request.media_type || @request.media_type =~ %r{application/.*json}
|
15
15
|
parse_json
|
16
16
|
elsif @optimistic_json
|
17
|
-
|
17
|
+
begin
|
18
|
+
parse_json
|
19
|
+
rescue MultiJson::LoadError
|
20
|
+
nil
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
params = if params
|
@@ -2,10 +2,11 @@ module Committee
|
|
2
2
|
class RequestValidator
|
3
3
|
def initialize(link, options = {})
|
4
4
|
@link = link
|
5
|
+
@check_content_type = options.fetch(:check_content_type, true)
|
5
6
|
end
|
6
7
|
|
7
8
|
def call(request, data)
|
8
|
-
check_content_type!(request, data)
|
9
|
+
check_content_type!(request, data) if @check_content_type
|
9
10
|
if @link.schema
|
10
11
|
valid, errors = @link.schema.validate(data)
|
11
12
|
if !valid
|
@@ -17,9 +18,14 @@ module Committee
|
|
17
18
|
|
18
19
|
private
|
19
20
|
|
21
|
+
def request_media_type(request)
|
22
|
+
request.content_type.to_s.split(";").first.to_s
|
23
|
+
end
|
24
|
+
|
20
25
|
def check_content_type!(request, data)
|
21
|
-
|
22
|
-
|
26
|
+
content_type = request_media_type(request)
|
27
|
+
if content_type && !empty_request?(request)
|
28
|
+
unless Rack::Mime.match?(content_type, @link.enc_type)
|
23
29
|
raise Committee::InvalidRequest,
|
24
30
|
%{"Content-Type" request header must be set to "#{@link.enc_type}".}
|
25
31
|
end
|
@@ -28,7 +34,7 @@ module Committee
|
|
28
34
|
|
29
35
|
def empty_request?(request)
|
30
36
|
# small optimization: assume GET and DELETE don't have bodies
|
31
|
-
return true if request.get? || request.delete?
|
37
|
+
return true if request.get? || request.delete? || !request.body
|
32
38
|
|
33
39
|
data = request.body.read
|
34
40
|
request.body.rewind
|
@@ -45,9 +45,9 @@ module Committee
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def check_content_type!(response)
|
48
|
-
unless Rack::Mime.match?(response_media_type(response), @link.
|
48
|
+
unless Rack::Mime.match?(response_media_type(response), @link.media_type)
|
49
49
|
raise Committee::InvalidResponse,
|
50
|
-
%{"Content-Type" response header must be set to "#{@link.
|
50
|
+
%{"Content-Type" response header must be set to "#{@link.media_type}".}
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -84,6 +84,16 @@ describe Committee::Middleware::RequestValidation do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
+
it "optionally skip content_type check" do
|
88
|
+
@app = new_rack_app(check_content_type: false)
|
89
|
+
params = {
|
90
|
+
"name" => "cloudnasium"
|
91
|
+
}
|
92
|
+
header "Content-Type", "text/html"
|
93
|
+
post "/apps", MultiJson.encode(params)
|
94
|
+
assert_equal 200, last_response.status
|
95
|
+
end
|
96
|
+
|
87
97
|
private
|
88
98
|
|
89
99
|
def new_rack_app(options = {})
|
@@ -42,6 +42,16 @@ describe Committee::RequestUnpacker do
|
|
42
42
|
assert_equal({ "x" => "y" }, params)
|
43
43
|
end
|
44
44
|
|
45
|
+
it "returns {} when unpacking non-JSON with optimistic_json" do
|
46
|
+
env = {
|
47
|
+
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
|
48
|
+
"rack.input" => StringIO.new('x=y&foo=42'),
|
49
|
+
}
|
50
|
+
request = Rack::Request.new(env)
|
51
|
+
params = Committee::RequestUnpacker.new(request, optimistic_json: true).call
|
52
|
+
assert_equal({}, params)
|
53
|
+
end
|
54
|
+
|
45
55
|
it "unpacks an empty hash on an empty request body" do
|
46
56
|
env = {
|
47
57
|
"CONTENT_TYPE" => "application/json",
|
@@ -16,6 +16,11 @@ describe Committee::RequestValidator do
|
|
16
16
|
})
|
17
17
|
end
|
18
18
|
|
19
|
+
it "passes through a valid request with Content-Type options" do
|
20
|
+
@headers = { "Content-Type" => "application/json; charset=utf-8" }
|
21
|
+
call({})
|
22
|
+
end
|
23
|
+
|
19
24
|
it "passes through a valid request" do
|
20
25
|
data = {
|
21
26
|
"name" => "heroku-api",
|
@@ -49,6 +54,15 @@ describe Committee::RequestValidator do
|
|
49
54
|
assert_equal message, e.message
|
50
55
|
end
|
51
56
|
|
57
|
+
it "allows skipping content_type check" do
|
58
|
+
@request =
|
59
|
+
Rack::Request.new({
|
60
|
+
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
|
61
|
+
"rack.input" => StringIO.new("{}"),
|
62
|
+
})
|
63
|
+
call({}, check_content_type: false)
|
64
|
+
end
|
65
|
+
|
52
66
|
it "detects an missing parameter in GET requests" do
|
53
67
|
# GET /apps/search?query=...
|
54
68
|
@link = @link = @schema.properties["app"].links[5]
|
@@ -83,7 +97,7 @@ describe Committee::RequestValidator do
|
|
83
97
|
|
84
98
|
private
|
85
99
|
|
86
|
-
def call(data)
|
87
|
-
Committee::RequestValidator.new(@link).call(@request, data)
|
100
|
+
def call(data, options={})
|
101
|
+
Committee::RequestValidator.new(@link, options).call(@request, data)
|
88
102
|
end
|
89
103
|
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.8.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: 2015-
|
12
|
+
date: 2015-07-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json_schema
|
@@ -161,9 +161,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
161
|
version: '0'
|
162
162
|
requirements: []
|
163
163
|
rubyforge_project:
|
164
|
-
rubygems_version: 2.
|
164
|
+
rubygems_version: 2.4.5
|
165
165
|
signing_key:
|
166
166
|
specification_version: 4
|
167
167
|
summary: A collection of Rack middleware to support JSON Schema.
|
168
168
|
test_files: []
|
169
|
-
has_rdoc:
|