Skip to content

Commit 36b6342

Browse files
committed
Check content types before processing API endpoint
Now that we are only checking the path before wrapping exceptions we still need to verify that the endpoint supports the JSON API spec. We do this via mime type negotiation when processing the request. If we do not have a valid type then we raise the customary Rails `UnknownFormat` exception.
1 parent 9c58e6e commit 36b6342

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

lib/kracken/controllers/json_api_compatible.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,18 @@ def verify_required_params!
102102
"Single beacon object provided but multiple resources requested"
103103
end
104104
end
105+
106+
# Negotiate the mime type for the request format
107+
#
108+
# This will modify the request object setting the format.
109+
def negotiate_mime
110+
return if request.negotiate_mime(ALLOWED_MEDIA_TYPES)
111+
raise ::ActionController::UnknownFormat
112+
end
113+
114+
private
115+
116+
ALLOWED_MEDIA_TYPES = [Mime[:json]].freeze
105117
end
106118
include DataIntegrity
107119

@@ -125,6 +137,7 @@ def self.included(base)
125137
base.instance_exec do
126138
extend Macros
127139

140+
before_action :negotiate_mime
128141
before_action :munge_chained_param_ids!
129142
skip_before_action :verify_authenticity_token, raise: false
130143

spec/requests/api_spec.rb

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,53 @@ module Kracken
44
RSpec.describe 'token authenticatable resource requests', type: :request do
55

66
def headers_with_token(token)
7-
{ 'HTTP_AUTHORIZATION'=>"Token token=\"#{token}\"" }
7+
{
8+
'HTTP_AUTHORIZATION'=>"Token token=\"#{token}\"",
9+
'HTTP_ACCEPT' => 'application/json',
10+
}
11+
end
12+
13+
# Temporary work around while we support versions of Rails before 4
14+
if Rails::VERSION::MAJOR >= 5
15+
def request_resource(path, params: {}, headers: {})
16+
get api_index_path, params: params, headers: headers
17+
end
18+
else
19+
def request_resource(path, params: {}, headers: {})
20+
get api_index_path, params, headers
21+
end
822
end
923

1024
let(:json){ Fixtures.auth_hash.to_json }
1125

12-
describe "authenticatable resource", type: :request do
26+
describe "authenticatable resource" do
1327
it "will raise error if there is no token" do
14-
expect{get api_index_path}.to raise_error Kracken::TokenUnauthorized
28+
expect {
29+
request_resource api_index_path
30+
}.to raise_error Kracken::TokenUnauthorized
1531
end
1632

1733
it "is redirected to the oauth server if there is no current user" do
1834
stub_request(:get, "https://account.radiusnetworks.com/auth/radius/user.json?oauth_token=123")
1935
.to_return(status: 200, body: json)
2036

21-
# Temporary work around while we support versions of Rails before 4
22-
if Rails::VERSION::MAJOR >= 5
23-
get api_index_path, params: {}, headers: headers_with_token("123")
24-
else
25-
get api_index_path, {}, headers_with_token("123")
26-
end
37+
request_resource api_index_path, headers: headers_with_token("123")
2738

2839
expect(response.status).to be 200
2940
end
3041
end
42+
43+
describe "content negotiation" do
44+
it "will raise an error with an incorrect accept header" do
45+
stub_request(:get, "https://account.radiusnetworks.com/auth/radius/user.json?oauth_token=123")
46+
.to_return(status: 200, body: json)
47+
48+
auth_headers = headers_with_token("123")
49+
auth_headers.delete 'HTTP_ACCEPT'
50+
expect {
51+
request_resource api_index_path, headers: auth_headers
52+
}.to raise_error ActionController::UnknownFormat
53+
end
54+
end
3155
end
3256
end

0 commit comments

Comments
 (0)