Skip to content
This repository has been archived by the owner on Jan 7, 2018. It is now read-only.

Commit

Permalink
Ensure that the error data yaml entered is the expected type (hash).
Browse files Browse the repository at this point in the history
This ensures that the error data isn't an unexpected type at the root
like a string: NREL/api-umbrella#153
  • Loading branch information
GUI committed Jun 15, 2015
1 parent 649f1b0 commit 5c94c91
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
16 changes: 16 additions & 0 deletions app/models/api/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Api::Settings
validates :authenticated_rate_limit_behavior,
:inclusion => { :in => %w(all api_key_only), :allow_blank => true }
validate :validate_error_data_yaml_strings
validate :validate_error_data

# Nested attributes
accepts_nested_attributes_for :headers, :rate_limits, :default_response_headers, :override_response_headers, :allow_destroy => true
Expand Down Expand Up @@ -214,4 +215,19 @@ def validate_error_data_yaml_strings
end
end
end

def validate_error_data
if(self.error_data.present?)
unless(self.error_data.kind_of?(Hash))
self.errors.add("error_data", "unexpected type (must be a hash)")
return false
end

self.error_data.each do |key, value|
unless(value.kind_of?(Hash))
self.errors.add("error_data.#{key}", "unexpected type (must be a hash)")
end
end
end
end
end
85 changes: 85 additions & 0 deletions spec/controllers/api/v1/apis_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,70 @@
end
end

shared_examples "api settings error data yaml strings" do |method, action|
it "returns validation error for invalid yaml" do
attributes = FactoryGirl.attributes_for(:api, {
:settings => FactoryGirl.attributes_for(:api_setting, {
:error_data_yaml_strings => {
:api_key_invalid => "foo: &",
:api_key_missing => "foo: bar\nhello: `world",
},
}),
})

admin_token_auth(@admin)
send(method, action, params.merge(:api => attributes))
response.status.should eql(422)
data = MultiJson.load(response.body)
data.keys.should eql(["errors"])
data["errors"].should eql({
"settings.error_data_yaml_strings.api_key_invalid" => ["YAML parsing error: (<unknown>): did not find expected alphabetic or numeric character while scanning an anchor at line 1 column 6"],
"settings.error_data_yaml_strings.api_key_missing" => ["YAML parsing error: (<unknown>): found character that cannot start any token while scanning for the next token at line 2 column 8"],
})
end

it "returns validation error for yaml that isn't a hash" do
attributes = FactoryGirl.attributes_for(:api, {
:settings => FactoryGirl.attributes_for(:api_setting, {
:error_data_yaml_strings => {
:api_key_invalid => "foo",
},
}),
})

admin_token_auth(@admin)
send(method, action, params.merge(:api => attributes))
response.status.should eql(422)
data = MultiJson.load(response.body)
data.keys.should eql(["errors"])
data["errors"].should eql({
"settings.error_data.api_key_invalid" => ["unexpected type (must be a hash)"],
})
end

it "accepts a yaml of hash data" do
attributes = FactoryGirl.attributes_for(:api, {
:settings => FactoryGirl.attributes_for(:api_setting, {
:error_data_yaml_strings => {
:api_key_invalid => "status_code: 422\nfoo: bar",
},
}),
})

admin_token_auth(@admin)
send(method, action, params.merge(:api => attributes))
response.status.should eql(if(action == :create) then 201 else 204 end)

api = Api.desc(:updated_at).first
api.settings.error_data.should eql({
"api_key_invalid" => {
"status_code" => 422,
"foo" => "bar",
},
})
end
end

describe "GET index" do
it "returns datatables output fields" do
admin_token_auth(@admin)
Expand Down Expand Up @@ -572,6 +636,12 @@
end

describe "POST create" do
let(:params) do
{
:format => "json",
}
end

describe "admin permissions" do
it "allows superuser admins to create any api" do
admin_token_auth(@admin)
Expand Down Expand Up @@ -868,6 +938,8 @@
it_behaves_like "api settings header fields - create", :override_response_headers
end

it_behaves_like "api settings error data yaml strings", :post, :create

describe "sort order" do
before(:each) do
Api.delete_all
Expand Down Expand Up @@ -971,6 +1043,17 @@
end

describe "PUT update" do
before(:each) do
@update_api = FactoryGirl.create(:api)
end

let(:params) do
{
:format => "json",
:id => @update_api.id,
}
end

describe "admin permissions" do
it "allows superuser admins to update any api" do
admin_token_auth(@admin)
Expand Down Expand Up @@ -1253,6 +1336,8 @@
describe "response override headers" do
it_behaves_like "api settings header fields - update", :override_response_headers
end

it_behaves_like "api settings error data yaml strings", :put, :update
end

describe "DELETE destroy" do
Expand Down

0 comments on commit 5c94c91

Please sign in to comment.