Restrict allow_charges attribute to read-only

We want people to use the UI to change this attribute.
This commit is contained in:
Maikel Linke
2022-03-03 12:20:45 +11:00
parent 3baed683b1
commit 41746459fa
7 changed files with 102 additions and 13 deletions

View File

@@ -7,6 +7,7 @@ module Api
include RequestTimeouts
include Pagy::Backend
include JsonApiPagination
include RaisingParameters
check_authorization
@@ -18,6 +19,7 @@ module Api
rescue_from CanCan::AccessDenied, with: :unauthorized
rescue_from ActiveRecord::RecordNotFound, with: :not_found
rescue_from Pagy::VariableError, with: :invalid_pagination
rescue_from ActionController::UnpermittedParameters, with: :unpermitted_parameters
private
@@ -60,6 +62,13 @@ module Api
json: json_api_error(exception.message)
end
def unpermitted_parameters(error)
message = I18n.t(:unpermitted_parameters, params: error.params.join(", "), scope: :api)
render status: :unprocessable_entity,
json: json_api_error(message)
end
def invalid_resource!(resource = nil)
render status: :unprocessable_entity,
json: json_api_invalid(

View File

@@ -0,0 +1,23 @@
# frozen_string_literal: true
# The API uses strict parameter checking.
#
# We want to raise errors when unused or unpermitted parameters are given
# to the API. You then know straight away when a parameter isn't used.
module RaisingParameters
extend ActiveSupport::Concern
# ActionController manages this config on a per-class basis. The subclass
# enables us to raise errors only here and not in the rest of the app.
class Parameters < ActionController::Parameters
def self.action_on_unpermitted_parameters
:raise
end
end
# We override the params method so that we always use the strict parameters.
# We could rename this method if we need access to the orginal as well.
def params
Parameters.new(super.to_unsafe_hash)
end
end

View File

@@ -21,6 +21,13 @@ class CustomerSchema < JsonApiSchema
[:enterprise_id, :email]
end
def self.writable_attributes
attributes.except(
:id,
:allow_charges,
)
end
def self.relationships
[:enterprise]
end

View File

@@ -1412,6 +1412,7 @@ en:
unknown_error: "Something went wrong. Our team has been notified."
invalid_api_key: "Invalid API key (%{key}) specified."
unauthorized: "You are not authorized to perform that action."
unpermitted_parameters: "Parameters not allowed in this request: %{params}"
invalid_resource: "Invalid resource. Please fix errors and try again."
resource_not_found: "The resource you were looking for could not be found."
enterprise_logo:

View File

@@ -0,0 +1,40 @@
# frozen_string_literal: true
require 'spec_helper'
describe RaisingParameters do
describe "Parameters" do
let(:params) do
RaisingParameters::Parameters.new(
controller: "example",
action: "update",
data: {
id: "unique",
admin: true,
}
)
end
it "raises an error when a parameter is not permitted" do
expect {
params.require(:data).permit(:id)
}.to raise_error(
ActionController::UnpermittedParameters
)
end
it "raises no error when all parameters are permitted" do
expect {
params.require(:data).permit(:id, :admin)
}.to_not raise_error
end
it "doesn't change standard parameter objects" do
original_params = ActionController::Parameters.new(one: 1, two: 2)
expect {
original_params.permit(:one)
}.to_not raise_error
end
end
end

View File

@@ -101,7 +101,7 @@ describe "Customers", type: :request do
parameter name: :customer, in: :body, schema: {
type: :object,
properties: CustomerSchema.attributes.except(:id),
properties: CustomerSchema.writable_attributes,
required: CustomerSchema.required_attributes
}
@@ -114,7 +114,26 @@ describe "Customers", type: :request do
end
schema "$ref": "#/components/schemas/resources/customer"
run_test!
run_test! do
expect(json_response[:data][:attributes]).to include(
allow_charges: false
)
end
end
response "422", "Unpermitted parameter" do
param(:customer) do
{
email: "test@example.com",
enterprise_id: enterprise1.id.to_s,
allow_charges: true,
}
end
schema "$ref": "#/components/schemas/error_response"
run_test! do
expect(json_error_detail).to eq "Parameters not allowed in this request: allow_charges"
end
end
response "422", "Unprocessable entity" do
@@ -187,7 +206,7 @@ describe "Customers", type: :request do
parameter name: :customer, in: :body, schema: {
type: :object,
properties: CustomerSchema.attributes,
properties: CustomerSchema.writable_attributes,
required: CustomerSchema.required_attributes
}
@@ -195,7 +214,6 @@ describe "Customers", type: :request do
param(:id) { customer1.id }
param(:customer) do
{
id: customer1.id.to_s,
email: "test@example.com",
enterprise_id: enterprise1.id.to_s
}

View File

@@ -279,9 +279,6 @@ paths:
email:
type: string
example: alice@example.com
allow_charges:
type: boolean
example: false
required:
- enterprise_id
- email
@@ -344,9 +341,6 @@ paths:
schema:
type: object
properties:
id:
type: integer
example: 1
enterprise_id:
type: integer
example: 2
@@ -365,9 +359,6 @@ paths:
email:
type: string
example: alice@example.com
allow_charges:
type: boolean
example: false
required:
- enterprise_id
- email