From 78a25dfd54edeb83b13b294a737caf952f28bcd5 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 10 Feb 2020 07:24:11 -0800 Subject: [PATCH] Validate that API article params are a Hash (#5963) * Add check for article param being a Hash & spec * Remove unnecessary blank line * Move logic to private method and before_action call * Change check_if to validate * Use is_a? to type check * Fix type check for specs --- app/controllers/api/v0/articles_controller.rb | 9 +++++++++ spec/requests/api/v0/articles_spec.rb | 20 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/app/controllers/api/v0/articles_controller.rb b/app/controllers/api/v0/articles_controller.rb index 3fadb7f27..5ee930465 100644 --- a/app/controllers/api/v0/articles_controller.rb +++ b/app/controllers/api/v0/articles_controller.rb @@ -7,6 +7,8 @@ module Api before_action :authenticate!, only: :me before_action -> { doorkeeper_authorize! :public }, only: %w[index show], if: -> { doorkeeper_token } + before_action :validate_article_param_is_hash, only: %w[create update] + before_action :set_cache_control_headers, only: %i[index show] before_action :cors_preflight_check @@ -116,6 +118,13 @@ module Api @user.any_admin? end end + + def validate_article_param_is_hash + return if params.to_unsafe_h.dig(:article).is_a?(Hash) + + message = "article param must be a JSON object. You provided article as a #{params[:article].class.name}" + render json: { error: message, status: 422 }, status: :unprocessable_entity + end end end end diff --git a/spec/requests/api/v0/articles_spec.rb b/spec/requests/api/v0/articles_spec.rb index 724494793..410955453 100644 --- a/spec/requests/api/v0/articles_spec.rb +++ b/spec/requests/api/v0/articles_spec.rb @@ -474,6 +474,16 @@ RSpec.describe "Api::V0::Articles", type: :request do expect(response).to have_http_status(:unprocessable_entity) end + it "fails if params are not a Hash" do + # Not using the nifty post_article helper method because it expects a Hash + headers = { "api-key" => api_secret.secret, "content-type" => "application/json" } + string_params = "this_string_is_definitely_not_a_hash" + post api_articles_path, params: { article: string_params }.to_json, headers: headers + + expect(response).to have_http_status(:unprocessable_entity) + expect(response.parsed_body["error"]).to be_present + end + it "creates an article belonging to the user" do post_article(title: Faker::Book.title) expect(response).to have_http_status(:created) @@ -941,6 +951,16 @@ RSpec.describe "Api::V0::Articles", type: :request do expect(response).to have_http_status(:ok) expect(article.reload.organization).to eq(organization) end + + it "fails if params are not a Hash" do + # Not using the nifty put_article helper method because it expects a Hash + headers = { "api-key" => api_secret.secret, "content-type" => "application/json" } + string_params = "this_string_is_definitely_not_a_hash" + put path, params: { article: string_params }.to_json, headers: headers + + expect(response).to have_http_status(:unprocessable_entity) + expect(response.parsed_body["error"]).to be_present + end end end end